@@ -21,6 +21,7 @@ import {
21
21
} from '../Utils/BlobDownloader' ;
22
22
import { showWarningBox } from '../UI/Messages/MessageBox' ;
23
23
import { displayBlackLoadingScreen } from '../Utils/BrowserExternalWindowUtils' ;
24
+ import { UserCancellationError } from '../LoginProvider/Utils' ;
24
25
let nextExternalEditorWindowId = 0 ;
25
26
26
27
const externalEditorIndexHtml : { [ 'piskel' | 'yarn' | 'jfxr' ] : string } = {
@@ -29,11 +30,20 @@ const externalEditorIndexHtml: { ['piskel' | 'yarn' | 'jfxr']: string } = {
29
30
jfxr : 'external/jfxr/jfxr-index.html' ,
30
31
} ;
31
32
32
- const openAndWaitForExternalEditorWindow = async (
33
+ const openAndWaitForExternalEditorWindow = async ( {
34
+ externalEditorWindow,
35
+ externalEditorName,
36
+ externalEditorInput,
37
+ signal,
38
+ } : { |
33
39
externalEditorWindow : any ,
34
- editorName : 'piskel' | 'yarn' | 'jfxr' ,
35
- externalEditorInput : ExternalEditorInput
36
- ) : Promise < ?ExternalEditorOutput > => {
40
+ externalEditorName : 'piskel' | 'yarn' | 'jfxr' ,
41
+ externalEditorInput : ExternalEditorInput ,
42
+ signal : AbortSignal ,
43
+ | } ) : Promise < ?ExternalEditorOutput > => {
44
+ if ( signal . aborted ) {
45
+ return Promise . reject ( new UserCancellationError ( '' ) ) ;
46
+ }
37
47
return new Promise ( ( resolve , reject ) => {
38
48
let externalEditorLoaded = false ;
39
49
let externalEditorClosed = false ;
@@ -53,7 +63,7 @@ const openAndWaitForExternalEditorWindow = async (
53
63
54
64
const { id, payload } = event . data ;
55
65
if ( id === `external-editor-ready` ) {
56
- console . info ( `External editor "${ editorName } " ready.` ) ;
66
+ console . info ( `External editor "${ externalEditorName } " ready.` ) ;
57
67
58
68
// Some browsers like Safari might not trigger the "load" event, but now we can
59
69
// be sure the editor is loaded: the proof being that we received this message.
@@ -74,7 +84,9 @@ const openAndWaitForExternalEditorWindow = async (
74
84
window . location . origin
75
85
) ;
76
86
} else if ( id === `save-external-editor-output` ) {
77
- console . info ( `Received data from external editor "${ editorName } ."` ) ;
87
+ console . info (
88
+ `Received data from external editor "${ externalEditorName } ."`
89
+ ) ;
78
90
// $FlowFixMe - assuming the typing is good.
79
91
externalEditorOutput = payload ;
80
92
} else if ( event . data . id === 'close' ) {
@@ -90,13 +102,20 @@ const openAndWaitForExternalEditorWindow = async (
90
102
return ;
91
103
}
92
104
externalEditorClosed = true ;
93
- console . info ( `External editor "${ editorName } " closed.` ) ;
105
+ console . info ( `External editor "${ externalEditorName } " closed.` ) ;
94
106
window . removeEventListener ( 'message' , onMessageEvent ) ;
95
107
resolve ( externalEditorOutput ) ;
96
108
} ;
97
109
110
+ signal . addEventListener ( 'abort' , ( ) => {
111
+ reject ( new UserCancellationError ( '' ) ) ;
112
+ if ( externalEditorClosed ) return ;
113
+ externalEditorWindow . close ( ) ;
114
+ onExternalEditorWindowClosed ( ) ;
115
+ } ) ;
116
+
98
117
externalEditorWindow . addEventListener ( 'load' , ( ) => {
99
- console . info ( `External editor "${ editorName } " loaded.` ) ;
118
+ console . info ( `External editor "${ externalEditorName } " loaded.` ) ;
100
119
externalEditorLoaded = true ;
101
120
102
121
externalEditorWindow . addEventListener ( 'unload' , ( ) => {
@@ -110,14 +129,14 @@ const openAndWaitForExternalEditorWindow = async (
110
129
// (though not on Safari), then the editor will send a `external-editor-ready` event
111
130
// (on all browsers), after which we will then be ready to have it open the resources.
112
131
// (see `open-external-editor-input`).
113
- externalEditorWindow . location = externalEditorIndexHtml [ editorName ] ;
132
+ externalEditorWindow . location = externalEditorIndexHtml [ externalEditorName ] ;
114
133
115
134
// If the editor is not ready after 10 seconds and not closed, force it to be closed.
116
135
// Something wrong is going on and we don't want to block the user.
117
136
setTimeout ( ( ) => {
118
137
if ( externalEditorLoaded || externalEditorClosed ) return ;
119
138
console . info (
120
- `External editor "${ editorName } not loaded after 10 seconds - closing its window."`
139
+ `External editor "${ externalEditorName } not loaded after 10 seconds - closing its window."`
121
140
) ;
122
141
123
142
// The external editor is not loaded after 10 seconds, abort.
@@ -232,7 +251,7 @@ const editWithBrowserExternalEditor = async ({
232
251
resourceKind : ResourceKind ,
233
252
options : EditWithExternalEditorOptions ,
234
253
| } ) => {
235
- const { project , resourceNames , resourceManagementProps } = options ;
254
+ const { project , resourceNames , resourceManagementProps , signal } = options ;
236
255
237
256
// Fetch all edited resources as base64 encoded "data urls" (`data:...`).
238
257
const resources = await downloadAndPrepareExternalEditorBase64Resources ( {
@@ -254,9 +273,7 @@ const editWithBrowserExternalEditor = async ({
254
273
255
274
sendExternalEditorOpened ( externalEditorName ) ;
256
275
const externalEditorOutput : ?ExternalEditorOutput = await openAndWaitForExternalEditorWindow (
257
- externalEditorWindow ,
258
- externalEditorName ,
259
- externalEditorInput
276
+ { externalEditorWindow, externalEditorName, externalEditorInput, signal }
260
277
) ;
261
278
if ( ! externalEditorOutput ) return null ; // Changes cancelled.
262
279
0 commit comments