YouTube Not Interested Button

Click once to mark any YouTube video as "Not Interested" and remove your watch history.

目前為 2025-11-25 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name           YouTube Not Interested Button
// @name:ja        YouTube 「興味なし」ボタン
// @namespace      https://github.com/tommyktech/YouTubeNotInterestedButton
// @description    Click once to mark any YouTube video as "Not Interested" and remove your watch history.
// @description:ja YouTubeの「興味なし」を1発で実行できるボタンを設置します
// @match          https://www.youtube.com/
// @match          https://www.youtube.com/?*
// @match          https://www.youtube.com/watch*
// @match          https://www.youtube.com/feed/history
// @grant          GM_addStyle
// @run-at         document-idle
// @version        0.13
// @homepageURL    https://github.com/tommyktech/YouTubeNotInterestedButton
// @supportURL     https://github.com/tommyktech/YouTubeNotInterestedButton/issues
// @author         https://github.com/tommyktech
// @license        Apache License 2.0
// ==/UserScript==
GM_addStyle(`
  div.yt-lockup-metadata-view-model__menu-button button.yt-spec-button-shape-next {
    width: 60px !important;
    height: 44px !important;
  }
  ytm-menu-renderer ytm-menu button c3-icon {
    width: 50px !important;
    height: 50px !important;
  }
  .additional-btn {
    position: absolute;
    font-size: 28px;
    padding: 2px;
    margin-right: 4px;
    border: none;
    background: transparent;
    height: 24px;
    width: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
    //opacity: 0.5;
  }

  .additional-btn span {
    //background: rgba(0,0,0,0.6);
    padding: 0px;
    height: 34px;
    width: 34px;
    font-size: 30;
    // border-radius: 4px;
    color: white;
  }

  .additional-btn svg {
    //background: rgba(0,0,0,0.6);
    padding: 0px;
    height: 28px;
    width: 28px;
    //border-radius: 4px;
    stroke: gray;
    fill: gray;
    stroke-width:0.5px;
  }

  .read-btn {
    right: 0px;
    bottom: 0px;
  //  top: 40px;
    z-index: 2000;
  }

  .not-interested-in-btn {
    right: 40px;
    bottom: 0px;
//    top: 70px;
    z-index: 2000;
  }

  .delete-history-btn {
    right: 0px;
    top: 40px;
    z-index:2000;
    width: 30px;
  }

`);

