Use rendered widths when inline reaction wrappers report non-numeric computed widths or zero client widths. Preserve existing block-control measurements in the extension and userscript, with generated-artifact browser regression coverage.
Add Firefox data consent, repair contributor sign-in, and introduce optional Hide clutter buttons. Harden video navigation, voting, and action layouts with shared browser regression coverage and reproducible release packaging.
Harden Shorts controls, reaction state, and navigation; share voting logic
with the extension; improve ratio-bar rendering; and add comprehensive Jest,
Playwright, artifact, and live-browser regression coverage.
Here's a description you could use for a commit message, PR, or changelog entry:
Harden button-lookup functions against missing/changed DOM elements
getButtons(), getLikeButton(), and getDislikeButton() previously assumed YouTube's like/dislike DOM structure was always present and would throw a TypeError (e.g. "Cannot read properties of null/undefined") whenever the expected elements weren't found — for example during early page load, mid-navigation, or after a YouTube layout change breaks a selector.
Changes:
getLikeButton() / getDislikeButton() now cache a single getButtons() result per call instead of invoking it multiple times within the same expression, avoiding inconsistent reads if the DOM mutates between calls, and return null early if getButtons() itself returns nothing.
Audited all direct callers of these three functions and added ?. / early-return guards where a null return wasn't already handled: isVideoLiked, isVideoNotLiked, getLikeTextContainer, setLikes on the like side; mobile isVideoDisliked, and getDislikeTextContainer's fallback branch on the dislike side (both previously used ?. on the outer button but still dereferenced a possibly-null nested querySelector("button") result unguarded).
Fixed getDislikeTextContainer short-circuiting to undefined instead of null when dislikeButton is missing, which meant its result === null fallback check never triggered and it could try appending to a null button.
Fixed setDislikes checking _container?.innerText !== dislikesCount (safe) but then assigning _container.innerText = ... unguarded in the branch body, which still threw when _container was null.
No behavior change when the expected elements are present — this only prevents uncaught exceptions when they're not, letting the existing polling loop (checkForJS_Finish, 111ms interval) retry on the next tick instead of the script erroring out.
* Added Option to Disable Logging By Default
* Added Userscript Support to Disable Logging
* Formatting and Fixed Compiling
* Updated Description of Setting Option
* Whitespace 😅
* Dot in Description of Setting option
* Typo in JAVASCRIPT
* Userscript - new (spring 2024) UI support
Add new player selector for isVideoLoaded() (fixes#1043)
* Githook tasks for 17f5bdf0 (in a separate commit for readability)
* Fix disappearing dislike counter - userscript
* Fix rate bar in userscript, disable it by default (it has been broken for ages)
* Fix event listeners being thrown away by YouTube in some cases
* Fix disappearing dislike count on button focus/unfocus
* Remove repetitive code from the userscript
* Userscript fix for disappearing dislikes while smartimations play
* Check if smartimationContainer exists
* Properly handle non-existing dislike button
In some cases, dislike button doesn't exist when we're trying to
interact with it. For end users, it manifested as dislike counter
appearing on both dislike button and share button (because
getDislikeButton was falling back to the second child of getButtons()).
I don't see an elegant way of fixing this without creating a fake button
in DOM specifically for this case or rewriting the whole userscript.
Ignoring this would result in errors appearing in console.
---------
Co-authored-by: Felix Nguyen <kokonguyen191@gmail.com>
The dislike number text got disabled whenever we clicked on the dislike button, it was because the addEventListener wasn't being attached to the correct like and dislike buttons (new).
Tested in chrome windows 11, version: 107.0.5304.107
In certain cases (see issue #741), the like/dislike buttons would be considered IN the viewport, despite its parent elements being hidden and its DOMRect being 0 on all sides. This way, added an additional check for considering these "hidden" buttons as NOT in the Viewport.
When like button is clicked, YT will update like count. This conflicts with user option "re-format like numbers". Force update like number.
attn #561#584