You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
165 lines
6.2 KiB
165 lines
6.2 KiB
/**
|
|
* Axel Search / 地址输入 解剖用浏览器脚本(纯字符串)
|
|
*/
|
|
|
|
export const SCAN_GLOBAL_AXEL_HOOKS = `() => {
|
|
var keys = Object.keys(window).filter(function(k) {
|
|
return /axel|mothership|place|search|quoter/i.test(k);
|
|
});
|
|
var hooks = {};
|
|
for (var i = 0; i < keys.length; i += 1) {
|
|
var k = keys[i];
|
|
try {
|
|
var v = window[k];
|
|
hooks[k] = typeof v;
|
|
} catch (e) {
|
|
hooks[k] = "inaccessible";
|
|
}
|
|
}
|
|
return {
|
|
windowKeys: keys.slice(0, 80),
|
|
hooks: hooks,
|
|
hasAxelStore: typeof window.__AXEL_STORE__ !== "undefined",
|
|
hasMothershipState: typeof window.__MOTHERSHIP_STATE__ !== "undefined",
|
|
googleLoaded: typeof google !== "undefined" && Boolean(google && google.maps),
|
|
pacContainers: document.querySelectorAll(".pac-container").length,
|
|
};
|
|
}`;
|
|
|
|
export const SCAN_INPUT_GM_AND_DOM = `() => {
|
|
var widget = document.querySelector("#react-quoter-landing-plugin");
|
|
if (!widget) {
|
|
return { ok: false, reason: "no-widget" };
|
|
}
|
|
var inputs = widget.querySelectorAll("input");
|
|
var rows = [];
|
|
for (var i = 0; i < inputs.length; i += 1) {
|
|
var inp = inputs[i];
|
|
var allKeys = Object.keys(inp);
|
|
var gmKeys = allKeys.filter(function(k) { return k.indexOf("gm_") === 0; });
|
|
var gmDetail = {};
|
|
for (var j = 0; j < gmKeys.length; j += 1) {
|
|
var gk = gmKeys[j];
|
|
var val = inp[gk];
|
|
gmDetail[gk] = {
|
|
type: typeof val,
|
|
hasGetPlace: Boolean(val && typeof val.getPlace === "function"),
|
|
};
|
|
}
|
|
rows.push({
|
|
index: i,
|
|
placeholder: inp.placeholder || "",
|
|
className: (inp.className || "").slice(0, 120),
|
|
pacTarget: inp.classList.contains("pac-target-input"),
|
|
valuePreview: (inp.value || "").replace(/\\s+/g, " ").trim().slice(0, 120),
|
|
gmKeys: gmKeys,
|
|
gmDetail: gmDetail,
|
|
ariaExpanded: inp.getAttribute("aria-expanded"),
|
|
ariaAutocomplete: inp.getAttribute("aria-autocomplete"),
|
|
role: inp.getAttribute("role"),
|
|
});
|
|
}
|
|
var iframes = Array.prototype.slice.call(document.querySelectorAll("iframe")).map(function(fr, idx) {
|
|
var info = { index: idx, src: (fr.src || "").slice(0, 160), id: fr.id || "", hasContentWindow: Boolean(fr.contentWindow) };
|
|
try {
|
|
var doc = fr.contentDocument;
|
|
info.inputCount = doc ? doc.querySelectorAll("input").length : 0;
|
|
info.pacCount = doc ? doc.querySelectorAll(".pac-container .pac-item").length : 0;
|
|
info.googleInFrame = Boolean(fr.contentWindow && fr.contentWindow.google && fr.contentWindow.google.maps);
|
|
} catch (e) {
|
|
info.crossOrigin = true;
|
|
}
|
|
return info;
|
|
});
|
|
return {
|
|
ok: true,
|
|
widgetTextPreview: (widget.innerText || "").replace(/\\s+/g, " ").trim().slice(0, 300),
|
|
inputs: rows,
|
|
pacItemCount: document.querySelectorAll(".pac-container .pac-item").length,
|
|
listboxOptionCount: widget.querySelectorAll('[role="listbox"] [role="option"]').length,
|
|
styledRowCount: widget.querySelectorAll("div[class*='sc-']").length,
|
|
iframes: iframes,
|
|
};
|
|
}`;
|
|
|
|
export const SCAN_SUGGESTION_ROWS = `() => {
|
|
var widget = document.querySelector("#react-quoter-landing-plugin");
|
|
if (!widget) return { ok: false, reason: "no-widget" };
|
|
var pac = [];
|
|
document.querySelectorAll(".pac-container .pac-item").forEach(function(item, idx) {
|
|
pac.push({
|
|
index: idx,
|
|
text: (item.textContent || "").replace(/\\s+/g, " ").trim().slice(0, 160),
|
|
className: (item.className || "").slice(0, 80),
|
|
});
|
|
});
|
|
var styled = [];
|
|
widget.querySelectorAll("div[class*='sc-']").forEach(function(row, idx) {
|
|
var text = (row.textContent || "").replace(/\\s+/g, " ").trim();
|
|
if (text.length < 10) return;
|
|
if (row.querySelector("input, textarea, button")) return;
|
|
styled.push({
|
|
index: idx,
|
|
text: text.slice(0, 160),
|
|
className: (row.className || "").slice(0, 100),
|
|
dataOptionId: row.getAttribute("data-option-id"),
|
|
dataPlaceId: row.getAttribute("data-place-id"),
|
|
role: row.getAttribute("role"),
|
|
});
|
|
});
|
|
var listbox = [];
|
|
widget.querySelectorAll('[role="listbox"] [role="option"]').forEach(function(opt, idx) {
|
|
listbox.push({
|
|
index: idx,
|
|
text: (opt.textContent || "").replace(/\\s+/g, " ").trim().slice(0, 160),
|
|
dataOptionId: opt.getAttribute("data-option-id"),
|
|
});
|
|
});
|
|
return { ok: true, pac: pac.slice(0, 12), styled: styled.slice(0, 20), listbox: listbox.slice(0, 12) };
|
|
}`;
|
|
|
|
export const SCAN_REACT_FIBER_ADDRESS = `() => {
|
|
var widget = document.querySelector("#react-quoter-landing-plugin");
|
|
if (!widget) return { ok: false, reason: "no-widget" };
|
|
var fiberKey = Object.keys(widget).find(function(k) {
|
|
return k.indexOf("__reactFiber$") === 0 || k.indexOf("__reactInternalInstance$") === 0;
|
|
});
|
|
if (!fiberKey) return { ok: false, reason: "no-fiber-on-widget" };
|
|
var hits = [];
|
|
var fiber = widget[fiberKey];
|
|
var depth = 0;
|
|
while (fiber && depth < 120) {
|
|
var name = "";
|
|
try {
|
|
name = (fiber.type && (fiber.type.displayName || fiber.type.name)) || "";
|
|
} catch (e) { name = ""; }
|
|
var props = fiber.memoizedProps || {};
|
|
var propKeys = Object.keys(props);
|
|
var interesting = /axel|search|candidate|place|address|select|quoter|location/i.test(name)
|
|
|| propKeys.some(function(k) { return /onSelect|onClick|placeId|address|search/i.test(k); });
|
|
if (interesting) {
|
|
var handlerKeys = propKeys.filter(function(k) {
|
|
return /^on[A-Z]/.test(k) || /place|address|select|search/i.test(k);
|
|
});
|
|
hits.push({
|
|
depth: depth,
|
|
componentName: name || "anonymous",
|
|
stateKeys: fiber.stateNode && fiber.stateNode.state
|
|
? Object.keys(fiber.stateNode.state).filter(function(k) {
|
|
return /pickup|delivery|address|place|search/i.test(k);
|
|
}).slice(0, 12)
|
|
: [],
|
|
handlerKeys: handlerKeys.slice(0, 16),
|
|
onSelectType: typeof props.onSelect,
|
|
onAddressSelectType: typeof props.onAddressSelect,
|
|
onClickPreview: typeof props.onClick === "function"
|
|
? Function.prototype.toString.call(props.onClick).replace(/\\s+/g, " ").slice(0, 200)
|
|
: null,
|
|
});
|
|
}
|
|
fiber = fiber.return;
|
|
depth += 1;
|
|
}
|
|
return { ok: true, fiberKey: fiberKey, hits: hits.slice(0, 40) };
|
|
}`;
|