userscripts icon indicating copy to clipboard operation
userscripts copied to clipboard

Script not working on new tab

Open levyashvin opened this issue 6 months ago • 5 comments

My system is ios 18.3, platform safari browser using the userscript app from appstore. I have a youtube script that removes comment sections and hides shorts on the mainpage. It also redirects shorts to the normal player. It works really well normally when i load into youtube but when i open a video in a new tab the acript doesnt work at all. In the newly opened tab if I navigate to other video or the homepage I can read comments/view shorts. Reloading the page seems to get the script working though. Not sure how to make it work otherwise. I have attached screenshots to show what it looks like when it works too.

my script:

// ==UserScript==
// @name         YouTube Mobile Cleaner (Shorts + Comments)
// @namespace    http://tampermonkey.net/
// @version      1.4
// @description  Removes Shorts shelf/header, redirects Shorts pages, and removes comments on m.youtube.com
// @match        *://m.youtube.com/*
// @match        *://www.youtube.com/shorts/*
// @match        *://youtube.com/shorts/*
// @run-at       document-end
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    const hideShorts = () => {
        // Remove Shorts grid items
        const shortsItems = document.querySelectorAll('ytm-shorts-lockup-view-model');
        shortsItems.forEach(short => {
            const shelfRow = short.closest('.ytGridShelfViewModelGridShelfRow');
            if (shelfRow) shelfRow.remove();
            else short.remove();
        });

        // Remove Shorts headers
        document.querySelectorAll('yt-section-header-view-model').forEach(header => {
            if (header.textContent.trim().toLowerCase().includes("shorts")) {
                header.remove();
            }
        });
    };

    const removeComments = () => {
        const commentsSection = document.querySelector('ytm-item-section-renderer[section-identifier="comments-entry-point"]');
        if (commentsSection) commentsSection.remove();
    };

    const redirectShorts = () => {
        const shortsMatch = location.pathname.match(/^\/shorts\/([a-zA-Z0-9_-]+)/);
        if (shortsMatch) {
            const videoId = shortsMatch[1];
            const redirectUrl = `/watch?v=${videoId}`;
            window.location.replace(redirectUrl);
        }
    };

    const runCleanup = () => {
        redirectShorts();
        setTimeout(() => {
            hideShorts();
            removeComments();
        }, 500); // Allow DOM to update
    };

    // Initial run
    runCleanup();

    // React to back/forward navigation
    window.addEventListener('popstate', runCleanup);

    // Patch pushState & replaceState for SPA navigation
    const patchHistoryMethod = (method) => {
        const original = history[method];
        history[method] = function () {
            const result = original.apply(this, arguments);
            runCleanup();
            return result;
        };
    };

    patchHistoryMethod('pushState');
    patchHistoryMethod('replaceState');

    // Observe dynamic content (scrolling, loading, etc.)
    const observer = new MutationObserver(() => {
        hideShorts();
        removeComments();
    });
    observer.observe(document.body, { childList: true, subtree: true });
})();

Image Image

levyashvin avatar May 19 '25 08:05 levyashvin

Have you seen the script has injected into the tab in the console?

If your script is just a simple alert() does it work in the new tab?

By the way, I modified your code format for easy reading.

ACTCD avatar May 19 '25 11:05 ACTCD

How do I check if the script has been injected in the console? this is the test alert script I used to check if I get the alert when I open a new tab and it doesnt work too

// ==UserScript==
// @name         Test Alert Script
// @namespace    http://tampermonkey.net/
// @version      1
// @description  Test if script runs on new tab load
// @match        *://m.youtube.com/*
// @run-at       document-start
// @grant        none
// ==/UserScript==

(function() {
    alert("Userscript is running");
})();

levyashvin avatar May 19 '25 17:05 levyashvin

How do I check if the script has been injected in the console?

You need to connect your iOS device to macOS and check it through Safari.

this is the test alert script I used to check if I get the alert when I open a new tab and it doesnt work too

It's weird, I remember there was a similar issue, but we didn't reproduce it.

  • https://github.com/quoid/userscripts/issues/639

