Giter VIP home page Giter VIP logo

userscript-supports's People

Contributors

cyfung1031 avatar sashaxser avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

sashaxser

userscript-supports's Issues

[YouTube EXPERIMENT_FLAGS Tamer Script] New flag destroying chat

Yesterday it seems some flag triggered on my account that completely breaks the live chat, creating an even worse memory leak that crashes the entire YouTube frame (even when embeded on mobile), but It only happens on my main and goes away if i switch channels. I found this script and while the full version didn't fix much, the basic variant removed the issue. Just two questions on this:

  • Would you be able to identify what flag is causing this new issue?
  • This script completely removes the emoji picker and autocomplete; I tried to debug myself with no luck, so would you perhaps know which flag is responsible for these?

Thank you for maintaining these, It's been really helpful!

data-code-url

adoption for data-code-url is pending to be added.

[YouTube Live Chat] Playback issue record

lcr = $('yt-live-chat-renderer')
replayQueue = lcr.replayBuffer_.replayQueue

(Ticked if fixed)

playerOffsetMs issue

  • issue "backward the timeline and then chat appearance get stopped" was resolved by youtube engineers in 2023(?)
  • &playerOffsetMs=XXX has been set for VODs with default collapsed live chat (sample link)
  • &playerOffsetMs=XXX has NOT been set for VODs with default expanded live chat (sample link)
  • playerOffsetMs would be the actual player's progress when the live chat get expanded, but if it is default expanded.. become a bug
  • replayQueue would have the initial data (by window.ytInitialData) when the live chat first loaded, but if the progress time from top window's player is far from that time, it will still keep and therefore those messages are fake.
    (e.g. progress = 80s, replayQueue is storing t=0s as ytInitialData is based on playerOffsetMs)
  • WTF is "yt-iframed-parent-ready". This looks reasonable but why no handling?

ticker animation issue

  • ticker animation do not have a proper mechanism for checking whether ticker shall animate or not.
  • the mechanism is simple and dumb - assume the video is playing and such that ticker appear must start countdown, and the animation will pause when the video is paused, then resume when video is resumed.
  • how can you assume the video is always playing? can't i just pause it and seek the progress? then the animation will automatically start WTF?
  • 2 obvious point to mention. first, if the chat is expanded when the video is paused, the status in iframe is always "video is playing". second, if the video is paused and then go backwards, there will be a seek continuation action so that the past tickers will be shown. the iframe already know it is paused but still start the animation without question.
  • the one by one adding by splice and then notify, make the entire page frozen when it is changed from background to foreground. (if there are many insertions and deletions during the time that the page is invisible)

ticker startime

ticker startime might not be the time when it is added to the dom tree.

  • delaying for batch rendering
  • the tickers at the t=0s are actually the tickers before the live show. therefore they will suddenly disappear as the engine only checks when it shall be disappear but without when it was started.

The extension doesn't work today (Restore YouTube Username from Handle to Custom)

I don't know why, but Restore YouTube Username from Handle to Custom stopped working on normal sessions.

Like this:

bullshphoto

Possibly something happened and well, it doesn't work.
Even on incognito stopped working.

I removed, restarted and even reinstalled it. Nothing happens.

Even restarted PC. Still nothing.

Is there any explanation and how to fix this problem? Thank you.

YouTube EXPERIMENT_FLAGS Tamer breaks video settings icons.

Specifically it's the KEEP_MIDDLEWAVE constant that when it's set most of the icons in the video settings menu disappear.
Setting it to false doesn't do anything, the line that sets it to true has to be commented out.

KEEP_MIDDLEWAVE uncommented:
image
KEEP_MIDDLEWAVE commented out:
image

It also seems to rename Ambient Mode to Cinematic Lighting and remove Annotations toggle.

Restore YouTube Username from Handle to Custom: Display username if user has no name

By default the script doesn't display anything if the person doesn't have a name, this is very inconvenient in comment sections, you can't know who is replying to whom, see example:

image

So I'd rather fallback to the username instead of just showing nothing.

I see that there is "Support for NO NAME (EXAMPLE)" in script's description, so this behavior is intended and you probably don't want to change the default to username fallback.