(function () {
    'use strict';

    var TILE_SELECTOR = 'yt-lockup-view-model';
    var MENU_BUTTON_SELECTOR = 'div.yt-lockup-metadata-view-model__menu-button button-view-model button';
    var MENU_SELECTOR = 'ytd-popup-container tp-yt-iron-dropdown';
    const PROCESSED_ATTR = 'data-yt-menu-opener-added';

    // Show overlay notice on top of screen
    function showOverlay(msg, duration = 3000, backgroundColor="white") {
        let el = document.createElement("div");
        el.textContent = msg;
        Object.assign(el.style, {
            position: "fixed",
            top: "0",
            left: "0",
            width: "100%",
            padding: "10px 16px",
            backgroundColor: backgroundColor,
            opacity: 0.5,
            color: "black",
            fontSize: "24px",
            zIndex: "99999",
            textAlign: "center"
        });
        document.body.appendChild(el);
        console.log("Displayed message:", msg);

        setTimeout(() => el.remove(), duration);
    }

    // Wait for selected element to appear
    function waitForElement(selector, rootElem = null, intervalMs = 100, timeoutMs = 2000) {
        return new Promise((resolve, reject) => {
            const start = Date.now();

            const timer = setInterval(() => {
                const elem = (rootElem || document).querySelector(selector);
                if (elem && elem.style.display != "none") {
                    clearInterval(timer);
                    resolve(elem);
                    return;
                }

                if (Date.now() - start > timeoutMs) {
                    clearInterval(timer);
                    reject(new Error("Timeout: Can't find the element:" + selector));
                }
            }, intervalMs);
        });
    }

    // dispatch tap action
    function dispatchTapLike(target) {
        if (!target) return false;
        try {target.focus({preventScroll:true}); } catch(e){}

        /*
        // 1) dispatch 'tap' which libraries like Polymer listen
        try {
            target.dispatchEvent(new CustomEvent('tap', { bubbles: true, cancelable: true, composed: true }));
            console.log('dispatched CustomEvent tap');
        } catch(e) { console.warn('tap custom event failed', e); }

        // 2) dispatch a series of pointer / mouse actions(including pointerType:'touch')
        try {
            const r = target.getBoundingClientRect();
            const cx = Math.round(r.left + r.width/2);
            const cy = Math.round(r.top + r.height/2);
            const pOpts = {
                bubbles: true, cancelable: true, composed: true,
                clientX: cx, clientY: cy, screenX: cx, screenY: cy,
                pointerId: Date.now() & 0xFFFF, pointerType: 'touch', isPrimary: true, pressure: 0.5, buttons: 1
            };
            target.dispatchEvent(new PointerEvent('pointerdown', pOpts));
            target.dispatchEvent(new PointerEvent('pointerup', pOpts));
            target.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, cancelable: true, clientX: cx, clientY: cy, buttons: 1 }));
            target.dispatchEvent(new MouseEvent('mouseup', { bubbles: true, cancelable: true, clientX: cx, clientY: cy, buttons: 1 }));
            target.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, clientX: cx, clientY: cy, buttons: 1 }));
            console.log('dispatched pointer/mouse sequence');
        } catch(e) {
            console.warn('pointer/mouse sequence failed', e);
        }
        */

        // 3) Dispatch touchstart/touchend if possible(depends on browsers)
        try {
            const r = target.getBoundingClientRect();
            const cx = Math.round(r.left + r.width/2);
            const cy = Math.round(r.top + r.height/2);
            const touch = new Touch({ identifier: Date.now(), target: target, clientX: cx, clientY: cy, screenX: cx, screenY: cy, pageX: cx, pageY: cy });
            const teStart = new TouchEvent('touchstart', { bubbles: true, cancelable: true, composed: true, touches: [touch], targetTouches: [touch], changedTouches: [touch] });
            const teEnd   = new TouchEvent('touchend',   { bubbles: true, cancelable: true, composed: true, touches: [], targetTouches: [], changedTouches: [touch] });
            target.dispatchEvent(teStart);
            target.dispatchEvent(teEnd);
            console.debug('dispatched touchstart/touchend');
        } catch(e) {
            console.warn('TouchEvent creation failed or not allowed', e);
        }

        // 4) finally dispatch DOM click()
        try {
            target.click();
            console.debug('called element.click()');
        } catch(e) {
            console.warn('element.click() threw', e);
            return false;
        }
        return true;
    }

    // attach 'Not Interested' button
    function attachNotInterestedInButton(tile) {
        const tileClassList = tile.classList

        // selector for original 'Not Interested'
        var svgPathData = "M12 1C5.925 1 1 5.925 1 12s4.925 11 11 11 11-4.925 11-11S18.075 1 12 1Zm0 2a9 9 0 018.246 12.605L4.755 6.661A8.99 8.99 0 0112 3ZM3.754 8.393l15.491 8.944A9 9 0 013.754 8.393Z";
        var SVG_SELECTOR = `path[d="${svgPathData}"]`

        // attach a custom 'Not Interested' button
        const notInterestedBtn = document.createElement('button');
        notInterestedBtn.className = 'additional-btn not-interested-in-btn';

        // create an SVG for the button
        const SVG_NS = "http://www.w3.org/2000/svg";
        const svg = document.createElementNS(SVG_NS, "svg");
        const path = document.createElementNS(SVG_NS, "path");
        path.setAttribute("d", "M12 1C5.925 1 1 5.925 1 12s4.925 11 11 11 11-4.925 11-11S18.075 1 12 1Zm0 2a9 9 0 018.246 12.605L4.755 6.661A8.99 8.99 0 0112 3ZM3.754 8.393l15.491 8.944A9 9 0 013.754 8.393Z");
        svg.appendChild(path);
        notInterestedBtn.appendChild(svg);
        if (tileClassList.contains("ytd-rich-item-renderer")) {
            // top page
            tile.parentElement.appendChild(notInterestedBtn);
        } else if (tileClassList.contains("ytd-item-section-renderer")) {
            // watch page
            tile.appendChild(notInterestedBtn);
        }

        // add eventlistener
        function onNotInterestedInButtonClick(ev) {
            ev.preventDefault();
            ev.stopPropagation();
            const menuBtn = tile.querySelector(MENU_BUTTON_SELECTOR);
            if (!menuBtn) {
                console.warn('menu button not found');
                return;
            }

            // Dispatch tap action to the menu button
            dispatchTapLike(menuBtn)

            // Check if the menu appeared
            waitForElement(MENU_SELECTOR).then(dropdown_el => {
                console.debug("dropdown_el:", dropdown_el)
                // Check if the target element appeared
                waitForElement(SVG_SELECTOR, dropdown_el).then(svg_el => {
                    console.debug("svg_el:", svg_el)
                    const result = dispatchTapLike(svg_el.parentElement.parentElement)
                    if (result) {
                        showOverlay('Sent "Not Interested In"');
                    }
                });
            });
        };
        notInterestedBtn.addEventListener('click', function(ev) {
            onNotInterestedInButtonClick(ev);
        });
    }

    // attach 'Already Watched' button
    function attachWatchedButton(tile) {
        const tileClassList = tile.classList

        // selector for original 'Not Interested' button
        var svgPathData = "M12 1C5.925 1 1 5.925 1 12s4.925 11 11 11 11-4.925 11-11S18.075 1 12 1Zm0 2a9 9 0 018.246 12.605L4.755 6.661A8.99 8.99 0 0112 3ZM3.754 8.393l15.491 8.944A9 9 0 013.754 8.393Z";
        var SVG_SELECTOR = `path[d="${svgPathData}"]`

        // attach a custom 'Already Watched' button
        const readBtn = document.createElement('button');
        readBtn.className = 'additional-btn read-btn';

        // create an SVG for the button
        const SVG_NS = "http://www.w3.org/2000/svg";
        const hide_svg = document.createElementNS(SVG_NS, "svg");
        const hide_path1 = document.createElementNS(SVG_NS, "path");
        hide_path1.setAttribute("d", "m6.666 5.303 2.122 1.272c4.486-1.548 10.002.26 12.08 5.426-.2.5-.435.968-.696 1.406l1.717 1.03c.41-.69.752-1.42 1.02-2.178a.77.77 0 000-.516l-.18-.473C19.998 4.436 12.294 2.448 6.667 5.303Zm-5.524.183a1.003 1.003 0 00.343 1.371l1.8 1.08a11.8 11.8 0 00-2.193 3.805.77.77 0 000 .516c2.853 8.041 12.37 9.784 18.12 5.235l2.273 1.364a1 1 0 101.03-1.714l-20-12a1 1 0 00-1.373.343Zm11.064 2.52L12 8c-.248 0-.49.022-.727.066l4.54 2.724a4 4 0 00-3.607-2.785ZM5.04 8.99l3.124 1.874C8.057 11.224 8 11.606 8 12l.005.206a4 4 0 003.79 3.79L12 16c1.05 0 2.057-.414 2.803-1.152l2.54 1.524C12.655 19.48 5.556 18.024 3.133 12A9.6 9.6 0 015.04 8.99ZM10 12v-.033l2.967 1.78a1.99 1.99 0 01-2.307-.262 2 2 0 01-.65-1.28L10 12Z");
        hide_svg.appendChild(hide_path1)
        readBtn.appendChild(hide_svg);
        if (tileClassList.contains("ytd-rich-item-renderer")) {
            // top page
            tile.parentElement.appendChild(readBtn);
        } else if (tileClassList.contains("ytd-item-section-renderer")) {
            // watch page
            tile.appendChild(readBtn);
        }

        // add eventlistener for the button
        function onReadButtonClick(ev) {
            ev.preventDefault();
            ev.stopPropagation();
            const menuBtn = tile.querySelector(MENU_BUTTON_SELECTOR);
            if (!menuBtn) {
                console.warn('menu button not found');
                return;
            }

            // Dispatch a tap to the menu button
            dispatchTapLike(menuBtn);

            // Repeat waiting for the element and tapping it
            (async () => {
                try {
                    // Wait for the menu to appear
                    const dropdown_el = await waitForElement(MENU_SELECTOR);
                    console.debug("dropdown_el:", dropdown_el);

                    console.debug("Wait for the 'Not Interested' item");
                    const svg_el = await waitForElement(SVG_SELECTOR, dropdown_el);
                    console.debug("The 'Not Interested' item has been found, so tap it.:", svg_el);
                    dispatchTapLike(svg_el.parentElement.parentElement);

                    console.debug("Wait for 'Tell us why' button to appear");
                    const TELL_ME_REASON_BUTTON = "div.ytNotificationMultiActionRendererButtonContainer div:nth-child(2) button-view-model button";
                    const send_reason_button = await waitForElement(TELL_ME_REASON_BUTTON, tile);

                    console.debug("Found the 'Tell us why' button. Then push it:", TELL_ME_REASON_BUTTON);
                    await new Promise(res => setTimeout(res, 200));

                    const sendReasonButtonResult = dispatchTapLike(send_reason_button);
                    if (!sendReasonButtonResult) {
                        console.warn("Can't push 'Tell us why' button");
                        return
                    }

                    console.debug("Wait for the checkbox to appear");
                    const REASON_DIALOG_SELECTOR = "tp-yt-paper-dialog";
                    const dialog_el = await waitForElement(REASON_DIALOG_SELECTOR);

                    const CHECKBOX_SELECTOR = "ytd-dismissal-follow-up-renderer div#content div#reasons ytd-dismissal-reason-text-renderer:nth-child(1) tp-yt-paper-checkbox:nth-child(1)";
                    const checkbox_el = await waitForElement(CHECKBOX_SELECTOR, dialog_el);
                    console.debug("click the checkbox:", checkbox_el);
                    dispatchTapLike(checkbox_el);

                    console.debug("Push the submit button");
                    const SUBMIT_BUTTON_SELECTOR = "ytd-dismissal-follow-up-renderer div#buttons ytd-button-renderer#submit"
                    const submit_button = await waitForElement(SUBMIT_BUTTON_SELECTOR, dialog_el);
                    const result = dispatchTapLike(submit_button);
                    showOverlay(result? 'Sent "Already Watched"':'Failed to send "Already Watched"');
                } catch (err) {
                    console.error("Error:", err);
                }
            })();
        }
        readBtn.addEventListener('click', function(ev) {
            onReadButtonClick(ev);
        });
    }

    // attach delete history button
    function attachDeleteHistoryButton(tile) {
        const tileClassList = tile.classList

        // Selector for 'Remove from watch history' icon
        var svgPathData = "M19 3h-4V2a1 1 0 00-1-1h-4a1 1 0 00-1 1v1H5a2 2 0 00-2 2h18a2 2 0 00-2-2ZM6 19V7H4v12a4 4 0 004 4h8a4 4 0 004-4V7h-2v12a2 2 0 01-2 2H8a2 2 0 01-2-2Zm4-11a1 1 0 00-1 1v8a1 1 0 102 0V9a1 1 0 00-1-1Zm4 0a1 1 0 00-1 1v8a1 1 0 002 0V9a1 1 0 00-1-1Z";
        var SVG_SELECTOR = `path[d="${svgPathData}"]`

        // add a custom 'Remove history' button
        const deleteBtn = document.createElement('button');
        deleteBtn.className = 'additional-btn delete-history-btn';
        const SVG_NS = "http://www.w3.org/2000/svg";
        const svg = document.createElementNS(SVG_NS, "svg");
        const path = document.createElementNS(SVG_NS, "path");
        path.setAttribute("d", "M12 1C5.925 1 1 5.925 1 12s4.925 11 11 11 11-4.925 11-11S18.075 1 12 1Zm0 2a9 9 0 018.246 12.605L4.755 6.661A8.99 8.99 0 0112 3ZM3.754 8.393l15.491 8.944A9 9 0 013.754 8.393Z");
        svg.appendChild(path);
        deleteBtn.appendChild(svg);
        if (tileClassList.contains("ytd-rich-item-renderer")) {
            // top page
            tile.parentElement.appendChild(deleteBtn);
        } else if (tileClassList.contains("ytd-item-section-renderer")) {
            // watch page
            tile.appendChild(deleteBtn);
        }

        // add event listener
        function onDeleteButtonClick(ev) {
            ev.preventDefault();
            ev.stopPropagation();
            const menuBtn = tile.querySelector(MENU_BUTTON_SELECTOR);
            if (!menuBtn) {
                console.warn('menu button not found');
                return;
            }

            // wait for menu to appear
            dispatchTapLike(menuBtn);

            // check if the menu is displayed
            waitForElement(MENU_SELECTOR).then(dropdown_el => {
                console.debug("dropdown_el:", dropdown_el)
                // Check if the target element has appeared
                waitForElement(SVG_SELECTOR, dropdown_el).then(svg_el => {
                    console.debug("svg_el:", svg_el)
                    const result = dispatchTapLike(svg_el.parentElement.parentElement)
                    if (result) {
                        showOverlay('Sent "Delete History"');
                    }
                });
            });
        };
        deleteBtn.addEventListener('click', function(ev) {
            onDeleteButtonClick(ev);
        });
    }

    // Attach custom buttons
    function attachButtons(tile, idx) {
        const tileRect = tile.getBoundingClientRect();

        if (!tile || tile.hasAttribute(PROCESSED_ATTR)) return;
        tile.setAttribute(PROCESSED_ATTR, '1');
        tile.style.position = 'relative';

        const pathName = location.pathname;

        if (pathName == "/" || pathName == "/watch") {
            attachNotInterestedInButton(tile);
            attachWatchedButton(tile);
        } else if (pathName == "/feed/history") {
            attachDeleteHistoryButton(tile);
        }
    }

    function attachUserFeedbackLink(targetElem) {
        function createCompactLink() {
            // const outerDiv = document.createElement("div");
            const a = document.createElement("a");
            a.style.justifyContent = "flex-start";
            a.href = "https://myactivity.google.com/page?utm_source=my-activity&hl=ja&page=youtube_user_feedback";
            a.rel = "nofollow";
            a.target = "_blank";
            a.className = "yt-spec-button-shape-next yt-spec-button-shape-next--text yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m yt-spec-button-shape-next--icon-leading yt-spec-button-shape-next--enable-backdrop-filter-experiment";
            a.setAttribute("aria-haspopup", "false");
            a.setAttribute("force-new-state", "true");
            a.setAttribute("aria-label", "すべての履歴を管理");
            a.setAttribute("aria-current", "false");
            a.setAttribute("aria-disabled", "false");

            // --- Icon wrapper ---
            const iconDiv = document.createElement("div");
            iconDiv.className = "yt-spec-button-shape-next__icon";
            iconDiv.setAttribute("aria-hidden", "true");

            const spanWrapper = document.createElement("span");
            spanWrapper.className = "ytIconWrapperHost";
            spanWrapper.style.width = "24px";
            spanWrapper.style.height = "24px";

            const iconShape = document.createElement("span");
            iconShape.className = "yt-icon-shape ytSpecIconShapeHost";

            const svgHolder = document.createElement("div");
            svgHolder.style.width = "100%";
            svgHolder.style.height = "100%";
            svgHolder.style.display = "block";
            svgHolder.style.fill = "currentcolor";

            const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
            svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
            svg.setAttribute("width", "24");
            svg.setAttribute("height", "24");
            svg.setAttribute("viewBox", "0 0 24 24");
            svg.setAttribute("focusable", "false");
            svg.setAttribute("aria-hidden", "true");
            svg.style.pointerEvents = "none";
            svg.style.display = "inherit";
            svg.style.width = "100%";
            svg.style.height = "100%";

            const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
            path.setAttribute("d",
                              "M12.844 1h-1.687a2 2 0 00-1.962 1.616 3 3 0 01-3.92 2.263 2 2 0 00-2.38.891l-.842 1.46a2 2 0 00.417 2.507 3 3 0 010 4.525 2 2 0 00-.417 2.507l.843 1.46a2 2 0 002.38.892 3.001 3.001 0 013.918 2.263A2 2 0 0011.157 23h1.686a2 2 0 001.963-1.615 3.002 3.002 0 013.92-2.263 2 2 0 002.38-.892l.842-1.46a2 2 0 00-.418-2.507 3 3 0 010-4.526 2 2 0 00.418-2.508l-.843-1.46a2 2 0 00-2.38-.891 3 3 0 01-3.919-2.263A2 2 0 0012.844 1Zm-1.767 2.347a6 6 0 00.08-.347h1.687a4.98 4.98 0 002.407 3.37 4.98 4.98 0 004.122.4l.843 1.46A4.98 4.98 0 0018.5 12a4.98 4.98 0 001.716 3.77l-.843 1.46a4.98 4.98 0 00-4.123.4A4.979 4.979 0 0012.843 21h-1.686a4.98 4.98 0 00-2.408-3.371 4.999 4.999 0 00-4.12-.399l-.844-1.46A4.979 4.979 0 005.5 12a4.98 4.98 0 00-1.715-3.77l.842-1.459a4.98 4.98 0 004.123-.399 4.981 4.981 0 002.327-3.025ZM16 12a4 4 0 11-7.999 0 4 4 0 018 0Zm-4 2a2 2 0 100-4 2 2 0 000 4Z"
                             );

            svg.appendChild(path);
            svgHolder.appendChild(svg);
            iconShape.appendChild(svgHolder);
            spanWrapper.appendChild(iconShape);
            iconDiv.appendChild(spanWrapper);

            // --- Button label ---
            const labelDiv = document.createElement("div");
            labelDiv.className = "yt-spec-button-shape-next__button-text-content";

            const labelSpan = document.createElement("span");
            labelSpan.className = "yt-core-attributed-string yt-core-attributed-string--white-space-no-wrap";
            labelSpan.setAttribute("role", "text");
            labelSpan.textContent = "Delete User Feedbacks";

            labelDiv.appendChild(labelSpan);

            // --- Touch feedback ---
            const touch = document.createElement("yt-touch-feedback-shape");
            touch.className = "yt-spec-touch-feedback-shape yt-spec-touch-feedback-shape--touch-response";
            touch.setAttribute("aria-hidden", "true");

            const stroke = document.createElement("div");
            stroke.className = "yt-spec-touch-feedback-shape__stroke";

            const fill = document.createElement("div");
            fill.className = "yt-spec-touch-feedback-shape__fill";

            touch.appendChild(stroke);
            touch.appendChild(fill);

            // --- assemble ---
            a.appendChild(iconDiv);
            a.appendChild(labelDiv);
            a.appendChild(touch);
            // outerDiv.append(a);

            return a;
        }

        targetElem.appendChild(createCompactLink());
    }

    function scanTargets() {
        // attach buttons
        document.querySelectorAll(TILE_SELECTOR).forEach((tile, idx) => attachButtons(tile, idx));

        // attach User Feedback Link into History page
        const pathName = location.pathname;
        if (pathName == "/feed/history") {
            const elem = document.querySelector("ytd-browse-feed-actions-renderer div#contents");
            if (!elem || elem.hasAttribute(PROCESSED_ATTR)) return;
            if (elem.children.length < 7) return;

            elem.setAttribute(PROCESSED_ATTR, '1');
            console.log("attachUserFeedbackLink");
            attachUserFeedbackLink(elem);
        }
    }
    new MutationObserver(scanTargets).observe(document.body, { childList: true, subtree: true });

})();