javascript - Getting the actual HTML after a transition accures in a youtube page (chrome extension) -


i'm working on chrome extension should run script in every youtube watch page (i.e, https://www.youtube.com/watch?v=yisbvr69r7u)

in script want itag's of video (which can script in every youtube video page parsing "url_encoded_fmt_stream_map" property in yt.config)

the problem can't find property parsing (document.body.innerhtml) of pages.

here's manifest.json:

{   "manifest_version": 2,    "name"            : "test extension",   "version"         : "0.0",    "background": {     "scripts": ["background.js"]   },    "permissions": [     "https://www.youtube.com/*", "tabs", "webnavigation"   ] } 

i know youtube use transitions between pages (for example if clicked on video watch red bar on top of page appears video page appears), use webnavigation onhistorystateupdated event execute script page after transition ends.

background.js:

const r = /https:\/\/www\.youtube\.com\/watch\?v=(.*?)(&.*)?/; chrome.webnavigation.onhistorystateupdated.addlistener(function(details) {     if(r.test(details.url))         chrome.tabs.executescript(details.tabid,{file:"script.js"}); }); 

and script.js:

function geturlmap(bodyhtml) {     var r = /"url_encoded_fmt_stream_map":"(.*?)"/;     var matches = bodyhtml.match(r);     return matches[1]; }  function gettags(fmts_info) {     var tags = [];     r = /itag=(.*?)\\u/;     console.log(fmts_info[0]);     for(var = 0; < fmts_info.length; i++) {         matches = fmts_info[i].match(r);         tags[i] = matches[1];     }     return tags; }  console.log(gettags(geturlmap(document.body.innerhtml).split(','))); 

the extension when go youtube watch page directly (openning new tab on chrome , go directly say: https://www.youtube.com/watch?v=yisbvr69r7u), shows in console itag's of video correctly. problem comes when come youtube watch page transition (for example youtube index page video page clicking on video), in case have error in console:

uncaught typeerror: cannot read property '1' of null  script.js:4 

when let script.js show (document.body) in console, can't find "url_encoded_stream_map" there

it seems problem how deal transitions in page.

i searched lot solve problem nothing worked me.

i tried using content-scripts seems content scripts inserted in page when it's loaded, , not when transition accures.

i want actual html of page, has itag's in it!

edit:

this no duplicated this

tried manifest.json:

{   "manifest_version": 2,    "name"            : "test extension",   "version"         : "0.0",    "content_scripts": [{       "matches": [ "*://*.youtube.com/*" ],       "js": [ "script.js" ],       "run_at": "document_start"   }] } 

script.js:

document.addeventlistener("spfdone", process); document.addeventlistener("domcontentloaded", process);  function geturlmap(bodyhtml) {     var r = /"url_encoded_fmt_stream_map":"(.*?)"/;     var matches = bodyhtml.match(r);     return matches[1]; }  function gettags(fmts_info) {     var tags = [];     r = /itag=(.*?)\\u/;     for(var = 0; < fmts_info.length; i++) {         matches = fmts_info[i].match(r);         tags[i] = matches[1];     }     return tags; }  function process() {     if (location.pathname != "/watch") {         return;     }     console.log(gettags(geturlmap(document.body.innerhtml).split(','))); } 

but problem not solved!

if debug script see url_encoded_fmt_stream_map isn't added anywhere in document after in-site navigation. hacking site js shows ytplayer.config variable updated directly in such cases.

we'll have inject our script page itself.

declare content script runs on of youtube in manifest.json:

"content_scripts": [{   "matches": [ "*://*.youtube.com/*" ],   "js": [ "content.js" ],   "run_at": "document_start" }] 

content.js:

function injectedcode() {     document.addeventlistener("spfdone", process);     document.addeventlistener("domcontentloaded", process);      function process() {         function gettags(fmts_info) {             var tags = [];             r = /itag=(\d+)/;             for(var = 0; < fmts_info.length; i++) {                 var matches = fmts_info[i].match(r);                 if (matches)                     tags.push(matches[1]);             }             return tags;         }         if (location.href.indexof('watch?') < 0) {             return;         }         var tags = gettags(ytplayer.config.args.url_encoded_fmt_stream_map.split(','));         console.log(tags);     } }  function getfunctiontext(f) {     return f.tostring().match(/\{[\s\s]*\}$/)[0]; }  document.documentelement.appendchild(document.createelement("script")).text =     getfunctiontext(injectedcode) 

to pass results content script use custom events, or externally_connectable send data directly extension's background page script.


Comments