@@ -6,8 +6,12 @@ const { setTimeout } = ChromeUtils.importESModule(
66 "resource://gre/modules/Timer.sys.mjs" ,
77) ;
88
9+ // Define a type for the Gmail callback
10+ type GmailCallback = ( result : { success : boolean ; message ?: string } ) => void ;
11+
912export class NRWebContentModifierChild extends JSWindowActorChild {
1013 private oneDriveFileListCallback : ( ( data : string ) => void ) | null = null ;
14+ private gmailCallbacks : Map < string , GmailCallback > = new Map ( ) ; // Map to store Gmail callbacks
1115 private callbackTabId : string | null = null ;
1216 private extractionAttempts : number = 0 ;
1317
@@ -19,6 +23,10 @@ export class NRWebContentModifierChild extends JSWindowActorChild {
1923 Cu . exportFunction ( this . NRGetOneDriveFileNameList . bind ( this ) , window , {
2024 defineAs : "NRGetOneDriveFileNameList" ,
2125 } ) ;
26+ // Export NRSendGmail
27+ Cu . exportFunction ( this . NRSendGmail . bind ( this ) , window , {
28+ defineAs : "NRSendGmail" ,
29+ } ) ;
2230 }
2331 }
2432
@@ -94,12 +102,33 @@ export class NRWebContentModifierChild extends JSWindowActorChild {
94102 // 別のタブから送られてきたファイルデータを処理
95103 if ( this . oneDriveFileListCallback ) {
96104 console . log (
97- "NRWebContentModifier: Executing callback with file data from another tab" ,
105+ "NRWebContentModifier: Executing OneDrive callback with file data from another tab" ,
98106 ) ;
99107 this . oneDriveFileListCallback ( message . data . fileListJson ) ;
100108 return { success : true } ;
101109 }
102- return { success : false , reason : "No callback registered in this tab" } ;
110+ return {
111+ success : false ,
112+ reason : "No OneDrive callback registered in this tab" ,
113+ } ;
114+
115+ // Handle message to fill and send Gmail
116+ case "WebContentModifier:FillAndSendGmail" :
117+ console . log ( "NRWebContentModifier: Received FillAndSendGmail message" ) ;
118+ this . fillAndSendGmail (
119+ message . data . to ,
120+ message . data . subject ,
121+ message . data . body ,
122+ message . data . callbackId ,
123+ ) ;
124+ return null ;
125+
126+ // Handle result callback from Gmail tab
127+ // Asynchronous operation
128+ case "WebContentModifier:GmailResult" :
129+ console . log ( "NRWebContentModifier: Received GmailResult message" ) ;
130+ this . handleGmailResult ( message . data . callbackId , message . data . result ) ;
131+ return null ;
103132 }
104133 return null ;
105134 }
@@ -478,4 +507,164 @@ export class NRWebContentModifierChild extends JSWindowActorChild {
478507 } ;
479508 }
480509 }
510+
511+ // Function called from settings page to initiate Gmail sending
512+ NRSendGmail (
513+ to : string ,
514+ subject : string ,
515+ body : string ,
516+ callback : GmailCallback ,
517+ ) : void {
518+ console . log ( "NRWebContentModifier: NRSendGmail called" , {
519+ to,
520+ subject,
521+ body,
522+ } ) ;
523+ const callbackId = `gmail_${ Date . now ( ) } _${ Math . random ( ) } ` ;
524+ this . gmailCallbacks . set ( callbackId , callback ) ;
525+ console . log (
526+ `NRWebContentModifier: Registered Gmail callback with ID: ${ callbackId } ` ,
527+ ) ;
528+
529+ this . sendAsyncMessage ( "WebContentModifier:OpenGmailCompose" , {
530+ to,
531+ subject,
532+ body,
533+ callbackId, // Send the callback ID to the parent
534+ } ) ;
535+ }
536+
537+ // Handles the result message from the parent actor
538+ handleGmailResult (
539+ callbackId : string ,
540+ result : { success : boolean ; message ?: string } ,
541+ ) : void {
542+ const callback = this . gmailCallbacks . get ( callbackId ) ;
543+ if ( callback ) {
544+ console . log (
545+ `NRWebContentModifier: Executing Gmail callback for ID: ${ callbackId } ` ,
546+ result ,
547+ ) ;
548+ try {
549+ callback ( result ) ;
550+ } catch ( e ) {
551+ console . error (
552+ "NRWebContentModifier: Error executing Gmail callback:" ,
553+ e ,
554+ ) ;
555+ }
556+ this . gmailCallbacks . delete ( callbackId ) ; // Clean up the callback
557+ } else {
558+ console . warn (
559+ `NRWebContentModifier: No Gmail callback found for ID: ${ callbackId } ` ,
560+ ) ;
561+ }
562+ }
563+
564+ // This function runs in the Gmail compose tab
565+ async fillAndSendGmail (
566+ to : string ,
567+ subject : string ,
568+ body : string ,
569+ callbackId : string ,
570+ ) : Promise < void > {
571+ console . log ( "NRWebContentModifier: Attempting to fill and send Gmail" , {
572+ to,
573+ subject,
574+ /* body shortened */ body : body . substring ( 0 , 50 ) + "..." ,
575+ callbackId,
576+ } ) ;
577+
578+ // --- SELECTORS TO BE DEFINED LATER --- // <<< EDIT ME: Replace with actual selectors when known
579+ const toSelector = "input[aria-expanded='false']" ;
580+ const subjectSelector = "input[name='subjectbox']" ;
581+ const bodySelector = "div[writingsuggestions='false']" ;
582+ const sendButtonSelector = "[jslog^='32601;']" ;
583+ // --- END OF SELECTORS --- //
584+
585+ try {
586+ // Wait for elements to appear (simple delay for now, robust checking needed)
587+ await new Promise ( ( resolve ) => setTimeout ( resolve , 5000 ) ) ; // Wait 5 seconds for compose window
588+
589+ console . log ( "NRWebContentModifier: Looking for Gmail fields..." ) ;
590+
591+ const toElement = this . document ?. querySelector (
592+ toSelector ,
593+ ) as HTMLTextAreaElement ;
594+ const subjectElement = this . document ?. querySelector (
595+ subjectSelector ,
596+ ) as HTMLInputElement ;
597+ const bodyElement = this . document ?. querySelector (
598+ bodySelector ,
599+ ) as HTMLDivElement ;
600+ const sendButtonElement = this . document ?. querySelector (
601+ sendButtonSelector ,
602+ ) as HTMLDivElement ;
603+
604+ if ( ! toElement || ! subjectElement || ! bodyElement || ! sendButtonElement ) {
605+ console . error (
606+ "NRWebContentModifier: Could not find all Gmail elements." ,
607+ {
608+ toElement : ! ! toElement ,
609+ subjectElement : ! ! subjectElement ,
610+ bodyElement : ! ! bodyElement ,
611+ sendButtonElement : ! ! sendButtonElement ,
612+ } ,
613+ ) ;
614+ throw new Error ( "Could not find all required Gmail compose elements." ) ;
615+ }
616+
617+ console . log (
618+ "NRWebContentModifier: Found Gmail elements, filling fields..." ,
619+ ) ;
620+
621+ // Fill the fields
622+ // For 'To', directly setting value might work, or might need input simulation
623+ toElement . value = to ;
624+ // Dispatch input event if needed
625+ toElement . dispatchEvent ( new Event ( "input" , { bubbles : true } ) ) ;
626+ toElement . dispatchEvent ( new Event ( "change" , { bubbles : true } ) ) ;
627+
628+ subjectElement . value = subject ;
629+ subjectElement . dispatchEvent ( new Event ( "input" , { bubbles : true } ) ) ;
630+
631+ // Body might be a contentEditable div
632+ bodyElement . focus ( ) ; // Ensure focus before manipulating
633+ // Clear existing content if necessary
634+ // bodyElement.innerHTML = '';
635+ // Set new content - plain text for now
636+ bodyElement . textContent = body ;
637+ // Dispatch input event to simulate typing
638+ bodyElement . dispatchEvent ( new Event ( "input" , { bubbles : true } ) ) ;
639+
640+ // Short delay before clicking send
641+ await new Promise ( ( resolve ) => setTimeout ( resolve , 1000 ) ) ;
642+
643+ console . log ( "NRWebContentModifier: Clicking send button..." ) ;
644+ sendButtonElement . click ( ) ;
645+
646+ console . log (
647+ "NRWebContentModifier: Send button clicked. Assuming success for now." ,
648+ ) ;
649+
650+ // Send success result back to parent
651+ this . sendAsyncMessage ( "WebContentModifier:GmailSent" , {
652+ callbackId : callbackId ,
653+ result : { success : true } ,
654+ } ) ;
655+ } catch ( error ) {
656+ console . error (
657+ "NRWebContentModifier: Error filling or sending Gmail:" ,
658+ error ,
659+ ) ;
660+ // Send failure result back to parent
661+ this . sendAsyncMessage ( "WebContentModifier:GmailSent" , {
662+ callbackId : callbackId ,
663+ result : {
664+ success : false ,
665+ message : error instanceof Error ? error . message : String ( error ) ,
666+ } ,
667+ } ) ;
668+ }
669+ }
481670}
0 commit comments