diff --git a/scripts/liepin-send-dom.node-test.mjs b/scripts/liepin-send-dom.node-test.mjs
index dc4e9ae..546d624 100644
--- a/scripts/liepin-send-dom.node-test.mjs
+++ b/scripts/liepin-send-dom.node-test.mjs
@@ -97,6 +97,65 @@ test("do not mistake chat drawer history for a priority modal", async () => {
assert.equal(result.success, true);
});
+test("find chat composer when Liepin changes the container class", async () => {
+ const document = makeDocument(`
+
+ `);
+ const requestRecords = [];
+ const input = document.querySelector("textarea");
+ document.querySelector(".ant-im-btn").addEventListener("click", () => {
+ input.value = "";
+ requestRecords.push({
+ url: "https://api-c.liepin.com/api/com.liepin.im.c.chat.send-push",
+ status: 200,
+ });
+ });
+
+ const result = await runLiepinSend(document, {
+ message: "你好",
+ requestRecords,
+ sleep: async () => {},
+ });
+
+ assert.equal(result.success, true);
+});
+
+test("ignore login text in chat history when the chat panel is a dialog", async () => {
+ const document = makeDocument(`
+
+
+
不支持此消息查看,请登录“猎聘APP”查看消息内容!
+
+
+
+
+
+ `);
+ const requestRecords = [];
+ const input = document.querySelector("textarea");
+ document.querySelector(".ant-im-btn").addEventListener("click", () => {
+ input.value = "";
+ requestRecords.push({
+ url: "https://api-c.liepin.com/api/com.liepin.im.c.chat.send-push",
+ status: 200,
+ });
+ });
+
+ const result = await runLiepinSend(document, {
+ message: "你好",
+ requestRecords,
+ sleep: async () => {},
+ });
+
+ assert.equal(result.blockedModal, false);
+ assert.equal(result.success, true);
+});
+
test("close only visible priority communication modal before sending", async () => {
const document = makeDocument(`
diff --git a/src-tauri/src/rpa/liepin/send_text.js b/src-tauri/src/rpa/liepin/send_text.js
index 9df3f4d..74327f7 100644
--- a/src-tauri/src/rpa/liepin/send_text.js
+++ b/src-tauri/src/rpa/liepin/send_text.js
@@ -91,7 +91,7 @@ async function closePriorityModal(modal, document, sleep) {
}
function classifyModal(modal) {
- if (modal.querySelector(CHAT_CONTAINER_SELECTOR)) return "other";
+ if (findChatContainer(modal)) return "other";
const text = textOf(modal);
const hasPriorityTitle = Array.from(modal.querySelectorAll("h1, h2, h3, [class*='title'], [class*='header'], div, span"))
.some((node) => textOf(node) === "优先沟通");
@@ -136,19 +136,6 @@ async function handleKnownModal(document, sleep) {
};
}
-function findChatContainer(document) {
- const marker = findVisible(Array.from(document.querySelectorAll(CHAT_CONTAINER_SELECTOR)));
- if (!marker) return null;
- let candidate = marker;
- for (let container = marker; container && container !== document.body; container = container.parentElement) {
- if (findChatInput(container)) {
- candidate = container;
- if (findAnySendButton(container)) return container;
- }
- }
- return candidate;
-}
-
function findAnySendButton(container) {
return container
? Array.from(container.querySelectorAll(SEND_BUTTON_SELECTOR))
@@ -163,6 +150,42 @@ function findChatInput(container) {
return inputs.find((node) => !node.disabled && !node.readOnly) || null;
}
+function findInputContainer(input, boundary) {
+ for (let container = input?.parentElement; container; container = container.parentElement) {
+ if (findAnySendButton(container)) return container;
+ if (container === boundary) break;
+ }
+ return null;
+}
+
+function findChatContainer(root) {
+ const document = root.nodeType === 9 ? root : root.ownerDocument;
+ const boundary = root.nodeType === 9 ? document.body : root;
+ const marker = findVisible(Array.from(root.querySelectorAll(CHAT_CONTAINER_SELECTOR)));
+ if (marker) {
+ let candidate = marker;
+ for (let container = marker; container && container !== boundary; container = container.parentElement) {
+ if (findChatInput(container)) {
+ candidate = container;
+ if (findAnySendButton(container)) return container;
+ }
+ }
+ return candidate;
+ }
+
+ const markedInput = findVisible(Array.from(root.querySelectorAll(`[${CHAT_INPUT_MARKER}]`)));
+ const inputs = Array.from(root.querySelectorAll(INPUT_SELECTOR)).filter((node) => isVisible(node)
+ && !node.disabled && !node.readOnly);
+ if (markedInput) {
+ inputs.unshift(markedInput);
+ }
+ for (const input of inputs) {
+ const container = findInputContainer(input, boundary);
+ if (container) return container;
+ }
+ return null;
+}
+
function markLiepinChatInput(document) {
document.querySelectorAll(`[${CHAT_INPUT_MARKER}]`)
.forEach((node) => node.removeAttribute(CHAT_INPUT_MARKER));