@@ -18,6 +18,14 @@ define(function (require, exports, module) {
1818 var Buffer = Filer . Buffer ;
1919 var Path = Filer . Path ;
2020 var fs = Filer . fs ( ) ;
21+ var Dialogs = require ( "widgets/Dialogs" ) ;
22+ var DefaultDialogs = require ( "widgets/DefaultDialogs" ) ;
23+ var Strings = require ( "strings" ) ;
24+ var StringUtils = require ( "utils/StringUtils" ) ;
25+
26+ var CANCEL_OPERATION = - 1 ,
27+ OVERWRITE_OPERATION = 1 ,
28+ KEEP_EXISTING_OPERATION = 2 ;
2129
2230 // Mac and Windows clutter zip files with extra files/folders we don't need
2331 function skipFile ( filename ) {
@@ -56,6 +64,48 @@ define(function (require, exports, module) {
5664 CommandManager . execute ( Commands . FILE_REFRESH ) . always ( callback ) ;
5765 }
5866
67+ function showOverwriteWarning ( path , callback ) {
68+ var filepath = stripRoot ( path ) ;
69+
70+ Dialogs . showModalDialog (
71+ DefaultDialogs . DIALOG_ID_INFO ,
72+ Strings . FILE_EXISTS_HEADER ,
73+ StringUtils . format ( Strings . DND_FILE_REPLACE , filepath ) ,
74+ [ {
75+ className : Dialogs . DIALOG_BTN_CLASS_NORMAL ,
76+ id : Dialogs . DIALOG_BTN_CANCEL ,
77+ text : Strings . CANCEL
78+ } ,
79+ {
80+ className : Dialogs . DIALOG_BTN_CLASS_NORMAL ,
81+ id : Dialogs . DIALOG_BTN_IMPORT ,
82+ text : Strings . USE_IMPORTED
83+ } ,
84+ {
85+ className : Dialogs . DIALOG_BTN_CLASS_PRIMARY ,
86+ id : Dialogs . DIALOG_BTN_OK ,
87+ text : Strings . KEEP_EXISTING
88+ } ]
89+ ) . getPromise ( ) . then ( function ( id ) {
90+ var result ;
91+ if ( id === Dialogs . DIALOG_BTN_IMPORT ) {
92+ result = OVERWRITE_OPERATION ;
93+ } else if ( id === Dialogs . DIALOG_BTN_OK ) {
94+ result = KEEP_EXISTING_OPERATION ;
95+ } else if ( id === Dialogs . DIALOG_BTN_CANCEL ) {
96+ result = CANCEL_OPERATION ;
97+ }
98+ callback ( null , result ) ;
99+ } , callback ) ;
100+ }
101+
102+ function stripRoot ( path ) {
103+ var root = StartupState . project ( "root" ) ;
104+ var rootRegex = new RegExp ( "^" + root + "\/?" ) ;
105+
106+ return path . replace ( rootRegex , "" ) ;
107+ }
108+
59109 // zipfile can be a path (string) to a zipfile, or raw binary data.
60110 function unzip ( zipfile , options , callback ) {
61111 var projectPrefix = StartupState . project ( "zipFilenamePrefix" ) . replace ( / \/ ? $ / , "/" ) ;
@@ -105,28 +155,42 @@ define(function (require, exports, module) {
105155 var basedir = Path . dirname ( path . absPath ) ;
106156
107157 if ( path . isDirectory ) {
108- fs . mkdirp ( path . absPath , callback ) ;
109- } else {
110- // XXX: some zip files don't seem to be structured such that dirs
111- // get created before files. Create base dir if not there yet.
112- fs . stat ( basedir , function ( err , stats ) {
113- if ( err ) {
114- if ( err . code !== "ENOENT" ) {
158+ return fs . mkdirp ( path . absPath , callback ) ;
159+ }
160+
161+ // XXX: some zip files don't seem to be structured such that dirs
162+ // get created before files. Create base dir if not there yet.
163+ fs . mkdirp ( basedir , function ( err ) {
164+ if ( err ) {
165+ return callback ( err ) ;
166+ }
167+
168+ fs . stat ( path . absPath , function ( err , stats ) {
169+ if ( err && err . code !== "ENOENT" ) {
170+ return callback ( err ) ;
171+ }
172+
173+ if ( stats . type !== "FILE" ) {
174+ return callback ( ) ;
175+ }
176+
177+ showOverwriteWarning ( path . absPath , function ( err , result ) {
178+ if ( err ) {
115179 return callback ( err ) ;
116180 }
117181
118- fs . mkdirp ( basedir , function ( err ) {
119- if ( err ) {
120- return callback ( err ) ;
121- }
122-
182+ if ( result === OVERWRITE_OPERATION ) {
123183 FilerUtils . writeFileAsBinary ( path . absPath , path . data , callback ) ;
124- } ) ;
125- } else {
126- FilerUtils . writeFileAsBinary ( path . absPath , path . data , callback ) ;
127- }
184+ } else if ( result === KEEP_EXISTING_OPERATION ) {
185+ callback ( ) ;
186+ } else if ( result === CANCEL_OPERATION ) {
187+ callback ( new Error ( "Operation Cancelled" ) ) ;
188+ } else {
189+ callback ( new Error ( "Unknown result: " + result ) ) ;
190+ }
191+ } ) ;
128192 } ) ;
129- }
193+ } ) ;
130194 }
131195
132196 async . eachSeries ( filenames , decompress , function ( err ) {
@@ -245,11 +309,35 @@ define(function (require, exports, module) {
245309 }
246310
247311 fs . mkdirp ( basedir , function ( err ) {
248- if ( err && err . code !== "EEXIST" ) {
312+ if ( err ) {
249313 return callback ( err ) ;
250314 }
251315
252- FilerUtils . writeFileAsBinary ( path , new Buffer ( data ) , callback ) ;
316+ fs . stat ( path , function ( err , stats ) {
317+ if ( err && err . code !== "ENOENT" ) {
318+ return callback ( err ) ;
319+ }
320+
321+ if ( stats . type !== "FILE" ) {
322+ return callback ( ) ;
323+ }
324+
325+ showOverwriteWarning ( path , function ( err , result ) {
326+ if ( err ) {
327+ return callback ( err ) ;
328+ }
329+
330+ if ( result === OVERWRITE_OPERATION ) {
331+ FilerUtils . writeFileAsBinary ( path , new Buffer ( data ) , callback ) ;
332+ } else if ( result === KEEP_EXISTING_OPERATION ) {
333+ callback ( ) ;
334+ } else if ( result === CANCEL_OPERATION ) {
335+ callback ( new Error ( "Operation Cancelled" ) ) ;
336+ } else {
337+ callback ( new Error ( "Unknown result: " + result ) ) ;
338+ }
339+ } ) ;
340+ } ) ;
253341 } ) ;
254342 }
255343
0 commit comments