/** * Browser 执行脚本(纯字符串)。禁止改为 function。 */ export const SCROLL_WIDGET_INTO_VIEW = "(el) => { el.scrollIntoView({ block: 'start', inline: 'nearest', behavior: 'instant' }); }"; export const IS_SELECT_TAG = "(el) => el.tagName === 'SELECT'"; /** @deprecated Network-First 禁止 DOM 报价提取 */ export const COLLECT_EMBEDDED_JSON = `() => { const payloads = []; const next = document.getElementById("__NEXT_DATA__"); if (next && next.textContent) { try { payloads.push(JSON.parse(next.textContent)); } catch (e) {} } document.querySelectorAll('script[type="application/json"]').forEach((el) => { const text = el.textContent ? el.textContent.trim() : ""; if (!text) return; try { payloads.push(JSON.parse(text)); } catch (e) {} }); return payloads; }`; /** @deprecated Network-First 禁止 DOM 报价提取 */ export const COLLECT_CLIENT_STATE = `() => { const payloads = []; const next = document.getElementById("__NEXT_DATA__"); if (next && next.textContent) { try { payloads.push(JSON.parse(next.textContent)); } catch (e) {} } for (const key of Object.keys(window)) { if (!/quote|rate|pricing|apollo|relay|__NEXT/i.test(key)) continue; const val = window[key]; if (val && typeof val === "object") payloads.push(val); } return payloads; }`; export const COLLECT_ADDRESS_LABELS_FROM_DOM = `({ streetNumber, cityHint }) => { const results = []; const seen = new Set(); const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT); let node = walker.nextNode(); while (node) { const chunk = (node.textContent || "").trim(); const hitStreet = streetNumber && chunk.includes(streetNumber); const hitCity = cityHint.length >= 3 && chunk.toLowerCase().includes(cityHint.toLowerCase()); if (!hitStreet && !hitCity) { node = walker.nextNode(); continue; } let el = node.parentElement; for (let depth = 0; depth < 8 && el; depth += 1) { const tag = el.tagName.toLowerCase(); if (tag === "input" || tag === "textarea") break; const rowText = (el.innerText || "").replace(/\\s+/g, " ").trim(); if (rowText.length >= 8 && rowText.length <= 180 && (!streetNumber || rowText.includes(streetNumber))) { if (!seen.has(rowText)) { seen.add(rowText); results.push(rowText); } break; } el = el.parentElement; } node = walker.nextNode(); } return results; }`; /** Google Places pac-item:主行 + 副行,避免 innerText 粘连导致 suburb 丢失 */ export const COLLECT_PAC_ITEM_LABELS = `() => { const results = []; const seen = new Set(); document.querySelectorAll(".pac-container .pac-item").forEach((item) => { const main = item.querySelector(".pac-item-query")?.textContent?.replace(/\\s+/g, " ").trim() || ""; const secondary = item.querySelector(".pac-item-secondary")?.textContent?.replace(/\\s+/g, " ").trim() || ""; let label = ""; if (main && secondary) { label = main + "|" + secondary; } else { label = (item.innerText || "").replace(/\\s+/g, " ").trim(); } if (label.length >= 8 && !seen.has(label)) { seen.add(label); results.push(label); } }); return results; }`; /** MotherShip widget listbox + pac + styled-components:主行|副行(对齐图2/图3 多候选) */ export const COLLECT_WIDGET_SUGGESTION_LABELS = `(function() { var skipRe = /use my location|使用我的位置|get a freight|freight details|pick up from|deliver to|where to/i; var stateRe = /(USA|US|CA|NY|TX|FL|IL|PA|OH|GA|NC|MI|NJ|VA|WA|AZ|MA|TN|IN|MO|MD|WI|CO|MN|SC|AL|LA|KY|OR|OK|CT|UT|IA|NV|AR|MS|KS|NM|NE|WV|ID|HI|NH|ME|MT|RI|DE|SD|ND|AK|DC|VT|WY|PR)/; var seen = new Set(); var results = []; function push(label) { var t = (label || "").replace(/\\s+/g, " ").trim(); if (t.length < 8 || t.length > 180 || skipRe.test(t) || seen.has(t)) return; seen.add(t); results.push(t); } function pushLines(el) { var raw = (el.innerText || "").replace(/\\r/g, ""); var lines = raw.split("\\n").map(function(l) { return l.trim(); }).filter(Boolean); if (!lines.length || lines.some(function(l) { return skipRe.test(l); })) return; if (lines.length >= 2) { push(lines[0] + "|" + lines.slice(1).join(", ")); } else { push(lines[0]); } } // 1. ARIA listbox/option(标准) document.querySelectorAll("#react-quoter-landing-plugin [role='listbox'] [role='option']").forEach(pushLines); // 2. Google Places pac-container(标准) document.querySelectorAll(".pac-container .pac-item").forEach(function(item) { var mainEl = item.querySelector(".pac-item-query"); var secondaryEl = item.querySelector(".pac-item-secondary"); var main = mainEl && mainEl.textContent ? mainEl.textContent.replace(/\\s+/g, " ").trim() : ""; var secondary = secondaryEl && secondaryEl.textContent ? secondaryEl.textContent.replace(/\\s+/g, " ").trim() : ""; if (main && secondary) { push(main + "|" + secondary); } else { pushLines(item); } }); // 3. Styled-components 地址联想(MotherShip 自定义) if (results.length === 0) { var candidateTexts = new Set(); document.querySelectorAll("div[class*='sc-']").forEach(function(el) { var text = (el.innerText || "").replace(/\\s+/g, " ").trim(); if (text.length >= 15 && text.length <= 150 && text.indexOf(",") >= 0 && stateRe.test(text) && !skipRe.test(text)) { var rect = el.getBoundingClientRect(); if (rect.width > 300 && rect.height >= 30 && rect.height <= 70) { if (!candidateTexts.has(text)) { candidateTexts.add(text); push(text); } } } }); } // 4. 全局 [role="listbox"] 作为后备 if (results.length === 0) { document.querySelectorAll('[role="listbox"]:not(#react-quoter-landing-plugin *)').forEach(function(listbox) { listbox.querySelectorAll('[role="option"], [role="menuitem"], li').forEach(pushLines); }); } return results; })()`; export const PROBE_CARGO_UI = `(widgetEl, arg) => { const cargoFieldRe = new RegExp(arg.cargoFieldReSource, "i"); function collectBlockers(el) { const blockers = []; if (!el.isConnected) blockers.push("not_connected"); if (el.disabled) blockers.push("disabled"); if (el.readOnly) blockers.push("readonly"); const style = window.getComputedStyle(el); if (style.visibility === "hidden") blockers.push("visibility_hidden"); if (style.display === "none") blockers.push("display_none"); if (style.pointerEvents === "none") blockers.push("pointer_events_none"); const rect = el.getBoundingClientRect(); if (rect.width <= 0 || rect.height <= 0) blockers.push("zero_bounding_box"); if (typeof el.checkVisibility === "function") { try { if (!el.checkVisibility({ checkOpacity: true, checkVisibilityCSS: true })) { blockers.push("check_visibility_false"); } } catch (e) { blockers.push("check_visibility_error"); } } else if (el.offsetParent === null && style.position !== "fixed") { blockers.push("offset_parent_null"); } return blockers; } function isInteractive(el) { return collectBlockers(el).length === 0; } const mountedCargoFields = []; const interactiveCargoFields = []; const blockedCargoFields = []; for (const node of widgetEl.querySelectorAll("input,textarea")) { const el = node; const label = (el.placeholder || "") + " " + (el.getAttribute("aria-label") || ""); if (!cargoFieldRe.test(label)) continue; const snapshot = { placeholder: el.placeholder, ariaLabel: el.getAttribute("aria-label") }; const blockers = collectBlockers(el); const mounted = el.isConnected && !el.disabled && !el.readOnly; if (mounted) mountedCargoFields.push(snapshot); if (isInteractive(el)) interactiveCargoFields.push(snapshot); else if (mounted || blockers.length > 0) { blockedCargoFields.push({ placeholder: snapshot.placeholder, ariaLabel: snapshot.ariaLabel, blockers }); } } let phase = "no_cargo_inputs"; if (interactiveCargoFields.length > 0) phase = "interactive"; else if (mountedCargoFields.length > 0 || blockedCargoFields.length > 0) phase = "hydrating"; return { phase, mountedCargoFields, interactiveCargoFields, blockedCargoFields }; }`; export const WAIT_CARGO_INTERACTIVE = `({ selector, cargoReadyReSource }) => { function isInteractive(el) { if (!el.isConnected || el.disabled || el.readOnly) return false; const style = window.getComputedStyle(el); if (style.visibility === "hidden" || style.display === "none" || style.pointerEvents === "none") return false; const rect = el.getBoundingClientRect(); if (rect.width <= 0 || rect.height <= 0) return false; if (typeof el.checkVisibility === "function") { try { return el.checkVisibility({ checkOpacity: true, checkVisibilityCSS: true }); } catch (e) { return false; } } return el.offsetParent !== null || style.position === "fixed"; } const widget = document.querySelector(selector); if (!widget) return false; const readyRe = new RegExp(cargoReadyReSource, "i"); for (const node of widget.querySelectorAll("input,textarea")) { const el = node; const label = (el.placeholder || "") + " " + (el.getAttribute("aria-label") || ""); if (!readyRe.test(label)) continue; if (isInteractive(el)) return true; } return false; }`; export const FILL_CARGO_FIELD = `(widgetEl, arg) => { function isInteractive(el) { if (!el.isConnected || el.disabled || el.readOnly) return false; const style = window.getComputedStyle(el); if (style.visibility === "hidden" || style.display === "none" || style.pointerEvents === "none") return false; const rect = el.getBoundingClientRect(); if (rect.width <= 0 || rect.height <= 0) return false; if (typeof el.checkVisibility === "function") { try { return el.checkVisibility({ checkOpacity: true, checkVisibilityCSS: true }); } catch (e) { return false; } } return el.offsetParent !== null || style.position === "fixed"; } const re = new RegExp(arg.fieldRe, "i"); for (const node of widgetEl.querySelectorAll("input,textarea")) { const el = node; const label = (el.placeholder || "") + " " + (el.getAttribute("aria-label") || ""); if (!re.test(label) || !isInteractive(el)) continue; el.focus(); el.value = arg.val; el.dispatchEvent(new Event("input", { bubbles: true })); el.dispatchEvent(new Event("change", { bubbles: true })); return true; } return false; }`;