Lock tracker anchor to post action bar to prevent drift

This commit is contained in:
2026-02-26 00:22:42 +01:00
parent f2a12f1fbf
commit 2fc5dbfacc

View File

@@ -242,61 +242,36 @@ function getTrackerInsertionAnchorInPost(postElement, buttonBar) {
return anchor && anchor.parentElement === postElement ? anchor : null;
}
function resolveActionButtonBar(postElement, buttonBar) {
if (!postElement) {
return null;
}
if (buttonBar && buttonBar.isConnected && postElement.contains(buttonBar)) {
return buttonBar;
}
const resolved = findButtonBar(postElement);
if (resolved && resolved.isConnected && postElement.contains(resolved)) {
return resolved;
}
return null;
}
function getDirectActionAnchorInPost(postElement, buttonBar) {
if (!postElement) {
return null;
}
const seeds = [];
const seedSelectors = [
'[data-ad-rendering-role="share_button"]',
'[data-ad-rendering-role="comment_button"]',
'[data-ad-rendering-role*="gefällt"]',
'[data-ad-rendering-role*="like_button"]',
'[data-ad-rendering-role*="reaction-like"]'
];
seedSelectors.forEach((selector) => {
const candidate = postElement.querySelector(selector);
if (candidate) {
seeds.push(candidate);
}
});
if (buttonBar && postElement.contains(buttonBar)) {
seeds.push(buttonBar);
const resolvedButtonBar = resolveActionButtonBar(postElement, buttonBar);
if (!resolvedButtonBar) {
return null;
}
for (const seed of seeds) {
let current = seed.closest('[role="button"], button') || seed;
while (current && current !== postElement) {
if (!postElement.contains(current)) {
break;
}
const hasShare = Boolean(current.querySelector('[data-ad-rendering-role="share_button"]'));
const hasComment = Boolean(current.querySelector('[data-ad-rendering-role="comment_button"]'));
const hasLike = Boolean(
current.querySelector('[data-ad-rendering-role*="gefällt"], [data-ad-rendering-role*="like_button"], [data-ad-rendering-role*="reaction-like"]')
);
const interactionCount = [hasShare, hasComment, hasLike].filter(Boolean).length;
const hasComposer = Boolean(
current.querySelector('div[role="textbox"][contenteditable="true"], div[contenteditable="true"][data-lexical-editor="true"]')
);
if (interactionCount >= 2 && !hasComposer) {
return current;
}
current = current.parentElement;
}
}
if (buttonBar && buttonBar.parentElement && postElement.contains(buttonBar.parentElement)) {
return buttonBar;
}
return getTrackerInsertionAnchorInPost(postElement, buttonBar);
return getTopLevelAnchorWithinPost(postElement, resolvedButtonBar)
|| getTrackerInsertionAnchorInPost(postElement, resolvedButtonBar)
|| resolvedButtonBar;
}
function getTopLevelAnchorWithinPost(postElement, element) {
@@ -3932,8 +3907,8 @@ async function createTrackerUI(postElement, buttonBar, postNum = '?', options =
inserted = tryInsertBeforeReelsCommentComposer();
}
const directActionAnchor = getDirectActionAnchorInPost(postElement, buttonBar);
const inPostActionAnchor = getTopLevelAnchorWithinPost(postElement, directActionAnchor) || directActionAnchor;
const resolvedButtonBar = resolveActionButtonBar(postElement, buttonBar);
const inPostActionAnchor = getDirectActionAnchorInPost(postElement, resolvedButtonBar);
const commentSortAnchor = findAdjacentCommentSortAnchor(postElement, inPostActionAnchor);
const preferredAnchor = commentSortAnchor || inPostActionAnchor;
@@ -3948,8 +3923,8 @@ async function createTrackerUI(postElement, buttonBar, postNum = '?', options =
inserted = true;
}
// Strategy 2: Insert directly after the detected button bar if still inside the post container
if (!inserted && buttonBar && buttonBar.parentElement && postElement.contains(buttonBar.parentElement)) {
buttonBar.parentElement.insertBefore(container, buttonBar.nextSibling);
if (!inserted && resolvedButtonBar && resolvedButtonBar.parentElement && postElement.contains(resolvedButtonBar.parentElement)) {
resolvedButtonBar.parentElement.insertBefore(container, resolvedButtonBar.nextSibling);
console.log('[FB Tracker] Post #' + postNum + ' - UI inserted after button bar (in-post fallback). ID: #' + container.id);
inserted = true;
}
@@ -3991,14 +3966,14 @@ async function createTrackerUI(postElement, buttonBar, postNum = '?', options =
console.log('[FB Tracker] Post #' + postNum + ' - UI was removed, re-inserting...');
observer.disconnect();
// Try to re-insert
const currentDirectActionAnchor = getDirectActionAnchorInPost(postElement, buttonBar);
const currentInPostActionAnchor = getTopLevelAnchorWithinPost(postElement, currentDirectActionAnchor) || currentDirectActionAnchor;
const currentResolvedButtonBar = resolveActionButtonBar(postElement, buttonBar);
const currentInPostActionAnchor = getDirectActionAnchorInPost(postElement, currentResolvedButtonBar);
const currentCommentSortAnchor = findAdjacentCommentSortAnchor(postElement, currentInPostActionAnchor);
const currentPreferredAnchor = currentCommentSortAnchor || currentInPostActionAnchor;
if (currentPreferredAnchor && currentPreferredAnchor.parentElement) {
currentPreferredAnchor.parentElement.insertBefore(container, currentPreferredAnchor.nextSibling);
} else if (buttonBar && buttonBar.parentElement && postElement.contains(buttonBar.parentElement)) {
buttonBar.parentElement.insertBefore(container, buttonBar.nextSibling);
} else if (currentResolvedButtonBar && currentResolvedButtonBar.parentElement && postElement.contains(currentResolvedButtonBar.parentElement)) {
currentResolvedButtonBar.parentElement.insertBefore(container, currentResolvedButtonBar.nextSibling);
} else if (buttonBar && buttonBar.parentElement && buttonBar.parentElement.parentElement && !postElement.contains(buttonBar.parentElement.parentElement)) {
buttonBar.parentElement.parentElement.insertBefore(container, buttonBar.parentElement.nextSibling);
} else if (postElement) {