@@ -74,6 +74,7 @@ export class Tab extends StatefulClass {
7474
7575 // make sure it's top level, ctxInit calls for all frames too
7676 if ( ctx . window == frame . frame . contentWindow ) {
77+ injectTitleWatcher ( ctx . client , this ) ;
7778 injectHistoryEmulation ( ctx . client , this ) ;
7879 injectDevtools ( ctx . client , this ) ;
7980 }
@@ -117,6 +118,8 @@ export class Tab extends StatefulClass {
117118 }
118119 } else {
119120 this . internalpage = null ;
121+ // placeholder title until the page fills in
122+ this . title = url . href ;
120123 this . frame . go ( url ) ;
121124 }
122125 }
@@ -404,6 +407,37 @@ function injectContextMenu(client: ScramjetClient, tab: Tab) {
404407 } ) ;
405408}
406409
410+ function injectTitleWatcher ( client : ScramjetClient , tab : Tab ) {
411+ const framedoc = client . global . document ;
412+ const head = framedoc . querySelector ( "head" ) ! ;
413+ const observer = new MutationObserver ( ( ) => {
414+ const title = framedoc . querySelector ( "title" ) ;
415+ if ( title ) {
416+ tab . title = title . textContent || "New Tab" ;
417+ } else {
418+ tab . title = "New Tab" ;
419+ }
420+ const favicon = framedoc . querySelector (
421+ "link[rel='icon'], link[rel='shortcut icon']"
422+ ) ;
423+ if ( favicon ) {
424+ const iconhref = favicon . getAttribute ( "href" ) ;
425+ if ( iconhref ) {
426+ const rewritten = scramjet . encodeUrl ( new URL ( iconhref , client . url ) ) ;
427+ tab . icon = rewritten ;
428+ } else {
429+ tab . icon = "/vite.svg" ;
430+ }
431+ } else {
432+ tab . icon = scramjet . encodeUrl ( new URL ( "/favicon.ico" , client . url ) ) ;
433+ }
434+ } ) ;
435+ observer . observe ( head , {
436+ childList : true ,
437+ subtree : true ,
438+ } ) ;
439+ }
440+
407441// frame.frame.addEventListener("load", (e) => {
408442// tab.url = frame.client.url.href;
409443// });
@@ -427,39 +461,6 @@ function injectContextMenu(client: ScramjetClient, tab: Tab) {
427461// },
428462// });
429463
430- // const framedoc = ctx.window.document;
431-
432- // const head = framedoc.querySelector("head")!;
433- // const observer = new MutationObserver(() => {
434- // const title = framedoc.querySelector("title");
435- // if (title) {
436- // tab.title = title.textContent || "New Tab";
437- // } else {
438- // tab.title = "New Tab";
439- // }
440- // const favicon = framedoc.querySelector(
441- // "link[rel='icon'], link[rel='shortcut icon']"
442- // );
443- // if (favicon) {
444- // const iconhref = favicon.getAttribute("href");
445- // if (iconhref) {
446- // const rewritten = scramjet.encodeUrl(
447- // new URL(iconhref, frame.client.url)
448- // );
449- // tab.icon = rewritten;
450- // } else {
451- // tab.icon = "/vite.svg";
452- // }
453- // } else {
454- // tab.icon = scramjet.encodeUrl(
455- // new URL("/favicon.ico", frame.client.url)
456- // );
457- // }
458- // });
459- // observer.observe(head, {
460- // childList: true,
461- // subtree: true,
462- // });
463464// const anchorObserver = new MutationObserver((mutations) => {
464465// mutations.forEach((mutation) => {
465466// mutation.addedNodes.forEach((node) => {
0 commit comments