@concord-consortium/cloud-file-manager 2.1.0-pre.15 → 2.1.0-pre.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/client.js +1 -1
- package/dist/cjs/providers/provider-interface.js +1 -1
- package/dist/cjs/utils/ios-file-saver.d.ts +42 -0
- package/dist/cjs/utils/ios-file-saver.js +98 -0
- package/dist/cjs/utils/ios-file-saver.js.map +1 -0
- package/dist/cjs/views/local-file-tab-save-view.js +45 -24
- package/dist/cjs/views/local-file-tab-save-view.js.map +1 -1
- package/dist/esm/client.js +1 -1
- package/dist/esm/providers/provider-interface.js +1 -1
- package/dist/esm/utils/ios-file-saver.d.ts +42 -0
- package/dist/esm/utils/ios-file-saver.js +91 -0
- package/dist/esm/utils/ios-file-saver.js.map +1 -0
- package/dist/esm/views/local-file-tab-save-view.js +45 -24
- package/dist/esm/views/local-file-tab-save-view.js.map +1 -1
- package/dist/examples/index.html +1 -0
- package/dist/examples/local-json-save.html +36 -0
- package/dist/index.html +1 -1
- package/dist/js/app.js +1 -1
- package/dist/js/app.js.LICENSE.txt +0 -2
- package/dist/js/app.js.map +1 -1
- package/package.json +5 -3
- package/dist/cjs/lib/file-saver.d.ts +0 -2
- package/dist/cjs/lib/file-saver.js +0 -164
- package/dist/cjs/lib/file-saver.js.map +0 -1
- package/dist/esm/lib/file-saver.d.ts +0 -2
- package/dist/esm/lib/file-saver.js +0 -164
- package/dist/esm/lib/file-saver.js.map +0 -1
package/dist/cjs/client.js
CHANGED
|
@@ -236,7 +236,7 @@ class CloudFileManagerClient {
|
|
|
236
236
|
}
|
|
237
237
|
// initialize the cloudContentFactory with all data we want in the envelope
|
|
238
238
|
provider_interface_1.cloudContentFactory.setEnvelopeMetadata({
|
|
239
|
-
cfmVersion: '2.1.0-pre.
|
|
239
|
+
cfmVersion: '2.1.0-pre.16', // replaced by version number at build time
|
|
240
240
|
appName: this.appOptions.appName || "",
|
|
241
241
|
appVersion: this.appOptions.appVersion || "",
|
|
242
242
|
appBuildNum: this.appOptions.appBuildNum || ""
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for detecting iOS Safari and handling iOS-specific file download issues.
|
|
3
|
+
*
|
|
4
|
+
* iOS Safari 18.2+ has a bug where blob URLs created with URL.createObjectURL()
|
|
5
|
+
* don't properly save to the Files app - they get stuck in Safari's temporary
|
|
6
|
+
* download cache. This module provides detection and a data URL workaround.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Detects if the current browser is Safari on iOS.
|
|
10
|
+
* This includes iPad in desktop mode (which reports as "Macintosh" but has touch).
|
|
11
|
+
*/
|
|
12
|
+
export declare function isIOSSafari(): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Converts a Blob to a data URL using FileReader.
|
|
15
|
+
* This is a workaround for iOS Safari's blob URL issues.
|
|
16
|
+
*
|
|
17
|
+
* @param blob - The blob to convert
|
|
18
|
+
* @returns Promise<string> - The data URL
|
|
19
|
+
*/
|
|
20
|
+
export declare function blobToDataUrl(blob: Blob): Promise<string>;
|
|
21
|
+
/**
|
|
22
|
+
* Downloads a file using a data URL approach.
|
|
23
|
+
* Creates a temporary anchor element with the data URL and triggers a click.
|
|
24
|
+
*
|
|
25
|
+
* Note: The `download` attribute behavior varies by browser for data URLs.
|
|
26
|
+
* Testing on iOS Safari 18.7 showed the filename is honored, though older
|
|
27
|
+
* versions may use a generic name. Desktop browsers generally respect the
|
|
28
|
+
* filename value.
|
|
29
|
+
*
|
|
30
|
+
* @param blob - The file content as a Blob
|
|
31
|
+
* @param filename - The filename for the download
|
|
32
|
+
*/
|
|
33
|
+
export declare function downloadViaDataUrl(blob: Blob, filename: string): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Handles file download on iOS Safari, working around the blob URL bug.
|
|
36
|
+
* Uses data URL approach which triggers Safari's standard download dialog.
|
|
37
|
+
*
|
|
38
|
+
* @param blob - The file content as a Blob
|
|
39
|
+
* @param filename - The filename to use
|
|
40
|
+
* @returns Promise<boolean> - true if handled, false if should use default behavior
|
|
41
|
+
*/
|
|
42
|
+
export declare function handleIOSDownload(blob: Blob, filename: string): Promise<boolean>;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Utilities for detecting iOS Safari and handling iOS-specific file download issues.
|
|
4
|
+
*
|
|
5
|
+
* iOS Safari 18.2+ has a bug where blob URLs created with URL.createObjectURL()
|
|
6
|
+
* don't properly save to the Files app - they get stuck in Safari's temporary
|
|
7
|
+
* download cache. This module provides detection and a data URL workaround.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.handleIOSDownload = exports.downloadViaDataUrl = exports.blobToDataUrl = exports.isIOSSafari = void 0;
|
|
11
|
+
/**
|
|
12
|
+
* Detects if the current browser is Safari on iOS.
|
|
13
|
+
* This includes iPad in desktop mode (which reports as "Macintosh" but has touch).
|
|
14
|
+
*/
|
|
15
|
+
function isIOSSafari() {
|
|
16
|
+
if (typeof navigator === 'undefined')
|
|
17
|
+
return false;
|
|
18
|
+
const ua = navigator.userAgent;
|
|
19
|
+
// Check for iOS devices (iPhone, iPad, iPod)
|
|
20
|
+
// Also check for iPad in desktop mode (reports as Macintosh but has touch capability)
|
|
21
|
+
// Regular Macs report maxTouchPoints = 0, iPads report 5
|
|
22
|
+
const isIOS = /iPad|iPhone|iPod/.test(ua) ||
|
|
23
|
+
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 0);
|
|
24
|
+
// Check for Safari (not Chrome, Firefox, Edge, etc. on iOS)
|
|
25
|
+
// All iOS browsers use WebKit, but we specifically want Safari's behavior
|
|
26
|
+
const isSafari = /Safari/.test(ua) && !/Chrome|CriOS|FxiOS|EdgiOS|OPiOS/.test(ua);
|
|
27
|
+
return isIOS && isSafari;
|
|
28
|
+
}
|
|
29
|
+
exports.isIOSSafari = isIOSSafari;
|
|
30
|
+
/**
|
|
31
|
+
* Converts a Blob to a data URL using FileReader.
|
|
32
|
+
* This is a workaround for iOS Safari's blob URL issues.
|
|
33
|
+
*
|
|
34
|
+
* @param blob - The blob to convert
|
|
35
|
+
* @returns Promise<string> - The data URL
|
|
36
|
+
*/
|
|
37
|
+
function blobToDataUrl(blob) {
|
|
38
|
+
return new Promise((resolve, reject) => {
|
|
39
|
+
const reader = new FileReader();
|
|
40
|
+
reader.onloadend = () => {
|
|
41
|
+
if (typeof reader.result === 'string') {
|
|
42
|
+
resolve(reader.result);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
reject(new Error('FileReader did not return a string'));
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
reader.onerror = () => reject(reader.error);
|
|
49
|
+
reader.readAsDataURL(blob);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
exports.blobToDataUrl = blobToDataUrl;
|
|
53
|
+
/**
|
|
54
|
+
* Downloads a file using a data URL approach.
|
|
55
|
+
* Creates a temporary anchor element with the data URL and triggers a click.
|
|
56
|
+
*
|
|
57
|
+
* Note: The `download` attribute behavior varies by browser for data URLs.
|
|
58
|
+
* Testing on iOS Safari 18.7 showed the filename is honored, though older
|
|
59
|
+
* versions may use a generic name. Desktop browsers generally respect the
|
|
60
|
+
* filename value.
|
|
61
|
+
*
|
|
62
|
+
* @param blob - The file content as a Blob
|
|
63
|
+
* @param filename - The filename for the download
|
|
64
|
+
*/
|
|
65
|
+
async function downloadViaDataUrl(blob, filename) {
|
|
66
|
+
const dataUrl = await blobToDataUrl(blob);
|
|
67
|
+
// Create a temporary link and click it
|
|
68
|
+
const link = document.createElement('a');
|
|
69
|
+
link.href = dataUrl;
|
|
70
|
+
link.download = filename;
|
|
71
|
+
link.style.display = 'none';
|
|
72
|
+
document.body.appendChild(link);
|
|
73
|
+
link.click();
|
|
74
|
+
document.body.removeChild(link);
|
|
75
|
+
}
|
|
76
|
+
exports.downloadViaDataUrl = downloadViaDataUrl;
|
|
77
|
+
/**
|
|
78
|
+
* Handles file download on iOS Safari, working around the blob URL bug.
|
|
79
|
+
* Uses data URL approach which triggers Safari's standard download dialog.
|
|
80
|
+
*
|
|
81
|
+
* @param blob - The file content as a Blob
|
|
82
|
+
* @param filename - The filename to use
|
|
83
|
+
* @returns Promise<boolean> - true if handled, false if should use default behavior
|
|
84
|
+
*/
|
|
85
|
+
async function handleIOSDownload(blob, filename) {
|
|
86
|
+
if (!isIOSSafari())
|
|
87
|
+
return false;
|
|
88
|
+
try {
|
|
89
|
+
await downloadViaDataUrl(blob, filename);
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
// If data URL approach fails, let the caller use default behavior
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.handleIOSDownload = handleIOSDownload;
|
|
98
|
+
//# sourceMappingURL=ios-file-saver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ios-file-saver.js","sourceRoot":"","sources":["../../../src/code/utils/ios-file-saver.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH;;;GAGG;AACH,SAAgB,WAAW;IACzB,IAAI,OAAO,SAAS,KAAK,WAAW;QAAE,OAAO,KAAK,CAAA;IAElD,MAAM,EAAE,GAAG,SAAS,CAAC,SAAS,CAAA;IAE9B,6CAA6C;IAC7C,sFAAsF;IACtF,yDAAyD;IACzD,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,CAAC,SAAS,CAAC,QAAQ,KAAK,UAAU,IAAI,SAAS,CAAC,cAAc,GAAG,CAAC,CAAC,CAAA;IAErE,4DAA4D;IAC5D,0EAA0E;IAC1E,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,iCAAiC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAEjF,OAAO,KAAK,IAAI,QAAQ,CAAA;AAC1B,CAAC;AAhBD,kCAgBC;AAED;;;;;;GAMG;AACH,SAAgB,aAAa,CAAC,IAAU;IACtC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAA;QAC/B,MAAM,CAAC,SAAS,GAAG,GAAG,EAAE;YACtB,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACtC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;YACxB,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC,CAAA;YACzD,CAAC;QACH,CAAC,CAAA;QACD,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAC3C,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;IAC5B,CAAC,CAAC,CAAA;AACJ,CAAC;AAbD,sCAaC;AAED;;;;;;;;;;;GAWG;AACI,KAAK,UAAU,kBAAkB,CAAC,IAAU,EAAE,QAAgB;IACnE,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAA;IAEzC,uCAAuC;IACvC,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;IACxC,IAAI,CAAC,IAAI,GAAG,OAAO,CAAA;IACnB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;IACxB,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAA;IAC3B,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;IAC/B,IAAI,CAAC,KAAK,EAAE,CAAA;IACZ,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;AACjC,CAAC;AAXD,gDAWC;AAED;;;;;;;GAOG;AACI,KAAK,UAAU,iBAAiB,CAAC,IAAU,EAAE,QAAgB;IAClE,IAAI,CAAC,WAAW,EAAE;QAAE,OAAO,KAAK,CAAA;IAEhC,IAAI,CAAC;QACH,MAAM,kBAAkB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QACxC,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,kEAAkE;QAClE,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAVD,8CAUC"}
|
|
@@ -13,12 +13,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
13
13
|
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
14
14
|
*/
|
|
15
15
|
const create_react_class_1 = __importDefault(require("create-react-class"));
|
|
16
|
+
const file_saver_1 = require("file-saver");
|
|
16
17
|
const react_dom_factories_1 = __importDefault(require("react-dom-factories"));
|
|
17
18
|
const { div, input, button, a } = react_dom_factories_1.default;
|
|
18
|
-
const translate_1 = __importDefault(require("../utils/translate"));
|
|
19
19
|
const provider_interface_1 = require("../providers/provider-interface");
|
|
20
20
|
const provider_interface_2 = require("../providers/provider-interface");
|
|
21
|
-
const
|
|
21
|
+
const ios_file_saver_1 = require("../utils/ios-file-saver");
|
|
22
|
+
const translate_1 = __importDefault(require("../utils/translate"));
|
|
22
23
|
exports.default = (0, create_react_class_1.default)({
|
|
23
24
|
displayName: 'LocalFileSaveTab',
|
|
24
25
|
getInitialState() {
|
|
@@ -88,36 +89,56 @@ exports.default = (0, create_react_class_1.default)({
|
|
|
88
89
|
}
|
|
89
90
|
},
|
|
90
91
|
confirm(e, simulateClick) {
|
|
91
|
-
if (
|
|
92
|
-
if (
|
|
93
|
-
|
|
94
|
-
if (simulateClick) {
|
|
95
|
-
this.downloadRef.click();
|
|
96
|
-
}
|
|
92
|
+
if (this.confirmDisabled()) {
|
|
93
|
+
if (e != null) {
|
|
94
|
+
e.preventDefault();
|
|
97
95
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
// Lazily create blob only when needed (not needed for browsers with download attribute support)
|
|
99
|
+
const getBlob = () => this.props.client.getDownloadBlob(this.state.content, this.state.includeShareInfo, this.state.mimeType);
|
|
100
|
+
// Handle iOS Safari specially due to blob URL bugs in iOS 18.2+
|
|
101
|
+
if ((0, ios_file_saver_1.isIOSSafari)()) {
|
|
102
|
+
if (e != null) {
|
|
103
|
+
e.preventDefault();
|
|
104
|
+
}
|
|
105
|
+
this.handleIOSSave(getBlob());
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
// Standard download handling for other browsers
|
|
109
|
+
if (this.state.supportsDownloadAttribute) {
|
|
110
|
+
this.downloadRef.href = this.props.client.getDownloadUrl(this.state.content, this.state.includeShareInfo, this.state.mimeType);
|
|
111
|
+
if (simulateClick) {
|
|
112
|
+
this.downloadRef.click();
|
|
104
113
|
}
|
|
105
|
-
const metadata = new provider_interface_1.CloudMetadata({
|
|
106
|
-
name: this.state.downloadFilename.split('.')[0],
|
|
107
|
-
type: provider_interface_1.CloudMetadata.File,
|
|
108
|
-
parent: null,
|
|
109
|
-
provider: this.props.provider
|
|
110
|
-
});
|
|
111
|
-
this.props.dialog.callback(metadata);
|
|
112
|
-
this.props.close();
|
|
113
|
-
// return value indicates whether to trigger href
|
|
114
|
-
return this.state.supportsDownloadAttribute;
|
|
115
114
|
}
|
|
116
115
|
else {
|
|
116
|
+
(0, file_saver_1.saveAs)(getBlob(), this.state.downloadFilename, { autoBom: true });
|
|
117
117
|
if (e != null) {
|
|
118
118
|
e.preventDefault();
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
|
+
this.completeDownload();
|
|
122
|
+
// return value indicates whether to trigger href
|
|
123
|
+
return this.state.supportsDownloadAttribute;
|
|
124
|
+
},
|
|
125
|
+
async handleIOSSave(blob) {
|
|
126
|
+
const handled = await (0, ios_file_saver_1.handleIOSDownload)(blob, this.state.downloadFilename);
|
|
127
|
+
if (!handled) {
|
|
128
|
+
// Fall back to standard saveAs if iOS handling failed
|
|
129
|
+
(0, file_saver_1.saveAs)(blob, this.state.downloadFilename, { autoBom: true });
|
|
130
|
+
}
|
|
131
|
+
this.completeDownload();
|
|
132
|
+
},
|
|
133
|
+
completeDownload() {
|
|
134
|
+
const metadata = new provider_interface_1.CloudMetadata({
|
|
135
|
+
name: this.state.downloadFilename.split('.')[0],
|
|
136
|
+
type: provider_interface_1.CloudMetadata.File,
|
|
137
|
+
parent: null,
|
|
138
|
+
provider: this.props.provider
|
|
139
|
+
});
|
|
140
|
+
this.props.dialog.callback(metadata);
|
|
141
|
+
this.props.close();
|
|
121
142
|
},
|
|
122
143
|
contextMenu(e) {
|
|
123
144
|
this.downloadRef.href = this.props.client.getDownloadUrl(this.state.content, this.state.includeShareInfo, this.state.mimeType);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-file-tab-save-view.js","sourceRoot":"","sources":["../../../src/code/views/local-file-tab-save-view.ts"],"names":[],"mappings":";;;;;AAAA,oDAAoD;AACpD,uDAAuD;AACvD;;;;;;GAMG;AACH,4EAAiD;AACjD,8EAAmD;AACnD,MAAM,EAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAC,GAAG,6BAAiB,CAAA;AACjD,
|
|
1
|
+
{"version":3,"file":"local-file-tab-save-view.js","sourceRoot":"","sources":["../../../src/code/views/local-file-tab-save-view.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/client.js
CHANGED
|
@@ -206,7 +206,7 @@ class CloudFileManagerClient {
|
|
|
206
206
|
}
|
|
207
207
|
// initialize the cloudContentFactory with all data we want in the envelope
|
|
208
208
|
cloudContentFactory.setEnvelopeMetadata({
|
|
209
|
-
cfmVersion: '2.1.0-pre.
|
|
209
|
+
cfmVersion: '2.1.0-pre.16', // replaced by version number at build time
|
|
210
210
|
appName: this.appOptions.appName || "",
|
|
211
211
|
appVersion: this.appOptions.appVersion || "",
|
|
212
212
|
appBuildNum: this.appOptions.appBuildNum || ""
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for detecting iOS Safari and handling iOS-specific file download issues.
|
|
3
|
+
*
|
|
4
|
+
* iOS Safari 18.2+ has a bug where blob URLs created with URL.createObjectURL()
|
|
5
|
+
* don't properly save to the Files app - they get stuck in Safari's temporary
|
|
6
|
+
* download cache. This module provides detection and a data URL workaround.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Detects if the current browser is Safari on iOS.
|
|
10
|
+
* This includes iPad in desktop mode (which reports as "Macintosh" but has touch).
|
|
11
|
+
*/
|
|
12
|
+
export declare function isIOSSafari(): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Converts a Blob to a data URL using FileReader.
|
|
15
|
+
* This is a workaround for iOS Safari's blob URL issues.
|
|
16
|
+
*
|
|
17
|
+
* @param blob - The blob to convert
|
|
18
|
+
* @returns Promise<string> - The data URL
|
|
19
|
+
*/
|
|
20
|
+
export declare function blobToDataUrl(blob: Blob): Promise<string>;
|
|
21
|
+
/**
|
|
22
|
+
* Downloads a file using a data URL approach.
|
|
23
|
+
* Creates a temporary anchor element with the data URL and triggers a click.
|
|
24
|
+
*
|
|
25
|
+
* Note: The `download` attribute behavior varies by browser for data URLs.
|
|
26
|
+
* Testing on iOS Safari 18.7 showed the filename is honored, though older
|
|
27
|
+
* versions may use a generic name. Desktop browsers generally respect the
|
|
28
|
+
* filename value.
|
|
29
|
+
*
|
|
30
|
+
* @param blob - The file content as a Blob
|
|
31
|
+
* @param filename - The filename for the download
|
|
32
|
+
*/
|
|
33
|
+
export declare function downloadViaDataUrl(blob: Blob, filename: string): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Handles file download on iOS Safari, working around the blob URL bug.
|
|
36
|
+
* Uses data URL approach which triggers Safari's standard download dialog.
|
|
37
|
+
*
|
|
38
|
+
* @param blob - The file content as a Blob
|
|
39
|
+
* @param filename - The filename to use
|
|
40
|
+
* @returns Promise<boolean> - true if handled, false if should use default behavior
|
|
41
|
+
*/
|
|
42
|
+
export declare function handleIOSDownload(blob: Blob, filename: string): Promise<boolean>;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for detecting iOS Safari and handling iOS-specific file download issues.
|
|
3
|
+
*
|
|
4
|
+
* iOS Safari 18.2+ has a bug where blob URLs created with URL.createObjectURL()
|
|
5
|
+
* don't properly save to the Files app - they get stuck in Safari's temporary
|
|
6
|
+
* download cache. This module provides detection and a data URL workaround.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Detects if the current browser is Safari on iOS.
|
|
10
|
+
* This includes iPad in desktop mode (which reports as "Macintosh" but has touch).
|
|
11
|
+
*/
|
|
12
|
+
export function isIOSSafari() {
|
|
13
|
+
if (typeof navigator === 'undefined')
|
|
14
|
+
return false;
|
|
15
|
+
const ua = navigator.userAgent;
|
|
16
|
+
// Check for iOS devices (iPhone, iPad, iPod)
|
|
17
|
+
// Also check for iPad in desktop mode (reports as Macintosh but has touch capability)
|
|
18
|
+
// Regular Macs report maxTouchPoints = 0, iPads report 5
|
|
19
|
+
const isIOS = /iPad|iPhone|iPod/.test(ua) ||
|
|
20
|
+
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 0);
|
|
21
|
+
// Check for Safari (not Chrome, Firefox, Edge, etc. on iOS)
|
|
22
|
+
// All iOS browsers use WebKit, but we specifically want Safari's behavior
|
|
23
|
+
const isSafari = /Safari/.test(ua) && !/Chrome|CriOS|FxiOS|EdgiOS|OPiOS/.test(ua);
|
|
24
|
+
return isIOS && isSafari;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Converts a Blob to a data URL using FileReader.
|
|
28
|
+
* This is a workaround for iOS Safari's blob URL issues.
|
|
29
|
+
*
|
|
30
|
+
* @param blob - The blob to convert
|
|
31
|
+
* @returns Promise<string> - The data URL
|
|
32
|
+
*/
|
|
33
|
+
export function blobToDataUrl(blob) {
|
|
34
|
+
return new Promise((resolve, reject) => {
|
|
35
|
+
const reader = new FileReader();
|
|
36
|
+
reader.onloadend = () => {
|
|
37
|
+
if (typeof reader.result === 'string') {
|
|
38
|
+
resolve(reader.result);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
reject(new Error('FileReader did not return a string'));
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
reader.onerror = () => reject(reader.error);
|
|
45
|
+
reader.readAsDataURL(blob);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Downloads a file using a data URL approach.
|
|
50
|
+
* Creates a temporary anchor element with the data URL and triggers a click.
|
|
51
|
+
*
|
|
52
|
+
* Note: The `download` attribute behavior varies by browser for data URLs.
|
|
53
|
+
* Testing on iOS Safari 18.7 showed the filename is honored, though older
|
|
54
|
+
* versions may use a generic name. Desktop browsers generally respect the
|
|
55
|
+
* filename value.
|
|
56
|
+
*
|
|
57
|
+
* @param blob - The file content as a Blob
|
|
58
|
+
* @param filename - The filename for the download
|
|
59
|
+
*/
|
|
60
|
+
export async function downloadViaDataUrl(blob, filename) {
|
|
61
|
+
const dataUrl = await blobToDataUrl(blob);
|
|
62
|
+
// Create a temporary link and click it
|
|
63
|
+
const link = document.createElement('a');
|
|
64
|
+
link.href = dataUrl;
|
|
65
|
+
link.download = filename;
|
|
66
|
+
link.style.display = 'none';
|
|
67
|
+
document.body.appendChild(link);
|
|
68
|
+
link.click();
|
|
69
|
+
document.body.removeChild(link);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Handles file download on iOS Safari, working around the blob URL bug.
|
|
73
|
+
* Uses data URL approach which triggers Safari's standard download dialog.
|
|
74
|
+
*
|
|
75
|
+
* @param blob - The file content as a Blob
|
|
76
|
+
* @param filename - The filename to use
|
|
77
|
+
* @returns Promise<boolean> - true if handled, false if should use default behavior
|
|
78
|
+
*/
|
|
79
|
+
export async function handleIOSDownload(blob, filename) {
|
|
80
|
+
if (!isIOSSafari())
|
|
81
|
+
return false;
|
|
82
|
+
try {
|
|
83
|
+
await downloadViaDataUrl(blob, filename);
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
// If data URL approach fails, let the caller use default behavior
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=ios-file-saver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ios-file-saver.js","sourceRoot":"","sources":["../../../src/code/utils/ios-file-saver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;GAGG;AACH,MAAM,UAAU,WAAW;IACzB,IAAI,OAAO,SAAS,KAAK,WAAW;QAAE,OAAO,KAAK,CAAA;IAElD,MAAM,EAAE,GAAG,SAAS,CAAC,SAAS,CAAA;IAE9B,6CAA6C;IAC7C,sFAAsF;IACtF,yDAAyD;IACzD,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,CAAC,SAAS,CAAC,QAAQ,KAAK,UAAU,IAAI,SAAS,CAAC,cAAc,GAAG,CAAC,CAAC,CAAA;IAErE,4DAA4D;IAC5D,0EAA0E;IAC1E,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,iCAAiC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAEjF,OAAO,KAAK,IAAI,QAAQ,CAAA;AAC1B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,IAAU;IACtC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAA;QAC/B,MAAM,CAAC,SAAS,GAAG,GAAG,EAAE;YACtB,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACtC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;YACxB,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC,CAAA;YACzD,CAAC;QACH,CAAC,CAAA;QACD,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAC3C,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;IAC5B,CAAC,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAU,EAAE,QAAgB;IACnE,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAA;IAEzC,uCAAuC;IACvC,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;IACxC,IAAI,CAAC,IAAI,GAAG,OAAO,CAAA;IACnB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;IACxB,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAA;IAC3B,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;IAC/B,IAAI,CAAC,KAAK,EAAE,CAAA;IACZ,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;AACjC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAU,EAAE,QAAgB;IAClE,IAAI,CAAC,WAAW,EAAE;QAAE,OAAO,KAAK,CAAA;IAEhC,IAAI,CAAC;QACH,MAAM,kBAAkB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QACxC,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,kEAAkE;QAClE,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC"}
|
|
@@ -8,12 +8,13 @@
|
|
|
8
8
|
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
9
9
|
*/
|
|
10
10
|
import createReactClass from 'create-react-class';
|
|
11
|
+
import { saveAs } from 'file-saver';
|
|
11
12
|
import ReactDOMFactories from 'react-dom-factories';
|
|
12
13
|
const { div, input, button, a } = ReactDOMFactories;
|
|
13
|
-
import tr from '../utils/translate';
|
|
14
14
|
import { CloudMetadata } from '../providers/provider-interface';
|
|
15
15
|
import { cloudContentFactory } from '../providers/provider-interface';
|
|
16
|
-
import
|
|
16
|
+
import { isIOSSafari, handleIOSDownload } from '../utils/ios-file-saver';
|
|
17
|
+
import tr from '../utils/translate';
|
|
17
18
|
export default createReactClass({
|
|
18
19
|
displayName: 'LocalFileSaveTab',
|
|
19
20
|
getInitialState() {
|
|
@@ -83,36 +84,56 @@ export default createReactClass({
|
|
|
83
84
|
}
|
|
84
85
|
},
|
|
85
86
|
confirm(e, simulateClick) {
|
|
86
|
-
if (
|
|
87
|
-
if (
|
|
88
|
-
|
|
89
|
-
if (simulateClick) {
|
|
90
|
-
this.downloadRef.click();
|
|
91
|
-
}
|
|
87
|
+
if (this.confirmDisabled()) {
|
|
88
|
+
if (e != null) {
|
|
89
|
+
e.preventDefault();
|
|
92
90
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
// Lazily create blob only when needed (not needed for browsers with download attribute support)
|
|
94
|
+
const getBlob = () => this.props.client.getDownloadBlob(this.state.content, this.state.includeShareInfo, this.state.mimeType);
|
|
95
|
+
// Handle iOS Safari specially due to blob URL bugs in iOS 18.2+
|
|
96
|
+
if (isIOSSafari()) {
|
|
97
|
+
if (e != null) {
|
|
98
|
+
e.preventDefault();
|
|
99
|
+
}
|
|
100
|
+
this.handleIOSSave(getBlob());
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
// Standard download handling for other browsers
|
|
104
|
+
if (this.state.supportsDownloadAttribute) {
|
|
105
|
+
this.downloadRef.href = this.props.client.getDownloadUrl(this.state.content, this.state.includeShareInfo, this.state.mimeType);
|
|
106
|
+
if (simulateClick) {
|
|
107
|
+
this.downloadRef.click();
|
|
99
108
|
}
|
|
100
|
-
const metadata = new CloudMetadata({
|
|
101
|
-
name: this.state.downloadFilename.split('.')[0],
|
|
102
|
-
type: CloudMetadata.File,
|
|
103
|
-
parent: null,
|
|
104
|
-
provider: this.props.provider
|
|
105
|
-
});
|
|
106
|
-
this.props.dialog.callback(metadata);
|
|
107
|
-
this.props.close();
|
|
108
|
-
// return value indicates whether to trigger href
|
|
109
|
-
return this.state.supportsDownloadAttribute;
|
|
110
109
|
}
|
|
111
110
|
else {
|
|
111
|
+
saveAs(getBlob(), this.state.downloadFilename, { autoBom: true });
|
|
112
112
|
if (e != null) {
|
|
113
113
|
e.preventDefault();
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
|
+
this.completeDownload();
|
|
117
|
+
// return value indicates whether to trigger href
|
|
118
|
+
return this.state.supportsDownloadAttribute;
|
|
119
|
+
},
|
|
120
|
+
async handleIOSSave(blob) {
|
|
121
|
+
const handled = await handleIOSDownload(blob, this.state.downloadFilename);
|
|
122
|
+
if (!handled) {
|
|
123
|
+
// Fall back to standard saveAs if iOS handling failed
|
|
124
|
+
saveAs(blob, this.state.downloadFilename, { autoBom: true });
|
|
125
|
+
}
|
|
126
|
+
this.completeDownload();
|
|
127
|
+
},
|
|
128
|
+
completeDownload() {
|
|
129
|
+
const metadata = new CloudMetadata({
|
|
130
|
+
name: this.state.downloadFilename.split('.')[0],
|
|
131
|
+
type: CloudMetadata.File,
|
|
132
|
+
parent: null,
|
|
133
|
+
provider: this.props.provider
|
|
134
|
+
});
|
|
135
|
+
this.props.dialog.callback(metadata);
|
|
136
|
+
this.props.close();
|
|
116
137
|
},
|
|
117
138
|
contextMenu(e) {
|
|
118
139
|
this.downloadRef.href = this.props.client.getDownloadUrl(this.state.content, this.state.includeShareInfo, this.state.mimeType);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-file-tab-save-view.js","sourceRoot":"","sources":["../../../src/code/views/local-file-tab-save-view.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,uDAAuD;AACvD;;;;;;GAMG;AACH,OAAO,gBAAgB,MAAM,oBAAoB,CAAA;AACjD,OAAO,iBAAiB,MAAM,qBAAqB,CAAA;AACnD,MAAM,EAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAC,GAAG,iBAAiB,CAAA;AACjD,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"local-file-tab-save-view.js","sourceRoot":"","sources":["../../../src/code/views/local-file-tab-save-view.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,uDAAuD;AACvD;;;;;;GAMG;AACH,OAAO,gBAAgB,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AACnC,OAAO,iBAAiB,MAAM,qBAAqB,CAAA;AACnD,MAAM,EAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAC,GAAG,iBAAiB,CAAA;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAA;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAA;AACrE,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AACxE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAEnC,eAAe,gBAAgB,CAAC;IAE9B,WAAW,EAAE,kBAAkB;IAE/B,eAAe;QACb,oFAAoF;QACpF,mFAAmF;QACnF,kFAAkF;QAClF,mFAAmF;QACnF,8BAA8B;;QAE9B,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA;QAC/C,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAAA;QAC7B,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,KAAK,CAAA;QAEjC,MAAM,eAAe,GAAG,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,KAAI,IAAI,CAAA;QAC7C,MAAM,SAAS,GAAG,eAAe,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,SAAS,mCAAI,MAAM,CAAC,CAAA;QACxG,MAAM,QAAQ,GAAG,eAAe,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAA,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,iBAAiB,mCAAI,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,QAAQ,mCAAI,YAAY,CAAC,CAAA;QAC3I,MAAM,QAAQ,GAAG,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,IAAI,mCAAI,CAAC,EAAE,CAAC,4BAA4B,CAAC,CAAC,CAAA;QAErE,OAAO;YACL,QAAQ;YACR,yBAAyB,EAAE,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,QAAQ,KAAK,SAAS;YAC7E,gBAAgB,EAAE,IAAI,CAAC,mBAAmB,CAAC,eAAe,EAAE,QAAQ,EAAE,SAAS,CAAC;YAChF,SAAS;YACT,QAAQ;YACR,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE;YACzB,eAAe;YACf,gBAAgB,EAAE,eAAe;YACjC,UAAU,EAAE,eAAe;YAC3B,OAAO,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;SACtD,CAAA;IACH,CAAC;IAED,iBAAiB;QACf,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC;YAChC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,EAAE,EAAE,EAAE,CAAC,OAAY,EAAE,EAAE;gBACvG,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,2BAA2B,CAAC,OAAO,CAAC,CAAA;gBACjF,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CAAA;gBAC/I,OAAO,IAAI,CAAC,QAAQ,CAAC;oBACnB,UAAU,EAAE,IAAI;oBAChB,OAAO,EAAE,gBAAgB;iBAC1B,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;QACJ,CAAC;QAED,gFAAgF;QAChF,4EAA4E;QAC5E,mFAAmF;QACnF,+DAA+D;QAC/D,OAAO,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;IACjE,CAAC;IAED,oBAAoB;QAClB,OAAO,IAAI,CAAC,WAAW,CAAC,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;IACpE,CAAC;IAED,eAAe;QACb,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAA;QACvC,OAAO,IAAI,CAAC,QAAQ,CAAC;YACnB,QAAQ;YACR,gBAAgB,EAAE,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;SACvG,CAAC,CAAA;IACJ,CAAC;IAED,uBAAuB;QACrB,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAC,gBAAgB,EAAE,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAC,CAAC,CAAA;IAC5E,CAAC;IAED,mBAAmB,CAAC,eAAwB,EAAE,QAAgB,EAAE,SAAiB;QAC/E,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;QACjD,IAAI,eAAe,EAAE,CAAC;YACpB,OAAO,aAAa,CAAC,YAAY,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;QACvD,CAAC;aACI,CAAC;YACJ,OAAO,aAAa,CAAC,aAAa,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;QACxD,CAAC;IACH,CAAC;IAED,OAAO,CAAC,CAAM,EAAE,aAAsB;QACpC,IAAI,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YAC3B,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;gBACd,CAAC,CAAC,cAAc,EAAE,CAAA;YACpB,CAAC;YACD,OAAM;QACR,CAAC;QAED,gGAAgG;QAChG,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QAE7H,gEAAgE;QAChE,IAAI,WAAW,EAAE,EAAE,CAAC;YAClB,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;gBACd,CAAC,CAAC,cAAc,EAAE,CAAA;YACpB,CAAC;YACD,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,CAAA;YAC7B,OAAO,KAAK,CAAA;QACd,CAAC;QAED,gDAAgD;QAChD,IAAI,IAAI,CAAC,KAAK,CAAC,yBAAyB,EAAE,CAAC;YACzC,IAAI,CAAC,WAAW,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;YAC9H,IAAI,aAAa,EAAE,CAAC;gBAAC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAA;YAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;YACjE,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;gBACd,CAAC,CAAC,cAAc,EAAE,CAAA;YACpB,CAAC;QACH,CAAC;QAED,IAAI,CAAC,gBAAgB,EAAE,CAAA;QAEvB,iDAAiD;QACjD,OAAO,IAAI,CAAC,KAAK,CAAC,yBAAyB,CAAA;IAC7C,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,IAAU;QAC5B,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAA;QAC1E,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,sDAAsD;YACtD,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;QAC9D,CAAC;QACD,IAAI,CAAC,gBAAgB,EAAE,CAAA;IACzB,CAAC;IAED,gBAAgB;QACd,MAAM,QAAQ,GAAG,IAAI,aAAa,CAAC;YACjC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC/C,IAAI,EAAE,aAAa,CAAC,IAAI;YACxB,MAAM,EAAE,IAAI;YACZ,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ;SAC9B,CAAC,CAAA;QACF,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;QACpC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;IACpB,CAAC;IAED,WAAW,CAAC,CAAM;QAChB,IAAI,CAAC,WAAW,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;IAChI,CAAC;IAED,MAAM;QACJ,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;IACpB,CAAC;IAED,aAAa,CAAC,CAAM;QAClB,IAAI,CAAC,CAAC,CAAC,OAAO,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YAClD,CAAC,CAAC,cAAc,EAAE,CAAA;YAClB,CAAC,CAAC,eAAe,EAAE,CAAA;YACnB,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QAC1B,CAAC;IACH,CAAC;IAED,eAAe;QACb,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAA;IAC7E,CAAC;IAED,MAAM;QACJ,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,EAAE,CAAA;QAE9C,sBAAsB;QACtB,MAAM,cAAc,GAAG,CAAC,CAAC,CAAC;YACxB,IAAI,EAAE,GAAG;YACT,GAAG,EAAE,CAAC,GAAQ,EAAE,EAAE,GAAG,OAAO,IAAI,CAAC,WAAW,GAAG,GAAG,CAAA,CAAC,CAAC;YACpD,SAAS,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9C,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,gBAAgB;YACrC,aAAa,EAAE,IAAI,CAAC,WAAW;SAChC,EAAE,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAA;QAEhC,4CAA4C;QAC5C,MAAM,cAAc,GAAG,CAAC,MAAM,CAAC;YAC7B,GAAG,EAAE,CAAC,GAAQ,EAAE,EAAE,GAAG,OAAO,IAAI,CAAC,WAAW,GAAG,GAAG,CAAA,CAAC,CAAC;YACpD,SAAS,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;SAC/C,EAAE,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAA;QAEhC,OAAO,CAAC,GAAG,CAAC,EAAC,SAAS,EAAE,yBAAyB,EAAC,EAChD,CAAC,KAAK,CAAC,EAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAQ,EAAE,EAAE,GAAG,OAAO,IAAI,CAAC,WAAW,GAAG,GAAG,CAAA,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,uBAAuB,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,EAAE,IAAI,CAAC,aAAa,EAAC,CAAC,CAAC,EACtN,CAAC,GAAG,CAAC,EAAC,SAAS,EAAE,UAAU,EAAC,EAC1B,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;YAChD,CAAC,GAAG,CAAC,EAAC,SAAS,EAAE,eAAe,EAAC,EAC/B,CAAC,KAAK,CAAC,EAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,GAAQ,EAAE,EAAE,GAAG,OAAO,IAAI,CAAC,mBAAmB,GAAG,GAAG,CAAA,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,QAAQ,EAAE,IAAI,CAAC,uBAAuB,EAAC,CAAC,CAAC,EACvK,CAAC,EAAE,CAAC,qCAAqC,CAAC,CAAC,CAC5C,CAAC,CAAC,CAAC,CAAC,SAAS,CACjB,CAAC,EACF,CAAC,GAAG,CAAC,EAAC,SAAS,EAAE,SAAS,EAAC,EACzB,IAAI,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,cAAc,EACtE,CAAC,MAAM,CAAC,EAAC,OAAO,EAAE,IAAI,CAAC,MAAM,EAAC,EAAE,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAC9D,CAAC,CACH,CAAC,CAAA;IACJ,CAAC;CACF,CAAC,CAAA;AACF,SAAS,SAAS,CAAC,KAAU,EAAE,SAAc;IAC3C,OAAO,CAAC,OAAO,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AACxF,CAAC"}
|
package/dist/examples/index.html
CHANGED
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
<li><a href="show-close-confirm.html">Shows confirm dialog if closed when there are unsaved changes</a></li>
|
|
37
37
|
<li><a href="no-shared-google-drives.html">Disables shared Google drives</a></li>
|
|
38
38
|
<li><a href="codap3-local-file.html">CODAP v3 local file saves</a></li>
|
|
39
|
+
<li><a href="local-json-save.html">Local JSON Save (iOS Test)</a></li>
|
|
39
40
|
</ul>
|
|
40
41
|
</body>
|
|
41
42
|
</html>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
<head>
|
|
3
|
+
<script src="../js/globals.js"></script>
|
|
4
|
+
<script src="../js/app.js"></script>
|
|
5
|
+
<link rel="stylesheet" href="../css/app.css">
|
|
6
|
+
<title>Examples: Local JSON Save (iOS Test)</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="wrapper">
|
|
10
|
+
</div>
|
|
11
|
+
<script>
|
|
12
|
+
var options = {
|
|
13
|
+
app: "example-app/index.html",
|
|
14
|
+
mimeType: "application/json",
|
|
15
|
+
extension: "json",
|
|
16
|
+
appName: "iOS_Save_Test",
|
|
17
|
+
appVersion: "1.0",
|
|
18
|
+
appBuildNum: "1",
|
|
19
|
+
providers: [
|
|
20
|
+
"localFile",
|
|
21
|
+
],
|
|
22
|
+
ui: {
|
|
23
|
+
menu: CloudFileManager.DefaultMenu,
|
|
24
|
+
menuBar: {
|
|
25
|
+
info: "iOS Local Save Test"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
CloudFileManager.createFrame(options, "wrapper", function (event) {
|
|
30
|
+
if (event.type === 'connected') {
|
|
31
|
+
console.log('CFM connected');
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
</script>
|
|
35
|
+
</body>
|
|
36
|
+
</html>
|