@@ -44,7 +44,7 @@ async function handleCapoClick(event) {
4444 await chrome . scripting . executeScript ( {
4545 target : { tabId : tab . id } ,
4646 args : [ {
47- fn : 'logElement ' ,
47+ fn : 'logElementFromSelector ' ,
4848 args : [ weight , selector , innerHTML , isValid ]
4949 } ] ,
5050 func : capo
@@ -53,7 +53,7 @@ async function handleCapoClick(event) {
5353
5454async function capo ( { fn, args} = { } ) {
5555 const FN_EXPORTS = {
56- logElement
56+ logElementFromSelector
5757 } ;
5858
5959 const ElementWeights = {
@@ -196,6 +196,10 @@ async function capo({fn, args}={}) {
196196 function isPrefetchPrerender ( element ) {
197197 return element . matches ( 'link:is([rel=prefetch], [rel=dns-prefetch], [rel=prerender])' ) ;
198198 }
199+
200+ function isOriginTrial ( element ) {
201+ return element . matches ( 'meta[http-equiv="origin-trial"i]' ) ;
202+ }
199203
200204 function getWeight ( element ) {
201205 for ( [ id , detector ] of Object . entries ( ElementDetectors ) ) {
@@ -230,19 +234,57 @@ async function capo({fn, args}={}) {
230234
231235 return { visual, style} ;
232236 }
233-
237+
238+ // Adapted from https://glitch.com/~ot-decode.
239+ function decodeToken ( token ) {
240+ const buffer = new Uint8Array ( [ ...atob ( token ) ] . map ( a => a . charCodeAt ( 0 ) ) ) ;
241+ const view = new DataView ( buffer . buffer )
242+ const length = view . getUint32 ( 65 , false )
243+ const payload = JSON . parse ( ( new TextDecoder ( ) ) . decode ( buffer . slice ( 69 , 69 + length ) ) ) ;
244+ payload . expiry = new Date ( payload . expiry * 1000 ) ;
245+ return payload ;
246+ }
247+
248+ function logElement ( { viz, weight, element, isValid, omitPrefix = false } ) {
249+ if ( ! omitPrefix ) {
250+ viz . visual = `${ LOGGING_PREFIX } ${ viz . visual } ` ;
251+ }
252+
253+ let loggingLevel = 'log' ;
254+ const args = [ viz . visual , viz . style , weight + 1 , element ] ;
255+
256+ if ( isStaticHead && ! isValid ) {
257+ loggingLevel = 'warn' ;
258+ args . push ( '❌ invalid element' ) ;
259+ }
260+
261+ if ( isOriginTrial ( element ) ) {
262+ const token = element . getAttribute ( 'content' ) ;
263+ try {
264+ const payload = decodeToken ( token ) ;
265+ args . push ( payload ) ;
266+
267+ if ( payload . expiry < new Date ( ) ) {
268+ loggingLevel = 'warn' ;
269+ args . push ( '❌ expired' ) ;
270+ }
271+ } catch {
272+ loggingLevel = 'warn' ;
273+ args . push ( '❌ invalid token' ) ;
274+ }
275+ }
276+
277+ console [ loggingLevel ] ( ...args ) ;
278+ }
279+
234280 function logWeights ( ) {
235281 const headWeights = getHeadWeights ( ) ;
236282 const actualViz = visualizeWeights ( headWeights . map ( ( [ _ , weight ] ) => weight ) ) ;
237283
238284 console . groupCollapsed ( `${ LOGGING_PREFIX } Actual %c<head>%c order\n${ actualViz . visual } ` , 'font-family: monospace' , 'font-family: inherit' , ...actualViz . styles ) ;
239285 headWeights . forEach ( ( [ element , weight , isValid ] ) => {
240286 const viz = visualizeWeight ( weight ) ;
241- if ( isStaticHead && ! isValid ) {
242- console . warn ( viz . visual , viz . style , weight + 1 , element , '❌ invalid element' ) ;
243- } else {
244- console . log ( viz . visual , viz . style , weight + 1 , element ) ;
245- }
287+ logElement ( { viz, weight, element, isValid, omitPrefix : true } ) ;
246288 } ) ;
247289 console . log ( 'Actual %c<head>%c element' , 'font-family: monospace' , 'font-family: inherit' , head ) ;
248290 console . groupEnd ( ) ;
@@ -256,11 +298,7 @@ async function capo({fn, args}={}) {
256298 const sortedHead = document . createElement ( 'head' ) ;
257299 sortedWeights . forEach ( ( [ element , weight , isValid ] ) => {
258300 const viz = visualizeWeight ( weight ) ;
259- if ( isStaticHead && ! isValid ) {
260- console . warn ( viz . visual , viz . style , weight + 1 , element , '❌ invalid element' ) ;
261- } else {
262- console . log ( viz . visual , viz . style , weight + 1 , element ) ;
263- }
301+ logElement ( { viz, weight, element, isValid, omitPrefix : true } ) ;
264302 sortedHead . appendChild ( element . cloneNode ( true ) ) ;
265303 } ) ;
266304 console . log ( 'Sorted %c<head>%c element' , 'font-family: monospace' , 'font-family: inherit' , sortedHead ) ;
@@ -329,18 +367,14 @@ async function capo({fn, args}={}) {
329367 return element ;
330368 }
331369
332- function logElement ( weight , selector , innerHTML , isValid ) {
370+ function logElementFromSelector ( weight , selector , innerHTML , isValid ) {
333371 weight = + weight ;
334372 const viz = visualizeWeight ( weight ) ;
335373 let element = createElementFromSelector ( selector ) ;
336374 element . innerHTML = innerHTML ;
337375 element = getLoggableElement ( element ) ;
338376
339- if ( isValid ) {
340- console . log ( `${ LOGGING_PREFIX } ${ viz . visual } ` , viz . style , weight + 1 , element ) ;
341- } else {
342- console . warn ( `${ LOGGING_PREFIX } ${ viz . visual } ` , viz . style , weight + 1 , element , '❌ invalid element' ) ;
343- }
377+ logElement ( { viz, weight, element, isValid} ) ;
344378 }
345379
346380 function isValidElement ( element ) {
0 commit comments