return-youtube-dislike
return-youtube-dislike copied to clipboard
(Bug): "Dislike" is not replaced by the dislike count
Browser
Cent Browser
Browser Version
Chromium 86
Extension or Userscript?
Userscript
Extension/Userscript Version
3.0.1
Video link where you see the problem
any
What happened?
No dislike count is shown, just "Dislike".
How to reproduce/recreate?
Open any video. The console shows "Received Count", but the "Dislike" text is not replaced.
The issue wasn't there yesterday, and the html structure appears unchanged.
Manually executing the code leads to document.getElementById("menu-container")?.querySelector("#top-level-buttons-computed").children[1]
returning a valid element, eg:
<ytd-toggle-button-renderer class="style-scope ytd-menu-renderer force-icon-button style-text" use-keyboard-focused="" system-icons="" button-renderer="true" style-action-button="" is-icon-button=""><a class="yt-simple-endpoint style-scope ytd-toggle-button-renderer" tabindex="-1"><yt-icon-button id="button" class="style-scope ytd-toggle-button-renderer style-text"><!--css-build:shady--><button id="button" class="style-scope yt-icon-button" aria-label="Dislike this video" aria-pressed="false"><yt-icon class="style-scope ytd-toggle-button-renderer"><svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope yt-icon" style="pointer-events: none; display: block; width: 100%; height: 100%;"><g class="style-scope yt-icon"><path d="M17,4h-1H6.57C5.5,4,4.59,4.67,4.38,5.61l-1.34,6C2.77,12.85,3.82,14,5.23,14h4.23l-1.52,4.94C7.62,19.97,8.46,21,9.62,21 c0.58,0,1.14-0.24,1.52-0.65L17,14h4V4H17z M10.4,19.67C10.21,19.88,9.92,20,9.62,20c-0.26,0-0.5-0.11-0.63-0.3 c-0.07-0.1-0.15-0.26-0.09-0.47l1.52-4.94l0.4-1.29H9.46H5.23c-0.41,0-0.8-0.17-1.03-0.46c-0.12-0.15-0.25-0.4-0.18-0.72l1.34-6 C5.46,5.35,5.97,5,6.57,5H16v8.61L10.4,19.67z M20,13h-3V5h3V13z" class="style-scope yt-icon"></path></g></svg><!--css-build:shady--></yt-icon></button><yt-interaction id="interaction" class="circular style-scope yt-icon-button"><!--css-build:shady--><div class="stroke style-scope yt-interaction"></div><div class="fill style-scope yt-interaction"></div></yt-interaction></yt-icon-button><yt-formatted-string id="text" class="style-scope ytd-toggle-button-renderer style-text">Dislike</yt-formatted-string></a></ytd-toggle-button-renderer>
but executing .querySelector("#text")
on it returns null.
In a tab that was open before the issue appeared, .querySelector("#text")
returns the text element as expected.
<yt-formatted-string id="text" class="style-scope ytd-toggle-button-renderer style-text">Dislike</
It's right there. querySelector
should not give you null
. Something went wrong.
Did you try refreshing the page by clicking the circle-arrow button? Or open the same URL in a new tab?
Sometimes youtube decides not to reload the entire page for a new video, causing a lot of pain.
See https://github.com/Anarios/return-youtube-dislike/issues/645#issuecomment-1152774324
I did try all that, even opening youtube in an incognito window didn't change that strange behavior...
When I assign document.getElementById("menu-container")?.querySelector("#top-level-buttons-computed").children[1]
to a variable x
, copy the element with right-click and assign it to x.innerHTML
, x.querySelector("#text")
no longer returns null.
Does that make any sense to you?
edit:
and document.getElementById("menu-container")?.querySelector("#top-level-buttons-computed").children[1].querySelector("#text")
also correctly returns the text element after I reassign innerHTML...
It does not. I've never seen querySelector
malfunctions like that. It seems your first result (in x
) is incorrect.
Browser
Browser Version
Chromium 86
Did you try with a newer browser? Just run the code manually, no need to install extension or log in for now
The browser I'm using has no newer version available atm, but the strange thing it that it was working until now, and tabs that were not reloaded since yesterday still continue to show the correct behavior...
Firefox 101 does not show this issue for me.
I mean, it sucks it happened to you, but it can't be recreated by following certain steps, and it doesn't sound like an obvious oversight in our extension. Somehow query selector quit working. Maybe someone else here who's more familiar can help you?
After a browser restart, the issue persists.
I noticed there were 2 other suggestions when I typed in element.querySelector
: __shady_querySelector
and __shady_native_querySelector
. The former 2 don't appear to work, while the last returns the text element properly. I set up my script like this now:
function setDislikes(dislikesCount) {
if (isMobile) {
mobileDislikes = dislikesCount;
return;
}
var txt = getButtons().children[1].querySelector("#text");
if(txt === null){
txt = getButtons().children[1].__shady_querySelector("#text");
}
if(txt === null){
txt = getButtons().children[1].__shady_native_querySelector("#text");
}
if(txt === null){
cLog("3rd try failed...")
return
}
txt.innerText = dislikesCount;
}
which fixes the issue, but the question remains where the replacement of the querySelector method with a disfunctional one comes from. Am I hit by early A/B testing targeting sponsorblock, or could this be another benign script that is malfunctioning?
__shady_native_queryselector
gives just 18 google results, __shady_queryselector
19...
the method replacement appears to happen in webcomponents-sd.js
, loaded from https://www.youtube.com/s/desktop/1422277c/jsbin/webcomponents-sd.vflset/webcomponents-sd.js
.
In firefox, these methods also exist, but querySelector
and __shady_native_querySelector
both work correctly. The __shady_querySelector
returns null in firefox as well.
apparently related: https://web.dev/shadowdom-v1/ https://www.polymer-project.org/blog/shadydom
I don't really know what to do with this information to find out why this specific tag was affected the way it was though...
What about this? https://github.com/Polymer/polymer/issues/4172
Polymer.dom(document.getElementById("menu-container")?.querySelector("#top-level-buttons-computed").children[1])['node'].querySelector('#text')
What about this? Polymer/polymer#4172
Polymer.dom(document.getElementById("menu-container")?.querySelector("#top-level-buttons-computed").children[1])['node'].querySelector('#text')
This also returns null. Replacing querySelector with __shady_native_querySelector makes it return the correct element, just as without the Polymer.dom function.
getElementsByTagName("yt-formatted-string")[0]
also works in place of querySelector...
Seems to me to be a bug in the old version. Do we need backward compatibility?
https://en.wikipedia.org/wiki/Google_Chrome_version_history
90.0.4430 2021-04-14 A new way to implement and use Shadow DOM directly in HTML 86.0.4240 2020-10-06
http://www.centbrowser.com/history.html
v4.3.9.226 [2020-12-08] Upgraded to Chromium 86.0.4240.198
https://polymer-library.polymer-project.org/1.0/docs/release-notes#v-1-7-1
Release 1.7.1 (2016-12-14)
this is the first version after https://github.com/Polymer/polymer/issues/4172 No commits were linked to this issue. Perhaps it's only the Chrome change leading to your problem @shadoxxhd
https://github.com/Polymer/polymer/blob/master/CHANGELOG.md v3.3.1 (2019-11-08)
Make Closure compiler happier about ShadyDOM access (commit)
(not sure if this commit is related, but it's the last version before Chrome 90)
The strange thing is that until 5 days ago, everything was working properly, to the point where in unreloaded tabs querySelector did return the correct element instead of null, and in new tabs it didn't. And I can't imagine a browser bug being present only in some tabs...
And to me it doesn't seem too likely that either of these changes could be the reason for the strange selector behavior (I'm not a JS/web developer though, so take my impression with a grain of salt)...
Didn't the Polymer.dom()
test disprove https://github.com/Polymer/polymer/issues/4172 being the issue?
About backward compatibility, the question seems to be whether getElementsByTagName("yt-formatted-string")[0]
would have any downsides compared to querySelector("#text")
. If backwards compatability doesn't come with any performance cost, I think it is generally a good idea. Otherwise, just reference this issue if someone else has the same problem as I had...
Since this isn't really a bug and more of a rare edge case (and whatever the underlying bug is, it is nothing to do with RYD), I wouldn't mind if you want to close this issue as irrelevant.
edit or is it? I don't think it's certain yet that this isn't some A/B test that changes the like/dislike buttons to be in shady/shadow DOM... so what would be the best way to check for that?
I can't imagine a browser bug being present only in some tabs...
bitakshat — 6:08 PM UTC Hi, I'm working on a firefox extension to calculate video playback time for youtube. The extension works fine when its loaded on tab with youtube for the first time. When I open multiple youtube tabs it only works for the recent tab. How can I fix this? (its been a while since I'm working on this extension I've tried the most I can but still can't figure out. So I randomly joined this server. sorry If I'm in the wrong server or wrong channel. I just need some help)
source: https://discord.com/channels/909435648170160229/909435648665071660/993941459441037362
related?
related?
I don't think so, since multiple tabs were working before, and now the issue seems to be present in all tabs (certainly also in the most recent one).
quick question: do you open a new tab and immediately see it? or do you open a new tab "in background" first, and then immediately switch to it?
The strange thing is that until 5 days ago, everything was working properly
I agree, this is very strange. If I insist on the backward compatibility bug as the reason, I can argue that youtube recently made some changes in shady doms, and that triggered the old bug in the old browser version.
Why do they make it so complicated. I don't get it. It's a waste of time. That means they are paying people to do unnecessary work.
Maybe we can try this for now:
https://github.com/Anarios/return-youtube-dislike/blob/16b1c2ccf0ac7d419ae1df40bdd313234557807f/Extensions/combined/src/buttons.js#L39
Insert two new functions:
getLikeTextContainer() {
return getLikeButton().querySelector("#text") ?? getLikeButton().getElementsByTagName("yt-formatted-string")[0]
}
getDislikeTextContainer() {
return getDislikeButton().querySelector("#text") ?? getDislikeButton().getElementsByTagName("yt-formatted-string")[0]
}
Nullish coalescing prevents "0" being interpreted as invalid container
https://github.com/Anarios/return-youtube-dislike/blob/16b1c2ccf0ac7d419ae1df40bdd313234557807f/Extensions/combined/src/state.js#L124 change to:
getLikeTextContainer().innerText = likesCount;
https://github.com/Anarios/return-youtube-dislike/blob/16b1c2ccf0ac7d419ae1df40bdd313234557807f/Extensions/combined/src/state.js#L135 change to:
getDislikeTextContainer().innerText = dislikesCount;
https://github.com/Anarios/return-youtube-dislike/blob/16b1c2ccf0ac7d419ae1df40bdd313234557807f/Extensions/combined/src/state.js#L206 change to:
getDislikeTextContainer().innerText = localize(
I can't imagine a browser bug being present only in some tabs...
bitakshat — 6:08 PM UTC Hi, I'm working on a firefox extension to calculate video playback time for youtube. The extension works fine when its loaded on tab with youtube for the first time. When I open multiple youtube tabs it only works for the recent tab. How can I fix this? (its been a while since I'm working on this extension I've tried the most I can but still can't figure out. So I randomly joined this server. sorry If I'm in the wrong server or wrong channel. I just need some help)
source: https://discord.com/channels/909435648170160229/909435648665071660/993941459441037362
related?
As far as I can see, no. The cited extension has its own bad practices (many) causing problems. Shady DOMs is their last concern.
quick question: do you open a new tab and immediately see it? or do you open a new tab "in background" first, and then immediately switch to it?
I tried it early on on tabs that were loaded in the background as well as some that were reloaded/URL-pasted in new tab. The issue occured in all cases.
Maybe we can try this for now:
That looks like it would fix the issue; I personally used the .__shady_native_querySelector("#text")
as a fallback in my private tampermonkey script, but don't know which would be more stable and/or performant.
I wouldn't trust "undocumented" APIs (it's "shady" anyway) since one day or another it will change, and time spent now fixing it will become wasted.
I can confirm now that it is some sort of A/B test - when not logged in, the incognito tab behaved correctly (as in querySelector
returning the element) on multiple video pages, but as soon as I log in it starts returning null
.
Even on current firefox, when I am logged in querySelector returns null
, so it has nothing to do with browser/version.
Wow thank you @shadoxxhd This issue has been so long. For now, we can implemented the changes from above, until this A/B testing ends and whatever version is to be used from then on.
I started experiencing this issue recently, on both Chrome 105.0.5148.2 and Edge 103.0.1264.49.
I'm using version 3.0.1 of the userscript and had the same symptoms: Dev Tools console shows Return Youtube Dislike successfully setting up, registering button listeners, fetching votes and the received count, immediately followed by a TypeError: Cannot set properties of null (setting 'innerText')
.
I also tried an incognito tab, without logging to my account, but the issue persisted, so I'm not sure if whatever YouTube change that broke the extension still is in A/B testing or if it started rolling out widely now...
Also Firefox 102.0.1 / Userscript 3.0.1 from GreasyFork
With every video
01:45:46.677 [Return YouTube Dislikes] Received count: 54 2 Return YouTube Dislike.user.js:50:11
01:45:46.688 Uncaught (in promise) TypeError: getButtons().children[1].querySelector(...) is null
setDislikes moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/ Return YouTube Dislike.user.js#5:197
setState moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/ Return YouTube Dislike.user.js#5:325
promise callback*setState/< moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/ Return YouTube Dislike.user.js#5:319
promise callback*setState moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/ Return YouTube Dislike.user.js#5:318
setInitialState moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/ Return YouTube Dislike.user.js#5:399
checkForJS_Finish moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/ Return YouTube Dislike.user.js#5:534
setEventListeners moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/ Return YouTube Dislike.user.js#5:540
VMin041blywd9 moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/ Return YouTube Dislike.user.js#5:546
VMin041blywd9 moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/ Return YouTube Dislike.user.js#5:547
VMin041blywd9 moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/ Return YouTube Dislike.user.js#5:560
a moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/sandbox/injected-web.js:1
v moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/sandbox/injected-web.js:1
set moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/sandbox/injected-web.js:1
<anonymous> moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/ Return YouTube Dislike.user.js#5:1
c moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/sandbox/injected-web.js:1
ScriptData moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/sandbox/injected-web.js:1
onHandle moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/sandbox/injected-web.js:1
c moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/sandbox/injected-web.js:1
watch:197:28
01:45:46.691 Uncaught (in promise) TypeError: getButtons().children[1].querySelector(...) is null
setDislikes moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/ Return YouTube Dislike.user.js#5:197
setState moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/ Return YouTube Dislike.user.js#5:325
promise callback*setState/< moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/ Return YouTube Dislike.user.js#5:319
promise callback*setState moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/ Return YouTube Dislike.user.js#5:318
setInitialState moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/ Return YouTube Dislike.user.js#5:399
checkForJS_Finish moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/ Return YouTube Dislike.user.js#5:534
setEventListeners moz-extension://538351f7-2f69-433e-ae5b-62d10fc42979/ Return YouTube Dislike.user.js#5:540
xb https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/webcomponents-sd.vflset/webcomponents-sd.js:41
dispatchEvent https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:4188
fireEvent https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:4186
e https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:4177
61473_onFulfilled https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:877
fia https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:887
bia https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:887
executeCallbacks_ https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:886
xha https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:786
promise callback*Hg https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:786
Ig https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:785
cia https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:884
Zha https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:875
Yha https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:879
then https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:871
loadData https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:20714
yy https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:5079
Fy https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:5168
AXa https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:5172
ua https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:48
next https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:50
uaa https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:56
uaa https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:55
t https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:56
AXa https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:5170
job https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:4913
d https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/desktop_polymer.vflset/desktop_polymer.js:4900
I https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/scheduler.vflset/scheduler.js:29
O https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/scheduler.vflset/scheduler.js:38
P https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/scheduler.vflset/scheduler.js:31
requestIdleCallback handler*f.start https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/scheduler.vflset/scheduler.js:39
O https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/scheduler.vflset/scheduler.js:38
P https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/scheduler.vflset/scheduler.js:31
requestIdleCallback handler*f.start https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/scheduler.vflset/scheduler.js:39
O https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/scheduler.vflset/scheduler.js:38
S https://www.youtube.com/s/desktop/2cbeb7d0/jsbin/scheduler.vflset/scheduler.js:34
watch:197:28
Same problem here :+1: Looks like A/B testing to me. qutebrowser has the problem when I login to youtube, but a private BraveBrowser-Tab show the "old" UI. Btw, it would help the issue to add a proper title, I first thought I am the first person to experience the issue.
Edit: The following script from above works for me too:
function setDislikes(dislikesCount) { if (isMobile) { mobileDislikes = dislikesCount; return; } var txt = getButtons().children[1].querySelector("#text"); if(txt === null){ txt = getButtons().children[1].__shady_querySelector("#text"); } if(txt === null){ txt = getButtons().children[1].__shady_native_querySelector("#text"); } if(txt === null){ cLog("3rd try failed...") return } txt.innerText = dislikesCount; }
Can you please improve the title to make it easier to find & understand?