11import * as utils from "./utils.js" ;
22import List from "list.js" ;
33
4+ const loadingMessage = "Loading ..." ;
5+
46function licenseModal ( clone , options ) {
57 const { licenses, selectedNode } = options ;
68 if ( licenses === "unkown license" ) {
@@ -26,22 +28,64 @@ function locationToString(location) {
2628 return `[${ start } ] - [${ end } ]` ;
2729}
2830
31+ function getLineFromFile ( code , location ) {
32+ const [ [ startLine ] ] = location ;
33+ const lines = code . split ( '\n' ) ;
34+
35+ return lines [ startLine - 1 ] ;
36+ }
37+
38+ async function fetchCodeLine ( event , url , location , cache , lineId ) {
39+ const target = document . getElementById ( 'tooltip' ) ;
40+ target . style . visibility = 'visible' ;
41+
42+ if ( cache . has ( lineId ) ) {
43+ target . innerText = cache . get ( lineId ) ;
44+ event . stopPropagation ( ) ;
45+ return ;
46+ }
47+
48+ target . innerText = loadingMessage ;
49+ const code = await fetch ( url ) . then ( ( response ) => response . text ( ) ) ;
50+
51+ target . innerText = code . length ? getLineFromFile ( code , location ) : "Line not found ..." ;
52+ cache . set ( lineId , target . innerText ) ;
53+ event . stopPropagation ( ) ;
54+ }
55+
56+ function handleOutsideTooltipClick ( { target } ) {
57+ const tooltip = document . getElementById ( 'tooltip' ) ;
58+
59+ if ( ! tooltip ) {
60+ return ;
61+ }
62+
63+ if ( ( tooltip . innerHTML && tooltip . innerHTML !== loadingMessage ) && ! tooltip . contains ( target ) && tooltip . style . visibility === "visible" ) {
64+ tooltip . style . visibility = "hidden" ;
65+ tooltip . innerHTML = "" ;
66+ }
67+ }
68+
2969function warningModal ( clone , options ) {
3070 const { name, version, npmHomePageURL, homepage, warnings } = options ;
71+ const cache = new Map ( ) ;
3172
3273 const openLink = ( link ) => {
3374 return ( ) => window . open ( link ) . focus ( ) ;
3475 }
3576 const unpkgRootURL = `https://unpkg.com/${ name } @${ version } /` ;
36- const homePageBtn = clone . getElementById ( "warning-link-homepage" )
77+ const homePageBtn = clone . getElementById ( "warning-link-homepage" ) ;
3778 homePageBtn . addEventListener ( "click" , openLink ( homepage ) ) ;
3879 homePageBtn . querySelector ( "span" ) . textContent = homepage ;
3980 clone . getElementById ( "warning-link-npm" ) . addEventListener ( "click" , openLink ( npmHomePageURL ) ) ;
4081 clone . getElementById ( "warning-link-unpkg" ) . addEventListener ( "click" , openLink ( unpkgRootURL ) ) ;
82+ document . addEventListener ( "click" , handleOutsideTooltipClick ) ;
4183
4284 const tbody = clone . querySelector ( "#warnings-table tbody" ) ;
4385 for ( const { kind, file, value = null , location } of warnings ) {
4486 const line = tbody . insertRow ( 0 ) ;
87+ const lineId = Math . random ( ) . toString ( 36 ) . slice ( 2 ) ;
88+ const unpkgFile = `${ unpkgRootURL } ${ file } ` ;
4589
4690 const kindCell = line . insertCell ( 0 )
4791 kindCell . classList . add ( "type" ) ;
@@ -58,21 +102,29 @@ function warningModal(clone, options) {
58102 const errorCell = line . insertCell ( 2 ) ;
59103 errorCell . classList . add ( "highlight" ) ;
60104 errorCell . classList . add ( "msg" ) ;
61- const positionCell = line . insertCell ( 3 ) ;
62- positionCell . classList . add ( "position" ) ;
63105 if ( value !== null ) {
64106 errorCell . classList . add ( "clickable" ) ;
65107 errorCell . appendChild ( document . createTextNode ( value ) ) ;
66108 errorCell . addEventListener ( "click" , ( ) => utils . copyToClipboard ( value ) ) ;
67109 }
68110
111+ const positionCell = line . insertCell ( 3 ) ;
112+ positionCell . classList . add ( "position" ) ;
69113 if ( kind === "encoded-literal" ) {
70114 const text = location . map ( ( loc ) => locationToString ( loc ) ) . join ( " // " ) ;
71115 positionCell . appendChild ( document . createTextNode ( text ) ) ;
72116 }
73117 else {
74118 positionCell . appendChild ( document . createTextNode ( locationToString ( location ) ) ) ;
75119 }
120+
121+ const inspectCell = line . insertCell ( 4 ) ;
122+ inspectCell . innerHTML = "🔬" ;
123+ inspectCell . classList . add ( "inspect" ) ;
124+ if ( ! file . includes ( ".min" ) && kind !== "short-identifiers" && kind !== "obfuscated-code" ) {
125+ const currLocation = kind === "encoded-literal" ? location [ 0 ] : location ;
126+ inspectCell . addEventListener ( "click" , ( event ) => fetchCodeLine ( event , unpkgFile , currLocation , cache , lineId ) ) ;
127+ }
76128 }
77129
78130 setTimeout ( ( ) => {
@@ -81,9 +133,9 @@ function warningModal(clone, options) {
81133}
82134
83135export function openLicenseModal ( options = { } ) {
84- return ( ) => window . toggleModal ( "popup-license" , ( clone ) => licenseModal ( clone , options ) )
136+ return ( ) => window . toggleModal ( "popup-license" , ( clone ) => licenseModal ( clone , options ) ) ;
85137}
86138
87139export function openWarningsModal ( options = { } ) {
88- return ( ) => window . toggleModal ( "popup-warning" , ( clone ) => warningModal ( clone , options ) )
140+ return ( ) => window . toggleModal ( "popup-warning" , ( clone ) => warningModal ( clone , options ) ) ;
89141}
0 commit comments