Then, could you please help me how I can modify the script to achieve this?
Even better would be introducing some kind of options.

[Enhancement] JS Tamper - List Renderer

!function() {

  // https://www.youtube.com/s/desktop/28b0985e/jsbin/desktop_polymer.vflset/desktop_polymer.js

  /*
  var Lx = function(a) {
    this.event = a
};
*/

/*

    if (window.ShadyDOM && window.ShadyDOM.inUse && window.ShadyDOM.noPatch && window.ShadyDOM.Wrapper) {
        var NUa = window.ShadyDOM.Wrapper
          , OUa = function() {  // MUa
            return NUa.apply(this, arguments) || this  
        };
*/
       

/*

CP = new WeakMap();

Ki = {
  cancelDebouncedJobMap: new WeakMap(),
  cancelThrottledJobMap: new WeakMap(),
}

*/


/*

// psudeo element
    function kD(a) {
        return a instanceof lD ? a : new lD(a)
    }

    */



    var addToPool = function(element) { // Fib
        const componentName = element.is;
        if (componentName) {
            let pool = Cib.get(componentName);
            if (!pool) {
                pool = [];
                Cib.set(componentName, pool);
            }
            const poolConfig = getConfigEntry("ELEMENT_POOL_CONFIG") || {};
            let poolCap = poolConfig[componentName];
            if (void 0 === poolCap) {
                poolCap = sl("ELEMENT_POOL_DEFAULT_CAP", 0);
            }
            if (pool.length < poolCap) pool.push(element);
        } else
            zq(new Cm("Element pool should only handle custom elements:",element.nodeName))
    }


  /**
   * @param {string} componentName
   * @param {Element} elementNode
   * @param {boolean} isCustomCreation
   * @return {undefined}
   */
  function removeRendererStamper(componentName, elementNode, isCustomCreation) { // zUb
    if (isCustomCreation) {
      if (elementNode.is) {
        if (DP.has(elementNode)) {
          let options = DP.get(elementNode);
          let item = options.listener;
          delete elementNode[options.property];
          if ("element" === item.type) {
            elementNode.removeEventListener(item.eventName, item.handler);
          } else {
            if ("polymer" === item.type) {
              elementNode.unlisten(elementNode, item.eventName, item.methodName);
            }
          }
          DP.delete(elementNode);
        }
        addToPool(elementNode);
      } else {
        if (elementNode.__proto__ == HTMLElement.prototype) {
          elementNode = new Cm("Rendererstamper removed a non custom element", "Stamper: " + componentName + " element: " + (elementNode && elementNode.nodeName));
          zq(elementNode);
        }
      }
    }
  }


  var ytConfigData = yt.config_; // ql

  /**
   * @param {Text} componentName
   * @param {Node} parentNode
   * @param {Object} node
   * @param {boolean} isCustomCreation
   * @return {undefined}
   */
  function remove(componentName, parentNode, node, isCustomCreation) { // AUb
    var root = parentNode.node ? parentNode.node : parentNode;
    if (kD(node).parentNode === root) {
      parentNode.removeChild(node);
      removeRendererStamper(componentName, node, isCustomCreation);
    }
    let handler = CP.get(node);
    if (handler) {
      CP.delete(node);
      Ki.cancelJob(handler);
    }
    /** @type {boolean} */
    node.hidden = false;
  }
  /**
   * @param {string} name
   * @param {boolean} def
   * @return {any}
   */
  function getConfigEntry(name, def) { // sl
    return name in ytConfigData ? ytConfigData[name] : def;
  }
  /**
   * @param {string} name
   * @param {boolean} def
   * @return {boolean}
   */
  function hasConfigEntry(name, def) { // tl
    return !!getConfigEntry(name, def);
  }
  /**
   * @param {Object} obj
   * @param {Object} context
   * @return {string | null}
   */
  function getObjectTag(obj, context) { // vUb
    var key;
    for (key in obj) {
      if (obj.hasOwnProperty(key) && context[key]) {
        return key;
      }
    }
    return null;
  }
  /**
   * @param {any} val
   * @return {?}
   */
  function isReusedVal(val) { // yUb
      if (void 0 === val) {
          if (H("kevlar_tuner_should_test_reuse_components")) {
              return H("kevlar_tuner_should_reuse_components");
          } else {
              return hasConfigEntry("REUSE_COMPONENTS", false);
          }
      }
    return  val || false;
  }
  /**
   * @param {string} componentName
   * @param {Element} parent
   * @param {number} idx
   * @param {boolean} isCustomCreation
   * @return {undefined}
   */
  function removeAfterChildIdx(componentName, parent, idx, isCustomCreation) { // BUb
    if (!parent) return;
    if (!parent.children) return;
    /** @type {Element} */
    var child = parent.children[idx];
    if (child) {
      if (hasConfigEntry("DEFERRED_DETACH")) {
        for (; child && !CP.has(child); child = child.nextElementSibling) {
          /** @type {Object} */
          var node = child;
          /** @type {boolean} */
          node.hidden = true;
          var pdataOld = Gm(Ki, remove.bind(null, componentName, parent, node, isCustomCreation), 0);
          CP.set(node, pdataOld);
        }
      } else {
        for (; (node = parent.lastElementChild);) {
          parent.removeChild(node);
          removeRendererStamper(componentName, node, isCustomCreation);
          if (node == child) break;
        }
      }
    }
  }
  /**
   * @param {EventTarget} target
   * @param {string} evtType
   * @param {any} detail
   * @param {Object} eventOptions
   * @return {?}
   */
  function dispatchCustomEvent(target, evtType, detail, eventOptions) { // Xz
    if (!eventOptions) {
      eventOptions = {
        bubbles : true,
        cancelable : false,
        composed : true
      };
    }
    if (null !== detail) {
      if (void 0 !== detail) {
        /** @type {number} */
        eventOptions.detail = detail;
      }
    }
    /** @type {CustomEvent} */
    evtType = new CustomEvent(evtType, eventOptions);
    target.dispatchEvent(evtType);
    return evtType;
  }
  /**
   * @param {Element} elem
   * @return {?}
   */
  var getDomApi = function(elem) { // Mx
    elem = elem || document;
    if (elem instanceof MUa) {
      return elem;
    }
    if (elem instanceof Lx) {
      return elem;
    }
    var obj = elem.__domApi;
    if (!obj) {
      if (elem instanceof Event) {
        obj = new Lx(elem);
      } else {
        obj = new MUa(elem);
      }
      elem.__domApi = obj;
    }
    return obj;
  };

  const stableListKey1 = "kevlar_tuner_should_test_maintain_stable_list";
  const stableListKey2 = "kevlar_should_maintain_stable_list";
  window.myFuncs = {
    /**
     * @param {(Array<>|null)} dataArray
     * @param {string} containerId
     * @param {Object} childComponents
     * @param {boolean} isCustomCreation
     * @param {boolean} toDispatchFinished
     * @param {boolean} isStableList
     * @return {undefined}
     */
    stampDomArray_ : function(dataArray, containerId, childComponents, isCustomCreation, toDispatchFinished, isStableList) {
      var container = this.getStampContainer_(containerId);
      if (container) {
        let nativeElement = getDomApi(container)
        isCustomCreation = isReusedVal(isCustomCreation)
        if (dataArray) {
          /** @type {number} */
          let counter = 0;
          /** @type {number} */
          var idx = 0;
          var child;
          if (void 0 === isStableList) {
            isStableList = H(stableListKey1) ? H(stableListKey2) : hasConfigEntry("STAMPER_STABLE_LIST", false)
          } else {
            isStableList = isStableList || false;
          }
          if (isStableList) {
            for (child = nativeElement.firstElementChild;child && (!CP.has(child) && dataArray.length > idx);) {
              let dataEntry = dataArray[idx];
              let objectTag = getObjectTag(childComponents, dataEntry);
              if (objectTag) {
                var componentName = this.getComponentName_(childComponents[objectTag], dataEntry[objectTag])
                if (componentName != child.is) {
                  var node = this.createComponent_(childComponents[objectTag], dataEntry[objectTag], isCustomCreation);
                  var nextElm = getDomApi(child).nextElementSibling;
                  if (nextElm) {
                    nativeElement.insertBefore(node, nextElm);
                  } else {
                    nativeElement.appendChild(node);
                  }
                  remove(this.is, nativeElement, child, isCustomCreation);
                  child = node;
                } else {
                  this.telemetry_.reuse++;
                }
                this.deferRenderStamperBinding_(child, childComponents[objectTag], dataEntry[objectTag]);
                counter++;
                idx++;
                child = getDomApi(child).nextElementSibling;
              } else {
                idx++;
              }
            }
          }
          removeAfterChildIdx(this.is, nativeElement, counter, isCustomCreation);
          let childElement = child;
          if (dataArray.length > idx) {
            /** @type {DocumentFragment} */
            let newFragment = document.createDocumentFragment();
            /** @type {number} */
            let fragmentListCount = dataArray.length;
            for (;idx < fragmentListCount;idx++) {
              let oldFragment = dataArray[idx]
              const objectTag = getObjectTag(childComponents, oldFragment)
              if (objectTag) {
                child = this.createComponent_(childComponents[objectTag], oldFragment[objectTag], isCustomCreation);
                this.deferRenderStamperBinding_(child, childComponents[objectTag], oldFragment[objectTag]);
                newFragment.appendChild(child);
              }
            }
            if (childElement && (getDomApi(childElement).parentNode && (child && !CP.has(child)))) {
              nativeElement.insertBefore(newFragment, childElement);
            } else {
              nativeElement.appendChild(newFragment);
            }
          }
          this.flushRenderStamperComponentBindings_();
          if (this.markDirty) {
            this.markDirty();
          }
          if (toDispatchFinished) {
            dispatchCustomEvent(this.hostElement, "yt-rendererstamper-finished", {
              container : container
            });
          }
        } else {
          removeAfterChildIdx(this.is, nativeElement, 0, isCustomCreation);
        }
      } else {
        yq(new Cm("Container object not found", containerId, this.hostElement ? this.hostElement.is : ""));
      }
    }
  };
}();

