background.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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. // Clear badge if devtools panel is closed for this tab
  22. chrome.action.setBadgeText( { tabId: tabId, text: '' } ).catch( () => { /* Tab might be gone */ } );
  23. }
  24. } );
  25. } );
  26. // Listen for messages from the content script
  27. chrome.runtime.onMessage.addListener( ( message, sender, sendResponse ) => {
  28. if ( message.scheme ) {
  29. chrome.action.setIcon( {
  30. path: {
  31. 16: `icons/16-${message.scheme}.png`,
  32. 32: `icons/32-${message.scheme}.png`,
  33. 48: `icons/48-${message.scheme}.png`,
  34. 128: `icons/128-${message.scheme}.png`
  35. }
  36. } );
  37. }
  38. if ( sender.tab ) {
  39. const tabId = sender.tab.id;
  40. // If three.js is detected, show a badge
  41. if ( message.name === 'register' && message.detail && message.detail.revision ) {
  42. const revision = String( parseInt( message.detail.revision, 10 ) );
  43. chrome.action.setBadgeText( { tabId: tabId, text: revision } ).catch( () => { /* Tab might be gone */ } );
  44. chrome.action.setBadgeTextColor( { tabId: tabId, color: '#ffffff' } ).catch( () => { /* Tab might be gone */ } );
  45. chrome.action.setBadgeBackgroundColor( { tabId: tabId, color: '#049ef4' } ).catch( () => { /* Tab might be gone */ } );
  46. }
  47. const port = connections.get( tabId );
  48. if ( port ) {
  49. // Forward the message to the devtools panel
  50. try {
  51. port.postMessage( message );
  52. // Send immediate response to avoid "message channel closed" error
  53. sendResponse( { received: true } );
  54. } catch ( e ) {
  55. console.error( 'Error posting message to devtools:', e );
  56. // If the port is broken, clean up the connection
  57. connections.delete( tabId );
  58. }
  59. }
  60. }
  61. return false; // Return false to indicate synchronous handling
  62. } );
  63. // Listen for page navigation events
  64. chrome.webNavigation.onCommitted.addListener( details => {
  65. const { tabId, frameId } = details;
  66. // Clear badge on navigation, only for top-level navigation
  67. if ( frameId === 0 ) {
  68. chrome.action.setBadgeText( { tabId: tabId, text: '' } ).catch( () => { /* Tab might be gone */ } );
  69. }
  70. const port = connections.get( tabId );
  71. if ( port ) {
  72. port.postMessage( {
  73. id: 'three-devtools',
  74. type: 'committed',
  75. frameId: frameId
  76. } );
  77. }
  78. } );
  79. // Clear badge when a tab is closed
  80. chrome.tabs.onRemoved.addListener( ( tabId, removeInfo ) => {
  81. chrome.action.setBadgeText( { tabId: tabId, text: '' } ).catch( () => { /* Tab might be gone */ } );
  82. // Clean up connection if it exists for the closed tab
  83. if ( connections.has( tabId ) ) {
  84. connections.delete( tabId );
  85. }
  86. } );
粤ICP备19079148号