fix: clean up stray timestamp artifacts on search results
This commit is contained in:
@@ -18,6 +18,15 @@ const FEED_HOME_PATHS = ['/', '/home.php'];
|
||||
const sessionSearchRecordedUrls = new Set();
|
||||
const sessionSearchInfoCache = new Map();
|
||||
|
||||
function isOnSearchResultsPage() {
|
||||
try {
|
||||
const pathname = window.location && window.location.pathname;
|
||||
return typeof pathname === 'string' && pathname.startsWith(SEARCH_RESULTS_PATH_PREFIX);
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const trackerElementsByPost = new WeakMap();
|
||||
const postAdditionalNotes = new WeakMap();
|
||||
|
||||
@@ -1002,6 +1011,28 @@ function hidePostElement(postElement) {
|
||||
}
|
||||
|
||||
let removalRoot = elementToRemove;
|
||||
let parentForTimestampCheck = removalRoot.parentElement;
|
||||
while (parentForTimestampCheck && parentForTimestampCheck !== document.body && parentForTimestampCheck !== document.documentElement) {
|
||||
const siblings = Array.from(parentForTimestampCheck.children);
|
||||
const nonRootSiblings = siblings.filter((sibling) => sibling !== removalRoot);
|
||||
if (!nonRootSiblings.length) {
|
||||
break;
|
||||
}
|
||||
const hasOnlyTimestampSiblings = nonRootSiblings.every((sibling) => isTimestampArtifactNode(sibling));
|
||||
if (hasOnlyTimestampSiblings) {
|
||||
removalRoot = parentForTimestampCheck;
|
||||
parentForTimestampCheck = removalRoot.parentElement;
|
||||
continue;
|
||||
}
|
||||
const hasTimestampSibling = nonRootSiblings.some((sibling) => isTimestampArtifactNode(sibling));
|
||||
if (hasTimestampSibling && siblings.length <= 3) {
|
||||
removalRoot = parentForTimestampCheck;
|
||||
parentForTimestampCheck = removalRoot.parentElement;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
let parent = removalRoot.parentElement;
|
||||
|
||||
while (parent && parent !== document.body && parent !== document.documentElement) {
|
||||
@@ -1046,6 +1077,12 @@ function hidePostElement(postElement) {
|
||||
} else {
|
||||
removalRoot.style.display = 'none';
|
||||
}
|
||||
|
||||
if (removalParent) {
|
||||
cleanupDanglingSearchArtifacts(removalParent);
|
||||
} else {
|
||||
cleanupDanglingSearchArtifacts(document);
|
||||
}
|
||||
}
|
||||
|
||||
function collectButtonMeta(button) {
|
||||
@@ -3463,6 +3500,100 @@ function findAndClickCommentButton(postElement) {
|
||||
return false;
|
||||
}
|
||||
|
||||
function containsPostContent(element) {
|
||||
if (!element || element.nodeType !== Node.ELEMENT_NODE) {
|
||||
return false;
|
||||
}
|
||||
if (element.matches && element.matches('article, [role="article"]')) {
|
||||
return true;
|
||||
}
|
||||
if (element.querySelector && element.querySelector('article, [role="article"]')) {
|
||||
return true;
|
||||
}
|
||||
if (element.matches && element.matches('[data-fb-tracker-processed="1"]')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isTimestampArtifactNode(node) {
|
||||
if (!node || node.nodeType !== Node.ELEMENT_NODE) {
|
||||
return false;
|
||||
}
|
||||
if (!node.classList) {
|
||||
return false;
|
||||
}
|
||||
if (!node.classList.contains('__fb-light-mode') && !node.classList.contains('__fb-dark-mode')) {
|
||||
return false;
|
||||
}
|
||||
if (node.querySelector && node.querySelector('article, [role="article"]')) {
|
||||
return false;
|
||||
}
|
||||
const text = node.textContent ? node.textContent.trim() : '';
|
||||
if (!text) {
|
||||
return true;
|
||||
}
|
||||
if (text.length > 80) {
|
||||
return false;
|
||||
}
|
||||
const lowered = text.toLowerCase();
|
||||
const hasDate = /\b\d{1,2}\.\s*(?:jan|feb|mär|mae|apr|mai|jun|jul|aug|sep|okt|nov|dez)/i.test(lowered);
|
||||
const hasTime = /\b\d{1,2}[:.]\d{2}\b/.test(lowered);
|
||||
const hasMonthWord = /\b(?:januar|februar|märz|maerz|april|mai|juni|juli|august|september|oktober|november|dezember)\b/.test(lowered);
|
||||
if (hasDate || hasTime || hasMonthWord) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function removeNodeAndEmptyAncestors(node) {
|
||||
if (!node || node.nodeType !== Node.ELEMENT_NODE) {
|
||||
return;
|
||||
}
|
||||
const parents = [];
|
||||
let currentParent = node.parentElement;
|
||||
node.remove();
|
||||
|
||||
while (currentParent && currentParent !== document.body && currentParent !== document.documentElement) {
|
||||
parents.push(currentParent);
|
||||
currentParent = currentParent.parentElement;
|
||||
}
|
||||
|
||||
parents.forEach((parentNode) => {
|
||||
if (parentNode.childElementCount === 0) {
|
||||
parentNode.remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function cleanupDanglingSearchArtifacts(context) {
|
||||
if (!isOnSearchResultsPage()) {
|
||||
return;
|
||||
}
|
||||
const scope = (context && context.nodeType === Node.ELEMENT_NODE)
|
||||
? context
|
||||
: document;
|
||||
const candidates = scope.querySelectorAll('div.__fb-light-mode, div.__fb-dark-mode');
|
||||
candidates.forEach((node) => {
|
||||
if (!isTimestampArtifactNode(node)) {
|
||||
return;
|
||||
}
|
||||
const parent = node.parentElement;
|
||||
if (parent) {
|
||||
const hasContentSibling = Array.from(parent.children).some((child) => {
|
||||
if (child === node) {
|
||||
return false;
|
||||
}
|
||||
return containsPostContent(child);
|
||||
});
|
||||
if (hasContentSibling) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
removeNodeAndEmptyAncestors(node);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Find comment input field on current page
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user