22'use strict' ;
33console . log ( 'Background script loaded.' ) ;
44
5- chrome . action . setBadgeText ( { text : 'Diff' } ) ;
6-
75import DiffMatchPatch from "./diff_match_patch.js" ;
86
97// configuration constants
5957 console . warn ( 'Popup attach failed:' , err ) ;
6058}
6159
62- // Store the ID of the tab that initiated the license check
63- let originTabId ;
6460const dmp = new DiffMatchPatch ( ) ;
6561// In-memory cache of license term-frequency vectors (populated on demand)
6662let licenseVectorsCache = null ; // { license_key: { word: freq, ... } }
@@ -1077,42 +1073,47 @@ async function fetchLicenses(text, sendProgress, options = {}) {
10771073}
10781074
10791075// Process a license check request
1080- async function processLicenseCheck ( selectedText , scanFilter = FILTER_OPTIONS . BOTH ) {
1076+ async function processLicenseCheck ( tabId , selectedText , scanFilter = FILTER_OPTIONS . BOTH ) {
1077+ if ( ! tabId ) {
1078+ console . error ( 'processLicenseCheck called without a tab ID.' ) ;
1079+ return ;
1080+ }
1081+
10811082 if ( ! selectedText || selectedText . trim ( ) . length === 0 ) {
1082- showNotification ( originTabId , 'Please select some text to compare with licenses.' , 'warning' ) ;
1083+ showNotification ( tabId , 'Please select some text to compare with licenses.' , 'warning' ) ;
10831084 return ;
10841085 }
10851086
1086- if ( activeScans . has ( originTabId ) ) {
1087- showNotification ( originTabId , 'Already processing a license check. Please wait...' , 'info' ) ;
1087+ if ( activeScans . has ( tabId ) ) {
1088+ showNotification ( tabId , 'Already processing a license check. Please wait...' , 'info' ) ;
10881089 return ;
10891090 }
10901091
10911092 // Mark this tab as having an active scan
1092- activeScans . add ( originTabId ) ;
1093+ activeScans . add ( tabId ) ;
10931094
10941095 try {
10951096 // Make sure content script is available
1096- const ready = await ensureContentScript ( originTabId ) ;
1097+ const ready = await ensureContentScript ( tabId ) ;
10971098 if ( ! ready ) {
10981099 console . error ( 'Content script not available after injection attempts.' ) ;
10991100 return ;
11001101 }
11011102 // Show UI and clear previous results with retry
11021103 for ( const m of [ 'showUI' , 'clearResults' ] ) {
11031104 try {
1104- await sendMessageToTab ( originTabId , { action : m } ) ;
1105+ await sendMessageToTab ( tabId , { action : m } ) ;
11051106 } catch ( msgErr ) {
11061107 console . warn ( 'Retrying message' , m , 'after brief delay due to' , msgErr . message ) ;
11071108 await new Promise ( r => setTimeout ( r , 100 ) ) ;
1108- await sendMessageToTab ( originTabId , { action : m } ) ;
1109+ await sendMessageToTab ( tabId , { action : m } ) ;
11091110 }
11101111 }
11111112
11121113 // Progress callback for reporting scan progress
11131114 const sendProgress = async ( progress ) => {
11141115 try {
1115- await sendMessageToTab ( originTabId , {
1116+ await sendMessageToTab ( tabId , {
11161117 action : 'progressUpdate' ,
11171118 progress
11181119 } ) ;
@@ -1125,22 +1126,27 @@ async function processLicenseCheck(selectedText, scanFilter = FILTER_OPTIONS.BOT
11251126 const matches = await fetchLicenses ( selectedText , sendProgress , { filter : normalizeFilter ( scanFilter ) } ) ;
11261127
11271128 if ( matches && matches . length > 0 ) {
1129+ matches . sort ( ( a , b ) => {
1130+ const aScore = Number . parseFloat ( a ?. charSimilarity ?? a ?. score ?? 0 ) || 0 ;
1131+ const bScore = Number . parseFloat ( b ?. charSimilarity ?? b ?. score ?? 0 ) || 0 ;
1132+ return bScore - aScore ;
1133+ } ) ;
11281134 console . log ( 'Sending showResults with' , matches . length , 'matches. Top license:' , matches [ 0 ] ?. license ) ;
11291135 // Report the matches to the content script
1130- await sendMessageToTab ( originTabId , {
1136+ await sendMessageToTab ( tabId , {
11311137 action : 'showResults' ,
11321138 matches
11331139 } ) ;
11341140 } else {
1135- await sendMessageToTab ( originTabId , {
1141+ await sendMessageToTab ( tabId , {
11361142 action : 'showError' ,
11371143 error : 'No significant license matches found.'
11381144 } ) ;
11391145 }
11401146 } catch ( error ) {
11411147 console . error ( 'Error processing license check:' , error ) ;
11421148 try {
1143- await sendMessageToTab ( originTabId , {
1149+ await sendMessageToTab ( tabId , {
11441150 action : 'showError' ,
11451151 error : error . message || 'An unknown error occurred'
11461152 } ) ;
@@ -1149,7 +1155,7 @@ async function processLicenseCheck(selectedText, scanFilter = FILTER_OPTIONS.BOT
11491155 }
11501156 } finally {
11511157 // Remove this tab from active scans
1152- activeScans . delete ( originTabId ) ;
1158+ activeScans . delete ( tabId ) ;
11531159 }
11541160}
11551161
@@ -1184,29 +1190,38 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
11841190 if ( message . action === 'checkLicense' ) {
11851191 const selectedText = message . text ;
11861192 const scanFilter = normalizeFilter ( message . filter || currentScanFilter ) ;
1187- // Send an immediate response to keep the message port alive
1188- sendResponse ( { status : 'processing' } ) ;
1193+
1194+ const startProcessing = ( tabId ) => {
1195+ processLicenseCheck ( tabId , selectedText , scanFilter )
1196+ . then ( ( ) => {
1197+ sendResponse ( { status : 'complete' } ) ;
1198+ } )
1199+ . catch ( ( error ) => {
1200+ console . error ( 'processLicenseCheck failed:' , error ) ;
1201+ sendResponse ( { status : 'error' , error : error ?. message || 'Unknown error' } ) ;
1202+ } ) ;
1203+ } ;
11891204
11901205 // Store the tab ID that initiated the request
1191- originTabId = sender . tab ? sender . tab . id : null ;
1206+ const senderTabId = sender . tab ? sender . tab . id : null ;
11921207
1193- if ( ! originTabId ) {
1208+ if ( ! senderTabId ) {
11941209 // If no tab ID is available (e.g., sent from popup), get the current active tab
11951210 chrome . tabs . query ( { active : true , currentWindow : true } , ( tabs ) => {
11961211 if ( chrome . runtime . lastError || ! tabs || tabs . length === 0 ) {
1197- console . error ( 'Error getting active tab:' , chrome . runtime . lastError ?
1198- chrome . runtime . lastError . message : 'No active tabs found' ) ;
1212+ const errMsg = chrome . runtime . lastError ? chrome . runtime . lastError . message : 'No active tabs found' ;
1213+ console . error ( 'Error getting active tab:' , errMsg ) ;
1214+ sendResponse ( { status : 'error' , error : errMsg } ) ;
11991215 return ;
12001216 }
12011217
1202- originTabId = tabs [ 0 ] . id ;
1203- processLicenseCheck ( selectedText , scanFilter ) ;
1218+ startProcessing ( tabs [ 0 ] . id ) ;
12041219 } ) ;
12051220 } else {
1206- processLicenseCheck ( selectedText , scanFilter ) ;
1221+ startProcessing ( senderTabId ) ;
12071222 }
12081223
1209- return false ; // Don't need to keep port open for asynchronous response
1224+ return true ; // Keep the port open while processing completes
12101225 } else if ( message . action === 'noTextSelected' ) {
12111226 // Handle no text selected
12121227 chrome . tabs . query ( { active : true , currentWindow : true } , ( tabs ) => {
@@ -1616,11 +1631,10 @@ async function handleActionClick(tab, filterChoice) {
16161631
16171632 // Send single message to existing handler (adds iframe metadata for future use)
16181633 // Directly initiate processing instead of round-trip messaging
1619- originTabId = tab . id ;
16201634 sendMessageToTab ( tab . id , { action : 'showUI' } )
16211635 . catch ( ( ) => Promise . resolve ( ) )
16221636 . finally ( ( ) => {
1623- processLicenseCheck ( best . text , filterChoice ) ;
1637+ processLicenseCheck ( tab . id , best . text , filterChoice ) ;
16241638 } ) ;
16251639 } catch ( err ) {
16261640 console . error ( 'Selection collection error:' , err ) ;
@@ -1646,6 +1660,10 @@ ensureDatabaseReady('background-load');
16461660
16471661chrome . runtime . onInstalled . addListener ( async ( details ) => {
16481662 console . log ( '[LicenseMatch] onInstalled:' , details . reason ) ;
1663+ if ( details . reason === 'update' ) {
1664+ // Reset badge
1665+ updateBadge ( "green" ) ;
1666+ }
16491667 await ensureDatabaseReady ( 'onInstalled' ) ;
16501668} ) ;
16511669
0 commit comments