Deferred Message makes the chat message disappeared

Why?

https://greasyfork.org/scripts/469878-youtube-super-fast-chat/discussions/197267

img

Screen Shot 2023-08-17 at 4 29 09
'use strict';

(() => {

    function z(inputValue) {
        inputValue = yl(inputValue);
        if (inputValue === "false") {
            return false;
        }
        return !!(inputValue);
    }

    function lq(a) {
        kq(a, "WARNING")
    }

    const Ls = function (element = document) {
        if (element instanceof Js) {
            return element;
        }
        if (element instanceof Is) {
            return element;
        }
        
        let domApi = element.__domApi;
        
        if (!domApi) {
            domApi = element instanceof Event ? new Is(element) : new Js(element);
            element.__domApi = domApi;
        }
        
        return domApi;
    };

    const uE = new WeakMap;
    const vE = new WeakMap;
    function ZHa(objectA, objectB) {
        for (const property in objectA) {
            if (objectA.hasOwnProperty(property) && objectB[property]) {
                return property;
            }
        }
        return null;
    }
    function aIa(reuseComponentsFlag) {
        if (typeof reuseComponentsFlag === "undefined") {
            if (z("kevlar_tuner_should_test_reuse_components")) {
                return z("kevlar_tuner_should_reuse_components");
            }
            return ll("REUSE_COMPONENTS", false);
        }
        return reuseComponentsFlag || false;
    }
    function bIa(typeOfElement, childrenElement, reuseComponentsFlag) {
        reuseComponentsFlag && (childrenElement.is ? (vE.has(childrenElement) && (typeOfElement = vE.get(childrenElement),
        reuseComponentsFlag = typeOfElement.listener,
        delete childrenElement[typeOfElement.property],
        "element" === reuseComponentsFlag.type ? childrenElement.removeEventListener(reuseComponentsFlag.eventName, reuseComponentsFlag.handler) : "polymer" === reuseComponentsFlag.type && childrenElement.unlisten(childrenElement, reuseComponentsFlag.eventName, reuseComponentsFlag.methodName),
        vE.delete(childrenElement)),
        GC(childrenElement)) : childrenElement.__proto__ == HTMLElement.prototype && (childrenElement = new tm("Rendererstamper removed a non custom element","Stamper: " + typeOfElement + " element: " + (childrenElement && childrenElement.nodeName)),
        lq(childrenElement)))
    }
    function cIa(typeOfElement, domContainer, childrenElement, reuseComponentsFlag) {
        const node = domContainer.node ? domContainer.node : domContainer;
        if (Ls(childrenElement).parentNode == node) {
            domContainer.removeChild(childrenElement);
            bIa(typeOfElement, childrenElement, reuseComponentsFlag);
        }
        let timeoutId = uE.get(childrenElement);
        if (timeoutId) {
            uE.delete(childrenElement);
            xi.cancelJob(timeoutId);
        }
        childrenElement.hidden = false;
    }

    function dIa(typeOfElement, domContainer, index, reuseComponentsFlag) {
        if (domContainer && domContainer.children) {
            let childrenElement = domContainer.children[index];
            if (childrenElement) {
                if (ll("DEFERRED_DETACH")) {
                    while (childrenElement && !uE.has(childrenElement)) {
                        const e = typeOfElement;
                        const h = domContainer;
                        const l = childrenElement;
                        const m = reuseComponentsFlag;
                        l.hidden = true;
                        const timeoutId = Bm(0, cIa.bind(null, e, h, l, m), 0);
                        uE.set(l, timeoutId);
                        childrenElement = childrenElement.nextElementSibling;
                    }
                } else {
                    let element;
                    while (element = domContainer.lastElementChild) {
                        domContainer.removeChild(element);
                        bIa(typeOfElement, element, reuseComponentsFlag);
                        if (element === childrenElement) break;
                    }
                }
            }
        }
    }

    window.p301 = {
        Ls,
        aIa
    };

    window.q301 = {
        stampDomArray_: function (inputArray, containerId, pivotEntry, reuseComponentsFlag, fireEvent, maintainStableListFlag) {
            let container = this.getStampContainer_(containerId);

            if (container) {
                const domContainer = Ls(container);
                reuseComponentsFlag = aIa(reuseComponentsFlag);

                if (inputArray) {
                    let currentIndex = 0;
                    let arrayIndex = 0;
                    let currentNode;
 
                    let isMaintainStableListFlag = maintainStableListFlag === undefined ? z("kevlar_tuner_should_test_maintain_stable_list") ? z("kevlar_should_maintain_stable_list") : !!ll("STAMPER_STABLE_LIST", false) : maintainStableListFlag || false;

                    if (isMaintainStableListFlag) {
                        currentNode = domContainer.firstElementChild;
                        
                        while (currentNode && !uE.has(currentNode) && inputArray.length > arrayIndex) {
                            const currentEntry = inputArray[arrayIndex];
                            const extractedData = ZHa(pivotEntry, currentEntry);

                            if (extractedData) {
                                const componentName = this.getComponentName_(pivotEntry[extractedData], currentEntry[extractedData]);
                                if (componentName !== currentNode.is) {
                                    const newNode = this.createComponent_(pivotEntry[extractedData], currentEntry[extractedData], reuseComponentsFlag);
                                    const nextSiblingNode = Ls(currentNode).nextElementSibling;
                                    
                                    if (nextSiblingNode) {
                                        domContainer.insertBefore(newNode, nextSiblingNode);
                                    } else {
                                        domContainer.appendChild(newNode);
                                    }
                                    cIa(this.is, domContainer, currentNode, reuseComponentsFlag);
                                    currentNode = newNode;
                                } else {
                                    this.telemetry_.reuse++;
                                }
                                this.deferRenderStamperBinding_(currentNode, pivotEntry[extractedData], currentEntry[extractedData]);
                                currentIndex++;
                                arrayIndex++;
                                currentNode = Ls(currentNode).nextElementSibling;
                            } else {
                                arrayIndex++;
                            }
                        }
                    }
                    dIa(this.is, domContainer, currentIndex, reuseComponentsFlag);
                    const subsequentNode = currentNode;

                    if (inputArray.length > arrayIndex) {
                        const fragment = document.createDocumentFragment();
                        
                        for (; arrayIndex < inputArray.length; arrayIndex++) {
                            const currentValue = inputArray[arrayIndex];
                            const extractedValue = ZHa(pivotEntry, currentValue);
                            if (extractedValue) {
                                currentNode = this.createComponent_(pivotEntry[extractedValue], currentValue[extractedValue], reuseComponentsFlag);
                                this.deferRenderStamperBinding_(currentNode, pivotEntry[extractedValue], currentValue[extractedValue]);
                                fragment.appendChild(currentNode);
                            }
                        }

                        if (subsequentNode && Ls(subsequentNode).parentNode && currentNode && !uE.has(currentNode)) {
                            domContainer.insertBefore(fragment, subsequentNode);
                        } else {
                            domContainer.appendChild(fragment);
                        }
                    }
                    this.flushRenderStamperComponentBindings_();

                    if (this.markDirty) {
                        this.markDirty();
                    }
                    if (fireEvent) {
                        Au(this.hostElement, "yt-rendererstamper-finished", { container: container });
                    }
                } else {
                    dIa(this.is, domContainer, 0, reuseComponentsFlag);
                }
            } else {
                kq(new tm("Container object not found", containerId));
            }
        }
    };
})();

