Issue with opening share url in a new tab
andykamezou opened this issue · 9 comments
Link example http://radiko.jp/share/?t=20210329153524&sid=JORF
On Edge 89.0.774.63, (sometimes?) it will stuck in a loop (share -> radio page -> radiko out -> share -> radio page -> radiko out ...)
On Brave 1.22.70, it will navigate back to the empty new tab
I guess it's related to the recent change and somehow each browsers dealt with it differently.
if (window.location.hash == "#!/out"){
$.colorbox.close();
history.back()
}
Idea : Instead of relying on location hash, is it possible to deal with this directly?
area.js
$.Radiko.ajax('/area', function (data, status, xhr) {
/* snipped */
var areaFreeId = $.cookie('areafree_id');
if (typeof areaFreeId !== 'undefined') {
$.Radiko.area.id = areaFreeId;
}
else {
$.Radiko.area.id = defaultAreaId;
}
$.Radiko.header.create_header(getAreaId(), loginStatus);
}, function () {
$.Radiko.area.id = 'OUT'; //<---------
}, 'text', true).always(function () {
if ($.Radiko.area.id === 'OUT') {
window.location.hash = '#!/out';
}
$.Radiko.EventEmitter.trigger('radikoready');
});
The extension blocking ajax call to /area which make them to assign the default value of $.Radiko.area.id to "OUT". This seems to be the ultimate final check that causing user to be redirected to #!/out .
Override $.Radiko.area.id to any value (or to the relevant value from cookie) after they assign "OUT", and user will get a proper web page.
Idea : Instead of relying on location hash, is it possible to deal with this directly?
area.js
Override $.Radiko.area.id to any value (or to the relevant value from cookie) after they assign "OUT", and user will get a proper web page.
I thought about your idea but unfortunately, there's no way to assign $.Radiko.area.id just between they assigned "OUT" and .always(function ()
triggered AFAIK.
Yep, can't change the assignment because of always. So you need to override the whole function.
I managed to do it in my userscript, using it as a hotfix for the browser loop issue.
I override the $.Radiko.area.check_area()
. But keep in mind that I'm not good in JS.
I've tried various way to observe $.Radiko.area
to wait for it available as an object, but failed. So I did it by monitoring the ajax call, and override $.Radiko.area
as below :
/*
1. default.js first_call()
2. common.js $.Radiko.Display.common()
3. menu.js $.Radiko.menu.check_login()
4. menu.js $.Radiko.area.check_area('logout')
5. area.js
*/
var ajaxOpen = new Object();
ajaxOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, uri, async) {
ajaxOpen.apply(this, arguments);
if(uri.indexOf("/ap/member/webapi/member/login/check") > -1 ){
$.Radiko.area = {
check_area: function (/*loginStatus = "logout"*/) {
//most of these are from the original ajax success callback
var defaultAreaId = $.cookie('default_area_id') || "JP13"; //tokyo
$.cookie('default_area_id', defaultAreaId, { path: '/' });
$.cookie('tracking_area_id', defaultAreaId, { path: '/' });
window.areaId = defaultAreaId;
var areaFreeId = $.cookie('areafree_id');
if (typeof areaFreeId !== 'undefined') {
$.Radiko.area.id = areaFreeId;
}
else {
$.Radiko.area.id = defaultAreaId;
}
//$.Radiko.header.create_header(getAreaId(), loginStatus);
$.Radiko.EventEmitter.trigger('radikoready');
}
};
}
/*
//ajax call for /area won't happen anymore because $.Radiko.area override above
if(uri.indexOf("/area?") > -1 ){
console.log(" --- AREA --- ");
ajaxOpen.abort() //abort is not enough, because of the .always()
}
*/
}
Perhaps you know a better way to override that $.Radiko.area.check_area()
call.
Thanks for your code.
Basically , i don't want modify radiko's code , since it may change.
And have a test on https://github.com/jackyzy823/rajiko/archive/refs/tags/v0.2.8.zip (not upload to chrome web store) . it may fix this issue.
From a quick test, it seems good on Brave.<-- My initial thought
But inconsistent on Edge.
On Edge, most of the time it goes like : share url -> timeshift url -> out url -> timeshift url, pink interface but with home content.
But once in a while it will end with the proper timeshift page.
I think it depends on how slow/quick things being processed. When I open browser's DevTools, all the console logs & debugging slowing down the browser, it had enough time to process everything and it end with the correct timeshift page.
Immediately when I close DevTools, and retry any share url, most of the time it will end at timeshift url, pink interface but with home content.
These makes me realized that my Brave is connected to JP VPN, so this add more latency while loading all the ajax request and processing stuff. Immediately when I use my normal connection, Brave showing the same behaviour as Edge (inconsistent).
In other words, once the page reached "out url", the page render might have finished at the same time when window.location.href = event.oldURL
occur, and their page logic somehow ignore the hash change.
Perhaps try to add some delay? setTimeout? Let the "out url" settled down a bit before triggering the url change.
Can confirm it's inconsistent and depends on how slow it is.
And it's not limited to share link, directly open https://radiko.jp/#!/ts/*
links from location bar has chances to be redirected to out
too (but less frequently for some reason).
All my tests are done with my native non-Japan IP.
I really really have no idea about this.
in my understand,
window.addEventListener('hashchange', function(event) {
runs before DOM is loaded.
So it will 100% be triggered and triggered before whatever the network speed.
It is so weird.
I think it less about network speed, but more about how quick (or slow) the browser finished processing radiko's code.
In general, your fix works. It's just the url change happened too fast so the radiko's code that handling the page render is somehow ignoring the hash change. Or perhaps radiko's code didn't catch the hash change at all, so it rendered a wrong page.
As I proposed before, try add setTimeout :
//common_start.js
else{
setTimeout(function(){ window.location.href = event.oldURL; }, 3000);
//window.location.href = event.oldURL
}
I tried it just now. Probably not a pretty solution, but it works. Even 500ms seems enough. And that seems to confirm the wrong page was caused by the url changed too quick.
Thanks for your test.
I might found the key to the problem.
- area -> modify hash to
OUT
- path.js first initialization will do a dispatch which use
OUT
if (location.hash !== "") {
Path.dispatch(location.hash);
} - my hashchange listener will modify hash to
origin
- path.onhashchange will dispath to
origin
and step 2 and ( 3 + 4 ) order is not guaranteed.
so if 3+4 before 2 then it will go to right origin url then go to OUT
So the only way is to add some delay. 😞
Finally . I decide to hijack jquery.ajax to make $.Radiko.area.check_area
's error function not work and set a $.Radiko.area.id to bypass OUT
issue.
Dirty work. Dirty code. but make sense.