@@ -2028,6 +2028,10 @@ export class IDE {
2028
2028
loaded = false ;
2029
2029
/** Whether the IDE is currently loading a new document. */
2030
2030
loading = false ;
2031
+
2032
+ /** When attempting to overwrite an existing document with a new one, the ID of the document to overwrite. */
2033
+ overwriteId :string ;
2034
+
2031
2035
/** The current editor generation. Used for imposing a relative ordering on parses. */
2032
2036
generation = 0 ;
2033
2037
/** Whether the currently open document is a modified version of an example. */
@@ -2064,6 +2068,7 @@ export class IDE {
2064
2068
{ c : "main-pane" , children : [
2065
2069
this . noticesElem ( ) ,
2066
2070
this . editor . render ( ) ,
2071
+ this . overwriteId ? this . overwritePrompt ( ) : undefined ,
2067
2072
] } ,
2068
2073
this . comments . render ( )
2069
2074
] } ;
@@ -2087,6 +2092,37 @@ export class IDE {
2087
2092
}
2088
2093
}
2089
2094
2095
+ overwritePrompt ( ) :Elem {
2096
+ return { c : "modal-overlay" , children : [
2097
+ { c : "modal-window" , children : [
2098
+ { t : "h3" , text : "Overwrite existing copy?" } ,
2099
+ { c : "flex-row controls" , children : [
2100
+ { c : "btn load-btn" , text : "load existing" , click : this . loadExisting } ,
2101
+ { c : "btn danger overwrite-btn" , text : "overwrite" , click : this . overwriteDocument } ,
2102
+ ] }
2103
+ ] }
2104
+ ] } ;
2105
+ }
2106
+
2107
+ loadExisting = ( ) => {
2108
+ let id = this . overwriteId ;
2109
+ this . overwriteId = undefined ;
2110
+ this . loadFile ( id ) ;
2111
+ this . render ( ) ;
2112
+ }
2113
+
2114
+ overwriteDocument = ( ) => {
2115
+ let id = this . overwriteId ;
2116
+ this . overwriteId = undefined ;
2117
+ this . cloneDocument ( id ) ;
2118
+ this . render ( ) ;
2119
+ }
2120
+
2121
+ promptOverwrite ( neueId :string ) {
2122
+ this . overwriteId = neueId ;
2123
+ this . render ( ) ;
2124
+ }
2125
+
2090
2126
render ( ) {
2091
2127
// Update child states as necessary
2092
2128
this . renderer . render ( [ this . elem ( ) ] ) ;
@@ -2143,13 +2179,16 @@ export class IDE {
2143
2179
return false ;
2144
2180
}
2145
2181
2146
- // Otherwise we load the file from either localstorage or from the supplied
2147
- // examples object
2148
- let saves = JSON . parse ( localStorage . getItem ( "eve-saves" ) || "{}" ) ;
2149
- let code = saves [ docId ] ;
2150
- if ( code ) {
2151
- this . modified = true ;
2152
- } else {
2182
+ // Otherwise find the content locally.
2183
+ let code ;
2184
+ if ( this . local ) {
2185
+ let saves = JSON . parse ( localStorage . getItem ( "eve-saves" ) || "{}" ) ;
2186
+ code = saves [ docId ] ;
2187
+ if ( code ) {
2188
+ this . modified = true ;
2189
+ }
2190
+ }
2191
+ if ( ! code ) {
2153
2192
code = this . _fileCache [ docId ] ;
2154
2193
this . modified = false ;
2155
2194
}
@@ -2205,9 +2244,6 @@ export class IDE {
2205
2244
saveDocument ( ) {
2206
2245
if ( ! this . documentId || ! this . loaded ) return ;
2207
2246
2208
- let md = this . editor . toMarkdown ( ) ;
2209
- let isDirty = md !== this . _fileCache [ this . documentId ] ;
2210
-
2211
2247
// When we try to edit a gist-backed file we need to fork it and save the new file to disk.
2212
2248
// @FIXME : This is all terribly hacky, and needs to be cleaned up as part of the FileStore rework.
2213
2249
if ( this . documentId . indexOf ( "gist:" ) === 0 ) {
@@ -2216,22 +2252,17 @@ export class IDE {
2216
2252
let neueId = oldId . slice ( 5 ) ;
2217
2253
neueId = neueId . slice ( 0 , 7 ) + neueId . slice ( 32 ) ;
2218
2254
neueId = `/root/${ neueId } ` ;
2219
- this . documentId = neueId ;
2220
-
2221
- let navNode = this . navigator . nodes [ oldId ] ;
2222
- if ( navNode ) navNode . id = neueId ;
2223
- this . navigator . nodes [ oldId ] = undefined ;
2224
- this . navigator . nodes [ neueId ] = navNode ;
2225
- if ( this . navigator . currentId === oldId ) this . navigator . currentId = neueId ;
2226
2255
2227
- let currentHashChunks = location . hash . split ( "#" ) . slice ( 1 ) ;
2228
- let modified = neueId ;
2229
- if ( currentHashChunks [ 1 ] ) {
2230
- modified += `/#` + currentHashChunks [ 1 ] ;
2256
+ if ( this . _fileCache [ neueId ] ) {
2257
+ return this . promptOverwrite ( neueId ) ;
2258
+ } else {
2259
+ return this . cloneDocument ( neueId ) ;
2231
2260
}
2232
- location . hash = modified ;
2233
2261
}
2234
2262
2263
+ let md = this . editor . toMarkdown ( ) ;
2264
+ let isDirty = md !== this . _fileCache [ this . documentId ] ;
2265
+
2235
2266
// @NOTE : We sync this here to prevent a terrible reload bug that occurs when saving to the file system.
2236
2267
// This isn't really the right fix, but it's a quick one that helps prevent lost work in trivial cases
2237
2268
// like navigating the workspace.
@@ -2268,6 +2299,33 @@ export class IDE {
2268
2299
this . loadFile ( docId ) ;
2269
2300
}
2270
2301
2302
+ cloneDocument ( neueId :string ) {
2303
+ let oldId = this . documentId ;
2304
+ this . documentId = neueId ;
2305
+
2306
+ let navNode = this . navigator . nodes [ oldId ] ;
2307
+ if ( navNode ) {
2308
+ let neueNode :TreeNode = { } as any ;
2309
+ for ( let attr in navNode ) {
2310
+ neueNode [ attr ] = navNode [ attr ] ;
2311
+ }
2312
+ neueNode . id = neueId ;
2313
+ neueNode . children = [ ] ;
2314
+ this . navigator . nodes [ neueId ] = neueNode ;
2315
+ }
2316
+
2317
+ if ( this . navigator . currentId === oldId ) this . navigator . currentId = neueId ;
2318
+
2319
+ let currentHashChunks = location . hash . split ( "#" ) . slice ( 1 ) ;
2320
+ let modified = neueId ;
2321
+ if ( currentHashChunks [ 1 ] ) {
2322
+ modified += `/#` + currentHashChunks [ 1 ] ;
2323
+ }
2324
+ location . hash = modified ;
2325
+
2326
+ this . saveDocument ( ) ;
2327
+ }
2328
+
2271
2329
saveToGist ( ) {
2272
2330
// @FIXME : We really need a display name setup for documents.
2273
2331
let savingNotice = this . injectNotice ( "info" , "Saving..." ) ;
0 commit comments