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.
202 lines
6.3 KiB
202 lines
6.3 KiB
/**
|
|
* fix-place 浏览器脚本(纯字符串)。禁止改为 function 传入 page.evaluate。
|
|
*/
|
|
|
|
export const INVOKE_CAPTURED_PLACE_CHANGED = `(arg) => {
|
|
const pid = arg.pid;
|
|
const desc = arg.desc;
|
|
const loc = arg.loc || {};
|
|
const handlers = window.__rpaPlaceChangedHandlers || [];
|
|
if (!handlers.length) {
|
|
return { ok: false, reason: "no-captured-handlers", handlerCount: 0 };
|
|
}
|
|
const active = document.activeElement;
|
|
const lat =
|
|
typeof loc.latitude === "number"
|
|
? loc.latitude
|
|
: typeof loc.lat === "number"
|
|
? loc.lat
|
|
: 0;
|
|
const lng =
|
|
typeof loc.longitude === "number"
|
|
? loc.longitude
|
|
: typeof loc.lng === "number"
|
|
? loc.lng
|
|
: 0;
|
|
const placePayload = {
|
|
place_id: pid,
|
|
formatted_address: desc,
|
|
name: (desc.split(",")[0] || "").trim(),
|
|
geometry: {
|
|
location: {
|
|
lat: function() { return lat; },
|
|
lng: function() { return lng; },
|
|
},
|
|
},
|
|
address_components: loc.addressComponents || loc.address_components || [],
|
|
};
|
|
const ordered = handlers.slice().reverse();
|
|
const activeInput =
|
|
active && (active.tagName === "INPUT" || active.tagName === "TEXTAREA")
|
|
? active
|
|
: null;
|
|
const tryInvoke = function(entry) {
|
|
const inst = entry.instance;
|
|
const handler = entry.handler;
|
|
if (!inst || typeof handler !== "function") {
|
|
return { ok: false, reason: "bad-entry" };
|
|
}
|
|
const originalGetPlace =
|
|
typeof inst.getPlace === "function"
|
|
? inst.getPlace.bind(inst)
|
|
: function() { return {}; };
|
|
inst.getPlace = function() {
|
|
return placePayload;
|
|
};
|
|
try {
|
|
handler.call(inst);
|
|
return { ok: true, reason: "handler-invoked" };
|
|
} catch (e) {
|
|
return { ok: false, reason: "handler-threw:" + String(e) };
|
|
} finally {
|
|
setTimeout(function() {
|
|
inst.getPlace = originalGetPlace;
|
|
}, 120);
|
|
}
|
|
};
|
|
if (activeInput) {
|
|
for (let i = 0; i < ordered.length; i += 1) {
|
|
const entry = ordered[i];
|
|
if (entry.inputEl === activeInput) {
|
|
const result = tryInvoke(entry);
|
|
if (result.ok) {
|
|
return { ok: true, reason: result.reason, handlerCount: handlers.length };
|
|
}
|
|
}
|
|
}
|
|
}
|
|
for (let j = 0; j < ordered.length; j += 1) {
|
|
const fallback = tryInvoke(ordered[j]);
|
|
if (fallback.ok) {
|
|
return { ok: true, reason: fallback.reason, handlerCount: handlers.length };
|
|
}
|
|
}
|
|
return { ok: false, reason: "all-handlers-failed", handlerCount: handlers.length };
|
|
}`;
|
|
|
|
export const TRIGGER_GOOGLE_PLACE_CHANGED = `(arg) => {
|
|
const pid = arg.pid;
|
|
const desc = arg.desc;
|
|
const gmaps = window.google;
|
|
const resolveInstance = function() {
|
|
const instances = window.__rpaAutocompleteInstances || [];
|
|
if (instances.length > 0) {
|
|
return instances[instances.length - 1];
|
|
}
|
|
if (gmaps && gmaps.maps && gmaps.maps.places && gmaps.maps.places.Autocomplete) {
|
|
const AutocompleteCtor = gmaps.maps.places.Autocomplete;
|
|
const globalKeys = Object.keys(window).filter(function(k) {
|
|
try {
|
|
return window[k] instanceof AutocompleteCtor;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
});
|
|
if (globalKeys.length > 0) {
|
|
return window[globalKeys[0]];
|
|
}
|
|
}
|
|
const pacInput =
|
|
document.querySelector(".pac-target-input") ||
|
|
document.querySelector("#react-quoter-landing-plugin input");
|
|
if (!pacInput) {
|
|
return null;
|
|
}
|
|
const keys = Object.keys(pacInput);
|
|
for (let i = 0; i < keys.length; i += 1) {
|
|
const key = keys[i];
|
|
if (key.indexOf("gm_") !== 0) continue;
|
|
const val = pacInput[key];
|
|
if (val && typeof val.getPlace === "function") {
|
|
return val;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
const autocompleteInstance = resolveInstance();
|
|
if (!autocompleteInstance) {
|
|
return { ok: false, reason: "no-autocomplete-instance" };
|
|
}
|
|
if (!gmaps || !gmaps.maps || !gmaps.maps.event || typeof gmaps.maps.event.trigger !== "function") {
|
|
return { ok: false, reason: "google-maps-unavailable" };
|
|
}
|
|
const originalGetPlace = autocompleteInstance.getPlace.bind(autocompleteInstance);
|
|
autocompleteInstance.getPlace = function() {
|
|
return {
|
|
place_id: pid,
|
|
formatted_address: desc,
|
|
name: desc.split(",")[0],
|
|
geometry: { location: { lat: function() { return 0; }, lng: function() { return 0; } } },
|
|
};
|
|
};
|
|
gmaps.maps.event.trigger(autocompleteInstance, "place_changed");
|
|
setTimeout(function() {
|
|
autocompleteInstance.getPlace = originalGetPlace;
|
|
}, 100);
|
|
return { ok: true, reason: "triggered" };
|
|
}`;
|
|
|
|
export const CHECK_PICKUP_IN_REACT_STATE = `() => {
|
|
const widget = document.querySelector("#react-quoter-landing-plugin");
|
|
if (!widget) return false;
|
|
const fiberKey = Object.keys(widget).find(function(k) {
|
|
return k.indexOf("__reactFiber$") === 0 || k.indexOf("__reactInternalInstance$") === 0;
|
|
});
|
|
if (!fiberKey) return false;
|
|
let fiber = widget[fiberKey];
|
|
while (fiber) {
|
|
const state = fiber.stateNode && fiber.stateNode.state;
|
|
if (state) {
|
|
const pickup = state.pickupAddress || state.pickup || (state.addresses && state.addresses.pickup);
|
|
if (pickup && (pickup.placeId || pickup.formattedAddress)) {
|
|
return true;
|
|
}
|
|
}
|
|
fiber = fiber.return;
|
|
}
|
|
return false;
|
|
}`;
|
|
|
|
export const INJECT_REACT_STATE = `(arg) => {
|
|
const sideArg = arg.sideArg;
|
|
const pid = arg.pid;
|
|
const loc = arg.loc;
|
|
const desc = arg.desc;
|
|
const widget = document.querySelector("#react-quoter-landing-plugin");
|
|
if (!widget) return false;
|
|
const fiberKey = Object.keys(widget).find(function(k) {
|
|
return k.indexOf("__reactFiber$") === 0 || k.indexOf("__reactInternalInstance$") === 0;
|
|
});
|
|
if (!fiberKey) return false;
|
|
let fiber = widget[fiberKey];
|
|
while (fiber) {
|
|
const stateNode = fiber.stateNode;
|
|
if (stateNode && typeof stateNode.setState === "function") {
|
|
const state = stateNode.state;
|
|
if (state && ("pickupAddress" in state || "pickup" in state || "addresses" in state)) {
|
|
const addressData = {
|
|
placeId: pid,
|
|
location: loc,
|
|
formattedAddress: desc,
|
|
isCommitted: true,
|
|
};
|
|
const stateKey = sideArg === "pickup" ? "pickupAddress" : "deliveryAddress";
|
|
stateNode.setState({ [stateKey]: addressData });
|
|
return true;
|
|
}
|
|
}
|
|
fiber = fiber.return;
|
|
}
|
|
return false;
|
|
}`;
|