@@ -233,7 +233,7 @@ function layerTest(input: {
233233 readonly destroyAll ?: Effect . Effect < void > ;
234234 readonly onWindowCreate ?: Effect . Effect < void > ;
235235 readonly openedExternalUrls ?: unknown [ ] ;
236- readonly copiedTexts ?: string [ ] ;
236+ readonly onCopyText ?: ( text : string ) => Effect . Effect < void > ;
237237 readonly onPopupTemplate ?: ( input : ElectronMenu . ElectronMenuTemplateInput ) => Effect . Effect < void > ;
238238 readonly previewZoomReapplies ?: number [ ] ;
239239 readonly onReveal ?: ( window : Electron . BrowserWindow ) => void ;
@@ -325,10 +325,7 @@ function layerTest(input: {
325325 return true ;
326326 } ) ,
327327 openSystemSettings : ( ) => Effect . succeed ( true ) ,
328- copyText : ( text ) =>
329- Effect . sync ( ( ) => {
330- input . copiedTexts ?. push ( text ) ;
331- } ) ,
328+ copyText : input . onCopyText ?? ( ( ) => Effect . void ) ,
332329 } satisfies ElectronShell . ElectronShell [ "Service" ] ) ,
333330 layerElectronTheme ,
334331 layerElectronWindow ,
@@ -1186,6 +1183,56 @@ describe("DesktopWindow", () => {
11861183 } ) ,
11871184 ) ;
11881185
1186+ it . effect ( "offers to copy the bare address when right-clicking a mailto link" , ( ) =>
1187+ Effect . gen ( function * ( ) {
1188+ const fakeWindow = makeFakeBrowserWindow ( ) ;
1189+ const createCount = yield * Ref . make ( 0 ) ;
1190+ const mainWindow = yield * Ref . make < Option . Option < Electron . BrowserWindow > > ( Option . none ( ) ) ;
1191+ const popup = yield * Deferred . make < ElectronMenu . ElectronMenuTemplateInput > ( ) ;
1192+ const copied = yield * Deferred . make < string > ( ) ;
1193+ const layer = layerTest ( {
1194+ window : fakeWindow . window ,
1195+ createCount,
1196+ mainWindow,
1197+ onPopupTemplate : ( input ) => Deferred . succeed ( popup , input ) ,
1198+ onCopyText : ( text ) => Deferred . succeed ( copied , text ) ,
1199+ } ) ;
1200+
1201+ yield * Effect . gen ( function * ( ) {
1202+ const desktopWindow = yield * DesktopWindow . DesktopWindow ;
1203+ yield * desktopWindow . handleBackendReady ( new URL ( "http://127.0.0.1:3773" ) ) ;
1204+
1205+ const contextMenu = fakeWindow . webContentsListeners . get ( "context-menu" ) ;
1206+ if ( ! contextMenu ) {
1207+ return yield * Effect . die ( "context-menu listener was not registered" ) ;
1208+ }
1209+ contextMenu (
1210+ { preventDefault : vi . fn ( ) } ,
1211+ {
1212+ linkURL : "mailto:restaurant%40example.com?subject=Hi" ,
1213+ misspelledWord : "" ,
1214+ dictionarySuggestions : [ ] ,
1215+ mediaType : "none" ,
1216+ editFlags : { canCut : false , canCopy : false , canPaste : false , canSelectAll : true } ,
1217+ } ,
1218+ ) ;
1219+
1220+ const { template } = yield * Deferred . await ( popup ) ;
1221+ const copyEmail = template . find ( ( item ) => item . label === "Copy Email Address" ) ;
1222+ assert . isDefined (
1223+ copyEmail ,
1224+ `no "Copy Email Address" item in ${ JSON . stringify ( template . map ( ( item ) => item . label ?? item . role ?? item . type ) ) } ` ,
1225+ ) ;
1226+ copyEmail ?. click ?.(
1227+ { } as Electron . MenuItem ,
1228+ fakeWindow . window ,
1229+ { } as Electron . KeyboardEvent ,
1230+ ) ;
1231+ assert . equal ( yield * Deferred . await ( copied ) , "[email protected] " ) ; 1232+ } ) . pipe ( Effect . provide ( layer ) ) ;
1233+ } ) ,
1234+ ) ;
1235+
11891236 it . effect (
11901237 "retries opening the real main on activate when a failed post-readiness open left only the splash" ,
11911238 ( ) =>
0 commit comments