Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ GEM
racc
prettier_print (1.2.1)
racc (1.8.1)
rack (3.1.8)
rack (3.1.16)
rainbow (3.1.1)
regexp_parser (2.9.2)
rubocop (1.67.0)
Expand Down
183 changes: 183 additions & 0 deletions javascripts/discourse/initializers/alert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
import { reportNavigationClick } from "../lib/navigation.js";
import reportSearch from "../lib/search.js";
import { reportSidebarClick } from "../lib/sidebar.js";
import { reportTagsClick } from "../lib/tags.js";
import { reportTopicClick, reportTopicLeave } from "../lib/topic.js";

function isCookieAgreed() {
const regexp = /\bagreed-cookiepolicy=([^;])+/;
const res = document.cookie.match(regexp)?.[1];
return res === "1";
}

export default {
name: "alert",
initialize() {
import(
"https://unpkg.com/@opensig/open-analytics@0.0.9/dist/open-analytics.mjs"
).then(({ OpenAnalytics, getClientInfo, OpenEventKeys }) => {
const oa = new OpenAnalytics({
appKey: "openEuler",
request: (data) => {
if (!isCookieAgreed()) {
disableOA();
return;
}
fetch("https://dsapi.test.osinfra.cn/query/track/openeuler", {
body: JSON.stringify(data),
method: "POST",
headers: { "Content-Type": "application/json" },
});
},
});

/**
* 开启埋点上报功能
*
* 设置上报内容的header信息为浏览器相关信息
*/
const enableOA = () => {
oa.setHeader(getClientInfo());
oa.enableReporting(true);
};

/**
* 关闭埋点上报功能,清除localStorage中关于埋点的条目
*/
const disableOA = () => {
oa.enableReporting(false);
[
"oa-openEuler-client",
"oa-openEuler-events",
"oa-openEuler-session",
].forEach((key) => {
localStorage.removeItem(key);
});
};

function oaReport(event, eventData, $service = "forum", options) {
return oa.report(
event,
async (...opt) => {
return {
$service,
...(typeof eventData === "function"
? await eventData(...opt)
: eventData),
};
},
options
);
}

/**
* 上报PageView事件
* @param $referrer 从哪一个页面跳转过来
*/
const reportPV = ($referrer) => {
oaReport(OpenEventKeys.PV, ($referrer && { $referrer }) || null);
};

/**
* 上报性能指标
*/
const reportPerformance = () => {
oaReport(OpenEventKeys.LCP);
oaReport(OpenEventKeys.INP);
oaReport(OpenEventKeys.PageBasePerformance);
};

function listenCookieSet() {
if (isCookieAgreed()) {
enableOA();
}
const desc = Object.getOwnPropertyDescriptor(
Document.prototype,
"cookie"
);
Object.defineProperty(Document.prototype, "cookie", {
...desc,
set(val) {
desc.set.call(this, val);
if (isCookieAgreed()) {
enableOA();
} else {
disableOA();
}
},
});
}

function listenHistoryChange() {
let referrer;

["replaceState", "pushState"].forEach((method) => {
const native = History.prototype[method];
History.prototype[method] = function (...args) {
try {
if (oa.enabled) {
const beforePath = location.pathname;
native.call(this, ...args);
const afterPath = location.pathname;
if (
beforePath.startsWith("/t/topic/") &&
afterPath.startsWith("/t/topic/") &&
beforePath.split("/")[3] === afterPath.split("/")[3]
) {
return;
}
if (beforePath !== afterPath) {
reportPV(referrer);
window.dispatchEvent(
new CustomEvent("afterRouteChange", {
detail: { from: beforePath, to: afterPath },
})
);
}
} else {
native.call(this, ...args);
}
} catch {
native.call(this, ...args);
} finally {
referrer = location.href;
}
};
});

window.addEventListener("popstate", () => {
try {
const beforePath = new URL(referrer).pathname;
if (beforePath !== location.pathname) {
setTimeout(() => reportPV(referrer));
window.dispatchEvent(
new CustomEvent("afterRouteChange", {
detail: { from: beforePath, to: location.pathname },
})
);
}
} finally {
referrer = location.href;
}
});
}

listenCookieSet();
listenHistoryChange();
reportPV();
reportPerformance();

window._oaReport = oaReport;
window._enableOA = enableOA;
window._disableOA = disableOA;

reportSidebarClick();
reportNavigationClick();
reportTopicClick();
reportTopicLeave();
reportTagsClick();

reportSearch();
});
},
};
55 changes: 55 additions & 0 deletions javascripts/discourse/lib/navigation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { onNodeInserted } from "./utils.js";

