Harden tracker anchor detection for new comment layout
This commit is contained in:
@@ -309,17 +309,94 @@ function getTrackerInsertionAnchorInPost(postElement, buttonBar) {
|
|||||||
return anchor && anchor.parentElement === postElement ? anchor : null;
|
return anchor && anchor.parentElement === postElement ? anchor : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasCommentComposerSignal(node) {
|
||||||
|
if (!node || !node.querySelector) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Boolean(
|
||||||
|
node.querySelector(
|
||||||
|
'div[role="textbox"][contenteditable="true"], [role="textbox"][aria-label*="komment" i], [role="textbox"][aria-label*="comment" i], [role="textbox"][aria-placeholder*="komment" i], [role="textbox"][aria-placeholder*="comment" i]'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function countActionRoleSignals(node) {
|
||||||
|
if (!node || !node.querySelector) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasLike = Boolean(node.querySelector('[data-ad-rendering-role="like_button"], [data-ad-rendering-role*="gefällt" i]'));
|
||||||
|
const hasComment = Boolean(node.querySelector('[data-ad-rendering-role="comment_button"]'));
|
||||||
|
const hasShare = Boolean(node.querySelector('[data-ad-rendering-role="share_button"]'));
|
||||||
|
|
||||||
|
return [hasLike, hasComment, hasShare].filter(Boolean).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isReliableActionBarCandidate(postElement, candidate) {
|
||||||
|
if (!postElement || !candidate || !candidate.isConnected || !postElement.contains(candidate)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (candidate.closest('.fb-tracker-ui')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasCommentComposerSignal(candidate)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const buttonCount = candidate.querySelectorAll('[role="button"], button').length;
|
||||||
|
if (buttonCount > 80) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const actionRoleSignals = countActionRoleSignals(candidate);
|
||||||
|
if (actionRoleSignals >= 2) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasInteractionButtons(candidate);
|
||||||
|
}
|
||||||
|
|
||||||
|
function findActionBarByDataRoles(postElement) {
|
||||||
|
if (!postElement) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const markers = Array.from(postElement.querySelectorAll(
|
||||||
|
'[data-ad-rendering-role="like_button"], [data-ad-rendering-role*="gefällt" i], [data-ad-rendering-role="comment_button"], [data-ad-rendering-role="share_button"]'
|
||||||
|
));
|
||||||
|
|
||||||
|
for (const marker of markers) {
|
||||||
|
let current = marker;
|
||||||
|
for (let depth = 0; depth < 8 && current && current !== postElement; depth++) {
|
||||||
|
if (isReliableActionBarCandidate(postElement, current)) {
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
current = current.parentElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
function resolveActionButtonBar(postElement, buttonBar) {
|
function resolveActionButtonBar(postElement, buttonBar) {
|
||||||
if (!postElement) {
|
if (!postElement) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buttonBar && buttonBar.isConnected && postElement.contains(buttonBar)) {
|
const dataRoleResolved = findActionBarByDataRoles(postElement);
|
||||||
|
if (dataRoleResolved) {
|
||||||
|
return dataRoleResolved;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buttonBar && isReliableActionBarCandidate(postElement, buttonBar)) {
|
||||||
return buttonBar;
|
return buttonBar;
|
||||||
}
|
}
|
||||||
|
|
||||||
const resolved = findButtonBar(postElement);
|
const resolved = findButtonBar(postElement);
|
||||||
if (resolved && resolved.isConnected && postElement.contains(resolved)) {
|
if (resolved && isReliableActionBarCandidate(postElement, resolved)) {
|
||||||
return resolved;
|
return resolved;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -428,6 +505,29 @@ function findAdjacentCommentSortAnchor(postElement, actionAnchor = null) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function findCommentSortAnchorInPost(postElement) {
|
||||||
|
if (!postElement) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sortCandidates = Array.from(
|
||||||
|
postElement.querySelectorAll('[aria-label*="relevantes zuerst" i], [aria-label*="most relevant" i], [aria-label*="neueste" i], [aria-label*="newest" i], [role="button"], button')
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const candidate of sortCandidates) {
|
||||||
|
if (!isLikelyCommentSortNode(candidate)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const topLevel = getTopLevelAnchorWithinPost(postElement, candidate) || candidate;
|
||||||
|
if (topLevel && topLevel.parentElement && postElement.contains(topLevel)) {
|
||||||
|
return topLevel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
function createTrackerInsertionMarker() {
|
function createTrackerInsertionMarker() {
|
||||||
const marker = document.createElement('div');
|
const marker = document.createElement('div');
|
||||||
marker.className = 'fb-tracker-insertion-anchor';
|
marker.className = 'fb-tracker-insertion-anchor';
|
||||||
@@ -472,6 +572,14 @@ function positionTrackerInsertionMarker(postElement, marker, buttonBar, postNum
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fallbackSortAnchor = findCommentSortAnchorInPost(postElement);
|
||||||
|
if (fallbackSortAnchor && fallbackSortAnchor.parentElement) {
|
||||||
|
fallbackSortAnchor.parentElement.insertBefore(marker, fallbackSortAnchor);
|
||||||
|
setTrackerInsertionMarkerLocked(marker, true);
|
||||||
|
console.log('[FB Tracker] Post #' + postNum + ' - Marker fallback inserted before comment sort');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
postElement.appendChild(marker);
|
postElement.appendChild(marker);
|
||||||
setTrackerInsertionMarkerLocked(marker, false);
|
setTrackerInsertionMarkerLocked(marker, false);
|
||||||
console.log('[FB Tracker] Post #' + postNum + ' - Marker fallback appended to post');
|
console.log('[FB Tracker] Post #' + postNum + ' - Marker fallback appended to post');
|
||||||
|
|||||||
Reference in New Issue
Block a user