diff --git a/eslint.config.mjs b/eslint.config.mjs index 41477ae..e25e1a0 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,3 +1,11 @@ import DiscourseRecommendedTheme from "@discourse/lint-configs/eslint-theme"; -export default [...DiscourseRecommendedTheme]; +export default [...DiscourseRecommendedTheme, { + languageOptions: { + ecmaVersion: 2022, + sourceType: "module", + globals: { + _oaReport: 'readonly', + }, + } +}]; diff --git a/javascripts/discourse/lib/navigation.js b/javascripts/discourse/lib/navigation.js index 06a7461..93872dc 100644 --- a/javascripts/discourse/lib/navigation.js +++ b/javascripts/discourse/lib/navigation.js @@ -1,3 +1,4 @@ +import $ from "jquery"; import { onNodeInserted } from "./utils.js"; export function reportNavigationClick() { @@ -5,25 +6,31 @@ export function reportNavigationClick() { onNodeInserted( ".navigation-container .category-drop.is-expanded .select-kit-collection", (node) => { - window - .$(node) + $(node) .children() - .on("click", (ev) => + .on("click", (ev) => { + let textContent = ev.currentTarget.textContent?.trim(); + if (!textContent) { + return; + } + const sliceIndex = textContent.indexOf("×"); + if (sliceIndex >= 0) { + textContent = textContent.slice(0, sliceIndex); + } window._oaReport("click", { - target: ev.currentTarget.textContent.trim(), + target: textContent, type: "类别", module: "nav-dropdown", $url: location.href, - }) - ); + }); + }); } ); // 标签下拉点击 onNodeInserted( ".navigation-container .tag-drop.is-expanded .select-kit-collection", (node) => { - window - .$(node) + $(node) .children() .on("click", (ev) => window._oaReport("click", { @@ -39,8 +46,7 @@ export function reportNavigationClick() { onNodeInserted( ".navigation-container .solved-status-filter.is-expanded .select-kit-collection", (node) => { - window - .$(node) + $(node) .children() .on("click", (ev) => window._oaReport("click", { @@ -53,19 +59,15 @@ export function reportNavigationClick() { } ); - onNodeInserted( - "#navigation-bar", - (node) => { - window - .$(node) - .children() - .on("click", (ev) => - window._oaReport("click", { - target: ev.currentTarget.textContent.trim(), - module: "navigation", - $url: location.href, - }) - ); - } - ); + onNodeInserted("#navigation-bar", (node) => { + $(node) + .children() + .on("click", (ev) => + window._oaReport("click", { + target: ev.currentTarget.textContent.trim(), + module: "navigation", + $url: location.href, + }) + ); + }); } diff --git a/javascripts/discourse/lib/search.js b/javascripts/discourse/lib/search.js index 960a49e..40107db 100644 --- a/javascripts/discourse/lib/search.js +++ b/javascripts/discourse/lib/search.js @@ -1,4 +1,7 @@ -import { debounce, onNodeInserted } from "./utils.js"; +import $ from "jquery"; +import { onNodeInserted } from "./utils.js"; + +let searchKey = ""; function onClickSearchInput() { window._oaReport("click", { @@ -8,15 +11,6 @@ function onClickSearchInput() { }); } -function onInputSearchInput(ev) { - window._oaReport("input", { - type: "search-input", - module: "search", - content: ev.currentTarget.value.trim(), - $url: location.href, - }); -} - function onClickSearchHistory(ev) { window._oaReport("click", { type: "search-history", @@ -39,34 +33,88 @@ function onClickSuggestion(ev) { type: "search-suggestion", module: "search", target: ev.currentTarget.textContent.trim(), - searchContent: window.$(".search-input-wrapper input").get(0).value, + searchContent: searchKey, detail: ev.currentTarget.href, $url: location.href, }); } function onClickSearchResultTopic(ev) { - const current$ = window.$(ev.currentTarget); + const current$ = $(ev.currentTarget); window._oaReport("click", { type: "search-result", module: "search", target: current$.find(".first-line").text().trim(), - searchContent: window.$(".search-input-wrapper input").get(0).value, - detail: { - path: ev.currentTarget.href, - categories: current$.find(".badge-category__name").text().trim(), - tags: current$.find(".discourse-tags").text().trim(), - }, + searchContent: searchKey, + path: ev.currentTarget.href, + categories: current$.find(".badge-category__name").text().trim(), + tags: current$.find(".discourse-tags").text().trim(), + $url: location.href, + }); +} + +function onAIClick(ev) { + if (ev.currentTarget.disabled) { + return; + } + window._oaReport("click", { + type: "ai-toggle", + module: "search", + searchContent: decodeURIComponent(location.search.match(/\bq=([^&]+)/)[1]), + detail: ev.currentTarget.getAttribute("aria-checked"), + $url: location.href, + }); +} + +// 搜索结果页帖子的点击 +function onClickSearchResultPageTopic(ev) { + let link = ev.target; + if (link === ev.currentTarget) { + return; + } + while (!link.classList.contains("search-link")) { + link = link.parentElement; + if (link === ev.currentTarget || !link) { + return; + } + } + + let root = link; + while (!root.classList.contains("fps-result")) { + root = root.parentElement; + if (root === ev.currentTarget || !root) { + return; + } + } + const rank = [...root.parentElement.children].indexOf(root) + 1; + + const target$ = $(root); + window._oaReport("click", { + type: "search-result", + module: "search", + target: $(link).text().trim(), + searchContent: decodeURIComponent(location.search.match(/\bq=([^&]+)/)[1]), + rank, + path: $(link).attr("href"), + categories: target$.find(".badge-category__name").text().trim(), + tags: target$.find(".discourse-tags").text().trim(), $url: location.href, }); } export default function reportSearch() { onNodeInserted(".search-input-wrapper input", (node) => { - window.$(node).on("focus", onClickSearchInput); - window.$(node).on("input", debounce(onInputSearchInput, 300)); - window.$(node).on("keydown", (ev) => { + $(node).on("click", onClickSearchInput); + $(node).on("keydown", (ev) => { if (ev.key === "Enter") { + // 输入事件 + window._oaReport("input", { + type: "search-input", + module: "search", + content: ev.currentTarget.value.trim(), + $url: location.href, + }); + // 搜索事件 window._oaReport("input", { type: "search", module: "search", @@ -79,13 +127,11 @@ export default function reportSearch() { // 历史记录点击 onNodeInserted(".search-menu-panel .search-menu-recent", (node) => { - window - .$(node) + $(node) .children(".search-menu-assistant-item") .on("click", onClickSearchHistory); // 清除历史记录 - window - .$(node) + $(node) .find(".clear-recent-searches") .on("click", onClearSearchHistoryClick); }); @@ -94,15 +140,13 @@ export default function reportSearch() { onNodeInserted( ".search-menu-panel .results div[class^=search-result]", (node) => { + searchKey = $(".search-input-wrapper input").get(0).value; if (node.classList.contains("search-result-topic")) { // 话题结果点击 - window - .$(node) - .find(".list .item a") - .on("click", onClickSearchResultTopic); + $(node).find(".list .item a").on("click", onClickSearchResultTopic); } else { // 联想结果点击 - window.$(node).find(".list .item a").on("click", onClickSuggestion); + $(node).find(".list .item a").on("click", onClickSuggestion); } } ); @@ -110,56 +154,20 @@ export default function reportSearch() { window.addEventListener("afterRouteChange", ({ detail }) => { if (detail.to === "/search") { // 监听是否显示AI搜索结果的点击 - onNodeInserted('.search-advanced .semantic-search__results-toggle', (el) => { - window.$(el).on("click", (ev) => { - if (ev.currentTarget.disabled) return; - window._oaReport("click", { - type: "ai-toggle", - module: "search", - searchContent: decodeURIComponent( - location.search.match(/\bq=([^&]+)/)[1] - ), - detail: ev.currentTarget.getAttribute("aria-checked"), - $url: location.href, - }); - }); - }); + onNodeInserted( + ".search-advanced .semantic-search__results-toggle", + (el) => { + $(el).on("click", onAIClick); + } + ); onNodeInserted( ".search-results .fps-result:first-child", () => { - window.$(".search-results .fps-result-entries").on("click", (ev) => { - let link = ev.target; - if (link === ev.currentTarget) return; - while (!link.classList.contains("search-link")) { - link = link.parentElement; - if (link === ev.currentTarget || !link) return; - } - - let root = link; - while (!root.classList.contains("fps-result")) { - root = root.parentElement; - if (root === ev.currentTarget || !root) return; - } - const rank = [...root.parentElement.children].indexOf(root) + 1 - - const target$ = window.$(root); - window._oaReport("click", { - type: "search-result", - module: "search", - target: window.$(link).text().trim(), - searchContent: decodeURIComponent( - location.search.match(/\bq=([^&]+)/)[1] - ), - detail: { - rank, - path: window.$(link).attr("href"), - categories: target$.find(".badge-category__name").text().trim(), - tags: target$.find(".discourse-tags").text().trim(), - }, - $url: location.href, - }); - }); + $(".search-results .fps-result-entries").on( + "click", + onClickSearchResultPageTopic + ); }, true ); diff --git a/javascripts/discourse/lib/sidebar.js b/javascripts/discourse/lib/sidebar.js index 63c6a82..1207ed2 100644 --- a/javascripts/discourse/lib/sidebar.js +++ b/javascripts/discourse/lib/sidebar.js @@ -1,9 +1,9 @@ +import $ from "jquery"; import { onNodeInserted } from "./utils.js"; export function reportSidebarClick() { onNodeInserted("#sidebar-section-content-categories", (node) => { - window - .$(node) + $(node) .children() .on("click", (ev) => { window._oaReport("click", { @@ -15,8 +15,7 @@ export function reportSidebarClick() { }); }); onNodeInserted("#sidebar-section-content-tags", (node) => { - window - .$(node) + $(node) .children() .on("click", (ev) => { window._oaReport("click", { diff --git a/javascripts/discourse/lib/tags.js b/javascripts/discourse/lib/tags.js index a2c5462..793752b 100644 --- a/javascripts/discourse/lib/tags.js +++ b/javascripts/discourse/lib/tags.js @@ -13,7 +13,7 @@ export function reportTagsClick() { if (detail.to === "/tags") { onNodeInserted( ".all-tag-lists .tags-list", - node => { + (node) => { node.querySelectorAll(".tag-box")?.forEach((el) => { el.querySelector("a").addEventListener("click", allTagsClick); }); diff --git a/javascripts/discourse/lib/topic.js b/javascripts/discourse/lib/topic.js index c0f4b84..9e5ec26 100644 --- a/javascripts/discourse/lib/topic.js +++ b/javascripts/discourse/lib/topic.js @@ -1,3 +1,4 @@ +import $ from "jquery"; import { onNodeInserted } from "./utils.js"; function onTopicListClick(ev) { @@ -5,7 +6,9 @@ function onTopicListClick(ev) { return; } let target = ev.target; - while (!(target instanceof HTMLAnchorElement && target.classList.contains("title"))) { + while ( + !(target instanceof HTMLAnchorElement && target.classList.contains("title")) + ) { target = target.parentElement; if (target === ev.currentTarget || !target) { return; @@ -13,25 +16,28 @@ function onTopicListClick(ev) { } const mainLink = target.closest(".main-link"); - const categories = [...mainLink.querySelectorAll('.badge-category__wrapper')].map(el => el.textContent.trim()).join(); - const tags = mainLink.querySelector('.discourse-tags')?.textContent?.trim(); - const path = target.getAttribute('href').match(/^\/t\/topic\/[^/]+/)?.[0]; - sessionStorage.setItem('topicRead', JSON.stringify({ - title: target.textContent.trim(), - path, - readTime: Date.now(), - categories, - ...(tags && { tags }), - })); - window._oaReport("click", { - target: target.textContent.trim(), - type: 'topic-click', - $url: location.href, - detail: { + const categories = [...mainLink.querySelectorAll(".badge-category__wrapper")] + .map((el) => el.textContent.trim()) + .join(); + const tags = mainLink.querySelector(".discourse-tags")?.textContent?.trim(); + const path = target.getAttribute("href").match(/^\/t\/topic\/[^/]+/)?.[0]; + sessionStorage.setItem( + "topicRead", + JSON.stringify({ + title: target.textContent.trim(), path, + readTime: Date.now(), categories, ...(tags && { tags }), - } + }) + ); + window._oaReport("click", { + target: target.textContent.trim(), + type: "topic-click", + $url: location.href, + path, + categories, + ...(tags && { tags }), }); } @@ -39,16 +45,15 @@ function onTopicListClick(ev) { * 点击某个帖子 */ export function reportTopicClick() { - onNodeInserted( - '#main-outlet .topic-list .topic-list-body', - node => window.$(node).on('click', onTopicListClick) + onNodeInserted("#main-outlet .topic-list .topic-list-body", (node) => + $(node).on("click", onTopicListClick) ); } export function reportTopicLeave() { - window.addEventListener('afterRouteChange', ({ detail }) => { - if (detail.from.startsWith('/t/topic/')) { - const topicRead = sessionStorage.getItem('topicRead'); + window.addEventListener("afterRouteChange", ({ detail }) => { + if (detail.from.startsWith("/t/topic/")) { + const topicRead = sessionStorage.getItem("topicRead"); if (!topicRead) { return; } @@ -56,19 +61,16 @@ export function reportTopicLeave() { if (readInfo.path !== detail.from.match(/^\/t\/topic\/[^/]+/)?.[0]) { return; } - sessionStorage.removeItem('topicRead'); - window._oaReport( - 'pageLeave', - { - target: readInfo.title, - detail: { - path: readInfo.path, - readTime: Date.now() - Number(readInfo.readTime), - categories: readInfo.categories, - ...(readInfo.tags ? { tags: readInfo.tags } : null), - } - } - ); + sessionStorage.removeItem("topicRead"); + window._oaReport("pageLeave", { + target: readInfo.title, + detail: { + path: readInfo.path, + readTime: Date.now() - Number(readInfo.readTime), + categories: readInfo.categories, + ...(readInfo.tags ? { tags: readInfo.tags } : null), + }, + }); } }); }