• Also try this Browser script after searching to highlight only tweets between 5-140 characters, and excludes your preferred list of banned words. Press F12 and paste into Console.

Copy and Paste:

(() => {
  const config = {
    toggle: 2, // 0 = hide, 1 = replace, 2 = collapse with toggle
    minLength: 5,
    maxLength: 140,
    bannedWords: [
'nsfw','crypto','gore','slurs'
    ]
  };
  let bannedLower = config.bannedWords.map(w => w.toLowerCase());
  const processed = new WeakSet();
  function refreshBanned() {
    bannedLower = config.bannedWords.map(w => w.toLowerCase());
  }
  function containsBanned(text) {
    if (!text) return false;
    const t = text.toLowerCase().trim();
    return bannedLower.some(w => t.includes(w));
  }
function collapseTweet(article) {
  if (article._collapsed) return; // already processed
  // Wrap all tweet content in a container
  const contentWrapper = document.createElement('div');
  while (article.firstChild) {
    contentWrapper.appendChild(article.firstChild);
  }
  contentWrapper.style.display = 'none';
  contentWrapper.style.width = '100%';
  article.appendChild(contentWrapper);
  // Create a separate div for the button
  const buttonContainer = document.createElement('div');
  buttonContainer.style.width = '100%';
  buttonContainer.style.marginBottom = '4px';
  const button = document.createElement('button');
  button.textContent = 'Show/Hide';
  button.style.cssText = `
    font-size:14px;
    font-weight:bold;
    padding:6px 12px;
    background-color:#ffcc00;
    border:2px solid #cc9900;
    border-radius:6px;
    cursor:pointer;
    color:#000;
    transition: background-color 0.2s, transform 0.1s;
  `;
  button.onmouseover = () => button.style.backgroundColor = '#ffdd33';
  button.onmouseout = () => button.style.backgroundColor = '#ffcc00';
  button.onmousedown = () => button.style.transform = 'scale(0.95)';
  button.onmouseup = () => button.style.transform = 'scale(1)';
  button.onclick = () => {
    // Show the tweet content
    contentWrapper.style.display = '';
    // Remove the button container and HR so alignment is normal
    buttonContainer.remove();
    if (hr) hr.remove();
  };
  buttonContainer.appendChild(button);
  article.insertBefore(buttonContainer, contentWrapper);
  // Optional horizontal rule after the tweet
  const hr = document.createElement('hr');
  hr.style.margin = '4px 0';
  article.insertBefore(hr, contentWrapper.nextSibling);
  article._collapsed = true; // mark as processed
}
  function filterTweets() {
    document.querySelectorAll('article').forEach(article => {
      if (processed.has(article)) return;
      const tweetText = article.querySelector('div[lang]');
      if (!tweetText) return;
      processed.add(article);
      const text = tweetText.innerText.trim();
      const username = article.querySelector('div[dir="auto"] span')?.innerText || '';
      const pass = text.length >= config.minLength &&
                   text.length <= config.maxLength &&
                   !containsBanned(text) &&
                   !containsBanned(username);
      if (pass) {
        article.style.display = '';
        article.style.color = 'yellow';
      } else {
        if (config.toggle === 0) {
          article.style.display = 'none';
        } else if (config.toggle === 1) {
          article.style.display = '';
          tweetText.style.color = 'red';
          tweetText.textContent = '★FILTERED★';
        } else if (config.toggle === 2) {
          collapseTweet(article);
        }
      }
    });
  }
  // Menu
  const menu = document.createElement('div');
  menu.style.cssText = `
    position: fixed;
    top: 60px;
    right: 20px;
    z-index: 999999;
    background: #111;
    color: #eee;
    padding: 12px;
    font-size: 13px;
    width: 260px;
    border: 1px solid #444;
    display: block;
  `;
  menu.innerHTML = `
    <strong>Tweet Filter</strong>
    Toggle Mode:
    <select id="tf-toggle">
      <option value="0">Hide</option>
      <option value="1">Replace</option>
      <option value="2">Collapse</option>
    </select>
    Min Length: <input style="width:60px" type="number" id="tf-minlen">
    Max Length: <input style="width:60px" type="number" id="tf-maxlen">
    Banned Words:
    <textarea style="width:100%;height:80px" id="tf-banned"></textarea>
    <button id="tf-apply">Apply</button>
  `;
  document.body.appendChild(menu);
  const $ = id => document.getElementById(id);
  function syncMenu() {
    $('tf-toggle').value = config.toggle;
    $('tf-minlen').value = config.minLength;
    $('tf-maxlen').value = config.maxLength;
    $('tf-banned').value = config.bannedWords.join(',');
  }
  $('tf-apply').onclick = () => {
    config.toggle = Number($('tf-toggle').value);
    config.minLength = Number($('tf-minlen').value);
    config.maxLength = Number($('tf-maxlen').value);
    config.bannedWords = $('tf-banned').value.split(',').map(w => w.trim()).filter(Boolean);
    refreshBanned();
    processed.clear?.();
    filterTweets();
  };
  syncMenu();
  document.addEventListener('keydown', e => {
    if (e.key === 'F2') {
      e.preventDefault();
      menu.style.display = menu.style.display === 'none' ? 'block' : 'none';
    }
  });
  let scheduled = false;
  const observer = new MutationObserver(() => {
    if (scheduled) return;
    scheduled = true;
    requestAnimationFrame(() => {
      scheduled = false;
      filterTweets();
    });
  });
  filterTweets();
  observer.observe(document.body, { childList: true, subtree: true });
})();

Download

Download
xbettersearch 3.3 kB