diff --git a/src/main.js b/src/main.js
index 8ea41e3..04cebd8 100644
--- a/src/main.js
+++ b/src/main.js
@@ -4,20 +4,20 @@ import { currentAttribute } from './dom.js';
import { startRequestInterceptor } from './interceptor.js';
function findAnchorElement() {
- // Try several selectors in priority order. Torn's gym page renders the
- // training UI as
(the list of attribute
- // rows). Anchor the dialog above that list.
+ // Return the element to insert the dialog BEFORE in the DOM.
+ // The user wants the dialog between the notification wrapper and the
+ // gym content wrapper; we insert before gymContentWrapper.
const candidates = [
- 'ul[class*="properties"]',
- '[class*="gymContent"]',
- '[class*="gymContentWrapper"]',
- // Legacy fallbacks (kept in case Torn ever wraps the list in a form):
+ '[class*="gymContentWrapper"]', // outer wrapper — best insertion point
+ '[class*="gymContent"]', // inner wrapper (fallback)
+ 'ul[class*="properties"]', // the list itself (last resort)
+ // Legacy fallbacks (kept for robustness):
'form[action*="train"]',
'form.train-form',
'form[class*="train"]',
'[class*="train-button"]',
'button[class*="train"]',
- 'a[class*="train"]',
+ 'a[href*="train"]',
'button[name="train"]',
'a[href*="train"]',
];
@@ -99,20 +99,13 @@ function start() {
if (prefs.mode === 'anchored') {
const el = findAnchorElement();
if (el) {
- const rect = el.getBoundingClientRect();
- dialog.setMode('anchored', { canAnchor: true, rect: rect });
- if (typeof ResizeObserver !== 'undefined') {
- const ro = new ResizeObserver(function () {
- if (prefs.mode === 'anchored') dialog._positionAnchored(el.getBoundingClientRect());
- });
- ro.observe(el);
- }
+ dialog.setMode('anchored', { canAnchor: true, insertBefore: el });
anchorError = null;
return;
}
// Anchor selector missed — don't snap to default, just keep current
// position and show a note.
- anchorError = "Couldn't find the training form on this page.";
+ anchorError = "Couldn't find the training UI on this page.";
render();
return;
}