From 7eb4ce789a3c8b4e5f5fc8499ac56fc0419bcb6c Mon Sep 17 00:00:00 2001 From: Yui Date: Sat, 18 Jul 2026 11:17:04 +0800 Subject: [PATCH 01/30] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=95=BF=E6=96=87?= =?UTF-8?q?=E6=B2=89=E6=B5=B8=E9=98=85=E8=AF=BB=E6=A0=B7=E5=BC=8F=E4=B8=8E?= =?UTF-8?q?=E7=89=88=E5=BC=8F=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 1 + src/main/resources/js/long-article.js | 237 +++++--- src/main/resources/js/long-article.min.js | 2 +- src/main/resources/js/m-long-article.js | 157 +++--- src/main/resources/js/m-long-article.min.js | 2 +- src/main/resources/scss/index.scss | 525 ++++++++++++------ src/main/resources/scss/mobile-base.scss | 328 ++++++++--- .../skins/classic/mobile/article.ftl | 67 +-- .../resources/skins/classic/pc/article.ftl | 54 +- 9 files changed, 933 insertions(+), 440 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index e7af6bde..702198ef 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -103,6 +103,7 @@ - 首页两列对齐约束:`getIndexRecentArticles` 的第一页会插入全部置顶且不截断;第二页起需按第一页“置顶占位数”补偿 `fetchSize` 与分页偏移,并基于已排除置顶 ID 的普通文章序列取数,保证两列等高、不重复、不丢中间文章。 - 首页右侧排行补偿(无前端延迟):由 `IndexProcessor#loadIndexData` 按两列最新文章的最大行数计算 `rankCompensateRows`,先换算“右栏总补偿行数”再分摊到 `checkinVisibleCount/onlineVisibleCount`,Freemarker 直接按该数量渲染,不再依赖 JS 运行时增删行。 - 专栏封面链路:封面字段是 `long_article_column.columnCoverURL`;默认封面在 `LongArticleColumnQueryService` 填充;作者管理页为 `/column/manage`,编辑长篇页的弹窗脚本是 `long-article-cover-dialog.js`,新建长篇封面随 `/article` 请求的 `columnCoverURL` 写入;封面保存接口为 `POST /api/columns/{columnId}/cover`,处理器是 `LongArticleColumnProcessor`。 +- 长文阅读页以 `articleType=6` 区分,PC/移动模板均为 `skins/classic/*/article.ftl`,样式在 `index.scss`/`mobile-base.scss`,交互在 `long-article.js`/`m-long-article.js`;桌面宽度和两端字号统一保存在 `localStorage.longArticleSettings`,宽度仅在 PC 生效。 - 管理员文章页编辑长文专栏时,`admin/article.ftl` 会随文章表单提交 `columnCoverURL`,后端在 `ArticleMgmtService` 的文章事务内复用 `ColumnCoverMgmtService` 校验并更新或清空专栏封面。 - 路由总入口:`Router#requestMapping` + 各 Processor `register()`;新增路由先决定使用 `loginCheck` / `apiCheck` / `permission` / `anonymousViewCheck` 哪条链路。 - Latke 路由存在静态段被相邻动态段截获的风险(如 `/article/{id}/revisions/list` 可能进入 `/article/{id}/revisions/{revisionId}`);新增相邻路由时需避免路径歧义,或在处理方法中显式识别保留字。 diff --git a/src/main/resources/js/long-article.js b/src/main/resources/js/long-article.js index fc306a70..d607760d 100644 --- a/src/main/resources/js/long-article.js +++ b/src/main/resources/js/long-article.js @@ -7,139 +7,200 @@ * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . */ /** * Long article reading page functionality. */ window.LongArticle = { + storageKey: 'longArticleSettings', + allowedWidths: ['auto', '600', '800', '1000', '1200'], settings: { - theme: 'light', - fontSize: 18, - width: 900 + width: '800', + desktopFontSize: 18, + mobileFontSize: 16 }, - init: function() { + init: function () { + if (this.initialized) { + return; + } + this.initialized = true; this.loadSettings(); this.bindEvents(); this.applySettings(); }, - loadSettings: function() { - var saved = localStorage.getItem('longArticleSettings'); - if (saved) { - try { - this.settings = JSON.parse(saved); - } catch (e) { - console.error('Failed to parse settings', e); + loadSettings: function () { + var settings = { + width: '800', + desktopFontSize: 18, + mobileFontSize: 16 + }; + var saved; + + try { + saved = JSON.parse(window.localStorage.getItem(this.storageKey) || '{}'); + } catch (e) { + saved = {}; + } + + if (saved && typeof saved === 'object') { + settings.width = this.normalizeWidth(saved.width); + settings.desktopFontSize = this.normalizeFontSize(saved.desktopFontSize || saved.fontSize, 18, 32, 18); + settings.mobileFontSize = this.normalizeFontSize(saved.mobileFontSize, 16, 24, 16); + } + + try { + var legacyFontSize = parseInt(window.localStorage.getItem('longArticleFontSize'), 10); + if (!saved.desktopFontSize && !saved.fontSize && !isNaN(legacyFontSize)) { + settings.desktopFontSize = this.normalizeFontSize(legacyFontSize, 18, 32, 18); + settings.mobileFontSize = this.normalizeFontSize(legacyFontSize, 16, 24, 16); + } + var mobileSettings = JSON.parse(window.localStorage.getItem('mLongArticleSettings') || '{}'); + if (!saved.mobileFontSize && mobileSettings && !isNaN(parseInt(mobileSettings.fontSize, 10))) { + settings.mobileFontSize = this.normalizeFontSize(parseInt(mobileSettings.fontSize, 10), 16, 24, 16); } + window.localStorage.removeItem('longArticleFontSize'); + window.localStorage.removeItem('mLongArticleSettings'); + } catch (e) { + // Ignore unavailable or malformed legacy storage. } - }, - saveSettings: function() { - localStorage.setItem('longArticleSettings', JSON.stringify(this.settings)); + this.settings = settings; + this.saveSettings(); }, - applySettings: function() { - var body = document.body; - var container = document.querySelector('.long-article-container'); - var content = document.querySelector('.long-article-content'); + normalizeWidth: function (width) { + width = String(width || '800'); + return this.allowedWidths.indexOf(width) >= 0 ? width : '800'; + }, - // Theme - if (this.settings.theme === 'night') { - body.classList.add('night'); - } else { - body.classList.remove('night'); + normalizeFontSize: function (size, min, max, fallback) { + size = parseInt(size, 10); + if (isNaN(size)) { + return fallback; } + return Math.max(min, Math.min(max, size)); + }, - // Font size - if (content) { - content.style.fontSize = this.settings.fontSize + 'px'; + saveSettings: function () { + try { + window.localStorage.setItem(this.storageKey, JSON.stringify(this.settings)); + } catch (e) { + // Ignore unavailable storage. } - document.getElementById('fontSizeValue').textContent = this.settings.fontSize + 'px'; + }, - // Width - if (container) { - container.style.width = this.settings.width + 'px'; - } - document.documentElement.style.setProperty('--la-content-width', this.settings.width + 'px'); + applySettings: function () { + var root = document.documentElement; + var width = this.settings.width; + var halfWidth = width === 'auto' ? 'min(40vw, 600px)' : (parseInt(width, 10) / 2) + 'px'; + + root.style.setProperty('--long-article-width', width === 'auto' ? 'min(80vw, 1200px)' : width + 'px'); + root.style.setProperty('--long-article-half-width', halfWidth); + root.style.setProperty('--long-article-font-size', this.settings.desktopFontSize + 'px'); + this.updateWidthButtons(); }, - bindEvents: function() { + bindEvents: function () { var self = this; + var toolbar = document.querySelector('[data-long-article-toolbar]'); + if (!toolbar) { + return; + } + + toolbar.addEventListener('click', function (event) { + var actionElement = self.findActionElement(event.target, toolbar); + if (!actionElement) { + return; + } + var action = actionElement.getAttribute('data-long-article-action'); + if (action === 'top') { + self.scrollToTop(); + } else if (action === 'comments') { + self.scrollToComments(); + } else if (action === 'font-decrease') { + self.setFontSize(-2); + } else if (action === 'font-increase') { + self.setFontSize(2); + } else if (action === 'layout') { + self.toggleLayoutPanel(); + } else if (actionElement.hasAttribute('data-long-article-width')) { + self.setWidth(actionElement.getAttribute('data-long-article-width')); + } + }); - // Close settings panel when clicking outside - document.addEventListener('click', function(e) { - var panel = document.getElementById('settingsPanel'); - var toggle = document.querySelector('.sidebar-item[onclick*="openSettings"]'); - if (panel && panel.classList.contains('active')) { - if (!panel.contains(e.target) && (!toggle || !toggle.contains(e.target))) { - panel.classList.remove('active'); - } + document.addEventListener('click', function (event) { + var panel = document.getElementById('longArticleLayoutPanel'); + var layoutButton = toolbar.querySelector('[data-long-article-action="layout"]'); + if (panel && panel.classList.contains('is-open') && !panel.contains(event.target) && !layoutButton.contains(event.target)) { + self.closeLayoutPanel(); } }); }, - openSettings: function() { - var panel = document.getElementById('settingsPanel'); - if (panel) { - panel.classList.toggle('active'); + findActionElement: function (target, boundary) { + while (target && target !== boundary) { + if (target.nodeType === 1 && (target.hasAttribute('data-long-article-action') || target.hasAttribute('data-long-article-width'))) { + return target; + } + target = target.parentNode; } + return target && target !== boundary && target.nodeType === 1 ? target : null; }, - setTheme: function(theme) { - this.settings.theme = theme; + setFontSize: function (delta) { + this.settings.desktopFontSize = this.normalizeFontSize(this.settings.desktopFontSize + delta, 12, 32, 18); this.saveSettings(); this.applySettings(); - - // Update active state - var lightBtn = document.querySelector('.theme-btn.light'); - var nightBtn = document.querySelector('.theme-btn.night'); - if (lightBtn) lightBtn.classList.toggle('active', theme === 'light'); - if (nightBtn) nightBtn.classList.toggle('active', theme === 'night'); - }, - - setFontSize: function(delta) { - var newSize = this.settings.fontSize + delta; - if (newSize >= 12 && newSize <= 32) { - this.settings.fontSize = newSize; - this.saveSettings(); - this.applySettings(); - } }, - setWidth: function(width) { - this.settings.width = width; + setWidth: function (width) { + this.settings.width = this.normalizeWidth(width); this.saveSettings(); this.applySettings(); + this.closeLayoutPanel(); + }, - // Update active state - var widthBtns = document.querySelectorAll('.width-btn'); - widthBtns.forEach(function(btn) { - var btnWidth = btn.getAttribute('onclick').match(/\d+/); - if (btnWidth && parseInt(btnWidth[0]) === width) { - btn.classList.add('active'); - } else { - btn.classList.remove('active'); - } + updateWidthButtons: function () { + var width = this.settings.width; + document.querySelectorAll('[data-long-article-width]').forEach(function (button) { + button.classList.toggle('is-active', button.getAttribute('data-long-article-width') === width); }); }, - toggleNight: function() { - this.setTheme(this.settings.theme === 'night' ? 'light' : 'night'); + toggleLayoutPanel: function () { + var panel = document.getElementById('longArticleLayoutPanel'); + var button = document.querySelector('[data-long-article-action="layout"]'); + if (!panel || !button) { + return; + } + var open = !panel.classList.contains('is-open'); + panel.classList.toggle('is-open', open); + panel.setAttribute('aria-hidden', open ? 'false' : 'true'); + button.setAttribute('aria-expanded', open ? 'true' : 'false'); }, - scrollToTop: function() { - window.scrollTo({ - top: 0, - behavior: 'smooth' - }); + closeLayoutPanel: function () { + var panel = document.getElementById('longArticleLayoutPanel'); + var button = document.querySelector('[data-long-article-action="layout"]'); + if (panel) { + panel.classList.remove('is-open'); + panel.setAttribute('aria-hidden', 'true'); + } + if (button) { + button.setAttribute('aria-expanded', 'false'); + } + }, + + scrollToTop: function () { + window.scrollTo({top: 0, behavior: 'smooth'}); + }, + + scrollToComments: function () { + var comments = document.getElementById('comments'); + if (comments) { + comments.scrollIntoView({behavior: 'smooth'}); + } } }; diff --git a/src/main/resources/js/long-article.min.js b/src/main/resources/js/long-article.min.js index c3cd0a91..f7a49618 100644 --- a/src/main/resources/js/long-article.min.js +++ b/src/main/resources/js/long-article.min.js @@ -1 +1 @@ -window.LongArticle={settings:{theme:"light",fontSize:18,width:900},init:function(){this.loadSettings(),this.bindEvents(),this.applySettings()},loadSettings:function(){var t=localStorage.getItem("longArticleSettings");if(t)try{this.settings=JSON.parse(t)}catch(t){console.error("Failed to parse settings",t)}},saveSettings:function(){localStorage.setItem("longArticleSettings",JSON.stringify(this.settings))},applySettings:function(){var t=document.body,e=document.querySelector(".long-article-container"),i=document.querySelector(".long-article-content");"night"===this.settings.theme?t.classList.add("night"):t.classList.remove("night"),i&&(i.style.fontSize=this.settings.fontSize+"px"),document.getElementById("fontSizeValue").textContent=this.settings.fontSize+"px",e&&(e.style.width=this.settings.width+"px"),document.documentElement.style.setProperty("--la-content-width",this.settings.width+"px")},bindEvents:function(){document.addEventListener("click",function(t){var e=document.getElementById("settingsPanel"),i=document.querySelector('.sidebar-item[onclick*="openSettings"]');e&&e.classList.contains("active")&&(e.contains(t.target)||i&&i.contains(t.target)||e.classList.remove("active"))})},openSettings:function(){var t=document.getElementById("settingsPanel");t&&t.classList.toggle("active")},setTheme:function(t){this.settings.theme=t,this.saveSettings(),this.applySettings();var e=document.querySelector(".theme-btn.light"),i=document.querySelector(".theme-btn.night");e&&e.classList.toggle("active","light"===t),i&&i.classList.toggle("active","night"===t)},setFontSize:function(t){var e=this.settings.fontSize+t;e>=12&&e<=32&&(this.settings.fontSize=e,this.saveSettings(),this.applySettings())},setWidth:function(t){this.settings.width=t,this.saveSettings(),this.applySettings(),document.querySelectorAll(".width-btn").forEach(function(e){var i=e.getAttribute("onclick").match(/\d+/);i&&parseInt(i[0])===t?e.classList.add("active"):e.classList.remove("active")})},toggleNight:function(){this.setTheme("night"===this.settings.theme?"light":"night")},scrollToTop:function(){window.scrollTo({top:0,behavior:"smooth"})}}; \ No newline at end of file +window.LongArticle={storageKey:"longArticleSettings",allowedWidths:["auto","600","800","1000","1200"],settings:{width:"800",desktopFontSize:18,mobileFontSize:16},init:function(){this.initialized||(this.initialized=!0,this.loadSettings(),this.bindEvents(),this.applySettings())},loadSettings:function(){var t,e={width:"800",desktopFontSize:18,mobileFontSize:16};try{t=JSON.parse(window.localStorage.getItem(this.storageKey)||"{}")}catch(e){t={}}t&&"object"==typeof t&&(e.width=this.normalizeWidth(t.width),e.desktopFontSize=this.normalizeFontSize(t.desktopFontSize||t.fontSize,18,32,18),e.mobileFontSize=this.normalizeFontSize(t.mobileFontSize,16,24,16));try{var i=parseInt(window.localStorage.getItem("longArticleFontSize"),10);t.desktopFontSize||t.fontSize||isNaN(i)||(e.desktopFontSize=this.normalizeFontSize(i,18,32,18),e.mobileFontSize=this.normalizeFontSize(i,16,24,16));var o=JSON.parse(window.localStorage.getItem("mLongArticleSettings")||"{}");t.mobileFontSize||!o||isNaN(parseInt(o.fontSize,10))||(e.mobileFontSize=this.normalizeFontSize(parseInt(o.fontSize,10),16,24,16)),window.localStorage.removeItem("longArticleFontSize"),window.localStorage.removeItem("mLongArticleSettings")}catch(t){}this.settings=e,this.saveSettings()},normalizeWidth:function(t){return t=String(t||"800"),this.allowedWidths.indexOf(t)>=0?t:"800"},normalizeFontSize:function(t,e,i,o){return t=parseInt(t,10),isNaN(t)?o:Math.max(e,Math.min(i,t))},saveSettings:function(){try{window.localStorage.setItem(this.storageKey,JSON.stringify(this.settings))}catch(t){}},applySettings:function(){var t=document.documentElement,e=this.settings.width,i="auto"===e?"min(40vw, 600px)":parseInt(e,10)/2+"px";t.style.setProperty("--long-article-width","auto"===e?"min(80vw, 1200px)":e+"px"),t.style.setProperty("--long-article-half-width",i),t.style.setProperty("--long-article-font-size",this.settings.desktopFontSize+"px"),this.updateWidthButtons()},bindEvents:function(){var t=this,e=document.querySelector("[data-long-article-toolbar]");e&&(e.addEventListener("click",function(i){var o=t.findActionElement(i.target,e);if(o){var n=o.getAttribute("data-long-article-action");"top"===n?t.scrollToTop():"comments"===n?t.scrollToComments():"font-decrease"===n?t.setFontSize(-2):"font-increase"===n?t.setFontSize(2):"layout"===n?t.toggleLayoutPanel():o.hasAttribute("data-long-article-width")&&t.setWidth(o.getAttribute("data-long-article-width"))}}),document.addEventListener("click",function(i){var o=document.getElementById("longArticleLayoutPanel"),n=e.querySelector('[data-long-article-action="layout"]');o&&o.classList.contains("is-open")&&!o.contains(i.target)&&!n.contains(i.target)&&t.closeLayoutPanel()}))},findActionElement:function(t,e){for(;t&&t!==e;){if(1===t.nodeType&&(t.hasAttribute("data-long-article-action")||t.hasAttribute("data-long-article-width")))return t;t=t.parentNode}return t&&t!==e&&1===t.nodeType?t:null},setFontSize:function(t){this.settings.desktopFontSize=this.normalizeFontSize(this.settings.desktopFontSize+t,12,32,18),this.saveSettings(),this.applySettings()},setWidth:function(t){this.settings.width=this.normalizeWidth(t),this.saveSettings(),this.applySettings(),this.closeLayoutPanel()},updateWidthButtons:function(){var t=this.settings.width;document.querySelectorAll("[data-long-article-width]").forEach(function(e){e.classList.toggle("is-active",e.getAttribute("data-long-article-width")===t)})},toggleLayoutPanel:function(){var t=document.getElementById("longArticleLayoutPanel"),e=document.querySelector('[data-long-article-action="layout"]');if(t&&e){var i=!t.classList.contains("is-open");t.classList.toggle("is-open",i),t.setAttribute("aria-hidden",i?"false":"true"),e.setAttribute("aria-expanded",i?"true":"false")}},closeLayoutPanel:function(){var t=document.getElementById("longArticleLayoutPanel"),e=document.querySelector('[data-long-article-action="layout"]');t&&(t.classList.remove("is-open"),t.setAttribute("aria-hidden","true")),e&&e.setAttribute("aria-expanded","false")},scrollToTop:function(){window.scrollTo({top:0,behavior:"smooth"})},scrollToComments:function(){var t=document.getElementById("comments");t&&t.scrollIntoView({behavior:"smooth"})}}; \ No newline at end of file diff --git a/src/main/resources/js/m-long-article.js b/src/main/resources/js/m-long-article.js index 8df68581..fa41fea0 100644 --- a/src/main/resources/js/m-long-article.js +++ b/src/main/resources/js/m-long-article.js @@ -7,106 +7,123 @@ * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . */ /** * Mobile long article reading page functionality. */ window.MLongArticle = { + storageKey: 'longArticleSettings', settings: { - theme: 'light', - fontSize: 16 + width: '800', + desktopFontSize: 18, + mobileFontSize: 16 }, - init: function() { + init: function () { + if (this.initialized) { + return; + } + this.initialized = true; this.loadSettings(); this.bindEvents(); this.applySettings(); }, - loadSettings: function() { - var saved = localStorage.getItem('mLongArticleSettings'); - if (saved) { - try { - this.settings = JSON.parse(saved); - } catch (e) { - console.error('Failed to parse settings', e); + loadSettings: function () { + var settings = { + width: '800', + desktopFontSize: 18, + mobileFontSize: 16 + }; + var saved; + + try { + saved = JSON.parse(window.localStorage.getItem(this.storageKey) || '{}'); + } catch (e) { + saved = {}; + } + if (saved && typeof saved === 'object') { + settings.width = ['auto', '600', '800', '1000', '1200'].indexOf(String(saved.width || '800')) >= 0 ? String(saved.width || '800') : '800'; + settings.desktopFontSize = this.normalizeFontSize(saved.desktopFontSize || saved.fontSize, 18, 32, 18); + settings.mobileFontSize = this.normalizeFontSize(saved.mobileFontSize || saved.fontSize, 16, 24, 16); + } + + try { + var legacyFontSize = parseInt(window.localStorage.getItem('longArticleFontSize'), 10); + var oldSettings = JSON.parse(window.localStorage.getItem('mLongArticleSettings') || '{}'); + if (!saved.mobileFontSize && oldSettings && !isNaN(parseInt(oldSettings.fontSize, 10))) { + settings.mobileFontSize = this.normalizeFontSize(parseInt(oldSettings.fontSize, 10), 16, 24, 16); + } else if (!saved.mobileFontSize && !isNaN(legacyFontSize)) { + settings.mobileFontSize = this.normalizeFontSize(legacyFontSize, 16, 24, 16); } + window.localStorage.removeItem('longArticleFontSize'); + window.localStorage.removeItem('mLongArticleSettings'); + } catch (e) { + // Ignore unavailable or malformed legacy storage. } - }, - saveSettings: function() { - localStorage.setItem('mLongArticleSettings', JSON.stringify(this.settings)); + this.settings = settings; + this.saveSettings(); }, - applySettings: function() { - var body = document.body; - var content = document.querySelector('.m-long-article-content'); - - if (this.settings.theme === 'night') { - body.classList.add('night'); - } else { - body.classList.remove('night'); + normalizeFontSize: function (size, min, max, fallback) { + size = parseInt(size, 10); + if (isNaN(size)) { + return fallback; } + return Math.max(min, Math.min(max, size)); + }, - if (content) { - content.style.fontSize = this.settings.fontSize + 'px'; - } - var fontSizeEl = document.getElementById('mFontSizeValue'); - if (fontSizeEl) { - fontSizeEl.textContent = this.settings.fontSize + 'px'; + saveSettings: function () { + try { + window.localStorage.setItem(this.storageKey, JSON.stringify(this.settings)); + } catch (e) { + // Ignore unavailable storage. } }, - bindEvents: function() { - var self = this; + applySettings: function () { + document.documentElement.style.setProperty('--long-article-font-size', this.settings.mobileFontSize + 'px'); + }, - document.addEventListener('click', function(e) { - var panel = document.getElementById('mSettingsPanel'); - var toggle = document.querySelector('.m-action-btn[onclick*="openSettings"]'); - if (panel && panel.classList.contains('active')) { - if (!panel.contains(e.target) && (!toggle || !toggle.contains(e.target))) { - panel.classList.remove('active'); + bindEvents: function () { + var self = this; + var toolbar = document.querySelector('[data-long-article-toolbar]'); + if (!toolbar) { + return; + } + toolbar.addEventListener('click', function (event) { + var target = event.target; + while (target && target !== toolbar && !target.hasAttribute('data-long-article-action')) { + target = target.parentNode; + } + if (!target || target === toolbar) { + return; + } + var action = target.getAttribute('data-long-article-action'); + if (action === 'toggle') { + var open = !toolbar.classList.contains('is-open'); + toolbar.classList.toggle('is-open', open); + target.classList.toggle('active', open); + target.setAttribute('aria-expanded', open ? 'true' : 'false'); + } else if (action === 'top') { + window.scrollTo({top: 0, behavior: 'smooth'}); + } else if (action === 'comments') { + var comments = document.getElementById('comments'); + if (comments) { + comments.scrollIntoView({behavior: 'smooth'}); } + } else if (action === 'font-decrease') { + self.setFontSize(-2); + } else if (action === 'font-increase') { + self.setFontSize(2); } }); }, - openSettings: function() { - var panel = document.getElementById('mSettingsPanel'); - if (panel) { - panel.classList.toggle('active'); - } - }, - - setTheme: function(theme) { - this.settings.theme = theme; + setFontSize: function (delta) { + this.settings.mobileFontSize = this.normalizeFontSize(this.settings.mobileFontSize + delta, 12, 24, 16); this.saveSettings(); this.applySettings(); - - var lightBtn = document.querySelector('.m-theme-btn.light'); - var nightBtn = document.querySelector('.m-theme-btn.night'); - if (lightBtn) lightBtn.classList.toggle('active', theme === 'light'); - if (nightBtn) nightBtn.classList.toggle('active', theme === 'night'); - }, - - setFontSize: function(delta) { - var newSize = this.settings.fontSize + delta; - if (newSize >= 12 && newSize <= 24) { - this.settings.fontSize = newSize; - this.saveSettings(); - this.applySettings(); - } - }, - - toggleNight: function() { - this.setTheme(this.settings.theme === 'night' ? 'light' : 'night'); } }; diff --git a/src/main/resources/js/m-long-article.min.js b/src/main/resources/js/m-long-article.min.js index 9feb097f..3246c6fe 100644 --- a/src/main/resources/js/m-long-article.min.js +++ b/src/main/resources/js/m-long-article.min.js @@ -1 +1 @@ -window.MLongArticle={settings:{theme:"light",fontSize:16},init:function(){this.loadSettings(),this.bindEvents(),this.applySettings()},loadSettings:function(){var t=localStorage.getItem("mLongArticleSettings");if(t)try{this.settings=JSON.parse(t)}catch(t){console.error("Failed to parse settings",t)}},saveSettings:function(){localStorage.setItem("mLongArticleSettings",JSON.stringify(this.settings))},applySettings:function(){var t=document.body,e=document.querySelector(".m-long-article-content");"night"===this.settings.theme?t.classList.add("night"):t.classList.remove("night"),e&&(e.style.fontSize=this.settings.fontSize+"px");var n=document.getElementById("mFontSizeValue");n&&(n.textContent=this.settings.fontSize+"px")},bindEvents:function(){document.addEventListener("click",function(t){var e=document.getElementById("mSettingsPanel"),n=document.querySelector('.m-action-btn[onclick*="openSettings"]');e&&e.classList.contains("active")&&(e.contains(t.target)||n&&n.contains(t.target)||e.classList.remove("active"))})},openSettings:function(){var t=document.getElementById("mSettingsPanel");t&&t.classList.toggle("active")},setTheme:function(t){this.settings.theme=t,this.saveSettings(),this.applySettings();var e=document.querySelector(".m-theme-btn.light"),n=document.querySelector(".m-theme-btn.night");e&&e.classList.toggle("active","light"===t),n&&n.classList.toggle("active","night"===t)},setFontSize:function(t){var e=this.settings.fontSize+t;e>=12&&e<=24&&(this.settings.fontSize=e,this.saveSettings(),this.applySettings())},toggleNight:function(){this.setTheme("night"===this.settings.theme?"light":"night")}}; \ No newline at end of file +window.MLongArticle={storageKey:"longArticleSettings",settings:{width:"800",desktopFontSize:18,mobileFontSize:16},init:function(){this.initialized||(this.initialized=!0,this.loadSettings(),this.bindEvents(),this.applySettings())},loadSettings:function(){var t,e={width:"800",desktopFontSize:18,mobileFontSize:16};try{t=JSON.parse(window.localStorage.getItem(this.storageKey)||"{}")}catch(e){t={}}t&&"object"==typeof t&&(e.width=["auto","600","800","1000","1200"].indexOf(String(t.width||"800"))>=0?String(t.width||"800"):"800",e.desktopFontSize=this.normalizeFontSize(t.desktopFontSize||t.fontSize,18,32,18),e.mobileFontSize=this.normalizeFontSize(t.mobileFontSize||t.fontSize,16,24,16));try{var i=parseInt(window.localStorage.getItem("longArticleFontSize"),10),o=JSON.parse(window.localStorage.getItem("mLongArticleSettings")||"{}");t.mobileFontSize||!o||isNaN(parseInt(o.fontSize,10))?t.mobileFontSize||isNaN(i)||(e.mobileFontSize=this.normalizeFontSize(i,16,24,16)):e.mobileFontSize=this.normalizeFontSize(parseInt(o.fontSize,10),16,24,16),window.localStorage.removeItem("longArticleFontSize"),window.localStorage.removeItem("mLongArticleSettings")}catch(t){}this.settings=e,this.saveSettings()},normalizeFontSize:function(t,e,i,o){return t=parseInt(t,10),isNaN(t)?o:Math.max(e,Math.min(i,t))},saveSettings:function(){try{window.localStorage.setItem(this.storageKey,JSON.stringify(this.settings))}catch(t){}},applySettings:function(){document.documentElement.style.setProperty("--long-article-font-size",this.settings.mobileFontSize+"px")},bindEvents:function(){var t=this,e=document.querySelector("[data-long-article-toolbar]");e&&e.addEventListener("click",function(i){for(var o=i.target;o&&o!==e&&!o.hasAttribute("data-long-article-action");)o=o.parentNode;if(o&&o!==e){var n=o.getAttribute("data-long-article-action");if("toggle"===n){var s=!e.classList.contains("is-open");e.classList.toggle("is-open",s),o.classList.toggle("active",s),o.setAttribute("aria-expanded",s?"true":"false")}else if("top"===n)window.scrollTo({top:0,behavior:"smooth"});else if("comments"===n){var a=document.getElementById("comments");a&&a.scrollIntoView({behavior:"smooth"})}else"font-decrease"===n?t.setFontSize(-2):"font-increase"===n&&t.setFontSize(2)}})},setFontSize:function(t){this.settings.mobileFontSize=this.normalizeFontSize(this.settings.mobileFontSize+t,12,24,16),this.saveSettings(),this.applySettings()}}; \ No newline at end of file diff --git a/src/main/resources/scss/index.scss b/src/main/resources/scss/index.scss index 81adad5d..8551aae3 100644 --- a/src/main/resources/scss/index.scss +++ b/src/main/resources/scss/index.scss @@ -5101,30 +5101,184 @@ code .dec { /* start long-article */ .long-article-content { - max-width: 800px; - margin: 0 auto; - padding: 40px 60px; - font-size: 18px; - line-height: 1.8; + max-width: none; + margin: 36px 0 0; + padding: 0; + color: #25332a; + font-size: var(--long-article-font-size, 18px); + line-height: 1.9; + overflow-wrap: anywhere; + + > p { + margin: 1.15em 0; + text-indent: 2em; + } + + > p:has(> img), + > p:has(> picture), + > p:has(> video), + > p:has(> iframe) { + text-indent: 0; + } + + > h1, + > h2, + > h3, + > h4, + > h5, + > h6 { + margin: 1.8em 0 0.75em; + color: #1f2e24; + line-height: 1.45; + text-indent: 0; + } + + > ul, + > ol, + > blockquote, + > pre, + > table, + > figure { + margin-top: 1.35em; + margin-bottom: 1.35em; + text-indent: 0; + } + + blockquote { + padding: 14px 18px; + border-left: 4px solid #9bb4a0; + background: #f0f5ef; + color: #526259; + } + + img { + display: block; + max-width: 100%; + height: auto; + margin: 1.6em auto; + } + + table { + display: block; + max-width: 100%; + overflow-x: auto; + } + + pre { + border-radius: 8px; + } + + :not(pre) > code { + border-radius: 4px; + background: #edf2ec; + color: #35513d; + } } .long-article-meta { - text-align: right; - color: #888; - font-size: 13px; - margin-bottom: 15px; + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 6px 10px; + margin-top: 14px; + color: #718078; + font-size: 14px; + line-height: 1.6; + text-align: left; a { - color: #888; + color: #526c5a; text-decoration: none; &:hover { - color: #4285f4; + color: #2f6a43; } } .long-article-author { - margin-right: 15px; + color: #2f4937; + font-weight: 600; + } +} + +.long-article-meta__separator { + color: #9ba79f; +} + +.article.long-article-page { + min-height: 100vh; + padding-top: 0; + background: #c7d8ca; + color: #25332a; + + > .nav, + > .footer { + display: none; + } + + .article-container { + box-sizing: border-box; + width: min(var(--long-article-width, 800px), calc(100vw - 28px)); + max-width: none; + margin: 36px auto 0; + border: 1px solid rgba(72, 101, 79, 0.12); + border-radius: 12px; + background: #fbfcf8; + box-shadow: 0 12px 36px rgba(48, 73, 55, 0.1); + } + + .article-body { + padding: 0; + } + + .article-body > .wrapper { + box-sizing: border-box; + width: 100%; + max-width: none; + padding: 54px clamp(32px, 6vw, 72px) 46px; + } + + h1.article-title { + margin: 0; + padding: 0; + color: #1d2b21; + font-size: 32px; + font-weight: 650; + line-height: 1.35; + text-align: left; + + svg { + width: 30px; + height: 30px; + vertical-align: -4px; + } + } + + > .main { + box-sizing: border-box; + margin-top: 36px; + padding: 38px 0 48px; + border-top: 1px solid rgba(72, 101, 79, 0.12); + background: #dce8de; + } + + #articleCommentsPanel { + box-sizing: border-box; + width: min(var(--long-article-width, 800px), calc(100vw - 28px)); + max-width: none; + margin: 0 auto; + padding: 26px; + border: 1px solid rgba(72, 101, 79, 0.1); + border-radius: 12px; + background: #f8faf6; + } + + .article-footer { + box-sizing: border-box; + width: min(var(--long-article-width, 800px), calc(100vw - 28px)); + max-width: none; + margin-right: auto; + margin-left: auto; } } @@ -5384,36 +5538,38 @@ code .dec { .long-article-settings { position: fixed; - right: 20px; + left: min(calc(50% + min(var(--long-article-half-width, 400px), calc(50vw - 14px)) + 14px), calc(100vw - 58px)); top: 50%; transform: translateY(-50%); - z-index: 100; + z-index: 101; display: flex; flex-direction: column; - gap: 10px; + gap: 8px; } .long-article-settings-btn { width: 44px; height: 44px; - border-radius: 50%; - border: none; - background: #fff; - box-shadow: 0 2px 8px rgba(0,0,0,0.1); - cursor: pointer; display: flex; align-items: center; justify-content: center; - color: #666; - transition: all 0.2s; + padding: 0; + border: 1px solid rgba(72, 101, 79, 0.15); + border-radius: 8px; + background: rgba(248, 251, 247, 0.96); + box-shadow: 0 4px 14px rgba(48, 73, 55, 0.12); + color: #52685a; + cursor: pointer; font-size: 16px; - font-weight: bold; + font-weight: 600; position: relative; + transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease, transform 0.2s ease; &:hover { - background: #f0f0f0; - color: #333; - transform: scale(1.1); + border-color: rgba(55, 100, 68, 0.35); + background: #fff; + color: #2f6a43; + transform: translateX(2px); } svg { @@ -5422,39 +5578,149 @@ code .dec { } } +.long-article-settings-btn--text { + font-size: 13px; +} + +.long-article-settings__count { + position: absolute; + top: -5px; + right: -5px; + min-width: 18px; + box-sizing: border-box; + padding: 1px 5px; + border-radius: 10px; + background: #c94e4e; + color: #fff; + font-size: 10px; + font-weight: 600; + line-height: 16px; + text-align: center; +} + +.long-article-layout { + position: relative; +} + +.long-article-layout-panel { + position: absolute; + right: 56px; + bottom: 0; + display: none; + width: 210px; + box-sizing: border-box; + padding: 14px; + border: 1px solid rgba(72, 101, 79, 0.16); + border-radius: 10px; + background: rgba(251, 253, 249, 0.98); + box-shadow: 0 12px 32px rgba(38, 61, 44, 0.18); + + &.is-open { + display: block; + } +} + +.long-article-layout-panel__title { + margin-bottom: 10px; + color: #52685a; + font-size: 13px; + font-weight: 600; +} + +.long-article-layout-panel__options { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 7px; + + button { + height: 32px; + padding: 0 8px; + border: 1px solid #d9e3da; + border-radius: 6px; + background: #f3f7f1; + color: #52685a; + cursor: pointer; + font-size: 12px; + + &:hover, + &.is-active { + border-color: #77977e; + background: #dfeadf; + color: #285a39; + } + + &.is-active { + font-weight: 600; + } + } +} + body.night { + &.long-article-page { + background: #26332b; + color: #d9e3db; + + .article-container { + border-color: rgba(204, 224, 209, 0.08); + background: #18231d; + box-shadow: 0 14px 40px rgba(0, 0, 0, 0.28); + } + + h1.article-title { + color: #eef4ef; + } + + > .main { + border-color: rgba(204, 224, 209, 0.08); + background: #202d25; + } + + #articleCommentsPanel { + border-color: rgba(204, 224, 209, 0.08); + background: #18231d; + } + } + .long-article-content { - background-color: #1a1a1a; - color: #e0e0e0; + color: #d9e3db; a { - color: #6bb3ff; + color: #8fc9a0; } blockquote { - border-color: #444; - color: #bbb; + border-color: #587663; + background: #223128; + color: #b8c7bc; } - code { - background-color: #2d2d2d; - color: #e0e0e0; + > h1, + > h2, + > h3, + > h4, + > h5, + > h6 { + color: #edf4ef; } pre { - background-color: #2d2d2d; + background-color: #111a15; + } + + :not(pre) > code { + background: #27362c; + color: #b9d6c1; } } .long-article-meta { - color: #888; - border-color: #333; + color: #93a299; a { - color: #888; + color: #a9c7b1; &:hover { - color: #6bb3ff; + color: #c6e5ce; } } } @@ -5523,26 +5789,69 @@ body.night { } .long-article-settings-btn { - background: #2d2d2d; - color: #999; + border-color: rgba(190, 214, 196, 0.12); + background: rgba(28, 41, 33, 0.96); + color: #a7b7ac; &:hover { - background: #3d3d3d; - color: #fff; + border-color: rgba(190, 214, 196, 0.25); + background: #26382d; + color: #e3ece5; + } + } + + .long-article-layout-panel { + border-color: rgba(190, 214, 196, 0.12); + background: rgba(24, 35, 29, 0.98); + box-shadow: 0 12px 32px rgba(0, 0, 0, 0.32); + } + + .long-article-layout-panel__title { + color: #a7b7ac; + } + + .long-article-layout-panel__options button { + border-color: #34483a; + background: #223128; + color: #b2c2b7; + + &:hover, + &.is-active { + border-color: #6c9177; + background: #304637; + color: #e3ece5; } } } @media (max-width: 768px) { - .long-article-content { - padding: 20px 15px; - font-size: 16px; + .article.long-article-page { + .article-container { + margin-top: 14px; + border-radius: 9px; + } + + .article-body > .wrapper { + padding: 36px 24px; + } + + h1.article-title { + font-size: 26px; + } + + > .main { + margin-top: 20px; + padding: 24px 0 30px; + } + + #articleCommentsPanel { + padding: 18px; + border-radius: 9px; + } } - .long-article-meta { - font-size: 13px; - padding: 10px 15px; - margin-bottom: 15px; + .long-article-content { + margin-top: 28px; } .article-nav-scope__tabs { @@ -5573,122 +5882,18 @@ body.night { text-align: left; } - // 长文章时,将文章操作按钮移到右下角 - .long-article-page .article-actions { - position: fixed; - bottom: 10px; - right: 10px; - margin: 0 !important; - z-index: 98; - - .fn-right { - display: flex; - flex-direction: column; - gap: 8px; - background: rgba(255, 255, 255, 0.95); - padding: 8px; - border-radius: 8px; - box-shadow: 0 2px 12px rgba(0,0,0,0.15); - - span, a { - display: flex; - align-items: center; - justify-content: center; - width: 32px; - height: 32px; - margin: 0; - } - } - } - - body.night.long-article-page .article-actions .fn-right { - background: rgba(45, 45, 45, 0.95); - } - .long-article-settings { - position: fixed; - right: 10px; - top: 50%; - transform: translateY(-50%); - flex-direction: column; - gap: 8px; - background: transparent; - padding: 0; - box-shadow: none; - border-radius: 0; - z-index: 99; + right: 8px; + left: auto; } .long-article-settings-btn { - width: 36px; - height: 36px; - border-radius: 50%; - padding: 0; - flex-direction: row; - gap: 0; - background: rgba(255, 255, 255, 0.95); - box-shadow: 0 2px 8px rgba(0,0,0,0.15); - transition: all 0.3s; - - svg { - width: 20px; - height: 20px; - } - - span { - font-size: 14px; - font-weight: bold; - } - - &.hide { - opacity: 0; - pointer-events: none; - transform: translateX(60px); - } - } - - .long-article-toggle-btn { - width: 36px; - height: 36px; - border-radius: 50%; - background: rgba(255, 255, 255, 0.95); - border: none; - box-shadow: 0 2px 8px rgba(0,0,0,0.15); - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - color: #666; - font-size: 18px; - font-weight: bold; - transition: all 0.3s; - - &.active { - background: #4285f4; - color: #fff; - } + width: 40px; + height: 40px; } - body.night { - .long-article-settings-btn { - background: rgba(45, 45, 45, 0.95); - color: #999; - - &:hover { - background: rgba(61, 61, 61, 0.95); - color: #fff; - } - } - - .long-article-toggle-btn { - background: rgba(45, 45, 45, 0.95); - color: #999; - - &.active { - background: #4285f4; - color: #fff; - } - } + .long-article-layout-panel { + right: 50px; } } diff --git a/src/main/resources/scss/mobile-base.scss b/src/main/resources/scss/mobile-base.scss index 717a74d7..31f47280 100644 --- a/src/main/resources/scss/mobile-base.scss +++ b/src/main/resources/scss/mobile-base.scss @@ -5399,61 +5399,195 @@ only screen and (device-width: 414px) and (device-height: 896px) and (-webkit-de /* start long-article */ .long-article-content { - padding: 20px 15px; - font-size: 16px; - line-height: 1.8; + padding: 0; + color: #25332a; + font-size: var(--long-article-font-size, 16px); + line-height: 1.9; + overflow-wrap: anywhere; + + > p { + margin: 1.1em 0; + text-indent: 2em; + } + + > p:has(> img), + > p:has(> picture), + > p:has(> video), + > p:has(> iframe) { + text-indent: 0; + } + + > h1, + > h2, + > h3, + > h4, + > h5, + > h6 { + margin: 1.65em 0 0.7em; + color: #1f2e24; + line-height: 1.45; + text-indent: 0; + } + + > ul, + > ol, + > blockquote, + > pre, + > table, + > figure { + margin-top: 1.25em; + margin-bottom: 1.25em; + text-indent: 0; + } + + blockquote { + padding: 12px 14px; + border-left: 4px solid #9bb4a0; + background: #f0f5ef; + color: #526259; + } + + img { + display: block; + max-width: 100%; + height: auto; + margin: 1.4em auto; + } + + table { + display: block; + max-width: 100%; + overflow-x: auto; + } + + pre { + border-radius: 7px; + } + + :not(pre) > code { + border-radius: 4px; + background: #edf2ec; + color: #35513d; + } } .long-article-meta { - text-align: right; - color: #888; + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 4px 8px; + margin: 10px 0 0; + padding: 0; + color: #718078; font-size: 13px; - padding: 10px 0; - margin-bottom: 10px; + line-height: 1.55; + text-align: left; a { - color: #888; + color: #526c5a; text-decoration: none; &:hover { - color: #4285f4; + color: #2f6a43; } } .long-article-author { - margin-right: 15px; + color: #2f4937; + font-weight: 600; } } +.long-article-meta__separator { + color: #9ba79f; +} + body.long-article-page { + min-height: 100vh; width: 100%; margin: 0; padding: 0; overflow-x: hidden; box-sizing: border-box; + background: #c7d8ca; + color: #25332a; - .main, - .article-container, - .wrapper, - .article-body { - width: 100% !important; - max-width: 100% !important; - margin: 0 !important; - padding: 0 14px !important; - overflow-x: hidden !important; - box-sizing: border-box !important; + > .nav, + > .footer { + display: none; + } + + > .main { + box-sizing: border-box; + margin: 0; + padding: 14px 14px 30px; + background: #c7d8ca; + box-shadow: none; + } + + > .main > .article-actions { + display: none; + } + + .article-main { + overflow: hidden; + padding: 0; + border: 1px solid rgba(72, 101, 79, 0.12); + border-radius: 10px; + background: #fbfcf8; + box-shadow: 0 8px 24px rgba(48, 73, 55, 0.1); + } + + .article-main > .wrapper { + width: auto; + max-width: none; + margin: 0; + padding: 34px 20px 30px; + overflow-x: hidden; + box-sizing: border-box; } .article-title { - padding-right: 0; - padding-left: 0; + margin: 0; + padding: 0; box-sizing: border-box; + color: #1d2b21; + font-size: 26px; + font-weight: 650; + line-height: 1.35; + text-align: left; + + > a { + color: inherit; + } } .long-article-content { + width: 100%; max-width: 100%; - padding: 20px 0; + margin-top: 28px; + padding: 0; box-sizing: border-box; + color: #25332a; + font-size: var(--long-article-font-size, 16px); + line-height: 1.9; + + > p { + margin: 1.1em 0; + } + } + + #comments { + box-sizing: border-box; + margin: 20px 0 0; + padding: 20px 14px; + border: 1px solid rgba(72, 101, 79, 0.1); + border-radius: 10px; + background: #f7faf5; + } + + .side { + display: none; } } @@ -5700,31 +5834,57 @@ body.long-article-page { .long-article-settings { position: fixed; - right: 10px; - top: 50%; - transform: translateY(-50%); + right: 12px; + bottom: calc(18px + env(safe-area-inset-bottom)); display: flex; flex-direction: column; gap: 8px; + align-items: flex-end; z-index: 99; } +.long-article-settings__actions { + display: flex; + max-height: calc(100vh - 92px); + max-height: calc(100dvh - 92px); + flex-direction: column; + gap: 7px; + overflow-y: auto; + opacity: 0; + pointer-events: none; + scrollbar-width: none; + transform: translateY(10px); + transition: opacity 0.2s ease, transform 0.2s ease; + visibility: hidden; + + &::-webkit-scrollbar { + display: none; + } +} + +.long-article-settings.is-open .long-article-settings__actions { + opacity: 1; + pointer-events: auto; + transform: translateY(0); + visibility: visible; +} + .long-article-settings-btn { - width: 44px; - height: 44px; - border-radius: 50%; - border: none; + width: 40px; + height: 40px; + border: 1px solid rgba(72, 101, 79, 0.15); + border-radius: 8px; background: rgba(255, 255, 255, 0.95); - box-shadow: 0 2px 8px rgba(0,0,0,0.15); + box-shadow: 0 4px 12px rgba(48, 73, 55, 0.15); cursor: pointer; display: flex; flex-direction: column; align-items: center; justify-content: center; - color: #666; + color: #52685a; font-size: 14px; - font-weight: bold; - transition: all 0.3s; + font-weight: 600; + transition: background 0.2s ease, color 0.2s ease, transform 0.2s ease; gap: 1px; position: relative; @@ -5736,8 +5896,8 @@ body.long-article-page { } span { - font-size: 14px; - font-weight: bold; + font-size: 13px; + font-weight: 600; } &.has-cnt { @@ -5749,76 +5909,103 @@ body.long-article-page { .count { font-size: 10px; line-height: 1; - font-weight: bold; + font-weight: 600; } } &.ft-red { color: #f44336; } - - &.hide { - opacity: 0; - pointer-events: none; - transform: translateX(60px); - } } .long-article-toggle-btn { - width: 44px; - height: 44px; - border-radius: 50%; + width: 40px; + height: 40px; + border-radius: 8px; background: rgba(255, 255, 255, 0.95); - border: none; - box-shadow: 0 2px 8px rgba(0,0,0,0.15); + border: 1px solid rgba(72, 101, 79, 0.15); + box-shadow: 0 4px 12px rgba(48, 73, 55, 0.15); cursor: pointer; display: flex; align-items: center; justify-content: center; - color: #666; + color: #52685a; font-size: 18px; - font-weight: bold; - transition: all 0.3s; + font-weight: 600; + transition: background 0.2s ease, color 0.2s ease; &.active { - background: #4285f4; + background: #3e7250; color: #fff; } } body.night { + &.long-article-page { + background: #26332b; + color: #d9e3db; + + > .main { + background: #26332b; + } + + .article-main { + border-color: rgba(204, 224, 209, 0.08); + background: #18231d; + box-shadow: 0 10px 28px rgba(0, 0, 0, 0.24); + } + + .article-title, + .article-title > a { + color: #eef4ef; + } + + #comments { + border-color: rgba(204, 224, 209, 0.08); + background: #18231d; + } + } + .long-article-content { - background-color: #1a1a1a; - color: #e0e0e0; + color: #d9e3db; a { - color: #6bb3ff; + color: #8fc9a0; } blockquote { - border-color: #444; - color: #bbb; + border-color: #587663; + background: #223128; + color: #b8c7bc; } - code { - background-color: #2d2d2d; - color: #e0e0e0; + > h1, + > h2, + > h3, + > h4, + > h5, + > h6 { + color: #edf4ef; } pre { - background-color: #2d2d2d; + background-color: #111a15; + } + + :not(pre) > code { + background: #27362c; + color: #b9d6c1; } } .long-article-meta { - color: #888; - border-color: #333; + color: #93a299; a { - color: #888; + color: #a9c7b1; &:hover { - color: #6bb3ff; + color: #c6e5ce; } } } @@ -5877,17 +6064,18 @@ body.night { .long-article-settings-btn, .long-article-toggle-btn { - background: rgba(45, 45, 45, 0.95); - color: #999; + border-color: rgba(190, 214, 196, 0.12); + background: rgba(28, 41, 33, 0.96); + color: #a7b7ac; &:hover { - background: rgba(61, 61, 61, 0.95); - color: #fff; + background: #26382d; + color: #e3ece5; } } .long-article-toggle-btn.active { - background: #4285f4; + background: #3e7250; color: #fff; } } diff --git a/src/main/resources/skins/classic/mobile/article.ftl b/src/main/resources/skins/classic/mobile/article.ftl index c8e2f80d..4e53156f 100644 --- a/src/main/resources/skins/classic/mobile/article.ftl +++ b/src/main/resources/skins/classic/mobile/article.ftl @@ -109,6 +109,19 @@ ${article.articleTitleEmoj} + <#if 6 == article.articleType> + +
<#if 6 != article.articleType && article.sysMetal != "[]"> <#list article.sysMetal?eval as metal> @@ -235,10 +248,6 @@ <#include "common/article-adjacent-nav.ftl"> <#if 6 == article.articleType> - <#if article.isMyArticle && article.longArticleReadStat??>
长文阅读激励
@@ -488,89 +497,82 @@
<#if 6 == article.articleType> -
- - - - - <#if permissions["commonThankArticle"].permissionGrant> - <#if permissions["commonGoodArticle"].permissionGrant> - <#if permissions["commonBadArticle"].permissionGrant> - <#if isLoggedIn && isFollowing> - <#else> - <#if permissions["commonViewArticleHistory"].permissionGrant && article.articleRevisionCount > 1> - - <#if article.isMyArticle && 3 != article.articleType && permissions["commonUpdateArticle"].permissionGrant> - <#if article.isMyArticle && permissions["commonStickArticle"].permissionGrant> - <#if permissions["articleUpdateArticleBasic"].permissionGrant> - +
+ - <#include "footer.ftl"> <#if isLoggedIn && discussionViewable && article.articleCommentable && permissions["commonAddComment"].permissionGrant> @@ -616,6 +618,9 @@ + <#if 6 == article.articleType> + + <#include "footer.ftl"> @@ -854,6 +867,9 @@ +<#if 6 == article.articleType> + + diff --git a/src/main/resources/skins/classic/pc/article.ftl b/src/main/resources/skins/classic/pc/article.ftl index 565c6942..dd614b30 100644 --- a/src/main/resources/skins/classic/pc/article.ftl +++ b/src/main/resources/skins/classic/pc/article.ftl @@ -80,9 +80,12 @@ +<#assign hidePageChrome = (6 == article.articleType)>

"${article.articlePreviewContent}"

+<#if !hidePageChrome> <#include "header.ftl"> +
<#if showTopAd && 6 != article.articleType> @@ -658,6 +661,7 @@ class="ft-13">${article.thankedCnt}
+<#if !hidePageChrome>

@@ -752,6 +756,7 @@

+ <#if 6 == article.articleType>
diff --git a/src/main/resources/skins/classic/pc/footer.ftl b/src/main/resources/skins/classic/pc/footer.ftl index 0828cbe0..880b4589 100644 --- a/src/main/resources/skins/classic/pc/footer.ftl +++ b/src/main/resources/skins/classic/pc/footer.ftl @@ -18,6 +18,7 @@ along with this program. If not, see . --> +<#if !(hidePageChrome!false)> + From 92c25f90e76863d72b258536acc82989eee4bbb9 Mon Sep 17 00:00:00 2001 From: Yui Date: Sat, 18 Jul 2026 16:09:14 +0800 Subject: [PATCH 04/30] =?UTF-8?q?=E5=AF=B9=E9=BD=90=E9=95=BF=E6=96=87?= =?UTF-8?q?=E9=98=85=E8=AF=BB=E9=A1=B5=E9=B1=BC=E4=B9=8E=E9=85=8D=E8=89=B2?= =?UTF-8?q?=E5=B9=B6=E4=BF=AE=E5=A4=8D=E9=A1=B6=E9=83=A8=E7=95=99=E7=99=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/scss/index.scss | 85 ++++++++++++------------ src/main/resources/scss/mobile-base.scss | 56 ++++++++-------- 2 files changed, 68 insertions(+), 73 deletions(-) diff --git a/src/main/resources/scss/index.scss b/src/main/resources/scss/index.scss index 70e08060..f6881602 100644 --- a/src/main/resources/scss/index.scss +++ b/src/main/resources/scss/index.scss @@ -5208,7 +5208,8 @@ code .dec { .article.long-article-page { min-height: 100vh; padding-top: 0; - background: #c7d8ca; + overflow-x: hidden; + background: #c7dcc8; color: #25332a; > .nav, @@ -5221,11 +5222,11 @@ code .dec { box-sizing: border-box; width: min(var(--long-article-width, 800px), calc(100vw - 28px)); max-width: none; - margin: 36px auto 0; - border: 1px solid rgba(72, 101, 79, 0.12); - border-radius: 12px; - background: #fbfcf8; - box-shadow: 0 12px 36px rgba(48, 73, 55, 0.1); + margin: 0 auto; + border: 0; + border-radius: 0; + background: #dcebdd; + box-shadow: none; } .article-body { @@ -5236,7 +5237,7 @@ code .dec { box-sizing: border-box; width: 100%; max-width: none; - padding: 54px clamp(32px, 6vw, 72px) 46px; + padding: 80px clamp(32px, 6vw, 64px) 64px; } h1.article-title { @@ -5257,10 +5258,10 @@ code .dec { > .main { box-sizing: border-box; - margin-top: 36px; + margin-top: 0; padding: 38px 0 48px; - border-top: 1px solid rgba(72, 101, 79, 0.12); - background: #dce8de; + border-top: 0; + background: #c7dcc8; } #articleCommentsPanel { @@ -5269,9 +5270,9 @@ code .dec { max-width: none; margin: 0 auto; padding: 26px; - border: 1px solid rgba(72, 101, 79, 0.1); - border-radius: 12px; - background: #f8faf6; + border: 0; + border-radius: 0; + background: #dcebdd; } .article-footer { @@ -5555,9 +5556,9 @@ code .dec { align-items: center; justify-content: center; padding: 0; - border: 1px solid rgba(72, 101, 79, 0.15); + border: 0; border-radius: 8px; - background: rgba(248, 251, 247, 0.96); + background: #dcebdd; box-shadow: 0 4px 14px rgba(48, 73, 55, 0.12); color: #52685a; cursor: pointer; @@ -5613,7 +5614,7 @@ code .dec { padding: 14px; border: 1px solid rgba(72, 101, 79, 0.16); border-radius: 10px; - background: rgba(251, 253, 249, 0.98); + background: #ebfaeb; box-shadow: 0 12px 32px rgba(38, 61, 44, 0.18); &.is-open { @@ -5658,13 +5659,12 @@ code .dec { body.night { &.long-article-page { - background: #26332b; + background: #0a0a0a; color: #d9e3db; .article-container { - border-color: rgba(204, 224, 209, 0.08); - background: #18231d; - box-shadow: 0 14px 40px rgba(0, 0, 0, 0.28); + background: #111111; + box-shadow: none; } h1.article-title { @@ -5672,18 +5672,16 @@ body.night { } > .main { - border-color: rgba(204, 224, 209, 0.08); - background: #202d25; + background: #0a0a0a; } #articleCommentsPanel { - border-color: rgba(204, 224, 209, 0.08); - background: #18231d; + background: #111111; } } .long-article-content { - color: #d9e3db; + color: #989898; a { color: #8fc9a0; @@ -5701,7 +5699,7 @@ body.night { > h4, > h5, > h6 { - color: #edf4ef; + color: #989898; } pre { @@ -5790,37 +5788,36 @@ body.night { } .long-article-settings-btn { - border-color: rgba(190, 214, 196, 0.12); - background: rgba(28, 41, 33, 0.96); - color: #a7b7ac; + border: 0; + background: #191919; + color: #989898; &:hover { - border-color: rgba(190, 214, 196, 0.25); - background: #26382d; - color: #e3ece5; + background: #191919; + color: #989898; } } .long-article-layout-panel { - border-color: rgba(190, 214, 196, 0.12); - background: rgba(24, 35, 29, 0.98); + border: 0; + background: #1f1f1f; box-shadow: 0 12px 32px rgba(0, 0, 0, 0.32); } .long-article-layout-panel__title { - color: #a7b7ac; + color: #989898; } .long-article-layout-panel__options button { - border-color: #34483a; - background: #223128; - color: #b2c2b7; + border-color: #3a3a3a; + background: #191919; + color: #989898; &:hover, &.is-active { - border-color: #6c9177; - background: #304637; - color: #e3ece5; + border-color: #666; + background: #292929; + color: #fff; } } } @@ -5828,8 +5825,8 @@ body.night { @media (max-width: 768px) { .article.long-article-page { .article-container { - margin-top: 14px; - border-radius: 9px; + margin-top: 0; + border-radius: 0; } .article-body > .wrapper { @@ -5847,7 +5844,7 @@ body.night { #articleCommentsPanel { padding: 18px; - border-radius: 9px; + border-radius: 0; } } diff --git a/src/main/resources/scss/mobile-base.scss b/src/main/resources/scss/mobile-base.scss index 8935dc87..b344aac0 100644 --- a/src/main/resources/scss/mobile-base.scss +++ b/src/main/resources/scss/mobile-base.scss @@ -5509,7 +5509,7 @@ body.long-article-page { padding: 0; overflow-x: hidden; box-sizing: border-box; - background: #c7d8ca; + background: #c7dcc8; color: #25332a; > .nav, @@ -5521,8 +5521,8 @@ body.long-article-page { > .main { box-sizing: border-box; margin: 0; - padding: 14px 14px 30px; - background: #c7d8ca; + padding: 0 14px 30px; + background: #c7dcc8; box-shadow: none; } @@ -5533,10 +5533,10 @@ body.long-article-page { .article-main { overflow: hidden; padding: 0; - border: 1px solid rgba(72, 101, 79, 0.12); - border-radius: 10px; - background: #fbfcf8; - box-shadow: 0 8px 24px rgba(48, 73, 55, 0.1); + border: 0; + border-radius: 0; + background: #dcebdd; + box-shadow: none; } .article-main > .wrapper { @@ -5582,9 +5582,9 @@ body.long-article-page { box-sizing: border-box; margin: 20px 0 0; padding: 20px 14px; - border: 1px solid rgba(72, 101, 79, 0.1); - border-radius: 10px; - background: #f7faf5; + border: 0; + border-radius: 0; + background: #dcebdd; } .side { @@ -5873,9 +5873,9 @@ body.long-article-page { .long-article-settings-btn { width: 40px; height: 40px; - border: 1px solid rgba(72, 101, 79, 0.15); + border: 0; border-radius: 8px; - background: rgba(255, 255, 255, 0.95); + background: #dcebdd; box-shadow: 0 4px 12px rgba(48, 73, 55, 0.15); cursor: pointer; display: flex; @@ -5923,8 +5923,8 @@ body.long-article-page { width: 40px; height: 40px; border-radius: 8px; - background: rgba(255, 255, 255, 0.95); - border: 1px solid rgba(72, 101, 79, 0.15); + background: #dcebdd; + border: 0; box-shadow: 0 4px 12px rgba(48, 73, 55, 0.15); cursor: pointer; display: flex; @@ -5943,17 +5943,16 @@ body.long-article-page { body.night { &.long-article-page { - background: #26332b; + background: #0a0a0a; color: #d9e3db; > .main { - background: #26332b; + background: #0a0a0a; } .article-main { - border-color: rgba(204, 224, 209, 0.08); - background: #18231d; - box-shadow: 0 10px 28px rgba(0, 0, 0, 0.24); + background: #111111; + box-shadow: none; } .article-title, @@ -5962,13 +5961,12 @@ body.night { } #comments { - border-color: rgba(204, 224, 209, 0.08); - background: #18231d; + background: #111111; } } .long-article-content { - color: #d9e3db; + color: #989898; a { color: #8fc9a0; @@ -5986,7 +5984,7 @@ body.night { > h4, > h5, > h6 { - color: #edf4ef; + color: #989898; } pre { @@ -6065,18 +6063,18 @@ body.night { .long-article-settings-btn, .long-article-toggle-btn { - border-color: rgba(190, 214, 196, 0.12); - background: rgba(28, 41, 33, 0.96); - color: #a7b7ac; + border: 0; + background: #191919; + color: #989898; &:hover { - background: #26382d; - color: #e3ece5; + background: #191919; + color: #989898; } } .long-article-toggle-btn.active { - background: #3e7250; + background: #191919; color: #fff; } } From adcdb308545a50b9c30c721c2f74382c16c150c2 Mon Sep 17 00:00:00 2001 From: Yui Date: Sat, 18 Jul 2026 16:30:53 +0800 Subject: [PATCH 05/30] =?UTF-8?q?=E9=95=BF=E6=96=87=E8=AF=84=E8=AE=BA?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E4=BE=A7=E6=BB=91=E9=98=85=E8=AF=BB=E9=9D=A2?= =?UTF-8?q?=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 2 +- src/main/resources/js/long-article.js | 86 ++++- src/main/resources/js/long-article.min.js | 2 +- src/main/resources/js/m-long-article.js | 84 ++++- src/main/resources/js/m-long-article.min.js | 2 +- src/main/resources/scss/index.scss | 341 +++++++++++++++++- src/main/resources/scss/mobile-base.scss | 286 ++++++++++++++- .../skins/classic/mobile/article.ftl | 9 +- .../resources/skins/classic/pc/article.ftl | 9 +- 9 files changed, 796 insertions(+), 25 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 06413f5f..4a7ccc91 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -103,7 +103,7 @@ - 首页两列对齐约束:`getIndexRecentArticles` 的第一页会插入全部置顶且不截断;第二页起需按第一页“置顶占位数”补偿 `fetchSize` 与分页偏移,并基于已排除置顶 ID 的普通文章序列取数,保证两列等高、不重复、不丢中间文章。 - 首页右侧排行补偿(无前端延迟):由 `IndexProcessor#loadIndexData` 按两列最新文章的最大行数计算 `rankCompensateRows`,先换算“右栏总补偿行数”再分摊到 `checkinVisibleCount/onlineVisibleCount`,Freemarker 直接按该数量渲染,不再依赖 JS 运行时增删行。 - 专栏封面链路:封面字段是 `long_article_column.columnCoverURL`;默认封面在 `LongArticleColumnQueryService` 填充;作者管理页为 `/column/manage`,编辑长篇页的弹窗脚本是 `long-article-cover-dialog.js`,新建长篇封面随 `/article` 请求的 `columnCoverURL` 写入;封面保存接口为 `POST /api/columns/{columnId}/cover`,处理器是 `LongArticleColumnProcessor`。 -- 长文阅读页以 `articleType=6` 区分,PC/移动模板均为 `skins/classic/*/article.ftl`,样式在 `index.scss`/`mobile-base.scss`,交互在 `long-article.js`/`m-long-article.js`;模板通过 `hidePageChrome` 不渲染顶部与底部视觉内容,但 footer 的公共脚本仍需加载;桌面宽度和两端字号统一保存在 `localStorage.longArticleSettings`,宽度仅在 PC 生效。 +- 长文阅读页以 `articleType=6` 区分,PC/移动模板均为 `skins/classic/*/article.ftl`,样式在 `index.scss`/`mobile-base.scss`,交互在 `long-article.js`/`m-long-article.js`;模板通过 `hidePageChrome` 不渲染顶部与底部视觉内容,但 footer 的公共脚本仍需加载;桌面宽度和两端字号统一保存在 `localStorage.longArticleSettings`,宽度仅在 PC 生效;评论按钮控制右侧评论抽屉,现有评论列表、筛选、分页和编辑器均在抽屉链路内复用。 - 管理员文章页编辑长文专栏时,`admin/article.ftl` 会随文章表单提交 `columnCoverURL`,后端在 `ArticleMgmtService` 的文章事务内复用 `ColumnCoverMgmtService` 校验并更新或清空专栏封面。 - 路由总入口:`Router#requestMapping` + 各 Processor `register()`;新增路由先决定使用 `loginCheck` / `apiCheck` / `permission` / `anonymousViewCheck` 哪条链路。 - Latke 路由存在静态段被相邻动态段截获的风险(如 `/article/{id}/revisions/list` 可能进入 `/article/{id}/revisions/{revisionId}`);新增相邻路由时需避免路径歧义,或在处理方法中显式识别保留字。 diff --git a/src/main/resources/js/long-article.js b/src/main/resources/js/long-article.js index d607760d..7717a6a0 100644 --- a/src/main/resources/js/long-article.js +++ b/src/main/resources/js/long-article.js @@ -28,6 +28,10 @@ window.LongArticle = { this.loadSettings(); this.bindEvents(); this.applySettings(); + if (this.shouldOpenCommentsFromLocation()) { + this.openComments(); + this.focusLocationComment(); + } }, loadSettings: function () { @@ -118,7 +122,7 @@ window.LongArticle = { if (action === 'top') { self.scrollToTop(); } else if (action === 'comments') { - self.scrollToComments(); + self.toggleComments(); } else if (action === 'font-decrease') { self.setFontSize(-2); } else if (action === 'font-increase') { @@ -136,6 +140,15 @@ window.LongArticle = { if (panel && panel.classList.contains('is-open') && !panel.contains(event.target) && !layoutButton.contains(event.target)) { self.closeLayoutPanel(); } + if (event.target.closest && event.target.closest('[data-long-article-comments-close]')) { + self.closeComments(); + } + }); + + document.addEventListener('keydown', function (event) { + if (event.key === 'Escape' && self.isCommentsOpen()) { + self.closeComments(); + } }); }, @@ -197,10 +210,73 @@ window.LongArticle = { window.scrollTo({top: 0, behavior: 'smooth'}); }, - scrollToComments: function () { - var comments = document.getElementById('comments'); - if (comments) { - comments.scrollIntoView({behavior: 'smooth'}); + getCommentsPanel: function () { + return document.getElementById('articleCommentsPanel'); + }, + + isCommentsOpen: function () { + return document.body.classList.contains('long-article-comments-open'); + }, + + toggleComments: function () { + if (this.isCommentsOpen()) { + this.closeComments(); + } else { + this.openComments(); + } + }, + + openComments: function () { + var panel = this.getCommentsPanel(); + var button = document.querySelector('[data-long-article-action="comments"]'); + if (!panel) { + return; + } + this.closeLayoutPanel(); + document.body.classList.add('long-article-comments-open'); + panel.setAttribute('aria-hidden', 'false'); + if (button) { + button.classList.add('is-active'); + button.setAttribute('aria-expanded', 'true'); + } + }, + + closeComments: function () { + var panel = this.getCommentsPanel(); + var button = document.querySelector('[data-long-article-action="comments"]'); + var editorPanel = document.querySelector('.editor-panel'); + if (editorPanel && window.getComputedStyle(editorPanel).display !== 'none' && window.getComputedStyle(editorPanel).bottom === '0px' && window.Comment && typeof window.Comment._toggleReply === 'function') { + window.Comment._toggleReply(); + } + document.body.classList.remove('long-article-comments-open'); + if (panel) { + panel.setAttribute('aria-hidden', 'true'); + } + if (button) { + button.classList.remove('is-active'); + button.setAttribute('aria-expanded', 'false'); + } + }, + + shouldOpenCommentsFromLocation: function () { + var panel = this.getCommentsPanel(); + var hash = window.location.hash.replace(/^#/, ''); + var target = hash ? document.getElementById(hash) : null; + if (panel && target && panel.contains(target)) { + return true; } + return /(?:\?|&)(?:p|m|sort|author)=/.test(window.location.search); + }, + + focusLocationComment: function () { + var self = this; + window.setTimeout(function () { + var hash = window.location.hash.replace(/^#/, ''); + var target = hash ? document.getElementById(hash) : null; + var panel = self.getCommentsPanel(); + if (panel && target && panel.contains(target)) { + target.scrollIntoView({block: 'center'}); + } + }, 0); } }; diff --git a/src/main/resources/js/long-article.min.js b/src/main/resources/js/long-article.min.js index f7a49618..fa7296c2 100644 --- a/src/main/resources/js/long-article.min.js +++ b/src/main/resources/js/long-article.min.js @@ -1 +1 @@ -window.LongArticle={storageKey:"longArticleSettings",allowedWidths:["auto","600","800","1000","1200"],settings:{width:"800",desktopFontSize:18,mobileFontSize:16},init:function(){this.initialized||(this.initialized=!0,this.loadSettings(),this.bindEvents(),this.applySettings())},loadSettings:function(){var t,e={width:"800",desktopFontSize:18,mobileFontSize:16};try{t=JSON.parse(window.localStorage.getItem(this.storageKey)||"{}")}catch(e){t={}}t&&"object"==typeof t&&(e.width=this.normalizeWidth(t.width),e.desktopFontSize=this.normalizeFontSize(t.desktopFontSize||t.fontSize,18,32,18),e.mobileFontSize=this.normalizeFontSize(t.mobileFontSize,16,24,16));try{var i=parseInt(window.localStorage.getItem("longArticleFontSize"),10);t.desktopFontSize||t.fontSize||isNaN(i)||(e.desktopFontSize=this.normalizeFontSize(i,18,32,18),e.mobileFontSize=this.normalizeFontSize(i,16,24,16));var o=JSON.parse(window.localStorage.getItem("mLongArticleSettings")||"{}");t.mobileFontSize||!o||isNaN(parseInt(o.fontSize,10))||(e.mobileFontSize=this.normalizeFontSize(parseInt(o.fontSize,10),16,24,16)),window.localStorage.removeItem("longArticleFontSize"),window.localStorage.removeItem("mLongArticleSettings")}catch(t){}this.settings=e,this.saveSettings()},normalizeWidth:function(t){return t=String(t||"800"),this.allowedWidths.indexOf(t)>=0?t:"800"},normalizeFontSize:function(t,e,i,o){return t=parseInt(t,10),isNaN(t)?o:Math.max(e,Math.min(i,t))},saveSettings:function(){try{window.localStorage.setItem(this.storageKey,JSON.stringify(this.settings))}catch(t){}},applySettings:function(){var t=document.documentElement,e=this.settings.width,i="auto"===e?"min(40vw, 600px)":parseInt(e,10)/2+"px";t.style.setProperty("--long-article-width","auto"===e?"min(80vw, 1200px)":e+"px"),t.style.setProperty("--long-article-half-width",i),t.style.setProperty("--long-article-font-size",this.settings.desktopFontSize+"px"),this.updateWidthButtons()},bindEvents:function(){var t=this,e=document.querySelector("[data-long-article-toolbar]");e&&(e.addEventListener("click",function(i){var o=t.findActionElement(i.target,e);if(o){var n=o.getAttribute("data-long-article-action");"top"===n?t.scrollToTop():"comments"===n?t.scrollToComments():"font-decrease"===n?t.setFontSize(-2):"font-increase"===n?t.setFontSize(2):"layout"===n?t.toggleLayoutPanel():o.hasAttribute("data-long-article-width")&&t.setWidth(o.getAttribute("data-long-article-width"))}}),document.addEventListener("click",function(i){var o=document.getElementById("longArticleLayoutPanel"),n=e.querySelector('[data-long-article-action="layout"]');o&&o.classList.contains("is-open")&&!o.contains(i.target)&&!n.contains(i.target)&&t.closeLayoutPanel()}))},findActionElement:function(t,e){for(;t&&t!==e;){if(1===t.nodeType&&(t.hasAttribute("data-long-article-action")||t.hasAttribute("data-long-article-width")))return t;t=t.parentNode}return t&&t!==e&&1===t.nodeType?t:null},setFontSize:function(t){this.settings.desktopFontSize=this.normalizeFontSize(this.settings.desktopFontSize+t,12,32,18),this.saveSettings(),this.applySettings()},setWidth:function(t){this.settings.width=this.normalizeWidth(t),this.saveSettings(),this.applySettings(),this.closeLayoutPanel()},updateWidthButtons:function(){var t=this.settings.width;document.querySelectorAll("[data-long-article-width]").forEach(function(e){e.classList.toggle("is-active",e.getAttribute("data-long-article-width")===t)})},toggleLayoutPanel:function(){var t=document.getElementById("longArticleLayoutPanel"),e=document.querySelector('[data-long-article-action="layout"]');if(t&&e){var i=!t.classList.contains("is-open");t.classList.toggle("is-open",i),t.setAttribute("aria-hidden",i?"false":"true"),e.setAttribute("aria-expanded",i?"true":"false")}},closeLayoutPanel:function(){var t=document.getElementById("longArticleLayoutPanel"),e=document.querySelector('[data-long-article-action="layout"]');t&&(t.classList.remove("is-open"),t.setAttribute("aria-hidden","true")),e&&e.setAttribute("aria-expanded","false")},scrollToTop:function(){window.scrollTo({top:0,behavior:"smooth"})},scrollToComments:function(){var t=document.getElementById("comments");t&&t.scrollIntoView({behavior:"smooth"})}}; \ No newline at end of file +window.LongArticle={storageKey:"longArticleSettings",allowedWidths:["auto","600","800","1000","1200"],settings:{width:"800",desktopFontSize:18,mobileFontSize:16},init:function(){this.initialized||(this.initialized=!0,this.loadSettings(),this.bindEvents(),this.applySettings(),this.shouldOpenCommentsFromLocation()&&(this.openComments(),this.focusLocationComment()))},loadSettings:function(){var t,e={width:"800",desktopFontSize:18,mobileFontSize:16};try{t=JSON.parse(window.localStorage.getItem(this.storageKey)||"{}")}catch(e){t={}}t&&"object"==typeof t&&(e.width=this.normalizeWidth(t.width),e.desktopFontSize=this.normalizeFontSize(t.desktopFontSize||t.fontSize,18,32,18),e.mobileFontSize=this.normalizeFontSize(t.mobileFontSize,16,24,16));try{var n=parseInt(window.localStorage.getItem("longArticleFontSize"),10);t.desktopFontSize||t.fontSize||isNaN(n)||(e.desktopFontSize=this.normalizeFontSize(n,18,32,18),e.mobileFontSize=this.normalizeFontSize(n,16,24,16));var o=JSON.parse(window.localStorage.getItem("mLongArticleSettings")||"{}");t.mobileFontSize||!o||isNaN(parseInt(o.fontSize,10))||(e.mobileFontSize=this.normalizeFontSize(parseInt(o.fontSize,10),16,24,16)),window.localStorage.removeItem("longArticleFontSize"),window.localStorage.removeItem("mLongArticleSettings")}catch(t){}this.settings=e,this.saveSettings()},normalizeWidth:function(t){return t=String(t||"800"),this.allowedWidths.indexOf(t)>=0?t:"800"},normalizeFontSize:function(t,e,n,o){return t=parseInt(t,10),isNaN(t)?o:Math.max(e,Math.min(n,t))},saveSettings:function(){try{window.localStorage.setItem(this.storageKey,JSON.stringify(this.settings))}catch(t){}},applySettings:function(){var t=document.documentElement,e=this.settings.width,n="auto"===e?"min(40vw, 600px)":parseInt(e,10)/2+"px";t.style.setProperty("--long-article-width","auto"===e?"min(80vw, 1200px)":e+"px"),t.style.setProperty("--long-article-half-width",n),t.style.setProperty("--long-article-font-size",this.settings.desktopFontSize+"px"),this.updateWidthButtons()},bindEvents:function(){var t=this,e=document.querySelector("[data-long-article-toolbar]");e&&(e.addEventListener("click",function(n){var o=t.findActionElement(n.target,e);if(o){var i=o.getAttribute("data-long-article-action");"top"===i?t.scrollToTop():"comments"===i?t.toggleComments():"font-decrease"===i?t.setFontSize(-2):"font-increase"===i?t.setFontSize(2):"layout"===i?t.toggleLayoutPanel():o.hasAttribute("data-long-article-width")&&t.setWidth(o.getAttribute("data-long-article-width"))}}),document.addEventListener("click",function(n){var o=document.getElementById("longArticleLayoutPanel"),i=e.querySelector('[data-long-article-action="layout"]');o&&o.classList.contains("is-open")&&!o.contains(n.target)&&!i.contains(n.target)&&t.closeLayoutPanel(),n.target.closest&&n.target.closest("[data-long-article-comments-close]")&&t.closeComments()}),document.addEventListener("keydown",function(e){"Escape"===e.key&&t.isCommentsOpen()&&t.closeComments()}))},findActionElement:function(t,e){for(;t&&t!==e;){if(1===t.nodeType&&(t.hasAttribute("data-long-article-action")||t.hasAttribute("data-long-article-width")))return t;t=t.parentNode}return t&&t!==e&&1===t.nodeType?t:null},setFontSize:function(t){this.settings.desktopFontSize=this.normalizeFontSize(this.settings.desktopFontSize+t,12,32,18),this.saveSettings(),this.applySettings()},setWidth:function(t){this.settings.width=this.normalizeWidth(t),this.saveSettings(),this.applySettings(),this.closeLayoutPanel()},updateWidthButtons:function(){var t=this.settings.width;document.querySelectorAll("[data-long-article-width]").forEach(function(e){e.classList.toggle("is-active",e.getAttribute("data-long-article-width")===t)})},toggleLayoutPanel:function(){var t=document.getElementById("longArticleLayoutPanel"),e=document.querySelector('[data-long-article-action="layout"]');if(t&&e){var n=!t.classList.contains("is-open");t.classList.toggle("is-open",n),t.setAttribute("aria-hidden",n?"false":"true"),e.setAttribute("aria-expanded",n?"true":"false")}},closeLayoutPanel:function(){var t=document.getElementById("longArticleLayoutPanel"),e=document.querySelector('[data-long-article-action="layout"]');t&&(t.classList.remove("is-open"),t.setAttribute("aria-hidden","true")),e&&e.setAttribute("aria-expanded","false")},scrollToTop:function(){window.scrollTo({top:0,behavior:"smooth"})},getCommentsPanel:function(){return document.getElementById("articleCommentsPanel")},isCommentsOpen:function(){return document.body.classList.contains("long-article-comments-open")},toggleComments:function(){this.isCommentsOpen()?this.closeComments():this.openComments()},openComments:function(){var t=this.getCommentsPanel(),e=document.querySelector('[data-long-article-action="comments"]');t&&(this.closeLayoutPanel(),document.body.classList.add("long-article-comments-open"),t.setAttribute("aria-hidden","false"),e&&(e.classList.add("is-active"),e.setAttribute("aria-expanded","true")))},closeComments:function(){var t=this.getCommentsPanel(),e=document.querySelector('[data-long-article-action="comments"]'),n=document.querySelector(".editor-panel");n&&"none"!==window.getComputedStyle(n).display&&"0px"===window.getComputedStyle(n).bottom&&window.Comment&&"function"==typeof window.Comment._toggleReply&&window.Comment._toggleReply(),document.body.classList.remove("long-article-comments-open"),t&&t.setAttribute("aria-hidden","true"),e&&(e.classList.remove("is-active"),e.setAttribute("aria-expanded","false"))},shouldOpenCommentsFromLocation:function(){var t=this.getCommentsPanel(),e=window.location.hash.replace(/^#/,""),n=e?document.getElementById(e):null;return!!(t&&n&&t.contains(n))||/(?:\?|&)(?:p|m|sort|author)=/.test(window.location.search)},focusLocationComment:function(){var t=this;window.setTimeout(function(){var e=window.location.hash.replace(/^#/,""),n=e?document.getElementById(e):null,o=t.getCommentsPanel();o&&n&&o.contains(n)&&n.scrollIntoView({block:"center"})},0)}}; \ No newline at end of file diff --git a/src/main/resources/js/m-long-article.js b/src/main/resources/js/m-long-article.js index fa41fea0..7b6e52a8 100644 --- a/src/main/resources/js/m-long-article.js +++ b/src/main/resources/js/m-long-article.js @@ -27,6 +27,10 @@ window.MLongArticle = { this.loadSettings(); this.bindEvents(); this.applySettings(); + if (this.shouldOpenCommentsFromLocation()) { + this.openComments(); + this.focusLocationComment(); + } }, loadSettings: function () { @@ -109,21 +113,93 @@ window.MLongArticle = { } else if (action === 'top') { window.scrollTo({top: 0, behavior: 'smooth'}); } else if (action === 'comments') { - var comments = document.getElementById('comments'); - if (comments) { - comments.scrollIntoView({behavior: 'smooth'}); - } + self.toggleComments(); } else if (action === 'font-decrease') { self.setFontSize(-2); } else if (action === 'font-increase') { self.setFontSize(2); } }); + + document.addEventListener('click', function (event) { + if (event.target.closest && event.target.closest('[data-long-article-comments-close]')) { + self.closeComments(); + } + }); }, setFontSize: function (delta) { this.settings.mobileFontSize = this.normalizeFontSize(this.settings.mobileFontSize + delta, 12, 24, 16); this.saveSettings(); this.applySettings(); + }, + + getCommentsPanel: function () { + return document.getElementById('comments'); + }, + + isCommentsOpen: function () { + return document.body.classList.contains('long-article-comments-open'); + }, + + toggleComments: function () { + if (this.isCommentsOpen()) { + this.closeComments(); + } else { + this.openComments(); + } + }, + + openComments: function () { + var panel = this.getCommentsPanel(); + var button = document.querySelector('[data-long-article-action="comments"]'); + if (!panel) { + return; + } + document.body.classList.add('long-article-comments-open'); + panel.setAttribute('aria-hidden', 'false'); + if (button) { + button.classList.add('is-active'); + button.setAttribute('aria-expanded', 'true'); + } + }, + + closeComments: function () { + var panel = this.getCommentsPanel(); + var button = document.querySelector('[data-long-article-action="comments"]'); + var editorPanel = document.querySelector('.editor-panel'); + if (editorPanel && editorPanel.classList.contains('editor-panel--open') && window.Comment && typeof window.Comment._toggleReply === 'function') { + window.Comment._toggleReply(); + } + document.body.classList.remove('long-article-comments-open'); + if (panel) { + panel.setAttribute('aria-hidden', 'true'); + } + if (button) { + button.classList.remove('is-active'); + button.setAttribute('aria-expanded', 'false'); + } + }, + + shouldOpenCommentsFromLocation: function () { + var panel = this.getCommentsPanel(); + var hash = window.location.hash.replace(/^#/, ''); + var target = hash ? document.getElementById(hash) : null; + if (panel && target && panel.contains(target)) { + return true; + } + return /(?:\?|&)(?:p|m|sort|author)=/.test(window.location.search); + }, + + focusLocationComment: function () { + var self = this; + window.setTimeout(function () { + var hash = window.location.hash.replace(/^#/, ''); + var target = hash ? document.getElementById(hash) : null; + var panel = self.getCommentsPanel(); + if (panel && target && panel.contains(target)) { + target.scrollIntoView({block: 'center'}); + } + }, 0); } }; diff --git a/src/main/resources/js/m-long-article.min.js b/src/main/resources/js/m-long-article.min.js index 3246c6fe..2613b324 100644 --- a/src/main/resources/js/m-long-article.min.js +++ b/src/main/resources/js/m-long-article.min.js @@ -1 +1 @@ -window.MLongArticle={storageKey:"longArticleSettings",settings:{width:"800",desktopFontSize:18,mobileFontSize:16},init:function(){this.initialized||(this.initialized=!0,this.loadSettings(),this.bindEvents(),this.applySettings())},loadSettings:function(){var t,e={width:"800",desktopFontSize:18,mobileFontSize:16};try{t=JSON.parse(window.localStorage.getItem(this.storageKey)||"{}")}catch(e){t={}}t&&"object"==typeof t&&(e.width=["auto","600","800","1000","1200"].indexOf(String(t.width||"800"))>=0?String(t.width||"800"):"800",e.desktopFontSize=this.normalizeFontSize(t.desktopFontSize||t.fontSize,18,32,18),e.mobileFontSize=this.normalizeFontSize(t.mobileFontSize||t.fontSize,16,24,16));try{var i=parseInt(window.localStorage.getItem("longArticleFontSize"),10),o=JSON.parse(window.localStorage.getItem("mLongArticleSettings")||"{}");t.mobileFontSize||!o||isNaN(parseInt(o.fontSize,10))?t.mobileFontSize||isNaN(i)||(e.mobileFontSize=this.normalizeFontSize(i,16,24,16)):e.mobileFontSize=this.normalizeFontSize(parseInt(o.fontSize,10),16,24,16),window.localStorage.removeItem("longArticleFontSize"),window.localStorage.removeItem("mLongArticleSettings")}catch(t){}this.settings=e,this.saveSettings()},normalizeFontSize:function(t,e,i,o){return t=parseInt(t,10),isNaN(t)?o:Math.max(e,Math.min(i,t))},saveSettings:function(){try{window.localStorage.setItem(this.storageKey,JSON.stringify(this.settings))}catch(t){}},applySettings:function(){document.documentElement.style.setProperty("--long-article-font-size",this.settings.mobileFontSize+"px")},bindEvents:function(){var t=this,e=document.querySelector("[data-long-article-toolbar]");e&&e.addEventListener("click",function(i){for(var o=i.target;o&&o!==e&&!o.hasAttribute("data-long-article-action");)o=o.parentNode;if(o&&o!==e){var n=o.getAttribute("data-long-article-action");if("toggle"===n){var s=!e.classList.contains("is-open");e.classList.toggle("is-open",s),o.classList.toggle("active",s),o.setAttribute("aria-expanded",s?"true":"false")}else if("top"===n)window.scrollTo({top:0,behavior:"smooth"});else if("comments"===n){var a=document.getElementById("comments");a&&a.scrollIntoView({behavior:"smooth"})}else"font-decrease"===n?t.setFontSize(-2):"font-increase"===n&&t.setFontSize(2)}})},setFontSize:function(t){this.settings.mobileFontSize=this.normalizeFontSize(this.settings.mobileFontSize+t,12,24,16),this.saveSettings(),this.applySettings()}}; \ No newline at end of file +window.MLongArticle={storageKey:"longArticleSettings",settings:{width:"800",desktopFontSize:18,mobileFontSize:16},init:function(){this.initialized||(this.initialized=!0,this.loadSettings(),this.bindEvents(),this.applySettings(),this.shouldOpenCommentsFromLocation()&&(this.openComments(),this.focusLocationComment()))},loadSettings:function(){var t,e={width:"800",desktopFontSize:18,mobileFontSize:16};try{t=JSON.parse(window.localStorage.getItem(this.storageKey)||"{}")}catch(e){t={}}t&&"object"==typeof t&&(e.width=["auto","600","800","1000","1200"].indexOf(String(t.width||"800"))>=0?String(t.width||"800"):"800",e.desktopFontSize=this.normalizeFontSize(t.desktopFontSize||t.fontSize,18,32,18),e.mobileFontSize=this.normalizeFontSize(t.mobileFontSize||t.fontSize,16,24,16));try{var o=parseInt(window.localStorage.getItem("longArticleFontSize"),10),n=JSON.parse(window.localStorage.getItem("mLongArticleSettings")||"{}");t.mobileFontSize||!n||isNaN(parseInt(n.fontSize,10))?t.mobileFontSize||isNaN(o)||(e.mobileFontSize=this.normalizeFontSize(o,16,24,16)):e.mobileFontSize=this.normalizeFontSize(parseInt(n.fontSize,10),16,24,16),window.localStorage.removeItem("longArticleFontSize"),window.localStorage.removeItem("mLongArticleSettings")}catch(t){}this.settings=e,this.saveSettings()},normalizeFontSize:function(t,e,o,n){return t=parseInt(t,10),isNaN(t)?n:Math.max(e,Math.min(o,t))},saveSettings:function(){try{window.localStorage.setItem(this.storageKey,JSON.stringify(this.settings))}catch(t){}},applySettings:function(){document.documentElement.style.setProperty("--long-article-font-size",this.settings.mobileFontSize+"px")},bindEvents:function(){var t=this,e=document.querySelector("[data-long-article-toolbar]");e&&(e.addEventListener("click",function(o){for(var n=o.target;n&&n!==e&&!n.hasAttribute("data-long-article-action");)n=n.parentNode;if(n&&n!==e){var i=n.getAttribute("data-long-article-action");if("toggle"===i){var s=!e.classList.contains("is-open");e.classList.toggle("is-open",s),n.classList.toggle("active",s),n.setAttribute("aria-expanded",s?"true":"false")}else"top"===i?window.scrollTo({top:0,behavior:"smooth"}):"comments"===i?t.toggleComments():"font-decrease"===i?t.setFontSize(-2):"font-increase"===i&&t.setFontSize(2)}}),document.addEventListener("click",function(e){e.target.closest&&e.target.closest("[data-long-article-comments-close]")&&t.closeComments()}))},setFontSize:function(t){this.settings.mobileFontSize=this.normalizeFontSize(this.settings.mobileFontSize+t,12,24,16),this.saveSettings(),this.applySettings()},getCommentsPanel:function(){return document.getElementById("comments")},isCommentsOpen:function(){return document.body.classList.contains("long-article-comments-open")},toggleComments:function(){this.isCommentsOpen()?this.closeComments():this.openComments()},openComments:function(){var t=this.getCommentsPanel(),e=document.querySelector('[data-long-article-action="comments"]');t&&(document.body.classList.add("long-article-comments-open"),t.setAttribute("aria-hidden","false"),e&&(e.classList.add("is-active"),e.setAttribute("aria-expanded","true")))},closeComments:function(){var t=this.getCommentsPanel(),e=document.querySelector('[data-long-article-action="comments"]'),o=document.querySelector(".editor-panel");o&&o.classList.contains("editor-panel--open")&&window.Comment&&"function"==typeof window.Comment._toggleReply&&window.Comment._toggleReply(),document.body.classList.remove("long-article-comments-open"),t&&t.setAttribute("aria-hidden","true"),e&&(e.classList.remove("is-active"),e.setAttribute("aria-expanded","false"))},shouldOpenCommentsFromLocation:function(){var t=this.getCommentsPanel(),e=window.location.hash.replace(/^#/,""),o=e?document.getElementById(e):null;return!!(t&&o&&t.contains(o))||/(?:\?|&)(?:p|m|sort|author)=/.test(window.location.search)},focusLocationComment:function(){var t=this;window.setTimeout(function(){var e=window.location.hash.replace(/^#/,""),o=e?document.getElementById(e):null,n=t.getCommentsPanel();n&&o&&n.contains(o)&&o.scrollIntoView({block:"center"})},0)}}; \ No newline at end of file diff --git a/src/main/resources/scss/index.scss b/src/main/resources/scss/index.scss index f6881602..7ab18e4b 100644 --- a/src/main/resources/scss/index.scss +++ b/src/main/resources/scss/index.scss @@ -5206,6 +5206,7 @@ code .dec { } .article.long-article-page { + --long-article-comments-width: min(430px, calc(100vw - 72px)); min-height: 100vh; padding-top: 0; overflow-x: hidden; @@ -5218,6 +5219,13 @@ code .dec { display: none !important; } + #share, + .share, + .article-nav-scope, + .article-tail { + display: none !important; + } + .article-container { box-sizing: border-box; width: min(var(--long-article-width, 800px), calc(100vw - 28px)); @@ -5258,21 +5266,272 @@ code .dec { > .main { box-sizing: border-box; - margin-top: 0; - padding: 38px 0 48px; + min-height: 0; + height: 0; + margin: 0; + padding: 0; + overflow: visible; border-top: 0; - background: #c7dcc8; + background: transparent; } #articleCommentsPanel { + position: fixed; + top: 0; + right: 0; + bottom: 0; + z-index: 115; + display: flex; + flex-direction: column; box-sizing: border-box; - width: min(var(--long-article-width, 800px), calc(100vw - 28px)); + width: var(--long-article-comments-width); + height: 100vh; + height: 100dvh; max-width: none; - margin: 0 auto; - padding: 26px; + margin: 0; + padding: 0 20px 86px; + overflow-x: hidden; + overflow-y: auto; + overscroll-behavior: contain; border: 0; + border-left: 1px solid rgba(61, 91, 68, 0.14); border-radius: 0; background: #dcebdd; + box-shadow: -16px 0 38px rgba(40, 66, 47, 0.16); + transform: translateX(100%); + transition: transform 0.28s ease, visibility 0s linear 0.28s; + visibility: hidden; + + > .module { + flex: 0 0 auto; + margin: 14px 0 0; + border: 0; + background: transparent; + box-shadow: none; + } + + > .pagination { + flex: 0 0 auto; + margin: 18px auto 0; + float: none; + } + } + + &.long-article-comments-open { + #articleCommentsPanel { + transform: translateX(0); + transition-delay: 0s; + visibility: visible; + } + + .long-article-settings { + right: calc(var(--long-article-comments-width) + 14px); + left: auto; + z-index: 121; + } + } + + #comments { + order: -1; + margin: 0; + border: 0; + background: transparent; + box-shadow: none; + + .comments-header { + position: sticky; + top: 0; + z-index: 4; + margin: 0 -20px 6px; + padding: 22px 20px 16px; + border-bottom: 1px solid rgba(65, 94, 71, 0.14); + background: rgba(220, 235, 221, 0.97); + backdrop-filter: blur(8px); + } + + .comments-header__main > .fn-right { + display: none; + } + + .article-cmt-cnt { + color: #1f2e24; + font-size: 22px; + font-weight: 650; + } + + .long-article-comments-count { + margin-left: 4px; + color: #77857c; + font-size: 13px; + font-weight: 400; + } + + .comment-filterbar { + margin-top: 12px; + } + + .comment-segment { + border-color: rgba(65, 94, 71, 0.15); + background: #edf5ed; + } + + .comments-header a.comment-segment__item { + color: #68776e; + } + + .comments-header a.comment-segment__item:hover { + color: #2f4937; + background: rgba(255, 255, 255, 0.42); + } + + .comments-header a.comment-segment__item--active, + .comments-header a.comment-segment__item--active:hover { + background: #5f7e68; + color: #fff; + } + + .list { + background: transparent; + } + + .list > ul { + margin: 0; + padding: 0 0 12px; + } + + .list > ul > li, + .list > ul > li.cmt-perfect, + .list > ul > li.cmt-perfect:hover { + margin: 0; + padding: 18px 0; + border-bottom: 1px solid rgba(65, 94, 71, 0.12); + background: transparent; + } + + .list > ul > li > .fn-flex { + align-items: flex-start; + gap: 2px; + } + + .list > ul > li .avatar { + width: 34px; + height: 34px; + border-radius: 50%; + } + + .comment-info { + min-height: 22px; + color: #6f7d74; + line-height: 1.55; + } + + .comment-info a, + .comment-thread__meta a { + color: #405647; + font-weight: 600; + } + + .comment { + margin: 7px 0 0; + color: #243128; + font-size: 15px; + line-height: 1.75; + } + + .comment-action { + margin-top: 8px; + } + + .comment-thread { + margin: 12px 0 4px; + padding: 12px; + border: 0; + border-radius: 8px; + background: #edf5ed; + } + + .comment-thread__reply--nested::before, + .comment-thread__reply + .comment-thread__reply { + border-color: rgba(65, 94, 71, 0.12); + } + + .comment-thread__content { + color: #34463a; + } + + .comment__reply { + position: fixed; + right: 0; + bottom: 0; + z-index: 5; + box-sizing: border-box; + width: 100%; + margin: 0; + padding: 14px 20px; + border-top: 1px solid rgba(65, 94, 71, 0.14); + background: rgba(220, 235, 221, 0.97); + box-shadow: 0 -8px 22px rgba(40, 66, 47, 0.08); + backdrop-filter: blur(8px); + + .reply__text { + min-height: 38px; + box-sizing: border-box; + border-color: rgba(65, 94, 71, 0.14); + border-radius: 8px; + background: #edf5ed; + color: #65746a; + line-height: 36px; + } + } + } + + .long-article-comments-close { + display: inline-flex; + flex: 0 0 34px; + align-items: center; + justify-content: center; + width: 34px; + height: 34px; + margin-left: auto; + padding: 0; + border: 0; + border-radius: 50%; + background: rgba(95, 126, 104, 0.12); + box-shadow: none; + color: #617068; + + &:hover { + background: rgba(95, 126, 104, 0.2); + box-shadow: none; + color: #2f4937; + } + + svg { + width: 18px; + height: 18px; + } + } + + .editor-panel { + right: 0; + left: auto; + width: var(--long-article-comments-width); + max-width: var(--long-article-comments-width); + + .editor-bg { + display: none; + } + + .wrapper { + right: 0; + left: auto; + width: 100%; + max-width: 100%; + padding: 16px 20px 20px; + border-top: 1px solid rgba(65, 94, 71, 0.16); + background: #dcebdd; + box-shadow: 0 -12px 30px rgba(40, 66, 47, 0.16); + } } .article-footer { @@ -5574,6 +5833,11 @@ code .dec { transform: translateX(2px); } + &.is-active { + background: #3e7250; + color: #fff; + } + svg { width: 20px; height: 20px; @@ -5677,6 +5941,67 @@ body.night { #articleCommentsPanel { background: #111111; + border-left-color: rgba(255, 255, 255, 0.08); + box-shadow: -16px 0 38px rgba(0, 0, 0, 0.34); + } + + #comments { + .comments-header, + .comment__reply { + border-color: rgba(255, 255, 255, 0.08); + background: rgba(17, 17, 17, 0.97); + } + + .article-cmt-cnt { + color: #eef4ef; + } + + .long-article-comments-count, + .comment-info { + color: #858f88; + } + + .comment-segment, + .comment-thread, + .comment__reply .reply__text { + border-color: rgba(255, 255, 255, 0.08); + background: #191919; + } + + .comments-header a.comment-segment__item, + .comment-info a, + .comment-thread__meta a { + color: #aab4ad; + } + + .comments-header a.comment-segment__item--active, + .comments-header a.comment-segment__item--active:hover { + background: #465c4d; + color: #fff; + } + + .list > ul > li, + .list > ul > li.cmt-perfect, + .list > ul > li.cmt-perfect:hover { + border-color: rgba(255, 255, 255, 0.08); + background: transparent; + } + + .comment, + .comment-thread__content { + color: #b9c2bc; + } + } + + .long-article-comments-close { + background: #191919; + color: #989898; + } + + .editor-panel .wrapper { + border-color: rgba(255, 255, 255, 0.08); + background: #191919; + box-shadow: 0 -12px 30px rgba(0, 0, 0, 0.34); } } @@ -5824,6 +6149,8 @@ body.night { @media (max-width: 768px) { .article.long-article-page { + --long-article-comments-width: calc(100vw - 20px); + .article-container { margin-top: 0; border-radius: 0; @@ -5843,7 +6170,7 @@ body.night { } #articleCommentsPanel { - padding: 18px; + padding: 0 18px 82px; border-radius: 0; } } diff --git a/src/main/resources/scss/mobile-base.scss b/src/main/resources/scss/mobile-base.scss index b344aac0..2679a564 100644 --- a/src/main/resources/scss/mobile-base.scss +++ b/src/main/resources/scss/mobile-base.scss @@ -5503,6 +5503,7 @@ only screen and (device-width: 414px) and (device-height: 896px) and (-webkit-de } body.long-article-page { + --long-article-comments-width: min(430px, 100vw); min-height: 100vh; width: 100%; margin: 0; @@ -5518,6 +5519,13 @@ body.long-article-page { display: none !important; } + #share, + .share, + .article-nav-scope, + .article-tail { + display: none !important; + } + > .main { box-sizing: border-box; margin: 0; @@ -5579,12 +5587,222 @@ body.long-article-page { } #comments { + position: fixed; + top: 0; + right: 0; + bottom: 0; + z-index: 115; box-sizing: border-box; - margin: 20px 0 0; - padding: 20px 14px; + width: var(--long-article-comments-width); + height: 100vh; + height: 100dvh; + margin: 0; + padding: 0 14px calc(78px + env(safe-area-inset-bottom)); + overflow-x: hidden; + overflow-y: auto; + overscroll-behavior: contain; border: 0; + border-left: 1px solid rgba(61, 91, 68, 0.14); border-radius: 0; background: #dcebdd; + box-shadow: -12px 0 30px rgba(40, 66, 47, 0.16); + transform: translateX(100%); + transition: transform 0.28s ease, visibility 0s linear 0.28s; + visibility: hidden; + + .list.comments { + border: 0; + background: transparent; + box-shadow: none; + } + + .comments-header { + position: sticky; + top: 0; + z-index: 4; + margin: 0 -14px 6px; + padding: 18px 14px 14px; + border-bottom: 1px solid rgba(65, 94, 71, 0.14); + background: rgba(220, 235, 221, 0.97); + backdrop-filter: blur(8px); + } + + .comments-header__main > .fn-right { + display: none; + } + + .article-cmt-cnt { + color: #1f2e24; + font-size: 20px; + font-weight: 650; + } + + .long-article-comments-count { + margin-left: 4px; + color: #77857c; + font-size: 12px; + font-weight: 400; + } + + .comment-filterbar { + margin-top: 10px; + } + + .comment-segment { + border-color: rgba(65, 94, 71, 0.15); + background: #edf5ed; + } + + .comments-header a.comment-segment__item { + color: #68776e; + } + + .comments-header a.comment-segment__item--active, + .comments-header a.comment-segment__item--active:hover { + background: #5f7e68; + color: #fff; + } + + .list.comments > ul { + margin: 0; + padding: 0 0 10px; + } + + .list.comments > ul > li, + .list.comments > ul > li.cmt-perfect, + .list.comments > ul > li.cmt-perfect:hover { + margin: 0; + padding: 16px 0; + border-bottom: 1px solid rgba(65, 94, 71, 0.12); + background: transparent; + } + + .list.comments > ul > li .avatar { + width: 32px; + height: 32px; + border-radius: 50%; + } + + .comment-info { + color: #6f7d74; + line-height: 1.5; + } + + .comment-info a, + .comment-thread__meta a { + color: #405647; + font-weight: 600; + } + + .comment { + margin-top: 6px; + color: #243128; + font-size: 15px; + line-height: 1.7; + } + + .comment-thread { + margin: 10px 0 4px; + padding: 10px; + border: 0; + border-radius: 8px; + background: #edf5ed; + } + + .comment-thread__content { + color: #34463a; + } + + .comment__reply { + position: fixed; + right: 0; + bottom: 0; + z-index: 5; + box-sizing: border-box; + width: 100%; + margin: 0; + padding: 12px 14px calc(12px + env(safe-area-inset-bottom)); + border-top: 1px solid rgba(65, 94, 71, 0.14); + background: rgba(220, 235, 221, 0.97); + box-shadow: 0 -8px 22px rgba(40, 66, 47, 0.08); + backdrop-filter: blur(8px); + + .reply__text { + min-height: 38px; + border-color: rgba(65, 94, 71, 0.14); + border-radius: 8px; + background: #edf5ed; + color: #65746a; + line-height: 36px; + } + } + } + + &.long-article-comments-open #comments { + transform: translateX(0); + transition-delay: 0s; + visibility: visible; + } + + &.long-article-comments-open { + .long-article-settings { + z-index: 121; + } + + .long-article-settings__actions { + opacity: 1; + pointer-events: auto; + transform: translateY(0); + visibility: visible; + } + + .long-article-settings__actions > :not([data-long-article-action="comments"]), + .long-article-toggle-btn { + display: none; + } + } + + .long-article-comments-close { + display: inline-flex; + flex: 0 0 32px; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + margin-left: auto; + padding: 0; + border: 0; + border-radius: 50%; + background: rgba(95, 126, 104, 0.12); + box-shadow: none; + color: #617068; + + svg { + width: 17px; + height: 17px; + } + } + + .editor-panel { + right: 0; + left: auto; + width: var(--long-article-comments-width); + max-width: var(--long-article-comments-width); + + .editor-bg { + display: none; + } + + .wrapper { + right: 0; + left: auto; + width: 100%; + max-width: 100%; + border-radius: 10px 0 0; + border-top: 1px solid rgba(65, 94, 71, 0.16); + background: #dcebdd; + box-shadow: 0 -12px 30px rgba(40, 66, 47, 0.16); + } } .side { @@ -5917,6 +6135,11 @@ body.long-article-page { &.ft-red { color: #f44336; } + + &.is-active { + background: #3e7250; + color: #fff; + } } .long-article-toggle-btn { @@ -5962,6 +6185,65 @@ body.night { #comments { background: #111111; + border-left-color: rgba(255, 255, 255, 0.08); + box-shadow: -12px 0 30px rgba(0, 0, 0, 0.34); + + .comments-header, + .comment__reply { + border-color: rgba(255, 255, 255, 0.08); + background: rgba(17, 17, 17, 0.97); + } + + .article-cmt-cnt { + color: #eef4ef; + } + + .long-article-comments-count, + .comment-info { + color: #858f88; + } + + .comment-segment, + .comment-thread, + .comment__reply .reply__text { + border-color: rgba(255, 255, 255, 0.08); + background: #191919; + } + + .comments-header a.comment-segment__item, + .comment-info a, + .comment-thread__meta a { + color: #aab4ad; + } + + .comments-header a.comment-segment__item--active, + .comments-header a.comment-segment__item--active:hover { + background: #465c4d; + color: #fff; + } + + .list.comments > ul > li, + .list.comments > ul > li.cmt-perfect, + .list.comments > ul > li.cmt-perfect:hover { + border-color: rgba(255, 255, 255, 0.08); + background: transparent; + } + + .comment, + .comment-thread__content { + color: #b9c2bc; + } + } + + .long-article-comments-close { + background: #191919; + color: #989898; + } + + .editor-panel .wrapper { + border-color: rgba(255, 255, 255, 0.08); + background: #191919; + box-shadow: 0 -12px 30px rgba(0, 0, 0, 0.34); } } diff --git a/src/main/resources/skins/classic/mobile/article.ftl b/src/main/resources/skins/classic/mobile/article.ftl index fae445b0..ea423cd0 100644 --- a/src/main/resources/skins/classic/mobile/article.ftl +++ b/src/main/resources/skins/classic/mobile/article.ftl @@ -379,10 +379,15 @@
<#if article.articleCommentCount != 0>
@@ -507,7 +512,7 @@ - +
<#if article.articleCommentCount != 0>
@@ -765,7 +770,7 @@ - "},renderThreadPagination:function(e,t,n){if(e.find(".comment-thread__pager").remove(),n&&!(parseInt(n.paginationPageCount||0)<=1)){var i=parseInt(n.paginationCurrentPageNum||1),o=parseInt(n.paginationPageCount||1),r=['
'];i>1&&r.push(Comment.renderThreadPageButton(t,i-1,"上一页")),r.push('',i,"/",o,""),i"),e.append(r.join(""))}},getCommentQueryExtra:function(){return Label.commentQueryExtra||""},normalizeReactionSummary:function(e){if(Array.isArray(e))return e;if("string"!=typeof e||""===e)return[];try{var t=JSON.parse(e);return Array.isArray(t)?t:[]}catch(e){return[]}},getReactionMap:function(e){e=Comment.normalizeReactionSummary(e);for(var t={},n=0;n/g,">")},getReactionUserDetails:function(e){return e&&Array.isArray(e.userDetails)?e.userDetails:[]},renderReactionTip:function(e){var t=Comment.getReactionUserDetails(e);if(0===t.length)return"";for(var n=[],i=0;i'),n.push('',Comment.escapeReactionHtml(s),''),n.push("")}}return 0===n.length?"":''+n.join("")+""},renderReactionSummaryItems:function(e,t,n){for(var i=Comment.getReactionMap(t),o=[],r=0;r'),o.push('"),""!==m&&o.push(m,"")}}return o.join("")},renderReactionPanel:function(e,t){for(var n=['
'],i=0;i"),n.push('',o.emoji,""),n.push("")}return n.push("
"),n.join("")},renderReactionSummaryWidget:function(e,t,n){var i=Comment.renderReactionSummaryItems(e,t,n),o=['
'];return o.push('
'),o.push('
',i,"
"),o.join("")},renderReactionTriggerWidget:function(e,t,n){var i=n?" is-open":"",o=['
'];return o.push('"),o.push(Comment.renderReactionPanel(e,t)),o.push("
"),o.join("")},renderReactionBar:function(e,t,n,i,o){if("summary"===o)return Comment.renderReactionSummaryWidget(e,t,n);if("trigger"===o)return Comment.renderReactionTriggerWidget(e,n,i);var r=i?" is-open":"",a=Comment.renderReactionSummaryItems(e,t,n),s=['
'];return s.push('
'),s.push('
',a,"
"),s.push('
"),s.push(Comment.renderReactionPanel(e,n)),s.push("
"),s.join("")},getReactionWidgets:function(e){return $('.comment-reaction[data-target-id="'+e+'"]')},getInteractiveReactionWidgets:function(e){return $('.comment-reaction--combined[data-target-id="'+e+'"], .comment-reaction--trigger[data-target-id="'+e+'"]')},mountReactionTrigger:function(e,t,n,i){if(0!==e.length){var o=Comment.renderReactionBar(t,[],n,i,"trigger"),r=e.find('.comment-reaction--trigger[data-target-id="'+t+'"]');r.length>0?r.replaceWith(o):e.prepend(o)}},collectReactionShells:function(e){var t=e?$(e):$(document);return t.hasClass("comment-reaction-shell")?t.add(t.find(".comment-reaction-shell")):t.find(".comment-reaction-shell")},initReactionWidgets:function(e){Comment.collectReactionShells(e).each(function(){var e=$(this),t=e.attr("data-target-id"),n=e.attr("data-summary"),i=e.attr("data-current-user-reaction")||"",o=e.closest(".comment-action__bar").find(".action-btns").first(),r=e.closest(".comment-action__left").length>0&&o.length>0,a=Comment.renderReactionBar(t,n,i,!1,r?"summary":"combined");e.replaceWith(a),r&&Comment.mountReactionTrigger(o,t,i,!1)})},closeReactionPanels:function(e){var t=e?$(e):$(document),n=".comment-reaction--combined, .comment-reaction--trigger";(t.is(n)?t.add(t.find(n)):t.find(n)).removeClass("is-open")},toggleReactionPanel:function(e){var t=$(e).closest(".comment-reaction"),n=t.attr("data-target-id"),i=!t.hasClass("is-open");Comment.closeReactionPanels(),i&&Comment.getInteractiveReactionWidgets(n).addClass("is-open")},bindReactionPanels:function(){$(document).off("click.commentReaction").on("click.commentReaction",function(e){0===$(e.target).closest(".comment-reaction").length&&Comment.closeReactionPanels()})},updateReactionBars:function(e,t,n,i){var o=Comment.getReactionWidgets(e),r="boolean"==typeof i?i:Comment.getInteractiveReactionWidgets(e).first().hasClass("is-open");o.each(function(){var i=$(this),o="combined";i.hasClass("comment-reaction--summary")?o="summary":i.hasClass("comment-reaction--trigger")&&(o="trigger"),i.replaceWith(Comment.renderReactionBar(e,t,n,r,o))})},updateReactionFromChannel:function(e){var t=e.targetId||e.commentId;if(t){var n=Comment.getReactionWidgets(t);if(0!==n.length){var i=e.actorUserId===Label.currentUserId?e.actorReaction||"":n.first().attr("data-current-user-reaction")||"";Comment.updateReactionBars(t,e.summary||[],i,!1)}}},react:function(e,t,n){if(!Label.isLoggedIn)return Util.needLogin(),!1;var i=$(n).closest(".comment-reaction");if("true"===i.attr("data-loading"))return!1;$.ajax({url:Label.servePath+"/comment/reaction",type:"POST",data:JSON.stringify({commentId:e,groupType:"emoji",value:t}),beforeSend:function(){i.attr("data-loading","true").addClass("reaction-loading")},success:function(e){0===e.code?Comment.updateReactionBars(e.data.targetId,e.data.summary,e.data.currentUserReaction,!1):Util.alert(e.msg)},error:function(e){Util.alert(e.statusText)},complete:function(){i.removeAttr("data-loading").removeClass("reaction-loading")}})},report:function(e){var t=$(e);t.attr("disabled","disabled").css("opacity","0.3"),$.ajax({url:Label.servePath+"/report",type:"POST",cache:!1,data:JSON.stringify({reportDataId:$("#reportDialog").data("id"),reportDataType:$("#reportDialog").data("type"),reportType:$("input[name=report]:checked").val(),reportMemo:$("#reportTextarea").val()}),complete:function(e){t.removeAttr("disabled").css("opacity","1"),0===e.responseJSON.code?(Util.alert(Label.reportSuccLabel),$("#reportTextarea").val(""),$("#reportDialog").dialog("close")):Util.alert(e.responseJSON.msg)}})},accept:function(e,t,n){confirm(e)&&$.ajax({url:Label.servePath+"/comment/accept",type:"POST",headers:{csrfToken:Label.csrfToken},cache:!1,data:JSON.stringify({commentId:t}),success:function(e){0===e.code?($(n).closest("li").addClass("cmt-perfect"),$(n).remove()):Util.alert(e.msg)}})},remove:function(e){if(!confirm("删除评论需要100积分,"+Label.confirmRemoveLabel))return!1;$.ajax({url:Label.servePath+"/comment/"+e+"/remove",type:"POST",cache:!1,success:function(t,n){0===t.code?$("#"+e).remove():Util.alert(t.msg)}})},exchangeCmtSort:function(e){e=0===e?1:0;var t=Comment.getCommentQueryExtra().replace("&sort=hot","");window.location.href=window.location.pathname+"?m="+e+t+"#comments"},_bgFade:function(e,t){return 0!==e.length&&(!1!==(t=t||{}).scroll&&$(window).scrollTop(e[0].offsetTop-48),"comments"!==e.attr("id")&&!1!==t.highlight&&($(".comment-focus-highlight").removeClass("comment-focus-highlight"),e.addClass("comment-focus-highlight"),setTimeout(function(){e.removeClass("comment-focus-highlight")},1800),!0))},edit:function(e){Comment._toggleReply(),$(".cmt-anonymous").hide(),$.ajax({url:Label.servePath+"/comment/"+e+"/content",type:"GET",cache:!1,success:function(e,t){0===e.code&&Comment.editor.setValue(e.commentContent)}}),$("#replyUseName").html(' '+Label.commonUpdateCommentPermissionLabel+"").data("commentId",e)},goComment:function(e){var t=Comment.getCommentHashId(e);return(!t||!Comment.focusCommentById(t))&&(t&&Comment.isSameCommentPage(e)?(Comment.expandThreadForComment(t),!1):(window.location=e,!1))},focusCommentElement:function(e,t){return Comment._bgFade(e,t)},focusCommentById:function(e,t){var n=Comment.getCommentElement(e);return 1===n.length&&Comment.focusCommentElement(n,t)},focusLocationHash:function(){var e=Comment.getCommentHashId(window.location.hash);return!!e&&(!!Comment.focusCommentById(e)||Comment.expandThreadForComment(e))},expandThreadForComment:function(e){return $.ajax({url:Label.servePath+"/comment/thread/replies",type:"POST",data:JSON.stringify({commentId:e,anchorCommentId:e,userCommentViewMode:Label.userCommentViewMode,sort:Label.commentSort,author:Label.commentAuthorFilter?"1":""}),success:function(t){if(0!==t.code)return!1;Comment.renderThreadResponse(t.commentThreadRootId,t.commentThreadReplies||[],e,{pagination:t.pagination})}}),!0},renderThreadResponse:function(e,t,n,i){i=i||{};var o=Comment.getCommentElement(e);if(1!==o.length)return!1;var r=Comment.ensureThread(o,e);return r.find(".comment-thread__list").html(Comment.renderThreadReplies(t)),r.addClass("comment-thread--expanded"),r.find(".comment-thread__more").remove(),Comment.renderThreadPagination(r,e,i.pagination),Comment.initReactionWidgets(r),Util.listenUserCard(),Util.parseHljs(),Util.parseMarkdown(),!1===i.focus||!n||Comment.focusCommentById(n)},_toggleReply:function(e){return Label.isLoggedIn?0===$("#commentContent").length?(Util.alert(Label.notAllowCmtLabel),!1):"false"===$(this).data("hasPermission")?(Article.permissionTip(Label.noPermissionLabel),!1):$(".footer").attr("style")?($(".editor-panel .wrapper").slideUp(function(){$(".editor-panel").fadeOut(100),$(".footer").removeAttr("style")}),!1):($(".cmt-anonymous").show(),$(".footer").css("margin-bottom",$(".editor-panel > .wrapper").outerHeight()+"px"),$("#replyUseName").html(''+$(".article-title").text().replace(//g,">")+"").removeData(),"0px"!==$(".editor-panel").css("bottom")&&($(".editor-panel .wrapper").hide(),$(".editor-panel").css("bottom",0)),$(".editor-panel").show(),void $(".editor-panel .wrapper").slideDown(function(){Comment.editor.focus(),e&&e()})):(Util.needLogin(),!1)},loadEmojis:function(){let e=Comment.getEmojis(),t="";for(let n=0;n\n
\n \n`;$("#emojis").html(t)},confirmed:!1,delEmoji:function(e){if(!0===Comment.confirmed||confirm("确定要删除该表情包吗?")){Comment.confirmed=!0;let t=Comment.getEmojis();for(let n=0;n5242880?Util.alert("图片过大 (最大限制 5M)"):t.submit():Util.alert("只允许上传图片!")}}else t.submit()},formData:function(e){return e.serializeArray()},submit:function(e,t){},done:function(e,t){var n={result:{key:t.result.data.succMap[Object.keys(t.result.data.succMap)[0]]}};Comment.addEmoji(n.result.key)},fail:function(e,t){Util.alert("Upload error: "+t.errorThrown)}})},fromURL:function(){Util.alert('
\n\n
\n
\n \n
\n
',"从URL导入表情包"),$("#fromURL").focus(),$("#fromURL").unbind(),$("#fromURL").bind("keypress",function(e){"13"==e.keyCode&&(Comment.addEmoji($("#fromURL").val()),Util.closeAlert())})},addEmoji:function(){if(0!==arguments.length){var e=[];if(1===arguments.length&&Array.isArray(arguments[0]))e=arguments[0];else for(var t=0;t ul > li.focus").length&&"x"===Util.prevKey&&$("#comments .list > ul > li.focus .icon-reply").parent().click():Comment._toggleReply(),!1}).bind("keyup","h",function(){return 1===$("#comments .list > ul > li.focus").length&&"x"===Util.prevKey&&$("#comments .list > ul > li.focus .icon-heart").parent().click(),!1}).bind("keyup","t",function(){return 1===$("#comments .list > ul > li.focus").length&&"x"===Util.prevKey&&$("#comments .list > ul > li.focus .icon-thumbs-up").parent().click(),!1}).bind("keyup","d",function(){return 1===$("#comments .list > ul > li.focus").length&&"x"===Util.prevKey&&$("#comments .list > ul > li.focus .icon-thumbs-down").parent().click(),!1}).bind("keyup","c",function(){return 1===$("#comments .list > ul > li.focus .comment-info .icon-reply-to").length&&"x"===Util.prevKey&&$("#comments .list > ul > li.focus .comment-info .icon-reply-to").parent().click(),!1}).bind("keyup","m",function(){return 1===$("#comments .list > ul > li.focus .comment-action > .ft-fade > .fn-pointer").length&&"x"===Util.prevKey&&$("#comments .list > ul > li.focus .comment-action > .ft-fade > .fn-pointer").click(),!1}).bind("keyup","a",function(){return"x"===Util.prevKey&&1===$("#comments .list > ul > li.focus .icon-setting").parent().length&&(window.location=$("#comments .list > ul > li.focus .icon-setting").parent().attr("href")),!1}).bind("keyup","m",function(){return"v"===Util.prevKey&&Article.toggleToc(),!1}).bind("keyup","h",function(){return"v"===Util.prevKey&&$("#thankArticle").click(),!1}).bind("keyup","t",function(){return"v"===Util.prevKey&&$(".article-header .icon-thumbs-up").parent().click(),!1}).bind("keyup","d",function(){return"v"===Util.prevKey&&$(".article-header .icon-thumbs-down").parent().click(),!1}).bind("keyup","i",function(){return"v"===Util.prevKey&&$(".article-header .icon-view").parent().click(),!1}).bind("keyup","c",function(){return"v"===Util.prevKey&&$(".article-header .icon-star").parent().click(),!1}).bind("keyup","l",function(){return"v"===Util.prevKey&&$(".article-header .icon-history").parent().click(),!1}).bind("keyup","e",function(){return"v"===Util.prevKey&&1===$(".article-actions .icon-edit").parent().length&&(window.location=$(".article-actions .icon-edit").parent().attr("href")),!1}).bind("keyup","s",function(){return"v"===Util.prevKey&&1===$(".article-actions .icon-chevron-up").length&&Article.stick(Label.articleOId),!1}).bind("keyup","a",function(){return"v"===Util.prevKey&&1===$(".article-actions .icon-setting").parent().length&&(window.location=$(".article-actions .icon-setting").parent().attr("href")),!1}).bind("keyup","p",function(){return"v"===Util.prevKey&&1===$(".article-header a[rel=prev]").length&&(window.location=$(".article-header a[rel=prev]").attr("href")),!1}).bind("keyup","n",function(){return"v"===Util.prevKey&&1===$(".article-header a[rel=next]").length&&(window.location=$(".article-header a[rel=next]").attr("href")),!1})},init:function(){if($("#sendComment").click(function(){Comment._toggleReply()}),Comment.focusLocationHash(),this._initHotKey(),$.pjax({selector:"#comments .pagination a",container:"#comments",show:"",cache:!1,storage:!0,titleSuffix:"",callback:function(){Comment.initReactionWidgets($("#comments")),Util.parseMarkdown(),Util.parseHljs(),Util.listenUserCard(),Comment.focusLocationHash()}}),NProgress.configure({showSpinner:!1}),$("#comments").bind("pjax.start",function(){NProgress.start()}),$("#comments").bind("pjax.end",function(){NProgress.done()}),ArticleReaction.bindPanels(),ArticleReaction.initWidgets(),Comment.bindReactionPanels(),Comment.initReactionWidgets($("#comments")),!Label.isLoggedIn||!document.getElementById("commentContent"))return!1;Comment.editor=Util.newVditor({id:"commentContent",cache:!0,preview:{mode:"editor"},resize:{enable:!0,position:"top"},height:200,placeholder:Label.commentEditorPlaceholderLabel,ctrlEnter:function(){Comment.add(Label.articleOId,Label.csrfToken,document.getElementById("articleCommentBtn"))},esc:function(){$(".editor-hide").click()}})},thank:function(e,t,n,i,o){if(!Label.isLoggedIn)return Util.needLogin(),!1;if(0===i&&!confirm(n))return!1;var r={commentId:e};$.ajax({url:Label.servePath+"/comment/thank",type:"POST",headers:{csrfToken:t},cache:!1,data:JSON.stringify(r),error:function(e,t,n){Util.alert(n)},success:function(e,t){if(0===e.code){$(o).removeAttr("onclick");var n=$(''),i=$(o).offset().top,r=$(o).offset().left;n.css({"z-index":9999,top:i,left:r,position:"absolute","font-size":16,"-moz-user-select":"none","-webkit-user-select":"none","-ms-user-select":"none"}),$("body").append(n),n.animate({left:r-150,top:i-60,opacity:0},1e3,function(){var e=parseInt($(o).text());$(o).html(' '+(e+1)).addClass("ft-red"),n.remove()})}else Util.alert(e.msg)}})},showReply:function(e,t,n){var i=$(t).closest("li").find("."+n);if("comment-get-comment"===n){if(0!==i.find("li").length)return i.html(""),!1}else if(0===$(t).find(".icon-chevron-down").length)return $(t).find(".icon-chevron-up").removeClass("icon-chevron-up").addClass("icon-chevron-down").find("use").attr("xlink:href","#chevron-down"),i.html(""),!1;if("0.3"===$(t).css("opacity"))return!1;var o="/comment/replies";"comment-get-comment"===n&&(o="/comment/original"),$.ajax({url:Label.servePath+o,type:"POST",data:JSON.stringify({commentId:e,userCommentViewMode:Label.userCommentViewMode}),beforeSend:function(){$(t).css("opacity","0.3")},success:function(e,n){if(0!==e.code)return Util.alert(e.msg),!1;var o=e.commentReplies,r="";o instanceof Array||(o=[o]),0===o.length&&(r='
  • '+Label.removedLabel+"
  • ");for(var a=0;a
    ',r+='',r+='
    ',r+="
    ",r+='
    ',r+='',r+=Comment.renderCommentAuthorName(s),r+="",r+=Comment.renderOriginalAuthorLabel(s),r+=' • '+s.timeAgo,s.rewardedCnt>0&&(r+=' '+s.rewardedCnt+" "),r+="",r+='
    '+s.commentContent+"
    "+Comment.renderReactionBar(s.oId,s.reactionSummary,s.currentUserReaction)+"
    "}i.html("
      "+r+"
    "),Util.parseHljs(),Util.parseMarkdown(),$(t).find(".icon-chevron-down").removeClass("icon-chevron-down").addClass("icon-chevron-up").find("use").attr("xlink:href","#chevron-up")},error:function(e){Util.alert(e.statusText)},complete:function(){$(t).css("opacity","1")}})},showThreadReplies:function(e,t,n){if("0.3"===$(t).css("opacity"))return!1;$.ajax({url:Label.servePath+"/comment/thread/replies",type:"POST",data:JSON.stringify({commentId:e,paginationCurrentPageNum:n||1}),beforeSend:function(){$(t).css("opacity","0.3")},success:function(t){if(0!==t.code)return Util.alert(t.msg),!1;Comment.renderThreadResponse(t.commentThreadRootId||e,t.commentThreadReplies||[],null,{focus:!1,pagination:t.pagination})},error:function(e){Util.alert(e.statusText)},complete:function(){$(t).css("opacity","1")}})},add:function(e,t,n){var i={articleId:e,commentAnonymous:$("#commentAnonymous").prop("checked"),commentVisible:$("#commentVisible").prop("checked"),commentContent:Comment.editor.getValue(),userCommentViewMode:Label.userCommentViewMode};$("#replyUseName").data("commentOriginalCommentId")&&(i.commentOriginalCommentId=$("#replyUseName").data("commentOriginalCommentId"));var o=Label.servePath+"/comment",r="POST",a=$("#replyUseName").data("commentId");a&&(o=Label.servePath+"/comment/"+a,r="PUT"),$.ajax({url:o,type:r,headers:{csrfToken:t},cache:!1,data:JSON.stringify(i),beforeSend:function(){$(n).attr("disabled","disabled").css("opacity","0.3")},success:function(e,t){$(n).removeAttr("disabled").css("opacity","1"),0===e.code?(a&&(Comment.updateEditedCommentContent(a,e.commentContent),Comment.updateCommentHistoryAction(a,parseInt(e.commentRevisionCount||0))),i.commentOriginalCommentId&&Util.setUnreadNotificationCount(),Comment.editor.setValue(""),$(".editor-hide").click(),$("#replyUseName").text("").removeData(),i.commentOriginalCommentId&&Comment.focusCommentById(i.commentOriginalCommentId,{scroll:!1})):$("#addCommentTip").addClass("error").html("
    • "+e.msg+"
    ")},error:function(e){$("#addCommentTip").addClass("error").html("
    • "+e.statusText+"
    ")},complete:function(){$(n).removeAttr("disabled").css("opacity","1"),setTimeout(Util.listenUserCard,1e3)}})},reply:function(e,t){Comment._toggleReply(function(){var e=Comment.getCommentElement(t);0!==e.length&&$(window).height()-(e[0].offsetTop-$(window).scrollTop()+e.outerHeight())<$(".editor-panel .wrapper").outerHeight()&&$(window).scrollTop(e[0].offsetTop-($(window).height()-$(".editor-panel .wrapper").outerHeight()-e.outerHeight()))});var n="",i=Comment.escapeHTML(e),o=Comment.getCommentElement(t),r=o.find(">.fn-flex>div>a").clone();0===r.length&&(r=o.find(">.fn-flex .avatar").clone()),0===r.length?n=' '+i+"":r.is("a")?(r.addClass("ft-a-title").attr("href","#"+t).attr("onclick",'Comment._bgFade($("#'+t+'"))'),r.find("div").removeClass("avatar").addClass("avatar-small").after(" "+i).before(' '),n=r[0].outerHTML):(r.removeClass("avatar").addClass("avatar-small"),n=' '+r[0].outerHTML+" "+i+""),$("#replyUseName").html(n).data("commentOriginalCommentId",t)}},ArticleReaction={renderSummaryItems:function(e,t,n){for(var i=Comment.getReactionMap(t),o=[],r=0;r'),o.push('"),""!==m&&o.push(m,"")}}return o.join("")},renderPanel:function(e,t){for(var n=['
    '],i=0;i"),n.push('',o.emoji,""),n.push("")}return n.push("
    "),n.join("")},renderBar:function(e,t,n,i){var o=i?" is-open":"",r=['
    '];return r.push('
    '),r.push('
    ',ArticleReaction.renderSummaryItems(e,t,n),"
    "),r.push('
    "),r.push(ArticleReaction.renderPanel(e,n)),r.push("
    "),r.join("")},collectShells:function(e){var t=e?$(e):$(document);return t.hasClass("article-reaction-shell")?t.add(t.find(".article-reaction-shell")):t.find(".article-reaction-shell")},ensureShell:function(){if(!($(".article-reaction-shell, .article-reaction").length>0)&&Label.articleOId){var e=$(".article-main .tag-desc").first().closest(".fn-flex");0===e.length&&(e=$(".article-main .article-actions.action-btns").first()),0!==e.length&&$('
    ').insertAfter(e)}},getWidgets:function(e){return $('.article-reaction[data-target-id="'+e+'"]')},initWidgets:function(e){e||ArticleReaction.ensureShell(),ArticleReaction.collectShells(e).each(function(){var e=$(this);e.replaceWith(ArticleReaction.renderBar(e.attr("data-target-id"),e.attr("data-summary"),e.attr("data-current-user-reaction")||"",!1))})},closePanels:function(){$(".article-reaction.is-open").removeClass("is-open")},togglePanel:function(e){var t=$(e).closest(".article-reaction"),n=!t.hasClass("is-open");ArticleReaction.closePanels(),n&&t.addClass("is-open")},bindPanels:function(){$(document).off("click.articleReaction").on("click.articleReaction",function(e){0===$(e.target).closest(".article-reaction").length&&ArticleReaction.closePanels()})},updateBars:function(e,t,n,i){var o=ArticleReaction.getWidgets(e),r="boolean"==typeof i?i:o.first().hasClass("is-open");o.each(function(){$(this).replaceWith(ArticleReaction.renderBar(e,t,n,r))})},updateReactionFromChannel:function(e){var t=e.targetId,n=ArticleReaction.getWidgets(t);if(t&&0!==n.length){var i=e.actorUserId===Label.currentUserId?e.actorReaction||"":n.first().attr("data-current-user-reaction")||"";ArticleReaction.updateBars(t,e.summary||[],i,!1)}},react:function(e,t,n){if(!Label.isLoggedIn)return Util.needLogin(),!1;var i=$(n).closest(".article-reaction");if("true"===i.attr("data-loading"))return!1;$.ajax({url:Label.servePath+"/article/reaction",type:"POST",data:JSON.stringify({articleId:e,groupType:"emoji",value:t}),beforeSend:function(){i.attr("data-loading","true").addClass("reaction-loading")},success:function(e){0===e.code?ArticleReaction.updateBars(e.data.targetId,e.data.summary,e.data.currentUserReaction,!1):Util.alert(e.msg)},error:function(e){Util.alert(e.statusText)},complete:function(){i.removeAttr("data-loading").removeClass("reaction-loading")}})}},Article={initAudio:function(){$(".content-audio").each(function(){var e=$(this);new APlayer({element:this,narrow:!1,autoplay:!1,mutex:!0,theme:"#4285f4",preload:"none",mode:"circulation",music:{title:e.data("title"),author:'音乐分享',url:e.data("url"),pic:Label.staticServePath+"/images/music.png"}})});var e=$("#articleAudio");if(0===e.length)return!1;new APlayer({element:document.getElementById("articleAudio"),narrow:!1,autoplay:!1,mutex:!0,theme:"#4285f4",mode:"order",preload:"none",music:{title:"语音预览",author:'小薇',url:e.data("url"),pic:Label.staticServePath+"/images/blank.png"}})},permissionTip:function(e){Label.isLoggedIn?Util.alert(e):Util.needLogin()},voteUp:function(e,t,n){if(!Label.isLoggedIn)return Util.needLogin(),!1;var i=$(n),o=i.next();if(i.hasClass("disabled"))return!1;var r={dataId:e};i.addClass("disabled"),$.ajax({url:Label.servePath+"/vote/up/"+t,type:"POST",cache:!1,data:JSON.stringify(r),success:function(e,t){i.removeClass("disabled");var n=parseInt(i.text()),r=parseInt(o.text());0!==e.code?Util.alert(e.msg):0===e.type?i.html(' '+(n-1)).removeClass("ft-red"):(i.html(' '+(n+1)).addClass("ft-red"),o.hasClass("ft-red")&&o.html(' '+(r-1)).removeClass("ft-red"))}})},voteDown:function(e,t,n){if(!Label.isLoggedIn)return Util.needLogin(),!1;var i=$(n),o=i.prev();if(i.hasClass("disabled"))return!1;var r={dataId:e};i.addClass("disabled"),$.ajax({url:Label.servePath+"/vote/down/"+t,type:"POST",cache:!1,data:JSON.stringify(r),success:function(e,t){i.removeClass("disabled");var n=parseInt(o.text()),r=parseInt(i.text());if(0===e.code)return 1===e.type?i.html(' '+(r-1)).removeClass("ft-red"):(i.html(' '+(r+1)).addClass("ft-red"),o.hasClass("ft-red")&&o.html(' '+(n-1)).removeClass("ft-red")),!1;Util.alert(e.msg)}})},previewImgAfterLoading:function(){$(".img-preview img").css("transform","translate3d("+Math.max(0,$(window).width()-$(".img-preview img").width())/2+"px, "+Math.max(0,$(window).height()-$(".img-preview img").height())/2+"px, 0)"),setTimeout(function(){$(".img-preview").width($(window).width())},300)},init:function(){this.initToc(),this.share(),Util.parseHljs(),Util.parseMarkdown();var e=null;$(".article").on("dblclick",".vditor-reset img",function(){clearTimeout(e),$(this).hasClass("emoji")||1===$(this).closest(".editor-panel").length||1===$(this).closest(".ad").length||window.open($(this).attr("src"))}).on("click",".vditor-reset img",function(t){if(clearTimeout(e),!$(this).hasClass("emoji")&&1!==$(this).closest(".editor-panel").length&&1!==$(this).closest(".ad").length){var n=$(this),i=this;e=setTimeout(function(){var e=i.offsetTop,t=i.offsetLeft;1===n.closest(".comments").length&&(e+=n.closest("li")[0].offsetTop,t=t+$(".comments")[0].offsetLeft+15);var o=(n.attr("src")||"").split("?imageView2")[0],r=$('
    ').on("click",function(){$(this).remove()}),a=$("").css("transform","translate3d("+Math.max(0,t)+"px, "+Math.max(0,e-$(window).scrollTop())+"px, 0)").attr("src",o).on("load",Article.previewImgAfterLoading);r.append(a),$("body").append(r),$(".img-preview").css({"background-color":"#fff",position:"fixed"})},100)}}),$("#reportDialog").dialog({width:$(window).width()>500?500:$(window).width()-50,height:450,modal:!0,hideFooter:!0}),this.initAudio(),$(window).scroll(function(){var e=$(window).scrollTop();$(".share").css("top",e+60+"px"),e<$(".article-title").offset().top?($(".article-header").css("top","-60px"),$(".nav").show()):($(".article-header").css("top","0"),$(".nav").hide())}),$(window).resize(function(){Article.syncTocLayout()});var t=location.search.split("r=")[1];t&&sessionStorage.setItem("r",t.split("&")[0]),$(function(){$.ajax({url:Label.servePath+"/api/article/reward/senders/"+Label.articleOId,method:"GET",async:!1,headers:{csrfToken:Label.csrfToken},success:function(e){if(0===e.code&&""!==e.data){let t=e.data;for(let e=0;e\n
    \n
    \n
    \n")}Util.listenUserCard()}}})})},revision:function(e,t){if(!Label.isLoggedIn)return Util.needLogin(),!1;t||(t="article"),Article._revisionDialogOpen("comment"===t?"评论历史":"文章历史"),"comment"===t?Article._legacyRevision(e,t):Article._articleRevision(e)},_revisionDialogInit:function(){$("#revisionDialog").length>0||($("body").append(''),$("#revisionDialog .revision-modal__body").append($("#revision")),$("#revisionDialog .revision-modal__overlay, #revisionDialog .revision-modal__close").click(function(){Article._revisionDialogClose()}),$(document).off("keydown.revisionDialog").on("keydown.revisionDialog",function(e){"Escape"===e.key&&$("#revisionDialog").hasClass("is-open")&&Article._revisionDialogClose()}))},_revisionDialogOpen:function(e){Article._revisionDialogInit(),$("#revisionDialogTitle").text(e||"历史版本"),$("#revisionDialog").addClass("is-open").attr("aria-hidden","false"),$("body").addClass("revision-modal-open"),$("#revisionDialog .revision-modal__close").focus()},_revisionDialogClose:function(){$("#revisionDialog").removeClass("is-open").attr("aria-hidden","true"),$("body").removeClass("revision-modal-open")},_legacyRevision:function(e,t){$.ajax({url:Label.servePath+"/"+t+"/"+e+"/revisions",cache:!1,success:function(e,n){if(0===e.code){if(0===e.revisions.length||1===e.revisions.length)return $("#revision > .revisions").remove(),$("#revisions").html(""+Label.noRevisionLabel+""),!1;$("#revisions").html("").prev().remove(),$("#revisions").data("revisions",e.revisions).before('
    '+(e.revisions.length-1)+"~"+e.revisions.length+"/"+e.revisions.length+'
    '),e.revisions.length<=2&&$("#revision a").first().addClass("disabled");var i=JsDiff.createPatch("",e.revisions[e.revisions.length-2].revisionData.articleContent||e.revisions[e.revisions.length-2].revisionData.commentContent,e.revisions[e.revisions.length-1].revisionData.articleContent||e.revisions[e.revisions.length-1].revisionData.commentContent,e.revisions[e.revisions.length-2].revisionData.articleTitle||"",e.revisions[e.revisions.length-1].revisionData.articleTitle||"");return new Diff2HtmlUI({diff:i}).draw("#revisions",{matching:"lines",outputFormat:"side-by-side",synchronisedScroll:!0}),Article._revisionsControls(t),!1}Util.alert(e.msg)}})},_revisionsControls:function(e){var t=$("#revisions").data("revisions");$("#revision a.first").click(function(){if(!$(this).hasClass("disabled")){var e=parseInt($("#revision .revisions").text().split("~")[0]);e<=2?$(this).addClass("disabled"):$(this).removeClass("disabled"),t.length>2&&$("#revision a.last").removeClass("disabled"),$("#revision .revisions > span").html(e-1+"~"+e+"/"+t.length);var n=JsDiff.createPatch("",t[e-2].revisionData.articleContent||t[e-2].revisionData.commentContent,t[e-1].revisionData.articleContent||t[e-1].revisionData.commentContent,t[e-2].revisionData.articleTitle||"",t[e-1].revisionData.articleTitle||"");new Diff2HtmlUI({diff:n}).draw("#revisions",{matching:"lines",outputFormat:"side-by-side",synchronisedScroll:!0})}}),$("#revision a.last").click(function(){if(!$(this).hasClass("disabled")){var e=parseInt($("#revision .revisions span").text().split("~")[0]);e>t.length-3?$(this).addClass("disabled"):$(this).removeClass("disabled"),t.length>2&&$("#revision a.first").removeClass("disabled"),$("#revision .revisions > span").html(e+1+"~"+(e+2)+"/"+t.length);var n=JsDiff.createPatch("",t[e].revisionData.articleContent||t[e].revisionData.commentContent,t[e+1].revisionData.articleContent||t[e+1].revisionData.commentContent,t[e].revisionData.articleTitle||"",t[e+1].revisionData.articleTitle||"");new Diff2HtmlUI({diff:n}).draw("#revisions",{matching:"lines",outputFormat:"side-by-side",synchronisedScroll:!0})}})},_articleRevision:function(e){$("#revision > .revisions").remove(),$("#revisions").removeData("revisions").removeData("revisionDetails").html("加载中"),$.ajax({url:Label.servePath+"/article/"+e+"/revisions/list",cache:!1,success:function(t){if(0===t.code){var n=t.revisions||[];n.length<2?$("#revisions").html(""+Label.noRevisionLabel+""):($("#revisions").data("revisions",n).data("revisionDetails",{}).html(Article._revisionPickerHtml(n)),Article._revisionBindPicker(e),Article._revisionCompare(e))}else $("#revisions").html(""+Article._revisionEscapeHTML(t.msg||"加载失败")+"")},error:function(){$("#revisions").html("加载失败")}})},_revisionPickerHtml:function(e){for(var t=e.length-2,n=e.length-1,i="",o="",r=0;r
    '},_revisionOptionHtml:function(e,t){return'"},_revisionVersionLabel:function(e){return e.current?"当前 "+e.revisionTimeStr:e.revisionTimeStr},_revisionBindPicker:function(e){$("#revision .revision-picker__compare").click(function(){Article._revisionCompare(e)}),$("#revision .revision-picker__diff-only").change(function(){Article._revisionCompare(e)})},_revisionCompare:function(e){var t=$("#revision .revision-picker__base").val(),n=$("#revision .revision-picker__target").val(),i=$("#revision .revision-picker__diff-only").is(":checked");$("#revisions .revision-diff").html("加载中"),$.when(Article._revisionFetch(e,t),Article._revisionFetch(e,n)).done(function(e,t){Article._revisionRenderCompare(e,t,i)}).fail(function(e){$("#revisions .revision-diff").html(""+Article._revisionEscapeHTML(e||"加载失败")+"")})},_revisionFetch:function(e,t){var n=$("#revisions").data("revisionDetails")||{},i=$.Deferred();return n[t]?(i.resolve(n[t]),i.promise()):($.ajax({url:Label.servePath+"/article/"+e+"/revisions/"+encodeURIComponent(t),cache:!1,success:function(e){0===e.code?(n[t]=e.revision,$("#revisions").data("revisionDetails",n),i.resolve(e.revision)):i.reject(e.msg)},error:function(){i.reject("加载失败")}}),i.promise())},_revisionRenderCompare:function(e,t,n){var i=e.revisionData||{},o=t.revisionData||{},r=Article._revisionRenderInlineDiff("标题",i.articleTitle||"",o.articleTitle||"",n);r+=Article._revisionRenderLineDiff("内容",i.articleContent||"",o.articleContent||"",n),$("#revisions .revision-diff").html(r||"无差异")},_revisionRenderInlineDiff:function(e,t,n,i){for(var o=JsDiff.diffWordsWithSpace?JsDiff.diffWordsWithSpace(t,n):JsDiff.diffWords(t,n),r=!1,a="",s=0;s'+Article._revisionEscapeHTML(o[s].value)+"")}return i&&!r?"":'

    '+e+'

    '+a+"
    "},_revisionRenderLineDiff:function(e,t,n,i){for(var o=JsDiff.diffLines(t,n),r=!1,a="",s=0;s

    '+e+'

    '+a+"
    "},_revisionLineHtml:function(e,t){for(var n=Article._revisionSplitLines(e),i="",o=0;o'+Article._revisionEscapeHTML(n[o])+"
    ";return i},_revisionSplitLines:function(e){var t=e.split("\n");return""===t[t.length-1]&&t.pop(),t},_revisionEscapeHTML:function(e){return String(e).replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")},share:function(){var e=$("#qrCode").data("shareurl");$("#qrCode").qrcode({width:90,height:90,text:e}),$("body").click(function(){$("#qrCode").slideUp()}),$(".share > span").click(function(){var t=$(this).data("type");if(!t)return!1;if("wechat"===t)return $("#qrCode").slideToggle(),!1;if("copy"===t)return!1;var n=encodeURIComponent(Label.articleTitle+" - "+Label.symphonyLabel),i=encodeURIComponent(e),o=$(".article-info .avatar-mid").css("background-image");pic=o.substring(5,o.length-2);var r={};r.tencent="http://share.v.t.qq.com/index.php?c=share&a=index&title="+n+"&url="+i+"&pic="+pic,r.weibo="http://v.t.sina.com.cn/share/share.php?title="+n+"&url="+i+"&pic="+pic,r.google="https://plus.google.com/share?url="+i,r.twitter="https://twitter.com/intent/tweet?status="+n+" "+i,window.open(r[t],"_blank","top=100,left=200,width=648,height=618")}),$("#qrCode").click(function(){$(this).hide()}),$("#shareClipboard").mouseover(function(){$(this).attr("aria-label",Label.copyLabel)}),Util.clipboard($("#shareClipboard"),$("#shareClipboard").next(),function(){$("#shareClipboard").attr("aria-label",Label.copiedLabel)})},reward:function(e){confirm(Label.rewardConfirmLabel)&&$.ajax({url:Label.servePath+"/article/reward?articleId="+e,type:"POST",cache:!1,success:function(e,t){if(0!==e.code)Util.alert(e.msg);else{$("#articleRewardContent .vditor-reset").html(e.articleRewardContent),Util.parseHljs(),Util.parseMarkdown();var n=$("#articleRewardContent > span"),i=parseInt(n.text());n.addClass("ft-red").removeClass("ft-blue").html(i+1+" "+Label.rewardLabel).removeAttr("onclick")}},error:function(e){Util.needLogin()}})},thankArticle:function(e,t){return Label.isLoggedIn?!(0===t&&!confirm(Label.thankArticleConfirmLabel))&&(Label.currentUserName===Label.articleAuthorName?(Util.alert(Label.thankSelfLabel),!1):void $.ajax({url:Label.servePath+"/article/thank?articleId="+e,type:"POST",cache:!1,success:function(e,t){if(0===e.code){var n=parseInt($("#thankArticle").text());$("#thankArticle").removeAttr("onclick").html(''+(n+1)+"").addClass("ft-red").removeClass("ft-blue");var i=$(''),o=$("#thankArticle").offset().top,r=$("#thankArticle").offset().left;return i.css({"z-index":9999,top:o-20,left:r,position:"absolute","font-size":16,"-moz-user-select":"none","-webkit-user-select":"none","-ms-user-select":"none"}),$("body").append(i),i.animate({top:o-180,opacity:0},1500,function(){i.remove()}),!1}Util.alert(e.msg)}})):(Util.needLogin(),!1)},stick:function(e){confirm(Label.stickConfirmLabel)&&$.ajax({url:Label.servePath+"/article/stick?articleId="+e,type:"POST",cache:!1,success:function(e,t){Util.alert(e.msg),window.location.href=Label.servePath+"/recent"}})},playThought:function(e){var t=String.fromCharCode(31),n=String.fromCharCode(30),i=String.fromCharCode(29),o=String.fromCharCode(10),r=String.fromCharCode(24),a=$("#thoughtProgress > span"),s=$("#thoughtProgress > svg"),l="#articleThought",c=function(e,n){var o=e.split(t);3===o.length&&o.splice(0,0,"");var a=o[0],s=o[2].split("-"),l=o[3].split("-");if(s[0]=parseInt(s[0]),s[1]=parseInt(s[1]),l[0]=parseInt(l[0]),l[1]=parseInt(l[1]),a===r){for(var c=[],m=s[1],d=0;l[1],m").replace(/ /g," ").replace(/ /g,"    ");$(l).data("text",e).html(t)},parseInt(m[u].split(t)[1])/d);for(var h=0,f=parseInt(m[u-1].split(t)[1])/d,v=setInterval(function(){h>=f?(a.width("100%"),s.css("left","100%"),clearInterval(v)):(h+=20,s.css("left",100*h/f+"%"),a.width(100*h/f+"%"))},20),g="",b="",C=0,y=0,w=0;y").replace(/ /g," ").replace(/ /g,"    "),g=L,$(l).html(b),C=Math.max(C,$(l).height())}$("#thoughtProgressPreview").html('
    '+b+"
    "),$("#thoughtProgressPreview").dialog({modal:!0,hideFooter:!0}),s.click(function(){$("#thoughtProgressPreview").dialog("open")}),$(l).html(b).height(C).css("margin-bottom","15px").html("")},syncTocLayout:function(){var e=1===$("#articleToC").length;return $("body.article").toggleClass("article--has-toc",e),$(".article-body .wrapper, #articleCommentsPanel, .article-footer").css("margin-right",""),e&&$("#articleToC > .module-panel").height($(window).height()-48),e},initToc:function(){if(!this.syncTocLayout())return!1;var e=$("#articleToC"),t=$(".article-toc"),n=$(".article-content [id^=toc]"),i=!1;e.offset().top;toc=[],e.find("li").click(function(){var t=$(this);let n=$(this).find("a").text();n=normalizeHeadingIdFromString(n),document.getElementById(n).scrollIntoView({behavior:"smooth"}),setTimeout(function(){e.find("li").removeClass("current"),t.addClass("current")},50)}),$(window).scroll(function(o){if(parseInt($("#articleToC").css("right"))<0)return!1;$("#articleToC > .module-panel").height($(window).height()-49),toc=[],n.each(function(e){toc.push({id:this.id,offsetTop:this.offsetTop})});for(var r=$(window).scrollTop(),a=0,s=toc.length;a0?a-1:0;e.find('a[data-id="'+toc[l].id+'"]').parent().addClass("current");break}r>=toc[toc.length-1].offsetTop-53&&(e.find("li").removeClass("current"),e.find("li:last").addClass("current"));var c=e.find("li.current")[0].offsetTop;i||(t.scrollTop()c-30&&t.scrollTop(c)),setTimeout(function(){i=!1},600)}),$(window).scroll(),t.scrollTop(e.find("li.current")[0].offsetTop).scroll(function(){i=!0})},toggleToc:function(){var e=$("#articleToC");if(0===e.length)return!1;var t=$(".article-header .icon-unordered-list");t.hasClass("ft-red")?(e.animate({right:"-"+$("#articleToC").outerWidth()+"px"}),t.removeClass("ft-red"),$(".article-actions .icon-unordered-list").removeClass("ft-red")):(e.animate({right:0}),t.addClass("ft-red"),$(".article-actions .icon-unordered-list").addClass("ft-red"))},getNotificationCommentIds:function(e){var t=[],n=function(e){(e=String(e||"").replace(/^#/,"").trim())&&-1===t.indexOf(e)&&t.push(e)};return String(e||"").split(",").forEach(n),n(window.location.hash),t.join(",")},makeNotificationRead:function(e,t){var n={articleId:e,commentIds:Article.getNotificationCommentIds(t)};$.ajax({url:Label.servePath+"/notifications/make-read",type:"POST",cache:!1,data:JSON.stringify(n)})}},ArticleAdjacentNav={storageKey:"articleAdjacentSort",sortValues:["time","author","hot"],init:function(){var e=$("[data-article-nav-sort]");0!==e.length&&(this.applySort(e,this.getStoredSort()),this.bindSortChange(e))},getStoredSort:function(){var e=window.localStorage.getItem(this.storageKey);return this.isValidSort(e)?e:"time"},isValidSort:function(e){return-1!==this.sortValues.indexOf(e)},bindSortChange:function(e){var t=this;e.find(".article-nav-sort__input").on("change",function(){this.checked&&t.isValidSort(this.value)&&(window.localStorage.setItem(t.storageKey,this.value),t.applySort(e,this.value))})},applySort:function(e,t){e.find('.article-nav-sort__input[value="'+t+'"]').prop("checked",!0)}};Article.init(),$(document).ready(function(){ArticleAdjacentNav.init(),Comment.init(),EmojiGroups.init("Comment","New"),Comment.loadEmojiGroupsNew(),(()=>{let e=(new Date).getTime(),t=0;const n=function(){0!==t&&(clearTimeout(t),t=0),$("#emojiList").css("top","auto"),$("#emojiList").css("bottom","60px"),e=(new Date).getTime(),t=setTimeout(()=>{(new Date).getTime()-e<=700&&$("#emojiList").removeClass("showList")},null!==navigator.userAgent.match(/(phone|pad|pod|ios|Android|Mobile|BlackBerry|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian)/i)?0:600)};$("#emojiBtn").hover(function(){0!==t&&(clearTimeout(t),t=0),$("#emojiList").css("top","auto"),$("#emojiList").css("bottom","60px"),e=(new Date).getTime(),EmojiGroups.ensureCurrentFresh(Comment,"New"),setTimeout(()=>0!==$("#emojiBtn:hover").length&&$("#emojiList").addClass("showList"),300)},n),$("#emojiList").hover(function(){0!==t&&(clearTimeout(t),t=0),e=(new Date).getTime()},n)})(),ArticleChannel.init(Label.articleChannel),Label.isLoggedIn&&(Article.makeNotificationRead(Label.articleOId,Label.notificationCmtIds),setTimeout(function(){Util.setUnreadNotificationCount()},1e3))}),Article.initCollectButtons=function(){$(".comment-action .action-btns").each(function(){const e=$(this);if(e.data("collect-inited"))return;const t=e.closest("li").find(".vditor-reset.comment").first();if(!t.length)return;const n=t.find("img").filter(function(){return!$(this).hasClass("emoji")&&0===$(this).closest(".editor-panel, .ad").length}).map(function(){return $(this).attr("src")}).get().filter(Boolean),i=Array.from(new Set(n));if(!i.length)return;e.data("collect-inited",!0);const o=$('');o.append(' 收藏表情'),o.on("click",function(e){e.stopPropagation(),EmojiGroups.openCollectDialog(i)}),e.prepend(o).prepend(" ")})},$(function(){Article.initCollectButtons()}); \ No newline at end of file +function isLetterOrDigit(e){return/\p{L}|\p{N}/u.test(e)}function normalizeHeadingIdFromString(e,t){let n=e.replace(/^#+/,"");if(t){const e=new RegExp(t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g");n=n.replace(e,"")}let i="";for(const e of n)isLetterOrDigit(e)?i+=e:i+="-";return i=i.replace(/-{3,}/g,"--"),i.startsWith("--")&&(i="-"+i.slice(2)),i.endsWith("--")&&(i=i.slice(0,-2)+"-"),i}var Comment={editor:void 0,reactionOptions:[{value:"thumbsup",emoji:"👍"},{value:"thumbsdown",emoji:"👎"},{value:"check",emoji:"✅"},{value:"cross",emoji:"❌"},{value:"star",emoji:"⭐"},{value:"heart",emoji:"❤️"},{value:"fire",emoji:"🔥"},{value:"party",emoji:"🎉"},{value:"laugh",emoji:"😂"},{value:"wow",emoji:"😮"},{value:"clap",emoji:"👏"},{value:"hundred",emoji:"💯"},{value:"rocket",emoji:"🚀"},{value:"salute",emoji:"🖖"},{value:"handshake",emoji:"🤝"},{value:"raisedhands",emoji:"🙌"},{value:"mindblown",emoji:"🤯"},{value:"thinking",emoji:"🤔"},{value:"eyes",emoji:"👀"},{value:"cry",emoji:"😢"},{value:"angry",emoji:"😡"},{value:"pray",emoji:"🙏"},{value:"brokenheart",emoji:"💔"},{value:"skull",emoji:"💀"},{value:"clown",emoji:"🤡"},{value:"poop",emoji:"💩"},{value:"heartonfire",emoji:"❤️‍🔥"},{value:"plus",emoji:"➕1️⃣"}],isWideReactionOption:function(e){return"plus"===e.value||"heartonfire"===e.value},escapeHTML:function(e){return $("
    ").text(e||"").html()},renderCommentAuthorName:function(e){var t=Comment.escapeHTML(e.commentAuthorName);return e.commentAuthorNickName?Comment.escapeHTML(e.commentAuthorNickName)+" ("+t+")":t},renderOriginalAuthorLabel:function(e){var t=e.commentOriginalAuthorNickName||e.commentOriginalAuthorName;return t?'回复 @'+Comment.escapeHTML(t)+"":""},escapeJSString:function(e){return String(e||"").replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\r/g,"\\r").replace(/\n/g,"\\n")},getCommentHashId:function(e){var t=String(e||"").indexOf("#");return t<0?"":String(e).substring(t+1)},getCurrentPageNum:function(){var e=window.location.search.match(/[?&]p=(\d+)/);return e?parseInt(e[1]):1},getSearchValue:function(e,t){for(var n=String(e||"").replace(/^\?/,"").split("&"),i=0;i1?o[1]:""}return""},normalizeCommentSearch:function(e){for(var t=["p","m","sort","author"],n=[],i=0;i
    '),e.find(".comment-action").before(n)),n},renderThreadAction:function(e){return'
    '+Comment.renderReactionBar(e.oId,e.reactionSummary,e.currentUserReaction)+'
    '+Comment.renderThreadThankAction(e)+Comment.renderThreadVoteAction(e,!0)+Comment.renderThreadVoteAction(e,!1)+Comment.renderThreadReportAction(e)+Comment.renderThreadHistoryAction(e)+Comment.renderThreadEditAction(e)+Comment.renderThreadReplyAction(e)+"
    "},renderThreadThankAction:function(e){var t=Comment.escapeJSString(e.oId),n=Comment.escapeJSString(e.commentThankLabel),i=parseInt(e.commentAnonymous||0),o=parseInt(e.rewardedCnt||e.commentThankCnt||0),r=e.rewarded?" ft-red":"",a="";return e.rewarded||(a=Label.canThankComment?" onclick=\"Comment.thank('"+t+"', '"+Comment.escapeJSString(Label.csrfToken)+"', '"+n+"', "+i+', this)"':' onclick="Article.permissionTip(Label.noPermissionLabel)"'),' '+o+""},renderThreadVoteAction:function(e,t){var n=Comment.escapeJSString(e.oId),i=parseInt(e.commentVote)===(t?0:1),o=parseInt(t?e.commentGoodCnt||0:e.commentBadCnt||0),r=t?Label.upLabel:Label.downLabel,a=t?"thumbs-up":"thumbs-down",s=t?"voteUp":"voteDown",l=(t?Label.canGoodComment:Label.canBadComment)?"Article."+s+"('"+n+"', 'comment', this)":"Article.permissionTip(Label.noPermissionLabel)";return' '+o+""},renderThreadReportAction:function(e){var t=Comment.escapeJSString(e.oId);return'"},renderThreadReplyAction:function(e){return Label.isLoggedIn&&Label.canAddComment?'':""},renderThreadEditAction:function(e){return e.commentIsCurrentUser&&Label.canUpdateComment?'':""},renderThreadHistoryAction:function(e){return!Label.canViewCommentHistory||parseInt(e.commentRevisionCount||0)<2?"":''},updateCommentHistoryAction:function(e,t){var n=Comment.getCommentElement(e);if(n.hasClass("comment-thread__reply")){var i=n.find("> .comment-thread__body > .comment-thread__actions > .action-btns");if(i.children(".comment-history-action").remove(),!(t<2)){var o=Comment.renderThreadHistoryAction({oId:e,commentRevisionCount:t}),r=i.children(".comment-edit-action");1===r.length?r.before(o):i.append(o)}}else n.find(".icon-history").parent().toggle(t>=2)},updateEditedCommentContent:function(e,t){var n=Comment.getCommentElement(e);n.hasClass("comment-thread__reply")?n.find("> .comment-thread__body > .comment-thread__content").html(t):n.find("> .fn-flex > .fn-flex-1 > .vditor-reset").html(t)},getThreadReplyDepth:function(e){var t=parseInt(e.commentThreadDepth,10);if(!isNaN(t)&&t>=0)return t;var n=document.getElementById(e.commentOriginalCommentId);return n&&$(n).hasClass("comment-thread__reply")?(t=parseInt($(n).attr("data-thread-depth"),10),isNaN(t)?1:t+1):0},renderThreadReplyClass:function(e){return"comment-thread__reply"+(e>0?" comment-thread__reply--nested":"")},renderThreadReplyStyle:function(e){return' data-thread-depth="'+e+'" style="--comment-thread-indent:'+28*e+'px"'},renderThreadReply:function(e){var t=Comment.getThreadReplyDepth(e);return'
    '+Comment.renderCommentAuthorName(e)+""+Comment.renderOriginalAuthorLabel(e)+' • '+Comment.escapeHTML(e.timeAgo)+'
    '+e.commentContent+"
    "+Comment.renderThreadAction(e)+"
    "},renderThreadReplies:function(e){for(var t="",n=0;n'+Comment.escapeHTML(n)+""},renderThreadPagination:function(e,t,n){if(e.find(".comment-thread__pager").remove(),n&&!(parseInt(n.paginationPageCount||0)<=1)){var i=parseInt(n.paginationCurrentPageNum||1),o=parseInt(n.paginationPageCount||1),r=['
    '];i>1&&r.push(Comment.renderThreadPageButton(t,i-1,"上一页")),r.push('',i,"/",o,""),i"),e.append(r.join(""))}},getCommentQueryExtra:function(){return Label.commentQueryExtra||""},normalizeReactionSummary:function(e){if(Array.isArray(e))return e;if("string"!=typeof e||""===e)return[];try{var t=JSON.parse(e);return Array.isArray(t)?t:[]}catch(e){return[]}},getReactionMap:function(e){e=Comment.normalizeReactionSummary(e);for(var t={},n=0;n/g,">")},getReactionUserDetails:function(e){return e&&Array.isArray(e.userDetails)?e.userDetails:[]},renderReactionTip:function(e){var t=Comment.getReactionUserDetails(e);if(0===t.length)return"";for(var n=[],i=0;i'),n.push('',Comment.escapeReactionHtml(s),''),n.push("")}}return 0===n.length?"":''+n.join("")+""},renderReactionSummaryItems:function(e,t,n){for(var i=Comment.getReactionMap(t),o=[],r=0;r'),o.push('"),""!==m&&o.push(m,"")}}return o.join("")},renderReactionPanel:function(e,t){for(var n=['
    '],i=0;i"),n.push('',o.emoji,""),n.push("")}return n.push("
    "),n.join("")},renderReactionSummaryWidget:function(e,t,n){var i=Comment.renderReactionSummaryItems(e,t,n),o=['
    '];return o.push('
    '),o.push('
    ',i,"
    "),o.join("")},renderReactionTriggerWidget:function(e,t,n){var i=n?" is-open":"",o=['
    '];return o.push('"),o.push(Comment.renderReactionPanel(e,t)),o.push("
    "),o.join("")},renderReactionBar:function(e,t,n,i,o){if("summary"===o)return Comment.renderReactionSummaryWidget(e,t,n);if("trigger"===o)return Comment.renderReactionTriggerWidget(e,n,i);var r=i?" is-open":"",a=Comment.renderReactionSummaryItems(e,t,n),s=['
    '];return s.push('
    '),s.push('
    ',a,"
    "),s.push('
    "),s.push(Comment.renderReactionPanel(e,n)),s.push("
    "),s.join("")},getReactionWidgets:function(e){return $('.comment-reaction[data-target-id="'+e+'"]')},getInteractiveReactionWidgets:function(e){return $('.comment-reaction--combined[data-target-id="'+e+'"], .comment-reaction--trigger[data-target-id="'+e+'"]')},mountReactionTrigger:function(e,t,n,i){if(0!==e.length){var o=Comment.renderReactionBar(t,[],n,i,"trigger"),r=e.find('.comment-reaction--trigger[data-target-id="'+t+'"]');r.length>0?r.replaceWith(o):e.prepend(o)}},collectReactionShells:function(e){var t=e?$(e):$(document);return t.hasClass("comment-reaction-shell")?t.add(t.find(".comment-reaction-shell")):t.find(".comment-reaction-shell")},initReactionWidgets:function(e){Comment.collectReactionShells(e).each(function(){var e=$(this),t=e.attr("data-target-id"),n=e.attr("data-summary"),i=e.attr("data-current-user-reaction")||"",o=e.closest(".comment-action__bar").find(".action-btns").first(),r=e.closest(".comment-action__left").length>0&&o.length>0,a=Comment.renderReactionBar(t,n,i,!1,r?"summary":"combined");e.replaceWith(a),r&&Comment.mountReactionTrigger(o,t,i,!1)})},closeReactionPanels:function(e){var t=e?$(e):$(document),n=".comment-reaction--combined, .comment-reaction--trigger";(t.is(n)?t.add(t.find(n)):t.find(n)).removeClass("is-open")},toggleReactionPanel:function(e){var t=$(e).closest(".comment-reaction"),n=t.attr("data-target-id"),i=!t.hasClass("is-open");Comment.closeReactionPanels(),i&&Comment.getInteractiveReactionWidgets(n).addClass("is-open")},bindReactionPanels:function(){$(document).off("click.commentReaction").on("click.commentReaction",function(e){0===$(e.target).closest(".comment-reaction").length&&Comment.closeReactionPanels()})},updateReactionBars:function(e,t,n,i){var o=Comment.getReactionWidgets(e),r="boolean"==typeof i?i:Comment.getInteractiveReactionWidgets(e).first().hasClass("is-open");o.each(function(){var i=$(this),o="combined";i.hasClass("comment-reaction--summary")?o="summary":i.hasClass("comment-reaction--trigger")&&(o="trigger"),i.replaceWith(Comment.renderReactionBar(e,t,n,r,o))})},updateReactionFromChannel:function(e){var t=e.targetId||e.commentId;if(t){var n=Comment.getReactionWidgets(t);if(0!==n.length){var i=e.actorUserId===Label.currentUserId?e.actorReaction||"":n.first().attr("data-current-user-reaction")||"";Comment.updateReactionBars(t,e.summary||[],i,!1)}}},react:function(e,t,n){if(!Label.isLoggedIn)return Util.needLogin(),!1;var i=$(n).closest(".comment-reaction");if("true"===i.attr("data-loading"))return!1;$.ajax({url:Label.servePath+"/comment/reaction",type:"POST",data:JSON.stringify({commentId:e,groupType:"emoji",value:t}),beforeSend:function(){i.attr("data-loading","true").addClass("reaction-loading")},success:function(e){0===e.code?Comment.updateReactionBars(e.data.targetId,e.data.summary,e.data.currentUserReaction,!1):Util.alert(e.msg)},error:function(e){Util.alert(e.statusText)},complete:function(){i.removeAttr("data-loading").removeClass("reaction-loading")}})},report:function(e){var t=$(e);t.attr("disabled","disabled").css("opacity","0.3"),$.ajax({url:Label.servePath+"/report",type:"POST",cache:!1,data:JSON.stringify({reportDataId:$("#reportDialog").data("id"),reportDataType:$("#reportDialog").data("type"),reportType:$("input[name=report]:checked").val(),reportMemo:$("#reportTextarea").val()}),complete:function(e){t.removeAttr("disabled").css("opacity","1"),0===e.responseJSON.code?(Util.alert(Label.reportSuccLabel),$("#reportTextarea").val(""),$("#reportDialog").dialog("close")):Util.alert(e.responseJSON.msg)}})},accept:function(e,t,n){confirm(e)&&$.ajax({url:Label.servePath+"/comment/accept",type:"POST",headers:{csrfToken:Label.csrfToken},cache:!1,data:JSON.stringify({commentId:t}),success:function(e){0===e.code?($(n).closest("li").addClass("cmt-perfect"),$(n).remove()):Util.alert(e.msg)}})},remove:function(e){if(!confirm("删除评论需要100积分,"+Label.confirmRemoveLabel))return!1;$.ajax({url:Label.servePath+"/comment/"+e+"/remove",type:"POST",cache:!1,success:function(t,n){0===t.code?$("#"+e).remove():Util.alert(t.msg)}})},exchangeCmtSort:function(e){e=0===e?1:0;var t=Comment.getCommentQueryExtra().replace("&sort=hot","");window.location.href=window.location.pathname+"?m="+e+t+"#comments"},_bgFade:function(e,t){return 0!==e.length&&(!1!==(t=t||{}).scroll&&$(window).scrollTop(e[0].offsetTop-48),"comments"!==e.attr("id")&&!1!==t.highlight&&($(".comment-focus-highlight").removeClass("comment-focus-highlight"),e.addClass("comment-focus-highlight"),setTimeout(function(){e.removeClass("comment-focus-highlight")},1800),!0))},edit:function(e){Comment._toggleReply(),$(".cmt-anonymous").hide(),$.ajax({url:Label.servePath+"/comment/"+e+"/content",type:"GET",cache:!1,success:function(e,t){0===e.code&&Comment.editor.setValue(e.commentContent)}}),$("#replyUseName").html(' '+Label.commonUpdateCommentPermissionLabel+"").data("commentId",e)},goComment:function(e){var t=Comment.getCommentHashId(e);return(!t||!Comment.focusCommentById(t))&&(t&&Comment.isSameCommentPage(e)?(Comment.expandThreadForComment(t),!1):(window.location=e,!1))},focusCommentElement:function(e,t){return Comment._bgFade(e,t)},focusCommentById:function(e,t){var n=Comment.getCommentElement(e);return 1===n.length&&Comment.focusCommentElement(n,t)},focusLocationHash:function(){var e=Comment.getCommentHashId(window.location.hash);return!!e&&(!!Comment.focusCommentById(e)||Comment.expandThreadForComment(e))},expandThreadForComment:function(e){return $.ajax({url:Label.servePath+"/comment/thread/replies",type:"POST",data:JSON.stringify({commentId:e,anchorCommentId:e,userCommentViewMode:Label.userCommentViewMode,sort:Label.commentSort,author:Label.commentAuthorFilter?"1":""}),success:function(t){if(0!==t.code)return!1;Comment.renderThreadResponse(t.commentThreadRootId,t.commentThreadReplies||[],e,{pagination:t.pagination})}}),!0},renderThreadResponse:function(e,t,n,i){i=i||{};var o=Comment.getCommentElement(e);if(1!==o.length)return!1;var r=Comment.ensureThread(o,e);return r.find(".comment-thread__list").html(Comment.renderThreadReplies(t)),r.addClass("comment-thread--expanded"),r.find(".comment-thread__more").remove(),Comment.renderThreadPagination(r,e,i.pagination),Comment.initReactionWidgets(r),Util.listenUserCard(),Util.parseHljs(),Util.parseMarkdown(),!1===i.focus||!n||Comment.focusCommentById(n)},_hideReplyPanel:function(){var e=$(".editor-panel");return!(0===e.length||!e.hasClass("editor-panel--open"))&&(e.removeClass("editor-panel--open"),e.find(".wrapper").slideUp(function(){e.fadeOut(100),$(".footer").removeAttr("style")}),!1)},_toggleReply:function(e){if(!Label.isLoggedIn)return Util.needLogin(),!1;if(0===$("#commentContent").length)return Util.alert(Label.notAllowCmtLabel),!1;if("false"===$(this).data("hasPermission"))return Article.permissionTip(Label.noPermissionLabel),!1;var t=$(".editor-panel");if(t.hasClass("editor-panel--open"))return Comment._hideReplyPanel();document.body.classList.contains("long-article-page")&&window.LongArticle&&!window.LongArticle.isCommentsOpen()&&window.LongArticle.openComments(),$(".cmt-anonymous").show(),$(".footer").css("margin-bottom",$(".editor-panel > .wrapper").outerHeight()+"px"),$("#replyUseName").html(''+$(".article-title").text().replace(//g,">")+"").removeData(),"0px"!==t.css("bottom")&&(t.find(".wrapper").hide(),t.css("bottom",0)),t.show().addClass("editor-panel--open"),t.find(".wrapper").slideDown(function(){Comment.editor.focus(),e&&e()})},loadEmojis:function(){let e=Comment.getEmojis(),t="";for(let n=0;n\n
    \n \n`;$("#emojis").html(t)},confirmed:!1,delEmoji:function(e){if(!0===Comment.confirmed||confirm("确定要删除该表情包吗?")){Comment.confirmed=!0;let t=Comment.getEmojis();for(let n=0;n5242880?Util.alert("图片过大 (最大限制 5M)"):t.submit():Util.alert("只允许上传图片!")}}else t.submit()},formData:function(e){return e.serializeArray()},submit:function(e,t){},done:function(e,t){var n={result:{key:t.result.data.succMap[Object.keys(t.result.data.succMap)[0]]}};Comment.addEmoji(n.result.key)},fail:function(e,t){Util.alert("Upload error: "+t.errorThrown)}})},fromURL:function(){Util.alert('
    \n\n
    \n
    \n \n
    \n
    ',"从URL导入表情包"),$("#fromURL").focus(),$("#fromURL").unbind(),$("#fromURL").bind("keypress",function(e){"13"==e.keyCode&&(Comment.addEmoji($("#fromURL").val()),Util.closeAlert())})},addEmoji:function(){if(0!==arguments.length){var e=[];if(1===arguments.length&&Array.isArray(arguments[0]))e=arguments[0];else for(var t=0;t ul > li.focus").length&&"x"===Util.prevKey&&$("#comments .list > ul > li.focus .icon-reply").parent().click():Comment._toggleReply(),!1}).bind("keyup","h",function(){return 1===$("#comments .list > ul > li.focus").length&&"x"===Util.prevKey&&$("#comments .list > ul > li.focus .icon-heart").parent().click(),!1}).bind("keyup","t",function(){return 1===$("#comments .list > ul > li.focus").length&&"x"===Util.prevKey&&$("#comments .list > ul > li.focus .icon-thumbs-up").parent().click(),!1}).bind("keyup","d",function(){return 1===$("#comments .list > ul > li.focus").length&&"x"===Util.prevKey&&$("#comments .list > ul > li.focus .icon-thumbs-down").parent().click(),!1}).bind("keyup","c",function(){return 1===$("#comments .list > ul > li.focus .comment-info .icon-reply-to").length&&"x"===Util.prevKey&&$("#comments .list > ul > li.focus .comment-info .icon-reply-to").parent().click(),!1}).bind("keyup","m",function(){return 1===$("#comments .list > ul > li.focus .comment-action > .ft-fade > .fn-pointer").length&&"x"===Util.prevKey&&$("#comments .list > ul > li.focus .comment-action > .ft-fade > .fn-pointer").click(),!1}).bind("keyup","a",function(){return"x"===Util.prevKey&&1===$("#comments .list > ul > li.focus .icon-setting").parent().length&&(window.location=$("#comments .list > ul > li.focus .icon-setting").parent().attr("href")),!1}).bind("keyup","m",function(){return"v"===Util.prevKey&&Article.toggleToc(),!1}).bind("keyup","h",function(){return"v"===Util.prevKey&&$("#thankArticle").click(),!1}).bind("keyup","t",function(){return"v"===Util.prevKey&&$(".article-header .icon-thumbs-up").parent().click(),!1}).bind("keyup","d",function(){return"v"===Util.prevKey&&$(".article-header .icon-thumbs-down").parent().click(),!1}).bind("keyup","i",function(){return"v"===Util.prevKey&&$(".article-header .icon-view").parent().click(),!1}).bind("keyup","c",function(){return"v"===Util.prevKey&&$(".article-header .icon-star").parent().click(),!1}).bind("keyup","l",function(){return"v"===Util.prevKey&&$(".article-header .icon-history").parent().click(),!1}).bind("keyup","e",function(){return"v"===Util.prevKey&&1===$(".article-actions .icon-edit").parent().length&&(window.location=$(".article-actions .icon-edit").parent().attr("href")),!1}).bind("keyup","s",function(){return"v"===Util.prevKey&&1===$(".article-actions .icon-chevron-up").length&&Article.stick(Label.articleOId),!1}).bind("keyup","a",function(){return"v"===Util.prevKey&&1===$(".article-actions .icon-setting").parent().length&&(window.location=$(".article-actions .icon-setting").parent().attr("href")),!1}).bind("keyup","p",function(){return"v"===Util.prevKey&&1===$(".article-header a[rel=prev]").length&&(window.location=$(".article-header a[rel=prev]").attr("href")),!1}).bind("keyup","n",function(){return"v"===Util.prevKey&&1===$(".article-header a[rel=next]").length&&(window.location=$(".article-header a[rel=next]").attr("href")),!1})},init:function(){if($("#sendComment").click(function(){Comment._toggleReply()}),Comment.focusLocationHash(),this._initHotKey(),$.pjax({selector:"#comments .pagination a",container:"#comments",show:"",cache:!1,storage:!0,titleSuffix:"",callback:function(){Comment.initReactionWidgets($("#comments")),Util.parseMarkdown(),Util.parseHljs(),Util.listenUserCard(),Comment.focusLocationHash()}}),NProgress.configure({showSpinner:!1}),$("#comments").bind("pjax.start",function(){NProgress.start()}),$("#comments").bind("pjax.end",function(){NProgress.done()}),ArticleReaction.bindPanels(),ArticleReaction.initWidgets(),Comment.bindReactionPanels(),Comment.initReactionWidgets($("#comments")),!Label.isLoggedIn||!document.getElementById("commentContent"))return!1;Comment.editor=Util.newVditor({id:"commentContent",cache:!0,preview:{mode:"editor"},resize:{enable:!0,position:"top"},height:200,placeholder:Label.commentEditorPlaceholderLabel,ctrlEnter:function(){Comment.add(Label.articleOId,Label.csrfToken,document.getElementById("articleCommentBtn"))},esc:function(){$(".editor-hide").click()}})},thank:function(e,t,n,i,o){if(!Label.isLoggedIn)return Util.needLogin(),!1;if(0===i&&!confirm(n))return!1;var r={commentId:e};$.ajax({url:Label.servePath+"/comment/thank",type:"POST",headers:{csrfToken:t},cache:!1,data:JSON.stringify(r),error:function(e,t,n){Util.alert(n)},success:function(e,t){if(0===e.code){$(o).removeAttr("onclick");var n=$(''),i=$(o).offset().top,r=$(o).offset().left;n.css({"z-index":9999,top:i,left:r,position:"absolute","font-size":16,"-moz-user-select":"none","-webkit-user-select":"none","-ms-user-select":"none"}),$("body").append(n),n.animate({left:r-150,top:i-60,opacity:0},1e3,function(){var e=parseInt($(o).text());$(o).html(' '+(e+1)).addClass("ft-red"),n.remove()})}else Util.alert(e.msg)}})},showReply:function(e,t,n){var i=$(t).closest("li").find("."+n);if("comment-get-comment"===n){if(0!==i.find("li").length)return i.html(""),!1}else if(0===$(t).find(".icon-chevron-down").length)return $(t).find(".icon-chevron-up").removeClass("icon-chevron-up").addClass("icon-chevron-down").find("use").attr("xlink:href","#chevron-down"),i.html(""),!1;if("0.3"===$(t).css("opacity"))return!1;var o="/comment/replies";"comment-get-comment"===n&&(o="/comment/original"),$.ajax({url:Label.servePath+o,type:"POST",data:JSON.stringify({commentId:e,userCommentViewMode:Label.userCommentViewMode}),beforeSend:function(){$(t).css("opacity","0.3")},success:function(e,n){if(0!==e.code)return Util.alert(e.msg),!1;var o=e.commentReplies,r="";o instanceof Array||(o=[o]),0===o.length&&(r='
  • '+Label.removedLabel+"
  • ");for(var a=0;a
    ',r+='',r+='
    ',r+="
    ",r+='
    ',r+='',r+=Comment.renderCommentAuthorName(s),r+="",r+=Comment.renderOriginalAuthorLabel(s),r+=' • '+s.timeAgo,s.rewardedCnt>0&&(r+=' '+s.rewardedCnt+" "),r+="",r+='
    '+s.commentContent+"
    "+Comment.renderReactionBar(s.oId,s.reactionSummary,s.currentUserReaction)+"
    "}i.html("
      "+r+"
    "),Util.parseHljs(),Util.parseMarkdown(),$(t).find(".icon-chevron-down").removeClass("icon-chevron-down").addClass("icon-chevron-up").find("use").attr("xlink:href","#chevron-up")},error:function(e){Util.alert(e.statusText)},complete:function(){$(t).css("opacity","1")}})},showThreadReplies:function(e,t,n){if("0.3"===$(t).css("opacity"))return!1;$.ajax({url:Label.servePath+"/comment/thread/replies",type:"POST",data:JSON.stringify({commentId:e,paginationCurrentPageNum:n||1}),beforeSend:function(){$(t).css("opacity","0.3")},success:function(t){if(0!==t.code)return Util.alert(t.msg),!1;Comment.renderThreadResponse(t.commentThreadRootId||e,t.commentThreadReplies||[],null,{focus:!1,pagination:t.pagination})},error:function(e){Util.alert(e.statusText)},complete:function(){$(t).css("opacity","1")}})},add:function(e,t,n){var i={articleId:e,commentAnonymous:$("#commentAnonymous").prop("checked"),commentVisible:$("#commentVisible").prop("checked"),commentContent:Comment.editor.getValue(),userCommentViewMode:Label.userCommentViewMode};$("#replyUseName").data("commentOriginalCommentId")&&(i.commentOriginalCommentId=$("#replyUseName").data("commentOriginalCommentId"));var o=Label.servePath+"/comment",r="POST",a=$("#replyUseName").data("commentId");a&&(o=Label.servePath+"/comment/"+a,r="PUT"),$.ajax({url:o,type:r,headers:{csrfToken:t},cache:!1,data:JSON.stringify(i),beforeSend:function(){$(n).attr("disabled","disabled").css("opacity","0.3")},success:function(e,t){$(n).removeAttr("disabled").css("opacity","1"),0===e.code?(a&&(Comment.updateEditedCommentContent(a,e.commentContent),Comment.updateCommentHistoryAction(a,parseInt(e.commentRevisionCount||0))),i.commentOriginalCommentId&&Util.setUnreadNotificationCount(),Comment.editor.setValue(""),$(".editor-hide").click(),$("#replyUseName").text("").removeData(),i.commentOriginalCommentId&&Comment.focusCommentById(i.commentOriginalCommentId,{scroll:!1})):$("#addCommentTip").addClass("error").html("
    • "+e.msg+"
    ")},error:function(e){$("#addCommentTip").addClass("error").html("
    • "+e.statusText+"
    ")},complete:function(){$(n).removeAttr("disabled").css("opacity","1"),setTimeout(Util.listenUserCard,1e3)}})},reply:function(e,t){Comment._toggleReply(function(){var e=Comment.getCommentElement(t);0!==e.length&&$(window).height()-(e[0].offsetTop-$(window).scrollTop()+e.outerHeight())<$(".editor-panel .wrapper").outerHeight()&&$(window).scrollTop(e[0].offsetTop-($(window).height()-$(".editor-panel .wrapper").outerHeight()-e.outerHeight()))});var n="",i=Comment.escapeHTML(e),o=Comment.getCommentElement(t),r=o.find(">.fn-flex>div>a").clone();0===r.length&&(r=o.find(">.fn-flex .avatar").clone()),0===r.length?n=' '+i+"":r.is("a")?(r.addClass("ft-a-title").attr("href","#"+t).attr("onclick",'Comment._bgFade($("#'+t+'"))'),r.find("div").removeClass("avatar").addClass("avatar-small").after(" "+i).before(' '),n=r[0].outerHTML):(r.removeClass("avatar").addClass("avatar-small"),n=' '+r[0].outerHTML+" "+i+""),$("#replyUseName").html(n).data("commentOriginalCommentId",t)}},ArticleReaction={renderSummaryItems:function(e,t,n){for(var i=Comment.getReactionMap(t),o=[],r=0;r'),o.push('"),""!==m&&o.push(m,"")}}return o.join("")},renderPanel:function(e,t){for(var n=['
    '],i=0;i"),n.push('',o.emoji,""),n.push("")}return n.push("
    "),n.join("")},renderBar:function(e,t,n,i){var o=i?" is-open":"",r=['
    '];return r.push('
    '),r.push('
    ',ArticleReaction.renderSummaryItems(e,t,n),"
    "),r.push('
    "),r.push(ArticleReaction.renderPanel(e,n)),r.push("
    "),r.join("")},collectShells:function(e){var t=e?$(e):$(document);return t.hasClass("article-reaction-shell")?t.add(t.find(".article-reaction-shell")):t.find(".article-reaction-shell")},ensureShell:function(){if(!($(".article-reaction-shell, .article-reaction").length>0)&&Label.articleOId){var e=$(".article-main .tag-desc").first().closest(".fn-flex");0===e.length&&(e=$(".article-main .article-actions.action-btns").first()),0!==e.length&&$('
    ').insertAfter(e)}},getWidgets:function(e){return $('.article-reaction[data-target-id="'+e+'"]')},initWidgets:function(e){e||ArticleReaction.ensureShell(),ArticleReaction.collectShells(e).each(function(){var e=$(this);e.replaceWith(ArticleReaction.renderBar(e.attr("data-target-id"),e.attr("data-summary"),e.attr("data-current-user-reaction")||"",!1))})},closePanels:function(){$(".article-reaction.is-open").removeClass("is-open")},togglePanel:function(e){var t=$(e).closest(".article-reaction"),n=!t.hasClass("is-open");ArticleReaction.closePanels(),n&&t.addClass("is-open")},bindPanels:function(){$(document).off("click.articleReaction").on("click.articleReaction",function(e){0===$(e.target).closest(".article-reaction").length&&ArticleReaction.closePanels()})},updateBars:function(e,t,n,i){var o=ArticleReaction.getWidgets(e),r="boolean"==typeof i?i:o.first().hasClass("is-open");o.each(function(){$(this).replaceWith(ArticleReaction.renderBar(e,t,n,r))})},updateReactionFromChannel:function(e){var t=e.targetId,n=ArticleReaction.getWidgets(t);if(t&&0!==n.length){var i=e.actorUserId===Label.currentUserId?e.actorReaction||"":n.first().attr("data-current-user-reaction")||"";ArticleReaction.updateBars(t,e.summary||[],i,!1)}},react:function(e,t,n){if(!Label.isLoggedIn)return Util.needLogin(),!1;var i=$(n).closest(".article-reaction");if("true"===i.attr("data-loading"))return!1;$.ajax({url:Label.servePath+"/article/reaction",type:"POST",data:JSON.stringify({articleId:e,groupType:"emoji",value:t}),beforeSend:function(){i.attr("data-loading","true").addClass("reaction-loading")},success:function(e){0===e.code?ArticleReaction.updateBars(e.data.targetId,e.data.summary,e.data.currentUserReaction,!1):Util.alert(e.msg)},error:function(e){Util.alert(e.statusText)},complete:function(){i.removeAttr("data-loading").removeClass("reaction-loading")}})}},Article={initAudio:function(){$(".content-audio").each(function(){var e=$(this);new APlayer({element:this,narrow:!1,autoplay:!1,mutex:!0,theme:"#4285f4",preload:"none",mode:"circulation",music:{title:e.data("title"),author:'音乐分享',url:e.data("url"),pic:Label.staticServePath+"/images/music.png"}})});var e=$("#articleAudio");if(0===e.length)return!1;new APlayer({element:document.getElementById("articleAudio"),narrow:!1,autoplay:!1,mutex:!0,theme:"#4285f4",mode:"order",preload:"none",music:{title:"语音预览",author:'小薇',url:e.data("url"),pic:Label.staticServePath+"/images/blank.png"}})},permissionTip:function(e){Label.isLoggedIn?Util.alert(e):Util.needLogin()},voteUp:function(e,t,n){if(!Label.isLoggedIn)return Util.needLogin(),!1;var i=$(n),o=i.next();if(i.hasClass("disabled"))return!1;var r={dataId:e};i.addClass("disabled"),$.ajax({url:Label.servePath+"/vote/up/"+t,type:"POST",cache:!1,data:JSON.stringify(r),success:function(e,t){i.removeClass("disabled");var n=parseInt(i.text()),r=parseInt(o.text());0!==e.code?Util.alert(e.msg):0===e.type?i.html(' '+(n-1)).removeClass("ft-red"):(i.html(' '+(n+1)).addClass("ft-red"),o.hasClass("ft-red")&&o.html(' '+(r-1)).removeClass("ft-red"))}})},voteDown:function(e,t,n){if(!Label.isLoggedIn)return Util.needLogin(),!1;var i=$(n),o=i.prev();if(i.hasClass("disabled"))return!1;var r={dataId:e};i.addClass("disabled"),$.ajax({url:Label.servePath+"/vote/down/"+t,type:"POST",cache:!1,data:JSON.stringify(r),success:function(e,t){i.removeClass("disabled");var n=parseInt(o.text()),r=parseInt(i.text());if(0===e.code)return 1===e.type?i.html(' '+(r-1)).removeClass("ft-red"):(i.html(' '+(r+1)).addClass("ft-red"),o.hasClass("ft-red")&&o.html(' '+(n-1)).removeClass("ft-red")),!1;Util.alert(e.msg)}})},previewImgAfterLoading:function(){$(".img-preview img").css("transform","translate3d("+Math.max(0,$(window).width()-$(".img-preview img").width())/2+"px, "+Math.max(0,$(window).height()-$(".img-preview img").height())/2+"px, 0)"),setTimeout(function(){$(".img-preview").width($(window).width())},300)},init:function(){this.initToc(),this.share(),Util.parseHljs(),Util.parseMarkdown();var e=null;$(".article").on("dblclick",".vditor-reset img",function(){clearTimeout(e),$(this).hasClass("emoji")||1===$(this).closest(".editor-panel").length||1===$(this).closest(".ad").length||window.open($(this).attr("src"))}).on("click",".vditor-reset img",function(t){if(clearTimeout(e),!$(this).hasClass("emoji")&&1!==$(this).closest(".editor-panel").length&&1!==$(this).closest(".ad").length){var n=$(this),i=this;e=setTimeout(function(){var e=i.offsetTop,t=i.offsetLeft;1===n.closest(".comments").length&&(e+=n.closest("li")[0].offsetTop,t=t+$(".comments")[0].offsetLeft+15);var o=(n.attr("src")||"").split("?imageView2")[0],r=$('
    ').on("click",function(){$(this).remove()}),a=$("").css("transform","translate3d("+Math.max(0,t)+"px, "+Math.max(0,e-$(window).scrollTop())+"px, 0)").attr("src",o).on("load",Article.previewImgAfterLoading);r.append(a),$("body").append(r),$(".img-preview").css({"background-color":"#fff",position:"fixed"})},100)}}),$("#reportDialog").dialog({width:$(window).width()>500?500:$(window).width()-50,height:450,modal:!0,hideFooter:!0}),this.initAudio(),$(window).scroll(function(){var e=$(window).scrollTop();$(".share").css("top",e+60+"px"),e<$(".article-title").offset().top?($(".article-header").css("top","-60px"),$(".nav").show()):($(".article-header").css("top","0"),$(".nav").hide())}),$(window).resize(function(){Article.syncTocLayout()});var t=location.search.split("r=")[1];t&&sessionStorage.setItem("r",t.split("&")[0]),$(function(){$.ajax({url:Label.servePath+"/api/article/reward/senders/"+Label.articleOId,method:"GET",async:!1,headers:{csrfToken:Label.csrfToken},success:function(e){if(0===e.code&&""!==e.data){let t=e.data;for(let e=0;e\n
    \n
    \n
    \n")}Util.listenUserCard()}}})})},revision:function(e,t){if(!Label.isLoggedIn)return Util.needLogin(),!1;t||(t="article"),Article._revisionDialogOpen("comment"===t?"评论历史":"文章历史"),"comment"===t?Article._legacyRevision(e,t):Article._articleRevision(e)},_revisionDialogInit:function(){$("#revisionDialog").length>0||($("body").append(''),$("#revisionDialog .revision-modal__body").append($("#revision")),$("#revisionDialog .revision-modal__overlay, #revisionDialog .revision-modal__close").click(function(){Article._revisionDialogClose()}),$(document).off("keydown.revisionDialog").on("keydown.revisionDialog",function(e){"Escape"===e.key&&$("#revisionDialog").hasClass("is-open")&&Article._revisionDialogClose()}))},_revisionDialogOpen:function(e){Article._revisionDialogInit(),$("#revisionDialogTitle").text(e||"历史版本"),$("#revisionDialog").addClass("is-open").attr("aria-hidden","false"),$("body").addClass("revision-modal-open"),$("#revisionDialog .revision-modal__close").focus()},_revisionDialogClose:function(){$("#revisionDialog").removeClass("is-open").attr("aria-hidden","true"),$("body").removeClass("revision-modal-open")},_legacyRevision:function(e,t){$.ajax({url:Label.servePath+"/"+t+"/"+e+"/revisions",cache:!1,success:function(e,n){if(0===e.code){if(0===e.revisions.length||1===e.revisions.length)return $("#revision > .revisions").remove(),$("#revisions").html(""+Label.noRevisionLabel+""),!1;$("#revisions").html("").prev().remove(),$("#revisions").data("revisions",e.revisions).before('
    '+(e.revisions.length-1)+"~"+e.revisions.length+"/"+e.revisions.length+'
    '),e.revisions.length<=2&&$("#revision a").first().addClass("disabled");var i=JsDiff.createPatch("",e.revisions[e.revisions.length-2].revisionData.articleContent||e.revisions[e.revisions.length-2].revisionData.commentContent,e.revisions[e.revisions.length-1].revisionData.articleContent||e.revisions[e.revisions.length-1].revisionData.commentContent,e.revisions[e.revisions.length-2].revisionData.articleTitle||"",e.revisions[e.revisions.length-1].revisionData.articleTitle||"");return new Diff2HtmlUI({diff:i}).draw("#revisions",{matching:"lines",outputFormat:"side-by-side",synchronisedScroll:!0}),Article._revisionsControls(t),!1}Util.alert(e.msg)}})},_revisionsControls:function(e){var t=$("#revisions").data("revisions");$("#revision a.first").click(function(){if(!$(this).hasClass("disabled")){var e=parseInt($("#revision .revisions").text().split("~")[0]);e<=2?$(this).addClass("disabled"):$(this).removeClass("disabled"),t.length>2&&$("#revision a.last").removeClass("disabled"),$("#revision .revisions > span").html(e-1+"~"+e+"/"+t.length);var n=JsDiff.createPatch("",t[e-2].revisionData.articleContent||t[e-2].revisionData.commentContent,t[e-1].revisionData.articleContent||t[e-1].revisionData.commentContent,t[e-2].revisionData.articleTitle||"",t[e-1].revisionData.articleTitle||"");new Diff2HtmlUI({diff:n}).draw("#revisions",{matching:"lines",outputFormat:"side-by-side",synchronisedScroll:!0})}}),$("#revision a.last").click(function(){if(!$(this).hasClass("disabled")){var e=parseInt($("#revision .revisions span").text().split("~")[0]);e>t.length-3?$(this).addClass("disabled"):$(this).removeClass("disabled"),t.length>2&&$("#revision a.first").removeClass("disabled"),$("#revision .revisions > span").html(e+1+"~"+(e+2)+"/"+t.length);var n=JsDiff.createPatch("",t[e].revisionData.articleContent||t[e].revisionData.commentContent,t[e+1].revisionData.articleContent||t[e+1].revisionData.commentContent,t[e].revisionData.articleTitle||"",t[e+1].revisionData.articleTitle||"");new Diff2HtmlUI({diff:n}).draw("#revisions",{matching:"lines",outputFormat:"side-by-side",synchronisedScroll:!0})}})},_articleRevision:function(e){$("#revision > .revisions").remove(),$("#revisions").removeData("revisions").removeData("revisionDetails").html("加载中"),$.ajax({url:Label.servePath+"/article/"+e+"/revisions/list",cache:!1,success:function(t){if(0===t.code){var n=t.revisions||[];n.length<2?$("#revisions").html(""+Label.noRevisionLabel+""):($("#revisions").data("revisions",n).data("revisionDetails",{}).html(Article._revisionPickerHtml(n)),Article._revisionBindPicker(e),Article._revisionCompare(e))}else $("#revisions").html(""+Article._revisionEscapeHTML(t.msg||"加载失败")+"")},error:function(){$("#revisions").html("加载失败")}})},_revisionPickerHtml:function(e){for(var t=e.length-2,n=e.length-1,i="",o="",r=0;r
    '},_revisionOptionHtml:function(e,t){return'"},_revisionVersionLabel:function(e){return e.current?"当前 "+e.revisionTimeStr:e.revisionTimeStr},_revisionBindPicker:function(e){$("#revision .revision-picker__compare").click(function(){Article._revisionCompare(e)}),$("#revision .revision-picker__diff-only").change(function(){Article._revisionCompare(e)})},_revisionCompare:function(e){var t=$("#revision .revision-picker__base").val(),n=$("#revision .revision-picker__target").val(),i=$("#revision .revision-picker__diff-only").is(":checked");$("#revisions .revision-diff").html("加载中"),$.when(Article._revisionFetch(e,t),Article._revisionFetch(e,n)).done(function(e,t){Article._revisionRenderCompare(e,t,i)}).fail(function(e){$("#revisions .revision-diff").html(""+Article._revisionEscapeHTML(e||"加载失败")+"")})},_revisionFetch:function(e,t){var n=$("#revisions").data("revisionDetails")||{},i=$.Deferred();return n[t]?(i.resolve(n[t]),i.promise()):($.ajax({url:Label.servePath+"/article/"+e+"/revisions/"+encodeURIComponent(t),cache:!1,success:function(e){0===e.code?(n[t]=e.revision,$("#revisions").data("revisionDetails",n),i.resolve(e.revision)):i.reject(e.msg)},error:function(){i.reject("加载失败")}}),i.promise())},_revisionRenderCompare:function(e,t,n){var i=e.revisionData||{},o=t.revisionData||{},r=Article._revisionRenderInlineDiff("标题",i.articleTitle||"",o.articleTitle||"",n);r+=Article._revisionRenderLineDiff("内容",i.articleContent||"",o.articleContent||"",n),$("#revisions .revision-diff").html(r||"无差异")},_revisionRenderInlineDiff:function(e,t,n,i){for(var o=JsDiff.diffWordsWithSpace?JsDiff.diffWordsWithSpace(t,n):JsDiff.diffWords(t,n),r=!1,a="",s=0;s'+Article._revisionEscapeHTML(o[s].value)+"")}return i&&!r?"":'

    '+e+'

    '+a+"
    "},_revisionRenderLineDiff:function(e,t,n,i){for(var o=JsDiff.diffLines(t,n),r=!1,a="",s=0;s

    '+e+'

    '+a+"
    "},_revisionLineHtml:function(e,t){for(var n=Article._revisionSplitLines(e),i="",o=0;o'+Article._revisionEscapeHTML(n[o])+"
    ";return i},_revisionSplitLines:function(e){var t=e.split("\n");return""===t[t.length-1]&&t.pop(),t},_revisionEscapeHTML:function(e){return String(e).replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")},share:function(){var e=$("#qrCode").data("shareurl");$("#qrCode").qrcode({width:90,height:90,text:e}),$("body").click(function(){$("#qrCode").slideUp()}),$(".share > span").click(function(){var t=$(this).data("type");if(!t)return!1;if("wechat"===t)return $("#qrCode").slideToggle(),!1;if("copy"===t)return!1;var n=encodeURIComponent(Label.articleTitle+" - "+Label.symphonyLabel),i=encodeURIComponent(e),o=$(".article-info .avatar-mid").css("background-image");pic=o.substring(5,o.length-2);var r={};r.tencent="http://share.v.t.qq.com/index.php?c=share&a=index&title="+n+"&url="+i+"&pic="+pic,r.weibo="http://v.t.sina.com.cn/share/share.php?title="+n+"&url="+i+"&pic="+pic,r.google="https://plus.google.com/share?url="+i,r.twitter="https://twitter.com/intent/tweet?status="+n+" "+i,window.open(r[t],"_blank","top=100,left=200,width=648,height=618")}),$("#qrCode").click(function(){$(this).hide()}),$("#shareClipboard").mouseover(function(){$(this).attr("aria-label",Label.copyLabel)}),Util.clipboard($("#shareClipboard"),$("#shareClipboard").next(),function(){$("#shareClipboard").attr("aria-label",Label.copiedLabel)})},reward:function(e){confirm(Label.rewardConfirmLabel)&&$.ajax({url:Label.servePath+"/article/reward?articleId="+e,type:"POST",cache:!1,success:function(e,t){if(0!==e.code)Util.alert(e.msg);else{$("#articleRewardContent .vditor-reset").html(e.articleRewardContent),Util.parseHljs(),Util.parseMarkdown();var n=$("#articleRewardContent > span"),i=parseInt(n.text());n.addClass("ft-red").removeClass("ft-blue").html(i+1+" "+Label.rewardLabel).removeAttr("onclick")}},error:function(e){Util.needLogin()}})},thankArticle:function(e,t){return Label.isLoggedIn?!(0===t&&!confirm(Label.thankArticleConfirmLabel))&&(Label.currentUserName===Label.articleAuthorName?(Util.alert(Label.thankSelfLabel),!1):void $.ajax({url:Label.servePath+"/article/thank?articleId="+e,type:"POST",cache:!1,success:function(e,t){if(0===e.code){var n=parseInt($("#thankArticle").text());$("#thankArticle").removeAttr("onclick").html(''+(n+1)+"").addClass("ft-red").removeClass("ft-blue");var i=$(''),o=$("#thankArticle").offset().top,r=$("#thankArticle").offset().left;return i.css({"z-index":9999,top:o-20,left:r,position:"absolute","font-size":16,"-moz-user-select":"none","-webkit-user-select":"none","-ms-user-select":"none"}),$("body").append(i),i.animate({top:o-180,opacity:0},1500,function(){i.remove()}),!1}Util.alert(e.msg)}})):(Util.needLogin(),!1)},stick:function(e){confirm(Label.stickConfirmLabel)&&$.ajax({url:Label.servePath+"/article/stick?articleId="+e,type:"POST",cache:!1,success:function(e,t){Util.alert(e.msg),window.location.href=Label.servePath+"/recent"}})},playThought:function(e){var t=String.fromCharCode(31),n=String.fromCharCode(30),i=String.fromCharCode(29),o=String.fromCharCode(10),r=String.fromCharCode(24),a=$("#thoughtProgress > span"),s=$("#thoughtProgress > svg"),l="#articleThought",c=function(e,n){var o=e.split(t);3===o.length&&o.splice(0,0,"");var a=o[0],s=o[2].split("-"),l=o[3].split("-");if(s[0]=parseInt(s[0]),s[1]=parseInt(s[1]),l[0]=parseInt(l[0]),l[1]=parseInt(l[1]),a===r){for(var c=[],m=s[1],d=0;l[1],m").replace(/ /g," ").replace(/ /g,"    ");$(l).data("text",e).html(t)},parseInt(m[u].split(t)[1])/d);for(var h=0,f=parseInt(m[u-1].split(t)[1])/d,v=setInterval(function(){h>=f?(a.width("100%"),s.css("left","100%"),clearInterval(v)):(h+=20,s.css("left",100*h/f+"%"),a.width(100*h/f+"%"))},20),g="",C="",b=0,y=0,w=0;y").replace(/ /g," ").replace(/ /g,"    "),g=L,$(l).html(C),b=Math.max(b,$(l).height())}$("#thoughtProgressPreview").html('
    '+C+"
    "),$("#thoughtProgressPreview").dialog({modal:!0,hideFooter:!0}),s.click(function(){$("#thoughtProgressPreview").dialog("open")}),$(l).html(C).height(b).css("margin-bottom","15px").html("")},syncTocLayout:function(){var e=1===$("#articleToC").length;return $("body.article").toggleClass("article--has-toc",e),$(".article-body .wrapper, #articleCommentsPanel, .article-footer").css("margin-right",""),e&&$("#articleToC > .module-panel").height($(window).height()-48),e},initToc:function(){if(!this.syncTocLayout())return!1;var e=$("#articleToC"),t=$(".article-toc"),n=$(".article-content [id^=toc]"),i=!1;e.offset().top;toc=[],e.find("li").click(function(){var t=$(this);let n=$(this).find("a").text();n=normalizeHeadingIdFromString(n),document.getElementById(n).scrollIntoView({behavior:"smooth"}),setTimeout(function(){e.find("li").removeClass("current"),t.addClass("current")},50)}),$(window).scroll(function(o){if(parseInt($("#articleToC").css("right"))<0)return!1;$("#articleToC > .module-panel").height($(window).height()-49),toc=[],n.each(function(e){toc.push({id:this.id,offsetTop:this.offsetTop})});for(var r=$(window).scrollTop(),a=0,s=toc.length;a0?a-1:0;e.find('a[data-id="'+toc[l].id+'"]').parent().addClass("current");break}r>=toc[toc.length-1].offsetTop-53&&(e.find("li").removeClass("current"),e.find("li:last").addClass("current"));var c=e.find("li.current")[0].offsetTop;i||(t.scrollTop()c-30&&t.scrollTop(c)),setTimeout(function(){i=!1},600)}),$(window).scroll(),t.scrollTop(e.find("li.current")[0].offsetTop).scroll(function(){i=!0})},toggleToc:function(){var e=$("#articleToC");if(0===e.length)return!1;var t=$(".article-header .icon-unordered-list");t.hasClass("ft-red")?(e.animate({right:"-"+$("#articleToC").outerWidth()+"px"}),t.removeClass("ft-red"),$(".article-actions .icon-unordered-list").removeClass("ft-red")):(e.animate({right:0}),t.addClass("ft-red"),$(".article-actions .icon-unordered-list").addClass("ft-red"))},getNotificationCommentIds:function(e){var t=[],n=function(e){(e=String(e||"").replace(/^#/,"").trim())&&-1===t.indexOf(e)&&t.push(e)};return String(e||"").split(",").forEach(n),n(window.location.hash),t.join(",")},makeNotificationRead:function(e,t){var n={articleId:e,commentIds:Article.getNotificationCommentIds(t)};$.ajax({url:Label.servePath+"/notifications/make-read",type:"POST",cache:!1,data:JSON.stringify(n)})}},ArticleAdjacentNav={storageKey:"articleAdjacentSort",sortValues:["time","author","hot"],init:function(){var e=$("[data-article-nav-sort]");0!==e.length&&(this.applySort(e,this.getStoredSort()),this.bindSortChange(e))},getStoredSort:function(){var e=window.localStorage.getItem(this.storageKey);return this.isValidSort(e)?e:"time"},isValidSort:function(e){return-1!==this.sortValues.indexOf(e)},bindSortChange:function(e){var t=this;e.find(".article-nav-sort__input").on("change",function(){this.checked&&t.isValidSort(this.value)&&(window.localStorage.setItem(t.storageKey,this.value),t.applySort(e,this.value))})},applySort:function(e,t){e.find('.article-nav-sort__input[value="'+t+'"]').prop("checked",!0)}};Article.init(),$(document).ready(function(){ArticleAdjacentNav.init(),Comment.init(),EmojiGroups.init("Comment","New"),Comment.loadEmojiGroupsNew(),(()=>{let e=(new Date).getTime(),t=0;const n=function(){0!==t&&(clearTimeout(t),t=0),$("#emojiList").css("top","auto"),$("#emojiList").css("bottom","60px"),e=(new Date).getTime(),t=setTimeout(()=>{(new Date).getTime()-e<=700&&$("#emojiList").removeClass("showList")},null!==navigator.userAgent.match(/(phone|pad|pod|ios|Android|Mobile|BlackBerry|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian)/i)?0:600)};$("#emojiBtn").hover(function(){0!==t&&(clearTimeout(t),t=0),$("#emojiList").css("top","auto"),$("#emojiList").css("bottom","60px"),e=(new Date).getTime(),EmojiGroups.ensureCurrentFresh(Comment,"New"),setTimeout(()=>0!==$("#emojiBtn:hover").length&&$("#emojiList").addClass("showList"),300)},n),$("#emojiList").hover(function(){0!==t&&(clearTimeout(t),t=0),e=(new Date).getTime()},n)})(),ArticleChannel.init(Label.articleChannel),Label.isLoggedIn&&(Article.makeNotificationRead(Label.articleOId,Label.notificationCmtIds),setTimeout(function(){Util.setUnreadNotificationCount()},1e3))}),Article.initCollectButtons=function(){$(".comment-action .action-btns").each(function(){const e=$(this);if(e.data("collect-inited"))return;const t=e.closest("li").find(".vditor-reset.comment").first();if(!t.length)return;const n=t.find("img").filter(function(){return!$(this).hasClass("emoji")&&0===$(this).closest(".editor-panel, .ad").length}).map(function(){return $(this).attr("src")}).get().filter(Boolean),i=Array.from(new Set(n));if(!i.length)return;e.data("collect-inited",!0);const o=$('');o.append(' 收藏表情'),o.on("click",function(e){e.stopPropagation(),EmojiGroups.openCollectDialog(i)}),e.prepend(o).prepend(" ")})},$(function(){Article.initCollectButtons()}); \ No newline at end of file diff --git a/src/main/resources/js/long-article.js b/src/main/resources/js/long-article.js index 7717a6a0..2f48fe2a 100644 --- a/src/main/resources/js/long-article.js +++ b/src/main/resources/js/long-article.js @@ -104,6 +104,7 @@ window.LongArticle = { root.style.setProperty('--long-article-half-width', halfWidth); root.style.setProperty('--long-article-font-size', this.settings.desktopFontSize + 'px'); this.updateWidthButtons(); + this.updateLayoutMetrics(); }, bindEvents: function () { @@ -150,6 +151,10 @@ window.LongArticle = { self.closeComments(); } }); + + window.addEventListener('resize', function () { + self.updateLayoutMetrics(); + }); }, findActionElement: function (target, boundary) { @@ -206,6 +211,41 @@ window.LongArticle = { } }, + updateLayoutMetrics: function () { + var root = document.documentElement; + var viewportWidth = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0); + var selectedWidth = this.settings.width === 'auto' ? Math.min(viewportWidth * 0.8, 1200) : parseInt(this.settings.width, 10); + var closedArticleWidth = Math.min(selectedWidth, Math.max(320, viewportWidth - 28)); + var drawerWidth = viewportWidth <= 768 ? Math.max(320, viewportWidth - 20) : Math.min(430, Math.max(360, viewportWidth * 0.3)); + var articleDrawerGap = 14; + var toolbarGap = 14; + var toolbarWidth = 44; + var safeMargin = 14; + var inline = viewportWidth >= 1100; + var openArticleWidth = closedArticleWidth; + + if (inline) { + var maxInlineStageWidth = viewportWidth - (toolbarWidth + toolbarGap + safeMargin) * 2; + var maxInlineArticleWidth = maxInlineStageWidth - drawerWidth - articleDrawerGap; + openArticleWidth = Math.min(closedArticleWidth, Math.max(560, maxInlineArticleWidth)); + inline = openArticleWidth >= 560; + } + + var stageWidth = inline ? openArticleWidth + articleDrawerGap + drawerWidth : closedArticleWidth; + var stageLeft = Math.max(safeMargin, (viewportWidth - stageWidth) / 2); + var drawerLeft = inline ? stageLeft + openArticleWidth + articleDrawerGap : viewportWidth - drawerWidth; + var closedToolbarLeft = Math.min(viewportWidth - toolbarWidth - safeMargin, (viewportWidth - closedArticleWidth) / 2 + closedArticleWidth + toolbarGap); + var openToolbarLeft = inline ? Math.min(viewportWidth - toolbarWidth - safeMargin, stageLeft + stageWidth + toolbarGap) : closedToolbarLeft; + + root.style.setProperty('--long-article-stage-width', stageWidth + 'px'); + root.style.setProperty('--long-article-open-article-width', openArticleWidth + 'px'); + document.body.style.setProperty('--long-article-drawer-width', drawerWidth + 'px'); + root.style.setProperty('--long-article-drawer-left', drawerLeft + 'px'); + root.style.setProperty('--long-article-toolbar-closed-left', closedToolbarLeft + 'px'); + root.style.setProperty('--long-article-toolbar-open-left', openToolbarLeft + 'px'); + document.body.classList.toggle('long-article-comments-inline', inline); + }, + scrollToTop: function () { window.scrollTo({top: 0, behavior: 'smooth'}); }, @@ -233,6 +273,7 @@ window.LongArticle = { return; } this.closeLayoutPanel(); + this.updateLayoutMetrics(); document.body.classList.add('long-article-comments-open'); panel.setAttribute('aria-hidden', 'false'); if (button) { @@ -245,8 +286,8 @@ window.LongArticle = { var panel = this.getCommentsPanel(); var button = document.querySelector('[data-long-article-action="comments"]'); var editorPanel = document.querySelector('.editor-panel'); - if (editorPanel && window.getComputedStyle(editorPanel).display !== 'none' && window.getComputedStyle(editorPanel).bottom === '0px' && window.Comment && typeof window.Comment._toggleReply === 'function') { - window.Comment._toggleReply(); + if (editorPanel && window.getComputedStyle(editorPanel).display !== 'none' && window.Comment && typeof window.Comment._hideReplyPanel === 'function') { + window.Comment._hideReplyPanel(); } document.body.classList.remove('long-article-comments-open'); if (panel) { diff --git a/src/main/resources/js/long-article.min.js b/src/main/resources/js/long-article.min.js index fa7296c2..e06e5e32 100644 --- a/src/main/resources/js/long-article.min.js +++ b/src/main/resources/js/long-article.min.js @@ -1 +1 @@ -window.LongArticle={storageKey:"longArticleSettings",allowedWidths:["auto","600","800","1000","1200"],settings:{width:"800",desktopFontSize:18,mobileFontSize:16},init:function(){this.initialized||(this.initialized=!0,this.loadSettings(),this.bindEvents(),this.applySettings(),this.shouldOpenCommentsFromLocation()&&(this.openComments(),this.focusLocationComment()))},loadSettings:function(){var t,e={width:"800",desktopFontSize:18,mobileFontSize:16};try{t=JSON.parse(window.localStorage.getItem(this.storageKey)||"{}")}catch(e){t={}}t&&"object"==typeof t&&(e.width=this.normalizeWidth(t.width),e.desktopFontSize=this.normalizeFontSize(t.desktopFontSize||t.fontSize,18,32,18),e.mobileFontSize=this.normalizeFontSize(t.mobileFontSize,16,24,16));try{var n=parseInt(window.localStorage.getItem("longArticleFontSize"),10);t.desktopFontSize||t.fontSize||isNaN(n)||(e.desktopFontSize=this.normalizeFontSize(n,18,32,18),e.mobileFontSize=this.normalizeFontSize(n,16,24,16));var o=JSON.parse(window.localStorage.getItem("mLongArticleSettings")||"{}");t.mobileFontSize||!o||isNaN(parseInt(o.fontSize,10))||(e.mobileFontSize=this.normalizeFontSize(parseInt(o.fontSize,10),16,24,16)),window.localStorage.removeItem("longArticleFontSize"),window.localStorage.removeItem("mLongArticleSettings")}catch(t){}this.settings=e,this.saveSettings()},normalizeWidth:function(t){return t=String(t||"800"),this.allowedWidths.indexOf(t)>=0?t:"800"},normalizeFontSize:function(t,e,n,o){return t=parseInt(t,10),isNaN(t)?o:Math.max(e,Math.min(n,t))},saveSettings:function(){try{window.localStorage.setItem(this.storageKey,JSON.stringify(this.settings))}catch(t){}},applySettings:function(){var t=document.documentElement,e=this.settings.width,n="auto"===e?"min(40vw, 600px)":parseInt(e,10)/2+"px";t.style.setProperty("--long-article-width","auto"===e?"min(80vw, 1200px)":e+"px"),t.style.setProperty("--long-article-half-width",n),t.style.setProperty("--long-article-font-size",this.settings.desktopFontSize+"px"),this.updateWidthButtons()},bindEvents:function(){var t=this,e=document.querySelector("[data-long-article-toolbar]");e&&(e.addEventListener("click",function(n){var o=t.findActionElement(n.target,e);if(o){var i=o.getAttribute("data-long-article-action");"top"===i?t.scrollToTop():"comments"===i?t.toggleComments():"font-decrease"===i?t.setFontSize(-2):"font-increase"===i?t.setFontSize(2):"layout"===i?t.toggleLayoutPanel():o.hasAttribute("data-long-article-width")&&t.setWidth(o.getAttribute("data-long-article-width"))}}),document.addEventListener("click",function(n){var o=document.getElementById("longArticleLayoutPanel"),i=e.querySelector('[data-long-article-action="layout"]');o&&o.classList.contains("is-open")&&!o.contains(n.target)&&!i.contains(n.target)&&t.closeLayoutPanel(),n.target.closest&&n.target.closest("[data-long-article-comments-close]")&&t.closeComments()}),document.addEventListener("keydown",function(e){"Escape"===e.key&&t.isCommentsOpen()&&t.closeComments()}))},findActionElement:function(t,e){for(;t&&t!==e;){if(1===t.nodeType&&(t.hasAttribute("data-long-article-action")||t.hasAttribute("data-long-article-width")))return t;t=t.parentNode}return t&&t!==e&&1===t.nodeType?t:null},setFontSize:function(t){this.settings.desktopFontSize=this.normalizeFontSize(this.settings.desktopFontSize+t,12,32,18),this.saveSettings(),this.applySettings()},setWidth:function(t){this.settings.width=this.normalizeWidth(t),this.saveSettings(),this.applySettings(),this.closeLayoutPanel()},updateWidthButtons:function(){var t=this.settings.width;document.querySelectorAll("[data-long-article-width]").forEach(function(e){e.classList.toggle("is-active",e.getAttribute("data-long-article-width")===t)})},toggleLayoutPanel:function(){var t=document.getElementById("longArticleLayoutPanel"),e=document.querySelector('[data-long-article-action="layout"]');if(t&&e){var n=!t.classList.contains("is-open");t.classList.toggle("is-open",n),t.setAttribute("aria-hidden",n?"false":"true"),e.setAttribute("aria-expanded",n?"true":"false")}},closeLayoutPanel:function(){var t=document.getElementById("longArticleLayoutPanel"),e=document.querySelector('[data-long-article-action="layout"]');t&&(t.classList.remove("is-open"),t.setAttribute("aria-hidden","true")),e&&e.setAttribute("aria-expanded","false")},scrollToTop:function(){window.scrollTo({top:0,behavior:"smooth"})},getCommentsPanel:function(){return document.getElementById("articleCommentsPanel")},isCommentsOpen:function(){return document.body.classList.contains("long-article-comments-open")},toggleComments:function(){this.isCommentsOpen()?this.closeComments():this.openComments()},openComments:function(){var t=this.getCommentsPanel(),e=document.querySelector('[data-long-article-action="comments"]');t&&(this.closeLayoutPanel(),document.body.classList.add("long-article-comments-open"),t.setAttribute("aria-hidden","false"),e&&(e.classList.add("is-active"),e.setAttribute("aria-expanded","true")))},closeComments:function(){var t=this.getCommentsPanel(),e=document.querySelector('[data-long-article-action="comments"]'),n=document.querySelector(".editor-panel");n&&"none"!==window.getComputedStyle(n).display&&"0px"===window.getComputedStyle(n).bottom&&window.Comment&&"function"==typeof window.Comment._toggleReply&&window.Comment._toggleReply(),document.body.classList.remove("long-article-comments-open"),t&&t.setAttribute("aria-hidden","true"),e&&(e.classList.remove("is-active"),e.setAttribute("aria-expanded","false"))},shouldOpenCommentsFromLocation:function(){var t=this.getCommentsPanel(),e=window.location.hash.replace(/^#/,""),n=e?document.getElementById(e):null;return!!(t&&n&&t.contains(n))||/(?:\?|&)(?:p|m|sort|author)=/.test(window.location.search)},focusLocationComment:function(){var t=this;window.setTimeout(function(){var e=window.location.hash.replace(/^#/,""),n=e?document.getElementById(e):null,o=t.getCommentsPanel();o&&n&&o.contains(n)&&n.scrollIntoView({block:"center"})},0)}}; \ No newline at end of file +window.LongArticle={storageKey:"longArticleSettings",allowedWidths:["auto","600","800","1000","1200"],settings:{width:"800",desktopFontSize:18,mobileFontSize:16},init:function(){this.initialized||(this.initialized=!0,this.loadSettings(),this.bindEvents(),this.applySettings(),this.shouldOpenCommentsFromLocation()&&(this.openComments(),this.focusLocationComment()))},loadSettings:function(){var t,e={width:"800",desktopFontSize:18,mobileFontSize:16};try{t=JSON.parse(window.localStorage.getItem(this.storageKey)||"{}")}catch(e){t={}}t&&"object"==typeof t&&(e.width=this.normalizeWidth(t.width),e.desktopFontSize=this.normalizeFontSize(t.desktopFontSize||t.fontSize,18,32,18),e.mobileFontSize=this.normalizeFontSize(t.mobileFontSize,16,24,16));try{var n=parseInt(window.localStorage.getItem("longArticleFontSize"),10);t.desktopFontSize||t.fontSize||isNaN(n)||(e.desktopFontSize=this.normalizeFontSize(n,18,32,18),e.mobileFontSize=this.normalizeFontSize(n,16,24,16));var o=JSON.parse(window.localStorage.getItem("mLongArticleSettings")||"{}");t.mobileFontSize||!o||isNaN(parseInt(o.fontSize,10))||(e.mobileFontSize=this.normalizeFontSize(parseInt(o.fontSize,10),16,24,16)),window.localStorage.removeItem("longArticleFontSize"),window.localStorage.removeItem("mLongArticleSettings")}catch(t){}this.settings=e,this.saveSettings()},normalizeWidth:function(t){return t=String(t||"800"),this.allowedWidths.indexOf(t)>=0?t:"800"},normalizeFontSize:function(t,e,n,o){return t=parseInt(t,10),isNaN(t)?o:Math.max(e,Math.min(n,t))},saveSettings:function(){try{window.localStorage.setItem(this.storageKey,JSON.stringify(this.settings))}catch(t){}},applySettings:function(){var t=document.documentElement,e=this.settings.width,n="auto"===e?"min(40vw, 600px)":parseInt(e,10)/2+"px";t.style.setProperty("--long-article-width","auto"===e?"min(80vw, 1200px)":e+"px"),t.style.setProperty("--long-article-half-width",n),t.style.setProperty("--long-article-font-size",this.settings.desktopFontSize+"px"),this.updateWidthButtons(),this.updateLayoutMetrics()},bindEvents:function(){var t=this,e=document.querySelector("[data-long-article-toolbar]");e&&(e.addEventListener("click",function(n){var o=t.findActionElement(n.target,e);if(o){var i=o.getAttribute("data-long-article-action");"top"===i?t.scrollToTop():"comments"===i?t.toggleComments():"font-decrease"===i?t.setFontSize(-2):"font-increase"===i?t.setFontSize(2):"layout"===i?t.toggleLayoutPanel():o.hasAttribute("data-long-article-width")&&t.setWidth(o.getAttribute("data-long-article-width"))}}),document.addEventListener("click",function(n){var o=document.getElementById("longArticleLayoutPanel"),i=e.querySelector('[data-long-article-action="layout"]');o&&o.classList.contains("is-open")&&!o.contains(n.target)&&!i.contains(n.target)&&t.closeLayoutPanel(),n.target.closest&&n.target.closest("[data-long-article-comments-close]")&&t.closeComments()}),document.addEventListener("keydown",function(e){"Escape"===e.key&&t.isCommentsOpen()&&t.closeComments()}),window.addEventListener("resize",function(){t.updateLayoutMetrics()}))},findActionElement:function(t,e){for(;t&&t!==e;){if(1===t.nodeType&&(t.hasAttribute("data-long-article-action")||t.hasAttribute("data-long-article-width")))return t;t=t.parentNode}return t&&t!==e&&1===t.nodeType?t:null},setFontSize:function(t){this.settings.desktopFontSize=this.normalizeFontSize(this.settings.desktopFontSize+t,12,32,18),this.saveSettings(),this.applySettings()},setWidth:function(t){this.settings.width=this.normalizeWidth(t),this.saveSettings(),this.applySettings(),this.closeLayoutPanel()},updateWidthButtons:function(){var t=this.settings.width;document.querySelectorAll("[data-long-article-width]").forEach(function(e){e.classList.toggle("is-active",e.getAttribute("data-long-article-width")===t)})},toggleLayoutPanel:function(){var t=document.getElementById("longArticleLayoutPanel"),e=document.querySelector('[data-long-article-action="layout"]');if(t&&e){var n=!t.classList.contains("is-open");t.classList.toggle("is-open",n),t.setAttribute("aria-hidden",n?"false":"true"),e.setAttribute("aria-expanded",n?"true":"false")}},closeLayoutPanel:function(){var t=document.getElementById("longArticleLayoutPanel"),e=document.querySelector('[data-long-article-action="layout"]');t&&(t.classList.remove("is-open"),t.setAttribute("aria-hidden","true")),e&&e.setAttribute("aria-expanded","false")},updateLayoutMetrics:function(){var t=document.documentElement,e=Math.max(document.documentElement.clientWidth||0,window.innerWidth||0),n="auto"===this.settings.width?Math.min(.8*e,1200):parseInt(this.settings.width,10),o=Math.min(n,Math.max(320,e-28)),i=e<=768?Math.max(320,e-20):Math.min(430,Math.max(360,.3*e)),a=e>=1100,s=o;if(a){var l=e-144-i-14;a=(s=Math.min(o,Math.max(560,l)))>=560}var r=a?s+14+i:o,c=Math.max(14,(e-r)/2),d=a?c+s+14:e-i,m=Math.min(e-44-14,(e-o)/2+o+14),u=a?Math.min(e-44-14,c+r+14):m;t.style.setProperty("--long-article-stage-width",r+"px"),t.style.setProperty("--long-article-open-article-width",s+"px"),document.body.style.setProperty("--long-article-drawer-width",i+"px"),t.style.setProperty("--long-article-drawer-left",d+"px"),t.style.setProperty("--long-article-toolbar-closed-left",m+"px"),t.style.setProperty("--long-article-toolbar-open-left",u+"px"),document.body.classList.toggle("long-article-comments-inline",a)},scrollToTop:function(){window.scrollTo({top:0,behavior:"smooth"})},getCommentsPanel:function(){return document.getElementById("articleCommentsPanel")},isCommentsOpen:function(){return document.body.classList.contains("long-article-comments-open")},toggleComments:function(){this.isCommentsOpen()?this.closeComments():this.openComments()},openComments:function(){var t=this.getCommentsPanel(),e=document.querySelector('[data-long-article-action="comments"]');t&&(this.closeLayoutPanel(),this.updateLayoutMetrics(),document.body.classList.add("long-article-comments-open"),t.setAttribute("aria-hidden","false"),e&&(e.classList.add("is-active"),e.setAttribute("aria-expanded","true")))},closeComments:function(){var t=this.getCommentsPanel(),e=document.querySelector('[data-long-article-action="comments"]'),n=document.querySelector(".editor-panel");n&&"none"!==window.getComputedStyle(n).display&&window.Comment&&"function"==typeof window.Comment._hideReplyPanel&&window.Comment._hideReplyPanel(),document.body.classList.remove("long-article-comments-open"),t&&t.setAttribute("aria-hidden","true"),e&&(e.classList.remove("is-active"),e.setAttribute("aria-expanded","false"))},shouldOpenCommentsFromLocation:function(){var t=this.getCommentsPanel(),e=window.location.hash.replace(/^#/,""),n=e?document.getElementById(e):null;return!!(t&&n&&t.contains(n))||/(?:\?|&)(?:p|m|sort|author)=/.test(window.location.search)},focusLocationComment:function(){var t=this;window.setTimeout(function(){var e=window.location.hash.replace(/^#/,""),n=e?document.getElementById(e):null,o=t.getCommentsPanel();o&&n&&o.contains(n)&&n.scrollIntoView({block:"center"})},0)}}; \ No newline at end of file diff --git a/src/main/resources/js/m-long-article.js b/src/main/resources/js/m-long-article.js index 7b6e52a8..43c64bb6 100644 --- a/src/main/resources/js/m-long-article.js +++ b/src/main/resources/js/m-long-article.js @@ -168,8 +168,8 @@ window.MLongArticle = { var panel = this.getCommentsPanel(); var button = document.querySelector('[data-long-article-action="comments"]'); var editorPanel = document.querySelector('.editor-panel'); - if (editorPanel && editorPanel.classList.contains('editor-panel--open') && window.Comment && typeof window.Comment._toggleReply === 'function') { - window.Comment._toggleReply(); + if (editorPanel && editorPanel.classList.contains('editor-panel--open') && window.Comment && typeof window.Comment._hideReplyPanel === 'function') { + window.Comment._hideReplyPanel(); } document.body.classList.remove('long-article-comments-open'); if (panel) { diff --git a/src/main/resources/js/m-long-article.min.js b/src/main/resources/js/m-long-article.min.js index 2613b324..6f13694b 100644 --- a/src/main/resources/js/m-long-article.min.js +++ b/src/main/resources/js/m-long-article.min.js @@ -1 +1 @@ -window.MLongArticle={storageKey:"longArticleSettings",settings:{width:"800",desktopFontSize:18,mobileFontSize:16},init:function(){this.initialized||(this.initialized=!0,this.loadSettings(),this.bindEvents(),this.applySettings(),this.shouldOpenCommentsFromLocation()&&(this.openComments(),this.focusLocationComment()))},loadSettings:function(){var t,e={width:"800",desktopFontSize:18,mobileFontSize:16};try{t=JSON.parse(window.localStorage.getItem(this.storageKey)||"{}")}catch(e){t={}}t&&"object"==typeof t&&(e.width=["auto","600","800","1000","1200"].indexOf(String(t.width||"800"))>=0?String(t.width||"800"):"800",e.desktopFontSize=this.normalizeFontSize(t.desktopFontSize||t.fontSize,18,32,18),e.mobileFontSize=this.normalizeFontSize(t.mobileFontSize||t.fontSize,16,24,16));try{var o=parseInt(window.localStorage.getItem("longArticleFontSize"),10),n=JSON.parse(window.localStorage.getItem("mLongArticleSettings")||"{}");t.mobileFontSize||!n||isNaN(parseInt(n.fontSize,10))?t.mobileFontSize||isNaN(o)||(e.mobileFontSize=this.normalizeFontSize(o,16,24,16)):e.mobileFontSize=this.normalizeFontSize(parseInt(n.fontSize,10),16,24,16),window.localStorage.removeItem("longArticleFontSize"),window.localStorage.removeItem("mLongArticleSettings")}catch(t){}this.settings=e,this.saveSettings()},normalizeFontSize:function(t,e,o,n){return t=parseInt(t,10),isNaN(t)?n:Math.max(e,Math.min(o,t))},saveSettings:function(){try{window.localStorage.setItem(this.storageKey,JSON.stringify(this.settings))}catch(t){}},applySettings:function(){document.documentElement.style.setProperty("--long-article-font-size",this.settings.mobileFontSize+"px")},bindEvents:function(){var t=this,e=document.querySelector("[data-long-article-toolbar]");e&&(e.addEventListener("click",function(o){for(var n=o.target;n&&n!==e&&!n.hasAttribute("data-long-article-action");)n=n.parentNode;if(n&&n!==e){var i=n.getAttribute("data-long-article-action");if("toggle"===i){var s=!e.classList.contains("is-open");e.classList.toggle("is-open",s),n.classList.toggle("active",s),n.setAttribute("aria-expanded",s?"true":"false")}else"top"===i?window.scrollTo({top:0,behavior:"smooth"}):"comments"===i?t.toggleComments():"font-decrease"===i?t.setFontSize(-2):"font-increase"===i&&t.setFontSize(2)}}),document.addEventListener("click",function(e){e.target.closest&&e.target.closest("[data-long-article-comments-close]")&&t.closeComments()}))},setFontSize:function(t){this.settings.mobileFontSize=this.normalizeFontSize(this.settings.mobileFontSize+t,12,24,16),this.saveSettings(),this.applySettings()},getCommentsPanel:function(){return document.getElementById("comments")},isCommentsOpen:function(){return document.body.classList.contains("long-article-comments-open")},toggleComments:function(){this.isCommentsOpen()?this.closeComments():this.openComments()},openComments:function(){var t=this.getCommentsPanel(),e=document.querySelector('[data-long-article-action="comments"]');t&&(document.body.classList.add("long-article-comments-open"),t.setAttribute("aria-hidden","false"),e&&(e.classList.add("is-active"),e.setAttribute("aria-expanded","true")))},closeComments:function(){var t=this.getCommentsPanel(),e=document.querySelector('[data-long-article-action="comments"]'),o=document.querySelector(".editor-panel");o&&o.classList.contains("editor-panel--open")&&window.Comment&&"function"==typeof window.Comment._toggleReply&&window.Comment._toggleReply(),document.body.classList.remove("long-article-comments-open"),t&&t.setAttribute("aria-hidden","true"),e&&(e.classList.remove("is-active"),e.setAttribute("aria-expanded","false"))},shouldOpenCommentsFromLocation:function(){var t=this.getCommentsPanel(),e=window.location.hash.replace(/^#/,""),o=e?document.getElementById(e):null;return!!(t&&o&&t.contains(o))||/(?:\?|&)(?:p|m|sort|author)=/.test(window.location.search)},focusLocationComment:function(){var t=this;window.setTimeout(function(){var e=window.location.hash.replace(/^#/,""),o=e?document.getElementById(e):null,n=t.getCommentsPanel();n&&o&&n.contains(o)&&o.scrollIntoView({block:"center"})},0)}}; \ No newline at end of file +window.MLongArticle={storageKey:"longArticleSettings",settings:{width:"800",desktopFontSize:18,mobileFontSize:16},init:function(){this.initialized||(this.initialized=!0,this.loadSettings(),this.bindEvents(),this.applySettings(),this.shouldOpenCommentsFromLocation()&&(this.openComments(),this.focusLocationComment()))},loadSettings:function(){var t,e={width:"800",desktopFontSize:18,mobileFontSize:16};try{t=JSON.parse(window.localStorage.getItem(this.storageKey)||"{}")}catch(e){t={}}t&&"object"==typeof t&&(e.width=["auto","600","800","1000","1200"].indexOf(String(t.width||"800"))>=0?String(t.width||"800"):"800",e.desktopFontSize=this.normalizeFontSize(t.desktopFontSize||t.fontSize,18,32,18),e.mobileFontSize=this.normalizeFontSize(t.mobileFontSize||t.fontSize,16,24,16));try{var n=parseInt(window.localStorage.getItem("longArticleFontSize"),10),o=JSON.parse(window.localStorage.getItem("mLongArticleSettings")||"{}");t.mobileFontSize||!o||isNaN(parseInt(o.fontSize,10))?t.mobileFontSize||isNaN(n)||(e.mobileFontSize=this.normalizeFontSize(n,16,24,16)):e.mobileFontSize=this.normalizeFontSize(parseInt(o.fontSize,10),16,24,16),window.localStorage.removeItem("longArticleFontSize"),window.localStorage.removeItem("mLongArticleSettings")}catch(t){}this.settings=e,this.saveSettings()},normalizeFontSize:function(t,e,n,o){return t=parseInt(t,10),isNaN(t)?o:Math.max(e,Math.min(n,t))},saveSettings:function(){try{window.localStorage.setItem(this.storageKey,JSON.stringify(this.settings))}catch(t){}},applySettings:function(){document.documentElement.style.setProperty("--long-article-font-size",this.settings.mobileFontSize+"px")},bindEvents:function(){var t=this,e=document.querySelector("[data-long-article-toolbar]");e&&(e.addEventListener("click",function(n){for(var o=n.target;o&&o!==e&&!o.hasAttribute("data-long-article-action");)o=o.parentNode;if(o&&o!==e){var i=o.getAttribute("data-long-article-action");if("toggle"===i){var s=!e.classList.contains("is-open");e.classList.toggle("is-open",s),o.classList.toggle("active",s),o.setAttribute("aria-expanded",s?"true":"false")}else"top"===i?window.scrollTo({top:0,behavior:"smooth"}):"comments"===i?t.toggleComments():"font-decrease"===i?t.setFontSize(-2):"font-increase"===i&&t.setFontSize(2)}}),document.addEventListener("click",function(e){e.target.closest&&e.target.closest("[data-long-article-comments-close]")&&t.closeComments()}))},setFontSize:function(t){this.settings.mobileFontSize=this.normalizeFontSize(this.settings.mobileFontSize+t,12,24,16),this.saveSettings(),this.applySettings()},getCommentsPanel:function(){return document.getElementById("comments")},isCommentsOpen:function(){return document.body.classList.contains("long-article-comments-open")},toggleComments:function(){this.isCommentsOpen()?this.closeComments():this.openComments()},openComments:function(){var t=this.getCommentsPanel(),e=document.querySelector('[data-long-article-action="comments"]');t&&(document.body.classList.add("long-article-comments-open"),t.setAttribute("aria-hidden","false"),e&&(e.classList.add("is-active"),e.setAttribute("aria-expanded","true")))},closeComments:function(){var t=this.getCommentsPanel(),e=document.querySelector('[data-long-article-action="comments"]'),n=document.querySelector(".editor-panel");n&&n.classList.contains("editor-panel--open")&&window.Comment&&"function"==typeof window.Comment._hideReplyPanel&&window.Comment._hideReplyPanel(),document.body.classList.remove("long-article-comments-open"),t&&t.setAttribute("aria-hidden","true"),e&&(e.classList.remove("is-active"),e.setAttribute("aria-expanded","false"))},shouldOpenCommentsFromLocation:function(){var t=this.getCommentsPanel(),e=window.location.hash.replace(/^#/,""),n=e?document.getElementById(e):null;return!!(t&&n&&t.contains(n))||/(?:\?|&)(?:p|m|sort|author)=/.test(window.location.search)},focusLocationComment:function(){var t=this;window.setTimeout(function(){var e=window.location.hash.replace(/^#/,""),n=e?document.getElementById(e):null,o=t.getCommentsPanel();o&&n&&o.contains(n)&&n.scrollIntoView({block:"center"})},0)}}; \ No newline at end of file diff --git a/src/main/resources/scss/index.scss b/src/main/resources/scss/index.scss index 7ab18e4b..bc122dd4 100644 --- a/src/main/resources/scss/index.scss +++ b/src/main/resources/scss/index.scss @@ -5206,7 +5206,7 @@ code .dec { } .article.long-article-page { - --long-article-comments-width: min(430px, calc(100vw - 72px)); + --long-article-drawer-width: min(430px, calc(100vw - 72px)); min-height: 100vh; padding-top: 0; overflow-x: hidden; @@ -5226,15 +5226,28 @@ code .dec { display: none !important; } - .article-container { + .long-article-reading-stage { + display: flex; + align-items: flex-start; + column-gap: 0; box-sizing: border-box; width: min(var(--long-article-width, 800px), calc(100vw - 28px)); - max-width: none; + max-width: calc(100vw - 28px); margin: 0 auto; + transition: width 0.32s ease, column-gap 0.32s ease; + } + + .article-container { + flex: 0 0 100%; + box-sizing: border-box; + width: 100%; + max-width: none; + margin: 0; border: 0; border-radius: 0; background: #dcebdd; box-shadow: none; + transition: width 0.32s ease, flex-basis 0.32s ease; } .article-body { @@ -5264,8 +5277,10 @@ code .dec { } } - > .main { + .long-article-reading-stage > .main { + flex: 0 0 0; box-sizing: border-box; + width: 0; min-height: 0; height: 0; margin: 0; @@ -5273,18 +5288,17 @@ code .dec { overflow: visible; border-top: 0; background: transparent; + transition: width 0.32s ease, flex-basis 0.32s ease; } #articleCommentsPanel { - position: fixed; + position: sticky; top: 0; - right: 0; - bottom: 0; z-index: 115; display: flex; flex-direction: column; box-sizing: border-box; - width: var(--long-article-comments-width); + width: 100%; height: 100vh; height: 100dvh; max-width: none; @@ -5298,8 +5312,10 @@ code .dec { border-radius: 0; background: #dcebdd; box-shadow: -16px 0 38px rgba(40, 66, 47, 0.16); - transform: translateX(100%); - transition: transform 0.28s ease, visibility 0s linear 0.28s; + opacity: 0; + pointer-events: none; + transform: translateX(24px); + transition: opacity 0.24s ease, transform 0.32s ease, visibility 0s linear 0.32s; visibility: hidden; > .module { @@ -5310,6 +5326,10 @@ code .dec { box-shadow: none; } + > #comments { + margin-top: 0; + } + > .pagination { flex: 0 0 auto; margin: 18px auto 0; @@ -5318,19 +5338,61 @@ code .dec { } &.long-article-comments-open { + .long-article-settings { + right: auto; + left: var(--long-article-toolbar-open-left, calc(100vw - 58px)); + z-index: 121; + } + + .editor-panel { + right: auto; + left: var(--long-article-drawer-left, calc(100vw - var(--long-article-drawer-width))); + } + #articleCommentsPanel { + opacity: 1; + pointer-events: auto; transform: translateX(0); transition-delay: 0s; visibility: visible; } + } - .long-article-settings { - right: calc(var(--long-article-comments-width) + 14px); - left: auto; - z-index: 121; + &.long-article-comments-open.long-article-comments-inline { + .long-article-reading-stage { + column-gap: 14px; + width: var(--long-article-stage-width, calc(var(--long-article-width, 800px) + var(--long-article-drawer-width) + 14px)); + max-width: calc(100vw - 28px); + } + + .article-container { + flex-basis: var(--long-article-open-article-width, var(--long-article-width, 800px)); + width: var(--long-article-open-article-width, var(--long-article-width, 800px)); + } + + .long-article-reading-stage > .main { + flex-basis: var(--long-article-drawer-width); + width: var(--long-article-drawer-width); + height: auto; + } + } + + &.long-article-comments-open:not(.long-article-comments-inline) { + #articleCommentsPanel { + position: fixed; + right: auto; + bottom: 0; + left: var(--long-article-drawer-left, calc(100vw - var(--long-article-drawer-width))); + width: var(--long-article-drawer-width); } } + .long-article-settings { + right: auto; + left: var(--long-article-toolbar-closed-left, min(calc(50% + min(var(--long-article-half-width, 400px), calc(50vw - 14px)) + 14px), calc(100vw - 58px))); + transition: left 0.32s ease; + } + #comments { order: -1; margin: 0; @@ -5515,8 +5577,9 @@ code .dec { .editor-panel { right: 0; left: auto; - width: var(--long-article-comments-width); - max-width: var(--long-article-comments-width); + width: var(--long-article-drawer-width); + max-width: var(--long-article-drawer-width); + transition: left 0.32s ease; .editor-bg { display: none; @@ -5935,7 +5998,7 @@ body.night { color: #eef4ef; } - > .main { + .long-article-reading-stage > .main { background: #0a0a0a; } @@ -6149,8 +6212,6 @@ body.night { @media (max-width: 768px) { .article.long-article-page { - --long-article-comments-width: calc(100vw - 20px); - .article-container { margin-top: 0; border-radius: 0; @@ -6164,11 +6225,6 @@ body.night { font-size: 26px; } - > .main { - margin-top: 20px; - padding: 24px 0 30px; - } - #articleCommentsPanel { padding: 0 18px 82px; border-radius: 0; diff --git a/src/main/resources/skins/classic/pc/article.ftl b/src/main/resources/skins/classic/pc/article.ftl index 7a1fdf3b..28b65c00 100644 --- a/src/main/resources/skins/classic/pc/article.ftl +++ b/src/main/resources/skins/classic/pc/article.ftl @@ -86,6 +86,9 @@ <#if !hidePageChrome> <#include "header.ftl"> +<#if 6 == article.articleType> +
    +
    <#if showTopAd && 6 != article.articleType> @@ -561,6 +564,9 @@ <#if pjax>
    +<#if 6 == article.articleType> +
    +