1
+ class importExportUsingFileAPI {
2
+
3
+ saveNeeded : boolean ;
4
+ fileHandle : any ;
5
+ filename : string ;
6
+ lastsaved : string ;
7
+
8
+ constructor ( ) {
9
+ this . clear ( ) ;
10
+ //this.updateButtons();
11
+ }
12
+
13
+ clear ( ) {
14
+ this . saveNeeded = false ;
15
+ this . fileHandle = null ;
16
+ this . filename = null ;
17
+ }
18
+
19
+ updateLastSaved ( ) {
20
+ var currentdate = new Date ( ) ;
21
+ this . lastsaved = currentdate . getHours ( ) . toString ( ) . padStart ( 2 , '0' ) + ":" +
22
+ currentdate . getMinutes ( ) . toString ( ) . padStart ( 2 , '0' ) + ":" +
23
+ currentdate . getSeconds ( ) . toString ( ) . padStart ( 2 , '0' ) ; ;
24
+
25
+ //If there is an object on the screen that needs updating, do it
26
+ if ( document . getElementById ( 'exportscreen' ) as HTMLInputElement ) {
27
+ exportscreen ( ) ; // Update the export screen if we are actually on the export screen
28
+ }
29
+ }
30
+
31
+ //updateButtons() {
32
+ //document.getElementById('saveAsButton').disabled = !(this.fileAPIdata.saveNeeded);
33
+ /* document.getElementById('saveAsButton').disabled = false;
34
+ document.getElementById('saveButton').disabled = !(this.fileAPIdata.saveNeeded);
35
+ }*/
36
+
37
+ setSaveNeeded ( input ) {
38
+ let lastSaveNeeded = this . saveNeeded ;
39
+ this . saveNeeded = input ;
40
+ //if (input !== lastSaveNeeded) this.updateButtons();
41
+ }
42
+
43
+ async readFile ( ) {
44
+
45
+ [ this . fileHandle ] = await ( window as any ) . showOpenFilePicker ( {
46
+ types : [ {
47
+ description : 'Eendraadschema (.eds)' ,
48
+ accept : { 'application/eds' : [ '.eds' ] } ,
49
+ } ] ,
50
+ } ) ;
51
+
52
+ const file = await ( this . fileHandle as any ) . getFile ( ) ;
53
+ const contents = await file . text ( ) ;
54
+
55
+ this . filename = file . name ;
56
+ structure . properties . filename = file . name ;
57
+
58
+ this . setSaveNeeded ( false ) ;
59
+
60
+ this . updateLastSaved ( ) ; // Needed because import_to_structure whipes everything
61
+
62
+ return contents ;
63
+ }
64
+
65
+ async saveAs ( content : string ) {
66
+ const options = {
67
+ suggestedName : structure . properties . filename ,
68
+ types : [ {
69
+ description : 'Eendraadschema (.eds)' ,
70
+ accept : { 'application/eds' : [ '.eds' ] } ,
71
+ } ] ,
72
+ startIn : 'documents' // Suggests the Documents folder
73
+ } ;
74
+
75
+ this . fileHandle = await ( window as any ) . showSaveFilePicker ( options ) ;
76
+ await this . saveFile ( content , this . fileHandle ) ;
77
+
78
+
79
+ } ;
80
+
81
+ async saveFile ( content : any , handle : any ) {
82
+ const writable = await handle . createWritable ( ) ;
83
+ await writable . write ( content ) ;
84
+ await writable . close ( ) ;
85
+
86
+ this . filename = handle . name ;
87
+ structure . properties . filename = handle . name ;
88
+
89
+ this . setSaveNeeded ( false ) ;
90
+
91
+ this . updateLastSaved ( ) ;
92
+ } ;
93
+
94
+ async save ( content : string ) {
95
+ await this . saveFile ( content , this . fileHandle ) ;
96
+ } ;
97
+ }
98
+
99
+ var fileAPIobj = new importExportUsingFileAPI ( ) ;
100
+
101
+ /* FUNCTION importjson
102
+
103
+ This is the callback function for the legacy filepicker if the file API is not available in the browser */
104
+
105
+ var importjson = function ( event ) {
106
+ var input = event . target ;
107
+ var reader = new FileReader ( ) ;
108
+ var text :string = "" ;
109
+
110
+ reader . onload = function ( ) {
111
+ import_to_structure ( reader . result . toString ( ) ) ;
112
+ } ;
113
+
114
+ reader . readAsText ( input . files [ 0 ] ) ;
115
+
116
+ // Scroll to top left for the SVG, this can only be done at the end because "right col" has to actually be visible
117
+ /*const rightelem = document.getElementById("right_col");
118
+ if (rightelem != null) {
119
+ rightelem.scrollTop = 0;
120
+ rightelem.scrollLeft = 0;
121
+ }*/
122
+ } ;
123
+
124
+ /* FUNCTION importclicked()
125
+
126
+ Gets called when a user wants to open a file. Checks if the fileAPI is available in the browser.
127
+ If so, the fileAPI is used. If not, the legacy function importjson is called */
128
+
129
+ async function importclicked ( ) {
130
+ if ( ( window as any ) . showOpenFilePicker ) { // Use fileAPI
131
+ let data = await fileAPIobj . readFile ( ) ;
132
+ import_to_structure ( data ) ;
133
+ } else { // Legacy
134
+ document . getElementById ( 'importfile' ) . click ( ) ;
135
+ ( document . getElementById ( 'importfile' ) as HTMLInputElement ) . value = "" ;
136
+ }
137
+ }
138
+
1
139
/* FUNCTION upgrade_version
2
140
3
141
Takes a structure, usually imported from json into javascript object, and performs a version upgrade if needed.
@@ -212,6 +350,20 @@ function import_to_structure(mystring: string, redraw = true) {
212
350
// Clear the undo stack and push this one on top
213
351
undostruct . clear ( ) ;
214
352
undostruct . store ( ) ;
353
+
354
+ // Scroll to top left for the SVG and HTML, this can only be done at the end because "right col" has to actually be visible
355
+ const leftelem = document . getElementById ( "left_col" ) ;
356
+ if ( leftelem != null ) {
357
+ leftelem . scrollTop = 0 ;
358
+ leftelem . scrollLeft = 0 ;
359
+ }
360
+
361
+ const rightelem = document . getElementById ( "right_col" ) ;
362
+ if ( rightelem != null ) {
363
+ rightelem . scrollTop = 0 ;
364
+ rightelem . scrollLeft = 0 ;
365
+ }
366
+
215
367
}
216
368
217
369
function structure_to_json ( ) {
@@ -231,4 +383,79 @@ function structure_to_json() {
231
383
232
384
return ( text ) ;
233
385
386
+ }
387
+
388
+ /* FUNCTION download_by_blob
389
+
390
+ Downloads an EDS file to the user's PC
391
+
392
+ */
393
+
394
+ function download_by_blob ( text , filename , mimeType ) {
395
+
396
+ var element = document . createElement ( 'a' ) ;
397
+ if ( navigator . msSaveBlob ) {
398
+ navigator . msSaveBlob ( new Blob ( [ text ] , {
399
+ type : mimeType
400
+ } ) , filename ) ;
401
+ } else if ( URL && 'download' in element ) {
402
+ let uriContent = URL . createObjectURL ( new Blob ( [ text ] , { type : mimeType } ) ) ;
403
+ element . setAttribute ( 'href' , uriContent ) ;
404
+ element . setAttribute ( 'download' , filename ) ;
405
+ element . style . display = 'none' ;
406
+ document . body . appendChild ( element ) ;
407
+ element . click ( ) ;
408
+ document . body . removeChild ( element ) ;
409
+ } else {
410
+ this . location . go ( `${ mimeType } ,${ encodeURIComponent ( text ) } ` ) ;
411
+ }
412
+
413
+ }
414
+
415
+ /* FUNCTION exportScreen
416
+
417
+ Shows the exportscreen. It will look different depending on whether the browser supports the file API or not
418
+
419
+ */
420
+
421
+ function exportscreen ( ) {
422
+
423
+ var strleft : string = '<br><span id="exportscreen"></span>' ; //We need the id to check elsewhere that the screen is open
424
+
425
+ if ( ( window as any ) . showOpenFilePicker ) { // Use fileAPI
426
+
427
+ if ( fileAPIobj . filename != null ) {
428
+ strleft += 'Laatst geopend of opgeslagen om <b>' + fileAPIobj . lastsaved + '</b> met naam <b>' + fileAPIobj . filename + '</b><br><br>'
429
+ + 'Klik hieronder om bij te werken<br><br>'
430
+ strleft += '<button onclick="exportjson(saveAs = false)">Opslaan</button> ' ;
431
+ strleft += '<button onclick="exportjson(saveAs = true)">Opslaan als</button><br><br>' ;
432
+ } else {
433
+ strleft += 'Uw werk werd nog niet opgeslagen. Klik hieronder.<br><br>' ;
434
+ strleft += '<button onclick="exportjson(saveAs = true)">Opslaan als</button>' ;
435
+ strleft += '<br><br>' ;
436
+ }
437
+ strleft += '<table border=0>' ;
438
+ strleft += PROP_GDPR ( ) ; //Function returns empty for GIT version, returns GDPR notice when used online.
439
+ strleft += '</table>' ;
440
+
441
+ } else { // Legacy
442
+ strleft += '<table border=0><tr><td width=500 style="vertical-align:top;padding:5px">' ;
443
+ strleft += 'Bestandsnaam: <span id="settings"><code>' + structure . properties . filename + '</code><br><button onclick="HL_enterSettings()">Wijzigen</button> <button onclick="exportjson()">Opslaan</button></span>' ;
444
+ strleft += '</td><td style="vertical-align:top;padding:5px">'
445
+ strleft += 'U kan het schema opslaan op uw lokale harde schijf voor later gebruik. De standaard-naam is eendraadschema.eds. U kan deze wijzigen door links op "wijzigen" te klikken. ' ;
446
+ strleft += 'Klik vervolgens op "opslaan" en volg de instructies van uw browser. '
447
+ strleft += 'In de meeste gevallen zal uw browser het bestand automatisch plaatsen in de Downloads-folder tenzij u uw browser instelde dat die eerst een locatie moet vragen.<br><br>'
448
+ strleft += 'Eens opgeslagen kan het schema later opnieuw geladen worden door in het menu "openen" te kiezen en vervolgens het bestand op uw harde schijf te selecteren.<br><br>'
449
+ strleft += '</td></tr>' ;
450
+
451
+ strleft += PROP_GDPR ( ) ; //Function returns empty for GIT version, returns GDPR notice when used online.
452
+
453
+ strleft += '</table>' ;
454
+
455
+ // Plaats input box voor naam van het schema bovenaan --
456
+ strleft += '<br>' ;
457
+ }
458
+
459
+ document . getElementById ( "configsection" ) . innerHTML = strleft ;
460
+ hide2col ( ) ;
234
461
}
0 commit comments