export function reportNavigationClick() {
// 类别下拉点击
onNodeInserted(
".navigation-container .category-drop.is-expanded .select-kit-collection",
(node) => {
window
.$(node)
.children()
.on("click", (ev) =>
window._oaReport("click", {
target: ev.currentTarget.textContent.trim(),
type: "类别",
module: "nav-dropdown",
$url: location.href,
})
);
}
);
// 标签下拉点击
onNodeInserted(
".navigation-container .tag-drop.is-expanded .select-kit-collection",
(node) => {
window
.$(node)
.children()
.on("click", (ev) =>
window._oaReport("click", {
target: ev.currentTarget.textContent.trim(),
type: "标签",
module: "nav-dropdown",
$url: location.href,
})
);
}
);
// 所有下拉点击
onNodeInserted(
".navigation-container .has-selection.is-expanded .select-kit-collection",
(node) => {
window
.$(node)
.children()
.on("click", (ev) =>
window._oaReport("click", {
target: ev.currentTarget.textContent.trim(),
type: "所有",
module: "nav-dropdown",
$url: location.href,
})
);
}
);
}
110 changes: 110 additions & 0 deletions javascripts/discourse/lib/search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { debounce, onNodeInserted } from "./utils.js";

function onClickSearchInput() {
window._oaReport("click", {
type: "search-input",
module: 'search',
$url: location.href,
});
}

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",
module: 'search',
target: ev.currentTarget.textContent.trim(),
$url: location.href,
});
}

function onClearSearchHistoryClick() {
window._oaReport("click", {
type: "clear-search-history",
module: 'search',
$url: location.href,
});
}

function onClickSuggestion(ev) {
window._oaReport("click", {
type: "search-suggestion",
module: 'search',
target: ev.currentTarget.textContent.trim(),
detail: ev.currentTarget.href,
$url: location.href,
});
}

function onClickSearchResultTopic(ev) {
const current$ = window.$(ev.currentTarget);
window._oaReport("click", {
type: "search-result",
module: 'search',
target: current$.find(".first-line").text().trim(),
detail: {
path: ev.currentTarget.href,
categories: current$.find(".badge-category__name").text().trim(),
tags: current$.find(".discourse-tags").text().trim(),
},
$url: location.href,
});
}

export default function reportSearch() {
onNodeInserted(
".search-input-wrapper input",
(node) => {
window.$(node).on("click", onClickSearchInput);
window.$(node).on("input", debounce(onInputSearchInput, 300));
window.$(node).on("keydown", (ev) => {
if (ev.key === "Enter") {
window._oaReport("input", {
type: "search",
module: 'search',
content: ev.currentTarget.value.trim(),
$url: location.href,
});
}
});
}
);

// 历史记录点击
onNodeInserted(
".search-menu-panel .search-menu-recent",
(node) => {
window
.$(node)
.children(".search-menu-assistant-item")
.on("click", onClickSearchHistory);
// 清除历史记录
window
.$(node)
.find(".clear-recent-searches")
.on("click", onClearSearchHistoryClick);
}
);

// 联想/帖子结果点击
onNodeInserted(
".search-menu-panel .results div[class^=search-result]",
(node) => {
if (node.classList.contains("search-result-topic")) {
// 话题结果点击
window.$(node).find(".list .item a").on("click", onClickSearchResultTopic);
} else {
// 联想结果点击
window.$(node).find(".list .item a").on("click", onClickSuggestion);
}
}
);
}
30 changes: 30 additions & 0 deletions javascripts/discourse/lib/sidebar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { onNodeInserted } from "./utils.js";

export function reportSidebarClick() {
onNodeInserted("#sidebar-section-content-categories", (node) => {
window
.$(node)
.children()
.on("click", (ev) => {
window._oaReport("click", {
target: ev.currentTarget.textContent.trim(),
level1: "类别",
module: "sidebar",
$url: location.href,
});
});
});
onNodeInserted("#sidebar-section-content-tags", (node) => {
window
.$(node)
.children()
.on("click", (ev) => {
window._oaReport("click", {
target: ev.currentTarget.textContent.trim(),
level1: "标签",
module: "sidebar",
$url: location.href,
});
});
});
}
Loading
Loading