background.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // Map tab IDs to connections
  2. const connections = new Map();
  3. // Listen for connections from the devtools panel
  4. chrome.runtime.onConnect.addListener( port => {
  5. let tabId;
  6. // Listen for messages from the devtools panel
  7. port.onMessage.addListener( message => {
  8. if ( message.name === 'init' ) {
  9. tabId = message.tabId;
  10. connections.set( tabId, port );
  11. } else if ( message.name === 'request-state' && tabId ) {
  12. chrome.tabs.sendMessage( tabId, message );
  13. } else if ( tabId === undefined ) {
  14. console.warn( 'Background: Message received from panel before init:', message );
  15. }
  16. } );
  17. // Clean up when devtools is closed
  18. port.onDisconnect.addListener( () => {
  19. if ( tabId ) {
  20. connections.delete( tabId );
  21. }
  22. } );
  23. } );
  24. // Listen for messages from the content script
  25. chrome.runtime.onMessage.addListener( ( message, sender, sendResponse ) => {
  26. if ( message.scheme ) {
  27. chrome.action.setIcon( {
  28. path: {
  29. 128: `icons/128-${message.scheme}.png`
  30. }
  31. } );
  32. }
  33. if ( sender.tab ) {
  34. const tabId = sender.tab.id;
  35. // If three.js is detected, show a badge
  36. if ( message.name === 'register' && message.detail && message.detail.revision ) {
  37. const revision = String( parseInt( message.detail.revision, 10 ) );
  38. chrome.action.setBadgeText( { tabId: tabId, text: revision } ).catch( () => { /* Tab might be gone */ } );
  39. chrome.action.setBadgeTextColor( { tabId: tabId, color: '#ffffff' } ).catch( () => { /* Tab might be gone */ } );
  40. chrome.action.setBadgeBackgroundColor( { tabId: tabId, color: '#049ef4' } ).catch( () => { /* Tab might be gone */ } );
  41. }
  42. const port = connections.get( tabId );
  43. if ( port ) {
  44. // Forward the message to the devtools panel
  45. try {
  46. port.postMessage( message );
  47. // Send immediate response to avoid "message channel closed" error
  48. sendResponse( { received: true } );
  49. } catch ( e ) {
  50. console.error( 'Error posting message to devtools:', e );
  51. // If the port is broken, clean up the connection
  52. connections.delete( tabId );
  53. }
  54. }
  55. }
  56. return false; // Return false to indicate synchronous handling
  57. } );
  58. // Listen for page navigation events
  59. chrome.webNavigation.onCommitted.addListener( details => {
  60. const { tabId, frameId } = details;
  61. // Clear badge on navigation, only for top-level navigation
  62. if ( frameId === 0 ) {
  63. chrome.action.setBadgeText( { tabId: tabId, text: '' } ).catch( () => { /* Tab might be gone */ } );
  64. }
  65. const port = connections.get( tabId );
  66. if ( port ) {
  67. port.postMessage( {
  68. id: 'three-devtools',
  69. name: 'committed',
  70. frameId: frameId
  71. } );
  72. }
  73. } );
  74. // Clear badge when a tab is closed
  75. chrome.tabs.onRemoved.addListener( ( tabId, removeInfo ) => {
  76. chrome.action.setBadgeText( { tabId: tabId, text: '' } ).catch( () => { /* Tab might be gone */ } );
  77. // Clean up connection if it exists for the closed tab
  78. if ( connections.has( tabId ) ) {
  79. connections.delete( tabId );
  80. }
  81. } );
粤ICP备19079148号