fix(dom): scope value search near attribute, whole-word matching, panel-scoped gym name
This commit is contained in:
+42
-9
@@ -11,21 +11,23 @@ export function currentAttribute() {
|
||||
// Torn displays it as a capitalized word (e.g. "Strength") near the
|
||||
// top of the gym form.
|
||||
const KNOWN = ['strength', 'defense', 'speed', 'dexterity', 'endurance', 'intelligence'];
|
||||
const ATTR_RE = new RegExp('\\b(' + KNOWN.join('|') + ')\\b');
|
||||
|
||||
const headers = document.querySelectorAll('h1, h2, h3, h4, .title, .gym-title, [class*="gym"]');
|
||||
let attr = null;
|
||||
let attrEl = null;
|
||||
for (const el of headers) {
|
||||
const t = (el.textContent || '').trim().toLowerCase();
|
||||
for (const k of KNOWN) {
|
||||
if (t.includes(k)) { attr = k; break; }
|
||||
}
|
||||
if (attr) break;
|
||||
const m = t.match(ATTR_RE);
|
||||
if (m) { attr = m[1]; attrEl = el; break; }
|
||||
}
|
||||
if (!attr) return null;
|
||||
|
||||
// Current value: look for the prominent number on the page that is
|
||||
// formatted like a Torn attribute (e.g. "14,328,501").
|
||||
const valEl = findValueElement();
|
||||
// formatted like a Torn attribute (e.g. "14,328,501"). Search near
|
||||
// the attribute element so we don't pick up unrelated global numbers.
|
||||
let valEl = findValueNear(attrEl);
|
||||
if (!valEl) valEl = findValueElement(); // fallback: whole-page scan
|
||||
if (!valEl) return null;
|
||||
const current = parseNumber(valEl.textContent);
|
||||
if (current == null) return null;
|
||||
@@ -37,10 +39,34 @@ export function currentAttribute() {
|
||||
return { attr, current, gym };
|
||||
}
|
||||
|
||||
function findValueNear(el) {
|
||||
// Look at the element itself, then up to a few ancestors, then their descendants.
|
||||
// Prefer the largest formatted number within ~2 parent levels.
|
||||
const scope = [];
|
||||
let cur = el;
|
||||
for (let depth = 0; depth < 3 && cur; depth++) {
|
||||
scope.push(cur);
|
||||
cur = cur.parentElement;
|
||||
}
|
||||
let best = null;
|
||||
let bestN = -Infinity;
|
||||
for (const root of scope) {
|
||||
const candidates = root.querySelectorAll('*');
|
||||
for (const c of candidates) {
|
||||
if (c.children.length > 0) continue;
|
||||
const t = (c.textContent || '').trim();
|
||||
if (!/^[\d,]+(\.\d+)?$/.test(t)) continue;
|
||||
const n = parseNumber(t);
|
||||
if (n == null || n < 1) continue;
|
||||
if (n > bestN) { best = c; bestN = n; }
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
function findValueElement() {
|
||||
// Fallback only used when no element is found near the attribute.
|
||||
// Walk all elements; pick the largest formatted number on the page.
|
||||
// Torn renders the current attribute as a big number near the
|
||||
// "Property" label.
|
||||
const candidates = document.querySelectorAll('*');
|
||||
let best = null;
|
||||
let bestN = -Infinity;
|
||||
@@ -57,18 +83,25 @@ function findValueElement() {
|
||||
|
||||
function findGymName() {
|
||||
// Look for a known set of Torn gym name fragments. Adjust as needed.
|
||||
// Prefer an element that looks like the gym panel so we don't match
|
||||
// against global widgets (news, sidebar, ads).
|
||||
const panel = document.querySelector('.gym, #gym, [class*="gym-"], [class*="Gym"]');
|
||||
const roots = panel ? [panel, document.body] : [document.body];
|
||||
const known = [
|
||||
'Total Bastion', 'Frontline Fitness', 'Gym 300', 'Gym 500',
|
||||
'Baldr\'s Gym', 'Sportscience Laboratory', 'Premier Fitness',
|
||||
'Chrome Gym', 'Mr. Miyagi\'s', 'Power House',
|
||||
];
|
||||
const all = document.querySelectorAll('p, span, div, h1, h2, h3, h4, li');
|
||||
for (const root of roots) {
|
||||
const all = root.querySelectorAll('h1, h2, h3, h4, p, span, div, li');
|
||||
for (const el of all) {
|
||||
if (el.children.length > 0) continue;
|
||||
const t = (el.textContent || '').trim();
|
||||
for (const name of known) {
|
||||
if (t.includes(name)) return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user