Feature request: disable auto-pause on music.youtube.com

Hi, I found that auto-pause on music.youtube.com could be annoying. Could you please support the disable auto-pause feature on that domain? Simply adding the domain to this plugin's support list doesn't work. Maybe they are using different mechanisms? Thanks in advance.

[YouTube Super Fast Chat] Incompatible with BetterStreamChat's latest version - setting addition

Bug to be fixed.

// ==UserScript==
// @name        Testing Script 186
// @namespace   Violentmonkey Scripts
// @match       https://www.youtube.com/live_chat*
// @grant       none
// @version     1.0
// @author      -
// @description 8/19/2023, 11:41:39 PM
// @run-at              document-start
// @grant               none
// @unwrap
// @allFrames           true
// @inject-into         page
// ==/UserScript==

(() => {
  'use strict';

  const updateFlags = () => {
    const EXPERIMENT_FLAGS = (window.ytcfg && window.ytcfg.data_) ? window.ytcfg.data_.EXPERIMENT_FLAGS : null;
    if (!EXPERIMENT_FLAGS) return;
    Object.assign(EXPERIMENT_FLAGS, {
      kevlar_tuner_should_test_maintain_stable_list: true,
      kevlar_should_maintain_stable_list: true
    });
  };

  const mo = new MutationObserver(updateFlags);
  mo.observe(document, { subtree: true, childList: true });

  updateFlags();

})();