And I don't think I can reproduce your issue as well.

My advice is:

  • Try using the beta version and see if there is the same issue.
  • If so, try to get the log to check if there are some clues.
  • https://github.com/quoid/userscripts/issues/409

ACTCD avatar May 19 '25 18:05 ACTCD

@levyashvin By the way, does it happen only in iOS 18.3? Have you tested it in previous iOS versions?

ACTCD avatar May 21 '25 22:05 ACTCD

Nope, I havent tested it on any other version. I have just gotten into the habit of reloading the pages I open in a new tab for now.

levyashvin avatar May 22 '25 02:05 levyashvin

I am attempting to do something similar with YT, ie: just trying to unmute upon page-load, & ultimately trying to tie it into an iOS (18.5) Shortcut but I too am seeing a similar issue where the script just doesn't load. In my case it doesn't load on existing tabs either 😕

PS: I am using the (Mobile) Safari Web Inspector extension to examine the page source & I just don't see any of my code (I am using @inject-into content).

Re. the earlier suggestion to use alert(): I think Safari blocks pop-ups by default, no? Regardless, I have tried it with the pop-up blocker disabled too.

bkmdev avatar Jun 30 '25 00:06 bkmdev

@bkmdev Content scripts run in a isolation world and you can't see your scripts in the DOM.

Also I don't think you can unmute through script, this is a browser restriction and requires user gestures to play non-muted.

ACTCD avatar Jun 30 '25 02:06 ACTCD

@bkmdev Content scripts run in a isolation world and you can't see your scripts in the DOM.

The same issue happens with // @inject-into page.

Also I don't think you can unmute through script, this is a browser restriction and requires user gestures to play non-muted.

The unmute button is a normal HTML5 button with class ytp-unmute ?

The code works if manually run at the console, the Userscripts code just oddly doesn't seem to be available after page load.

How can I ensure it is?

bkmdev avatar Jun 30 '25 08:06 bkmdev

@bkmdev I was just explaining that you usually can't "automatically" unmute it via scripts, due to the design of the browser for that limitation. Just like you usually could change it in your browser settings, at least in macOS Safari you can find that setting (Websites -> Auto-Play).

As for whether the script is injected normally, test it through the easiest way, such as alert or console.log or any simple changes that won't go wrong, such as modifying the CSS color of the elements.

The same issue happens with // @inject-into page.

The page scope uses closed-shadow-root to warp your user script, and I'm not sure if other extensions can or read the code in it correctly. It lacks a lot of privileges of the real browser devtools console.

The best way is:

  • Check via macOS Safari console
  • After enabled the App logger, record and check the log.
    • https://github.com/quoid/userscripts/issues/804#issuecomment-2891943945

We need something reproducible to help locate and solve issues.

ACTCD avatar Jun 30 '25 10:06 ACTCD

@bkmdev What is your iOS version? And the Userscripts App version?

I seem to reproduce the issue in iOS 18.3 emulator. Further investigation is still needed.

ACTCD avatar Jun 30 '25 11:06 ACTCD

I think this is a bug in upstream (i.e. Safari), which exists in some iOS versions.

I haven't tested all iOS versions, but: 17.5 - Work 18.3.1 - Error 18.4.1 - Work

So, it looks like this upstream bug exists in the version around iOS 18.3. (Unrelated, but there is another issue in that version: https://discussions.apple.com/thread/255884009)

The cause of the issue is related to the "Show preview" feature, and in the video you can see that if I "Hide preview" then the issue is no longer reproduced.

https://github.com/user-attachments/assets/4e028031-2265-473d-8a5b-179cfb0a5597

The test script I'm using, it should work for most websites:

https://github.com/userscriptsup/testscripts/blob/main/userscripts/debug-injection-indication.user.js https://raw.githubusercontent.com/userscriptsup/testscripts/main/userscripts/debug-injection-indication.user.js

So, in conclusion, if you are using a buggy iOS version, please disable preview or upgrade your system.

ACTCD avatar Jun 30 '25 12:06 ACTCD