Skip to content

Instantly share code, notes, and snippets.

@nathansmith
Last active January 27, 2025 16:58
Show Gist options
  • Save nathansmith/a2ec33cdfdd78851feb860711b962001 to your computer and use it in GitHub Desktop.
Save nathansmith/a2ec33cdfdd78851feb860711b962001 to your computer and use it in GitHub Desktop.

Revisions

  1. nathansmith revised this gist Jan 27, 2025. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion [2] tweet-delete.js
    Original file line number Diff line number Diff line change
    @@ -89,7 +89,6 @@
    });
    }
    });

    }
    }

  2. nathansmith revised this gist Jan 27, 2025. 1 changed file with 3 additions and 2 deletions.
    5 changes: 3 additions & 2 deletions [2] tweet-delete.js
    Original file line number Diff line number Diff line change
    @@ -44,8 +44,9 @@

    const handleButtonClick = () => {
    // Get elements.
    const buttonForMenu = document.querySelector('section[aria-labelledby="accessible-list-0"] [aria-haspopup="menu"]');
    const buttonForUndoRetweet = document.querySelector('section[aria-labelledby="accessible-list-0"] [data-testid="unretweet"]');
    const section = document.querySelector('section[aria-labelledby="accessible-list-0"]');
    const buttonForMenu = section?.querySelector('[aria-haspopup="menu"]');
    const buttonForUndoRetweet = section?.querySelector('[data-testid="unretweet"]');

    // ======================================
    // Button for "undo retweet" exists: YES.
  3. nathansmith revised this gist Jan 27, 2025. 1 changed file with 6 additions and 6 deletions.
    12 changes: 6 additions & 6 deletions [2] tweet-delete.js
    Original file line number Diff line number Diff line change
    @@ -44,12 +44,12 @@

    const handleButtonClick = () => {
    // Get elements.
    const buttonForMenu = document.querySelector('main [aria-haspopup="menu"]');
    const buttonForUndoRetweet = document.querySelector('main [data-testid="unretweet"]');
    const buttonForMenu = document.querySelector('section[aria-labelledby="accessible-list-0"] [aria-haspopup="menu"]');
    const buttonForUndoRetweet = document.querySelector('section[aria-labelledby="accessible-list-0"] [data-testid="unretweet"]');

    // ==================================
    // Button "undo retweet" exists: YES.
    // ==================================
    // ======================================
    // Button for "undo retweet" exists: YES.
    // ======================================

    if (buttonForUndoRetweet) {
    // Fire events.
    @@ -96,7 +96,7 @@
    // Kickoff.
    // ========

    setInterval(handleButtonClick, 2000);
    setInterval(handleButtonClick, 5000);

    // =============
    // END: Closure.
  4. nathansmith revised this gist Jan 27, 2025. 1 changed file with 33 additions and 23 deletions.
    56 changes: 33 additions & 23 deletions [2] tweet-delete.js
    Original file line number Diff line number Diff line change
    @@ -3,22 +3,31 @@
    // ===============

    (() => {
    // ==========
    // Set later.
    // ==========

    let timerForElement;

    // =========================
    // Helper: wait for element.
    // =========================

    const waitForElement = (selector) => {
    // Clear timer.
    clearInterval(timerForElement);

    // Expose promise.
    return new Promise((resolve) => {
    // Set timer.
    const timerForCheck = setInterval(() => {
    timerForElement = setInterval(() => {
    // Get element.
    const element = document.querySelector(selector);

    // Element exists: YES.
    if (element) {
    // Clear timer.
    clearInterval(timerForCheck);
    clearInterval(timerForElement);

    // Promise resolve.
    resolve(element);
    @@ -33,7 +42,7 @@
    // Helper: click buttons.
    // ======================

    const handleButtonClick = async () => {
    const handleButtonClick = () => {
    // Get elements.
    const buttonForMenu = document.querySelector('main [aria-haspopup="menu"]');
    const buttonForUndoRetweet = document.querySelector('main [data-testid="unretweet"]');
    @@ -47,13 +56,13 @@
    buttonForUndoRetweet.click();

    // Get elements.
    const buttonForConfirm = await waitForElement('[data-testid="unretweetConfirm"]');

    // Button exists: YES.
    if (buttonForConfirm) {
    // Fire events.
    buttonForConfirm.click();
    }
    waitForElement('[data-testid="unretweetConfirm"]').then((buttonForConfirm) => {
    // Button exists: YES.
    if (buttonForConfirm) {
    // Fire events.
    buttonForConfirm.click();
    }
    });

    // ==================================
    // Button for "dot menu" exists: YES.
    @@ -63,22 +72,23 @@
    buttonForMenu.click();

    // Get elements.
    const buttonForDelete = await waitForElement('[data-testid="Dropdown"] [role="menuitem"]');

    // Button exists: YES.
    if (buttonForDelete && buttonForDelete.textContent.match('Delete')) {
    // Fire events.
    buttonForDelete.click();

    // Get elements.
    const buttonForConfirm = await waitForElement('[data-testid="confirmationSheetConfirm"]');

    waitForElement('[data-testid="Dropdown"] [role="menuitem"]').then((buttonForDelete) => {
    // Button exists: YES.
    if (buttonForConfirm) {
    if (buttonForDelete && buttonForDelete.textContent.match('Delete')) {
    // Fire events.
    buttonForConfirm.click();
    buttonForDelete.click();

    // Get elements.
    waitForElement('[data-testid="confirmationSheetConfirm"]').then((buttonForConfirm) => {
    // Button exists: YES.
    if (buttonForConfirm) {
    // Fire events.
    buttonForConfirm.click();
    }
    });
    }
    }
    });

    }
    }

  5. nathansmith revised this gist Jan 26, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion [1] tweet-delete.md
    Original file line number Diff line number Diff line change
    @@ -8,4 +8,4 @@

    But if you did — and left it running for a long while — it might eventually delete all tweets and retweets from your Twitter account.

    Again, not sure why anyone would do that. Perhaps just as a fun little JavaScript experiment. Pretty sure it voids the warranty. Just sayin'.
    Again, not sure why anyone would do that. Perhaps as a fun little JavaScript experiment. Pretty sure it voids the warranty. Just sayin'.
  6. nathansmith renamed this gist Jan 26, 2025. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  7. nathansmith revised this gist Jan 26, 2025. 2 changed files with 11 additions and 0 deletions.
    11 changes: 11 additions & 0 deletions [1] readme.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,11 @@
    🐦 Look, I'm not saying you should do this.

    1. Go to your Twitter profile page.

    2. Paste this into the console.

    3. Hit enter.

    But if you did — and left it running for a long while — it might eventually delete all tweets and retweets from your Twitter account.

    Again, not sure why anyone would do that. Perhaps just as a fun little JavaScript experiment. Pretty sure it voids the warranty. Just sayin'.
    File renamed without changes.
  8. nathansmith created this gist Jan 26, 2025.
    94 changes: 94 additions & 0 deletions tweet-delete.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,94 @@
    // ===============
    // START: Closure.
    // ===============

    (() => {
    // =========================
    // Helper: wait for element.
    // =========================

    const waitForElement = (selector) => {
    // Expose promise.
    return new Promise((resolve) => {
    // Set timer.
    const timerForCheck = setInterval(() => {
    // Get element.
    const element = document.querySelector(selector);

    // Element exists: YES.
    if (element) {
    // Clear timer.
    clearInterval(timerForCheck);

    // Promise resolve.
    resolve(element);
    }

    // Slight delay.
    }, 16);
    });
    };

    // ======================
    // Helper: click buttons.
    // ======================

    const handleButtonClick = async () => {
    // Get elements.
    const buttonForMenu = document.querySelector('main [aria-haspopup="menu"]');
    const buttonForUndoRetweet = document.querySelector('main [data-testid="unretweet"]');

    // ==================================
    // Button "undo retweet" exists: YES.
    // ==================================

    if (buttonForUndoRetweet) {
    // Fire events.
    buttonForUndoRetweet.click();

    // Get elements.
    const buttonForConfirm = await waitForElement('[data-testid="unretweetConfirm"]');

    // Button exists: YES.
    if (buttonForConfirm) {
    // Fire events.
    buttonForConfirm.click();
    }

    // ==================================
    // Button for "dot menu" exists: YES.
    // ==================================
    } else if (buttonForMenu) {
    // Fire events.
    buttonForMenu.click();

    // Get elements.
    const buttonForDelete = await waitForElement('[data-testid="Dropdown"] [role="menuitem"]');

    // Button exists: YES.
    if (buttonForDelete && buttonForDelete.textContent.match('Delete')) {
    // Fire events.
    buttonForDelete.click();

    // Get elements.
    const buttonForConfirm = await waitForElement('[data-testid="confirmationSheetConfirm"]');

    // Button exists: YES.
    if (buttonForConfirm) {
    // Fire events.
    buttonForConfirm.click();
    }
    }
    }
    }

    // ========
    // Kickoff.
    // ========

    setInterval(handleButtonClick, 2000);

    // =============
    // END: Closure.
    // =============
    })();