Remarks

Tested that it is not a bug in YouTube Super Fast Chat.
Opened an issue in derpierre65/BetterStreamChat#26


Pending new version publishing in Chrome Store

not working

i still get popup "Video paused. Continue watching?"

the tab was not focused after the video in the playlist ended, could this be the reason?

running Disable YouTube AutoPause v2022.12.28.1 on violent monkey on latest brave

Restore YouTube Username from Handle to Custom: Not working in Desktop Firefox when logged in

I suppose it is the same cause as yakisova41/return-youtube-comment-username#43, with its corresponding fix yakisova41/return-youtube-comment-username@8da40a3.

The script would not work on desktop Firefox when logged in. It works properly when not logged in on Firefox or if using chromium based browsers either logged in or not. No request is made to fetch the username in the Network tab, but I do not see any extra error messages either.

Reproduction Steps

  1. Create a new profile in Firefox, load in TamperMonkey/ViolentMonkey and your script from GreasyFork.
  2. Open www.youtube.com and pick a video, better pause once the video is loaded but not required.
  3. Scroll down and YouTube comments should have usernames, new browser?key= requests would appear if Network tab is open.
  4. Log in to YouTube, and return to the same video.
  5. Scroll down and YouTube comments should have handles, new browser?key= requests would not appear if Network tab is open.

Versions Tested

  • v0.5.7 to v0.5.10 (Firefox 114.0.2/TamperMonkey v4.18.1)
  • V0.5.10 (Firefox 114.0.2/ViolentMonkey v2.14.0)
  • v0.5.10 to v0.5.14 (Librewolf 110.0.1/ViolentMonkey v2.14.0)

[YouTube JS Engine Tamper] Delayed Animating Rolling Number Issue

Setting related: FIX_avoid_incorrect_video_meta

Related Functions:

  • yt-app.sendServiceAjax_
  • yt-app.getCancellableNetworkPromise_
  • ytd-video-primary-info-renderer.fetchUpdatedMetadata
screen-capture-14-reformatted-html5ified-slowest-000003725-000013524_Zl64F0is.mp4

Need to find a better way to cancel the timer once yt-navigate-start / yt-navigate-cache is triggered.

Currently I just use the url to detect which is not sufficient. (url != watch => bypass)

bug

Leetcode部分题目模板代码复制时出现复制不完整的情况: 如https://leetcode.cn/problems/implement-queue-using-stacks/
还原到默认的代码模板后,复制,粘贴时变成

class MyQueue {
public:
MyQueue() {

}

void push(int x) {

}

… */
后半部分内容丢失且变成"..."

Google Docs

If copy is disabled in google docs it still doesnt work

Documentation for "youtube-video-resize-fix"

Hi @cyfung1031 👋
I'm a contributor to a YouTube extension (ImprovedTube) and some months ago I developed a feature to swap the comments and videos sections.
May-27-2023 12-49-11

I encountered an annoying bug that made the video appear smaller than the player itself for whatever reason so I did a pretty rudimental code (Observers and inline width)

I'm now using your neat script instead of my temporary solution and I have to admit it's working well. I'm asking if you could add documentation of the script or a brief explanation. As far as I understand this allows the YouTube player to trigger resizeEvent by reading the values of the changed CSS instead of the native one.
Also, if you don't mind, let's connect on Discord 🥹 (I'm D_Rekk there)

[YouTube Super Fast Chat] TODO: Tickers Data & Rendering Issues

In Pressure Test, huge addition+deletion of tickers will freeze the browser.

yt-live-chat-ticker-renderer's


  • handleLiveChatAction
  • handleLiveChatActions

  • removeTickerItemById

  • _itemsChanged
  • itemsChanged

  • handleMarkChatItemAsDeletedAction
  • handleMarkChatItemsByAuthorAsDeletedAction
  • handleRemoveChatItemByAuthorAction

to be reviewed.

[YouTube JS Engine Tamer] About Dialog doesn't to show Contents

When trying to view channel's about dialog, only the header of the dialog appears.

about dialog bug

Setting ENABLE_discreteTasking to false seems to fix the issue.


Reproduction Steps:

  1. Go to an about page of any YouTube channel.
  2. Click the Tag Line (channel-tagline) to display the dialog

Issue 1. YouTube JS Engine Tamer makes content disappear.
Issue 2. YouTube EXPERIMENT_FLAGS Tamer makes no dialog by clicking the tagline.

[YouTube Super Fast Chat] [Record Purpose] Waiting Firefox to support `@property`

CodePen - Down the Rabbit Hole (with Web Animations API)

@property --ticker-rtime {
	syntax: "<percentage>";
	inherits: false;
	initial-value: 0%;
}

@keyFrames tickerAnimation {
	0% {
		--ticker-rtime: 40%;
	}
	100% {
		--ticker-rtime: 60%;
	}
}

[class] {
	--ticker-c1:rgba(144, 0, 0, 0.07);
	--ticker-c2:rgba(155, 0, 0, 0.06);
	animation: tickerAnimation 3ms forwards;
	--ticker-dtime:50%;    

/* OK in FF */

/*    background:linear-gradient(90deg, var(--ticker-c1),var(--ticker-c1) var(--ticker-dtime),var(--ticker-c2) var(--ticker-dtime),var(--ticker-c2)) !important; */

/* NG in FF */

/*    background:linear-gradient(90deg, var(--ticker-c1),var(--ticker-c1) var(--ticker-rtime),var(--ticker-c2) var(--ticker-rtime),var(--ticker-c2)) !important; */
}

  

Added detection code in v0.23.8 to avoid using in Firefox 116 Stable.

Details see:
https://stackoverflow.com/questions/69612853/using-css-can-i-check-if-a-browser-supports-the-css-properties-and-values-api/76937664#76937664

jsFiddle:
https://jsfiddle.net/lunarlogic489/xtb8que7/6/

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.