@concord-consortium/cloud-file-manager 2.0.0-pre.1
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/autolaunch/autolaunch.css +220 -0
- package/dist/autolaunch/autolaunch.html +133 -0
- package/dist/autolaunch/autolaunch.js +3 -0
- package/dist/autolaunch/autolaunch.js.LICENSE.txt +16 -0
- package/dist/autolaunch/autolaunch.js.map +1 -0
- package/dist/cjs/app-options.d.ts +118 -0
- package/dist/cjs/app-options.js +6 -0
- package/dist/cjs/app-options.js.map +1 -0
- package/dist/cjs/client.d.ts +165 -0
- package/dist/cjs/client.js +1391 -0
- package/dist/cjs/client.js.map +1 -0
- package/dist/cjs/cloud-file-manager.d.ts +16 -0
- package/dist/cjs/cloud-file-manager.js +79 -0
- package/dist/cjs/cloud-file-manager.js.map +1 -0
- package/dist/cjs/create-react-factory.d.ts +3 -0
- package/dist/cjs/create-react-factory.js +14 -0
- package/dist/cjs/create-react-factory.js.map +1 -0
- package/dist/cjs/index.d.ts +4 -0
- package/dist/cjs/index.js +21 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/lib/file-saver.d.ts +2 -0
- package/dist/cjs/lib/file-saver.js +164 -0
- package/dist/cjs/lib/file-saver.js.map +1 -0
- package/dist/cjs/providers/document-store-provider.d.ts +48 -0
- package/dist/cjs/providers/document-store-provider.js +541 -0
- package/dist/cjs/providers/document-store-provider.js.map +1 -0
- package/dist/cjs/providers/document-store-share-provider.d.ts +17 -0
- package/dist/cjs/providers/document-store-share-provider.js +126 -0
- package/dist/cjs/providers/document-store-share-provider.js.map +1 -0
- package/dist/cjs/providers/document-store-url.d.ts +32 -0
- package/dist/cjs/providers/document-store-url.js +75 -0
- package/dist/cjs/providers/document-store-url.js.map +1 -0
- package/dist/cjs/providers/google-drive-provider.d.ts +75 -0
- package/dist/cjs/providers/google-drive-provider.js +684 -0
- package/dist/cjs/providers/google-drive-provider.js.map +1 -0
- package/dist/cjs/providers/interactive-api-provider.d.ts +55 -0
- package/dist/cjs/providers/interactive-api-provider.js +382 -0
- package/dist/cjs/providers/interactive-api-provider.js.map +1 -0
- package/dist/cjs/providers/lara-provider.d.ts +47 -0
- package/dist/cjs/providers/lara-provider.js +547 -0
- package/dist/cjs/providers/lara-provider.js.map +1 -0
- package/dist/cjs/providers/legacy-google-drive-provider.d.ts +74 -0
- package/dist/cjs/providers/legacy-google-drive-provider.js +600 -0
- package/dist/cjs/providers/legacy-google-drive-provider.js.map +1 -0
- package/dist/cjs/providers/local-file-provider.d.ts +16 -0
- package/dist/cjs/providers/local-file-provider.js +65 -0
- package/dist/cjs/providers/local-file-provider.js.map +1 -0
- package/dist/cjs/providers/localstorage-provider.d.ts +20 -0
- package/dist/cjs/providers/localstorage-provider.js +122 -0
- package/dist/cjs/providers/localstorage-provider.js.map +1 -0
- package/dist/cjs/providers/patchable-content.d.ts +16 -0
- package/dist/cjs/providers/patchable-content.js +65 -0
- package/dist/cjs/providers/patchable-content.js.map +1 -0
- package/dist/cjs/providers/post-message-provider.d.ts +12 -0
- package/dist/cjs/providers/post-message-provider.js +39 -0
- package/dist/cjs/providers/post-message-provider.js.map +1 -0
- package/dist/cjs/providers/provider-interface.d.ts +168 -0
- package/dist/cjs/providers/provider-interface.js +399 -0
- package/dist/cjs/providers/provider-interface.js.map +1 -0
- package/dist/cjs/providers/readonly-provider.d.ts +22 -0
- package/dist/cjs/providers/readonly-provider.js +303 -0
- package/dist/cjs/providers/readonly-provider.js.map +1 -0
- package/dist/cjs/providers/s3-provider.d.ts +14 -0
- package/dist/cjs/providers/s3-provider.js +109 -0
- package/dist/cjs/providers/s3-provider.js.map +1 -0
- package/dist/cjs/providers/s3-share-provider.d.ts +18 -0
- package/dist/cjs/providers/s3-share-provider.js +124 -0
- package/dist/cjs/providers/s3-share-provider.js.map +1 -0
- package/dist/cjs/providers/share-provider-interface.d.ts +15 -0
- package/dist/cjs/providers/share-provider-interface.js +3 -0
- package/dist/cjs/providers/share-provider-interface.js.map +1 -0
- package/dist/cjs/providers/test-provider.d.ts +26 -0
- package/dist/cjs/providers/test-provider.js +73 -0
- package/dist/cjs/providers/test-provider.js.map +1 -0
- package/dist/cjs/providers/url-provider.d.ts +13 -0
- package/dist/cjs/providers/url-provider.js +58 -0
- package/dist/cjs/providers/url-provider.js.map +1 -0
- package/dist/cjs/ui.d.ts +51 -0
- package/dist/cjs/ui.js +216 -0
- package/dist/cjs/ui.js.map +1 -0
- package/dist/cjs/utils/config.d.ts +6 -0
- package/dist/cjs/utils/config.js +10 -0
- package/dist/cjs/utils/config.js.map +1 -0
- package/dist/cjs/utils/get-hash-param.d.ts +1 -0
- package/dist/cjs/utils/get-hash-param.js +24 -0
- package/dist/cjs/utils/get-hash-param.js.map +1 -0
- package/dist/cjs/utils/get-query-param.d.ts +1 -0
- package/dist/cjs/utils/get-query-param.js +23 -0
- package/dist/cjs/utils/get-query-param.js.map +1 -0
- package/dist/cjs/utils/is-array.d.ts +2 -0
- package/dist/cjs/utils/is-array.js +4 -0
- package/dist/cjs/utils/is-array.js.map +1 -0
- package/dist/cjs/utils/is-empty-object.d.ts +1 -0
- package/dist/cjs/utils/is-empty-object.js +7 -0
- package/dist/cjs/utils/is-empty-object.js.map +1 -0
- package/dist/cjs/utils/is-string.d.ts +2 -0
- package/dist/cjs/utils/is-string.js +4 -0
- package/dist/cjs/utils/is-string.js.map +1 -0
- package/dist/cjs/utils/lang/de.json +156 -0
- package/dist/cjs/utils/lang/el.json +156 -0
- package/dist/cjs/utils/lang/en-US.json +156 -0
- package/dist/cjs/utils/lang/es.json +156 -0
- package/dist/cjs/utils/lang/fa.json +156 -0
- package/dist/cjs/utils/lang/he.json +156 -0
- package/dist/cjs/utils/lang/ja.json +156 -0
- package/dist/cjs/utils/lang/ko.json +156 -0
- package/dist/cjs/utils/lang/nb.json +156 -0
- package/dist/cjs/utils/lang/nn.json +156 -0
- package/dist/cjs/utils/lang/pl.json +156 -0
- package/dist/cjs/utils/lang/pt-BR.json +156 -0
- package/dist/cjs/utils/lang/th.json +156 -0
- package/dist/cjs/utils/lang/tr.json +156 -0
- package/dist/cjs/utils/lang/zh-Hans.json +156 -0
- package/dist/cjs/utils/lang/zh-TW.json +156 -0
- package/dist/cjs/utils/report-error.d.ts +1 -0
- package/dist/cjs/utils/report-error.js +10 -0
- package/dist/cjs/utils/report-error.js.map +1 -0
- package/dist/cjs/utils/s3-share-provider-token-service-helper.d.ts +21 -0
- package/dist/cjs/utils/s3-share-provider-token-service-helper.js +97 -0
- package/dist/cjs/utils/s3-share-provider-token-service-helper.js.map +1 -0
- package/dist/cjs/utils/translate.d.ts +3 -0
- package/dist/cjs/utils/translate.js +108 -0
- package/dist/cjs/utils/translate.js.map +1 -0
- package/dist/cjs/utils/url-params.d.ts +2 -0
- package/dist/cjs/utils/url-params.js +16 -0
- package/dist/cjs/utils/url-params.js.map +1 -0
- package/dist/cjs/views/alert-dialog-view.d.ts +3 -0
- package/dist/cjs/views/alert-dialog-view.js +32 -0
- package/dist/cjs/views/alert-dialog-view.js.map +1 -0
- package/dist/cjs/views/app-view.d.ts +49 -0
- package/dist/cjs/views/app-view.js +272 -0
- package/dist/cjs/views/app-view.js.map +1 -0
- package/dist/cjs/views/authorize-mixin.d.ts +10 -0
- package/dist/cjs/views/authorize-mixin.js +69 -0
- package/dist/cjs/views/authorize-mixin.js.map +1 -0
- package/dist/cjs/views/blocking-modal-view.d.ts +3 -0
- package/dist/cjs/views/blocking-modal-view.js +32 -0
- package/dist/cjs/views/blocking-modal-view.js.map +1 -0
- package/dist/cjs/views/confirm-dialog-view.d.ts +3 -0
- package/dist/cjs/views/confirm-dialog-view.js +40 -0
- package/dist/cjs/views/confirm-dialog-view.js.map +1 -0
- package/dist/cjs/views/download-dialog-view.d.ts +3 -0
- package/dist/cjs/views/download-dialog-view.js +79 -0
- package/dist/cjs/views/download-dialog-view.js.map +1 -0
- package/dist/cjs/views/dropdown-anchors.d.ts +4 -0
- package/dist/cjs/views/dropdown-anchors.js +17 -0
- package/dist/cjs/views/dropdown-anchors.js.map +1 -0
- package/dist/cjs/views/dropdown-view.d.ts +3 -0
- package/dist/cjs/views/dropdown-view.js +152 -0
- package/dist/cjs/views/dropdown-view.js.map +1 -0
- package/dist/cjs/views/file-dialog-tab-view.d.ts +3 -0
- package/dist/cjs/views/file-dialog-tab-view.js +405 -0
- package/dist/cjs/views/file-dialog-tab-view.js.map +1 -0
- package/dist/cjs/views/icons/spin.d.ts +5 -0
- package/dist/cjs/views/icons/spin.js +46 -0
- package/dist/cjs/views/icons/spin.js.map +1 -0
- package/dist/cjs/views/import-tabbed-dialog-view.d.ts +3 -0
- package/dist/cjs/views/import-tabbed-dialog-view.js +78 -0
- package/dist/cjs/views/import-tabbed-dialog-view.js.map +1 -0
- package/dist/cjs/views/local-file-tab-list-view.d.ts +3 -0
- package/dist/cjs/views/local-file-tab-list-view.js +84 -0
- package/dist/cjs/views/local-file-tab-list-view.js.map +1 -0
- package/dist/cjs/views/local-file-tab-save-view.d.ts +3 -0
- package/dist/cjs/views/local-file-tab-save-view.js +157 -0
- package/dist/cjs/views/local-file-tab-save-view.js.map +1 -0
- package/dist/cjs/views/menu-bar-view.d.ts +3 -0
- package/dist/cjs/views/menu-bar-view.js +201 -0
- package/dist/cjs/views/menu-bar-view.js.map +1 -0
- package/dist/cjs/views/modal-dialog-view.d.ts +8 -0
- package/dist/cjs/views/modal-dialog-view.js +18 -0
- package/dist/cjs/views/modal-dialog-view.js.map +1 -0
- package/dist/cjs/views/modal-tabbed-dialog-view.d.ts +3 -0
- package/dist/cjs/views/modal-tabbed-dialog-view.js +25 -0
- package/dist/cjs/views/modal-tabbed-dialog-view.js.map +1 -0
- package/dist/cjs/views/modal-view.d.ts +36 -0
- package/dist/cjs/views/modal-view.js +70 -0
- package/dist/cjs/views/modal-view.js.map +1 -0
- package/dist/cjs/views/provider-tabbed-dialog-view.d.ts +3 -0
- package/dist/cjs/views/provider-tabbed-dialog-view.js +67 -0
- package/dist/cjs/views/provider-tabbed-dialog-view.js.map +1 -0
- package/dist/cjs/views/rename-dialog-view.d.ts +3 -0
- package/dist/cjs/views/rename-dialog-view.js +60 -0
- package/dist/cjs/views/rename-dialog-view.js.map +1 -0
- package/dist/cjs/views/select-interactive-state-dialog-view.d.ts +22 -0
- package/dist/cjs/views/select-interactive-state-dialog-view.js +93 -0
- package/dist/cjs/views/select-interactive-state-dialog-view.js.map +1 -0
- package/dist/cjs/views/select-provider-dialog-tab-view.d.ts +2 -0
- package/dist/cjs/views/select-provider-dialog-tab-view.js +16 -0
- package/dist/cjs/views/select-provider-dialog-tab-view.js.map +1 -0
- package/dist/cjs/views/share-dialog-status-view.d.ts +9 -0
- package/dist/cjs/views/share-dialog-status-view.js +24 -0
- package/dist/cjs/views/share-dialog-status-view.js.map +1 -0
- package/dist/cjs/views/share-dialog-tabs-view.d.ts +45 -0
- package/dist/cjs/views/share-dialog-tabs-view.js +93 -0
- package/dist/cjs/views/share-dialog-tabs-view.js.map +1 -0
- package/dist/cjs/views/share-dialog-view.d.ts +50 -0
- package/dist/cjs/views/share-dialog-view.js +220 -0
- package/dist/cjs/views/share-dialog-view.js.map +1 -0
- package/dist/cjs/views/share-loading-view.d.ts +2 -0
- package/dist/cjs/views/share-loading-view.js +16 -0
- package/dist/cjs/views/share-loading-view.js.map +1 -0
- package/dist/cjs/views/tabbed-panel-view.d.ts +3 -0
- package/dist/cjs/views/tabbed-panel-view.js +79 -0
- package/dist/cjs/views/tabbed-panel-view.js.map +1 -0
- package/dist/cjs/views/url-tab-view.d.ts +3 -0
- package/dist/cjs/views/url-tab-view.js +67 -0
- package/dist/cjs/views/url-tab-view.js.map +1 -0
- package/dist/css/app.css +6 -0
- package/dist/css/app.css.map +1 -0
- package/dist/esm/app-options.d.ts +118 -0
- package/dist/esm/app-options.js +2 -0
- package/dist/esm/app-options.js.map +1 -0
- package/dist/esm/client.d.ts +165 -0
- package/dist/esm/client.js +1384 -0
- package/dist/esm/client.js.map +1 -0
- package/dist/esm/cloud-file-manager.d.ts +16 -0
- package/dist/esm/cloud-file-manager.js +72 -0
- package/dist/esm/cloud-file-manager.js.map +1 -0
- package/dist/esm/create-react-factory.d.ts +3 -0
- package/dist/esm/create-react-factory.js +6 -0
- package/dist/esm/create-react-factory.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/lib/file-saver.d.ts +2 -0
- package/dist/esm/lib/file-saver.js +164 -0
- package/dist/esm/lib/file-saver.js.map +1 -0
- package/dist/esm/providers/document-store-provider.d.ts +48 -0
- package/dist/esm/providers/document-store-provider.js +536 -0
- package/dist/esm/providers/document-store-provider.js.map +1 -0
- package/dist/esm/providers/document-store-share-provider.d.ts +17 -0
- package/dist/esm/providers/document-store-share-provider.js +121 -0
- package/dist/esm/providers/document-store-share-provider.js.map +1 -0
- package/dist/esm/providers/document-store-url.d.ts +32 -0
- package/dist/esm/providers/document-store-url.js +73 -0
- package/dist/esm/providers/document-store-url.js.map +1 -0
- package/dist/esm/providers/google-drive-provider.d.ts +75 -0
- package/dist/esm/providers/google-drive-provider.js +656 -0
- package/dist/esm/providers/google-drive-provider.js.map +1 -0
- package/dist/esm/providers/interactive-api-provider.d.ts +55 -0
- package/dist/esm/providers/interactive-api-provider.js +374 -0
- package/dist/esm/providers/interactive-api-provider.js.map +1 -0
- package/dist/esm/providers/lara-provider.d.ts +47 -0
- package/dist/esm/providers/lara-provider.js +542 -0
- package/dist/esm/providers/lara-provider.js.map +1 -0
- package/dist/esm/providers/legacy-google-drive-provider.d.ts +74 -0
- package/dist/esm/providers/legacy-google-drive-provider.js +595 -0
- package/dist/esm/providers/legacy-google-drive-provider.js.map +1 -0
- package/dist/esm/providers/local-file-provider.d.ts +16 -0
- package/dist/esm/providers/local-file-provider.js +60 -0
- package/dist/esm/providers/local-file-provider.js.map +1 -0
- package/dist/esm/providers/localstorage-provider.d.ts +20 -0
- package/dist/esm/providers/localstorage-provider.js +117 -0
- package/dist/esm/providers/localstorage-provider.js.map +1 -0
- package/dist/esm/providers/patchable-content.d.ts +16 -0
- package/dist/esm/providers/patchable-content.js +60 -0
- package/dist/esm/providers/patchable-content.js.map +1 -0
- package/dist/esm/providers/post-message-provider.d.ts +12 -0
- package/dist/esm/providers/post-message-provider.js +34 -0
- package/dist/esm/providers/post-message-provider.js.map +1 -0
- package/dist/esm/providers/provider-interface.d.ts +168 -0
- package/dist/esm/providers/provider-interface.js +389 -0
- package/dist/esm/providers/provider-interface.js.map +1 -0
- package/dist/esm/providers/readonly-provider.d.ts +22 -0
- package/dist/esm/providers/readonly-provider.js +298 -0
- package/dist/esm/providers/readonly-provider.js.map +1 -0
- package/dist/esm/providers/s3-provider.d.ts +14 -0
- package/dist/esm/providers/s3-provider.js +104 -0
- package/dist/esm/providers/s3-provider.js.map +1 -0
- package/dist/esm/providers/s3-share-provider.d.ts +18 -0
- package/dist/esm/providers/s3-share-provider.js +122 -0
- package/dist/esm/providers/s3-share-provider.js.map +1 -0
- package/dist/esm/providers/share-provider-interface.d.ts +15 -0
- package/dist/esm/providers/share-provider-interface.js +2 -0
- package/dist/esm/providers/share-provider-interface.js.map +1 -0
- package/dist/esm/providers/test-provider.d.ts +26 -0
- package/dist/esm/providers/test-provider.js +71 -0
- package/dist/esm/providers/test-provider.js.map +1 -0
- package/dist/esm/providers/url-provider.d.ts +13 -0
- package/dist/esm/providers/url-provider.js +53 -0
- package/dist/esm/providers/url-provider.js.map +1 -0
- package/dist/esm/ui.d.ts +51 -0
- package/dist/esm/ui.js +208 -0
- package/dist/esm/ui.js.map +1 -0
- package/dist/esm/utils/config.d.ts +6 -0
- package/dist/esm/utils/config.js +6 -0
- package/dist/esm/utils/config.js.map +1 -0
- package/dist/esm/utils/get-hash-param.d.ts +1 -0
- package/dist/esm/utils/get-hash-param.js +21 -0
- package/dist/esm/utils/get-hash-param.js.map +1 -0
- package/dist/esm/utils/get-query-param.d.ts +1 -0
- package/dist/esm/utils/get-query-param.js +20 -0
- package/dist/esm/utils/get-query-param.js.map +1 -0
- package/dist/esm/utils/is-array.d.ts +2 -0
- package/dist/esm/utils/is-array.js +2 -0
- package/dist/esm/utils/is-array.js.map +1 -0
- package/dist/esm/utils/is-empty-object.d.ts +1 -0
- package/dist/esm/utils/is-empty-object.js +3 -0
- package/dist/esm/utils/is-empty-object.js.map +1 -0
- package/dist/esm/utils/is-string.d.ts +2 -0
- package/dist/esm/utils/is-string.js +2 -0
- package/dist/esm/utils/is-string.js.map +1 -0
- package/dist/esm/utils/lang/de.json +156 -0
- package/dist/esm/utils/lang/el.json +156 -0
- package/dist/esm/utils/lang/en-US.json +156 -0
- package/dist/esm/utils/lang/es.json +156 -0
- package/dist/esm/utils/lang/fa.json +156 -0
- package/dist/esm/utils/lang/he.json +156 -0
- package/dist/esm/utils/lang/ja.json +156 -0
- package/dist/esm/utils/lang/ko.json +156 -0
- package/dist/esm/utils/lang/nb.json +156 -0
- package/dist/esm/utils/lang/nn.json +156 -0
- package/dist/esm/utils/lang/pl.json +156 -0
- package/dist/esm/utils/lang/pt-BR.json +156 -0
- package/dist/esm/utils/lang/th.json +156 -0
- package/dist/esm/utils/lang/tr.json +156 -0
- package/dist/esm/utils/lang/zh-Hans.json +156 -0
- package/dist/esm/utils/lang/zh-TW.json +156 -0
- package/dist/esm/utils/report-error.d.ts +1 -0
- package/dist/esm/utils/report-error.js +6 -0
- package/dist/esm/utils/report-error.js.map +1 -0
- package/dist/esm/utils/s3-share-provider-token-service-helper.d.ts +21 -0
- package/dist/esm/utils/s3-share-provider-token-service-helper.js +87 -0
- package/dist/esm/utils/s3-share-provider-token-service-helper.js.map +1 -0
- package/dist/esm/utils/translate.d.ts +3 -0
- package/dist/esm/utils/translate.js +101 -0
- package/dist/esm/utils/translate.js.map +1 -0
- package/dist/esm/utils/url-params.d.ts +2 -0
- package/dist/esm/utils/url-params.js +14 -0
- package/dist/esm/utils/url-params.js.map +1 -0
- package/dist/esm/views/alert-dialog-view.d.ts +3 -0
- package/dist/esm/views/alert-dialog-view.js +27 -0
- package/dist/esm/views/alert-dialog-view.js.map +1 -0
- package/dist/esm/views/app-view.d.ts +49 -0
- package/dist/esm/views/app-view.js +267 -0
- package/dist/esm/views/app-view.js.map +1 -0
- package/dist/esm/views/authorize-mixin.d.ts +10 -0
- package/dist/esm/views/authorize-mixin.js +67 -0
- package/dist/esm/views/authorize-mixin.js.map +1 -0
- package/dist/esm/views/blocking-modal-view.d.ts +3 -0
- package/dist/esm/views/blocking-modal-view.js +27 -0
- package/dist/esm/views/blocking-modal-view.js.map +1 -0
- package/dist/esm/views/confirm-dialog-view.d.ts +3 -0
- package/dist/esm/views/confirm-dialog-view.js +35 -0
- package/dist/esm/views/confirm-dialog-view.js.map +1 -0
- package/dist/esm/views/download-dialog-view.d.ts +3 -0
- package/dist/esm/views/download-dialog-view.js +74 -0
- package/dist/esm/views/download-dialog-view.js.map +1 -0
- package/dist/esm/views/dropdown-anchors.d.ts +4 -0
- package/dist/esm/views/dropdown-anchors.js +10 -0
- package/dist/esm/views/dropdown-anchors.js.map +1 -0
- package/dist/esm/views/dropdown-view.d.ts +3 -0
- package/dist/esm/views/dropdown-view.js +147 -0
- package/dist/esm/views/dropdown-view.js.map +1 -0
- package/dist/esm/views/file-dialog-tab-view.d.ts +3 -0
- package/dist/esm/views/file-dialog-tab-view.js +400 -0
- package/dist/esm/views/file-dialog-tab-view.js.map +1 -0
- package/dist/esm/views/icons/spin.d.ts +5 -0
- package/dist/esm/views/icons/spin.js +39 -0
- package/dist/esm/views/icons/spin.js.map +1 -0
- package/dist/esm/views/import-tabbed-dialog-view.d.ts +3 -0
- package/dist/esm/views/import-tabbed-dialog-view.js +73 -0
- package/dist/esm/views/import-tabbed-dialog-view.js.map +1 -0
- package/dist/esm/views/local-file-tab-list-view.d.ts +3 -0
- package/dist/esm/views/local-file-tab-list-view.js +79 -0
- package/dist/esm/views/local-file-tab-list-view.js.map +1 -0
- package/dist/esm/views/local-file-tab-save-view.d.ts +3 -0
- package/dist/esm/views/local-file-tab-save-view.js +152 -0
- package/dist/esm/views/local-file-tab-save-view.js.map +1 -0
- package/dist/esm/views/menu-bar-view.d.ts +3 -0
- package/dist/esm/views/menu-bar-view.js +196 -0
- package/dist/esm/views/menu-bar-view.js.map +1 -0
- package/dist/esm/views/modal-dialog-view.d.ts +8 -0
- package/dist/esm/views/modal-dialog-view.js +13 -0
- package/dist/esm/views/modal-dialog-view.js.map +1 -0
- package/dist/esm/views/modal-tabbed-dialog-view.d.ts +3 -0
- package/dist/esm/views/modal-tabbed-dialog-view.js +20 -0
- package/dist/esm/views/modal-tabbed-dialog-view.js.map +1 -0
- package/dist/esm/views/modal-view.d.ts +36 -0
- package/dist/esm/views/modal-view.js +64 -0
- package/dist/esm/views/modal-view.js.map +1 -0
- package/dist/esm/views/provider-tabbed-dialog-view.d.ts +3 -0
- package/dist/esm/views/provider-tabbed-dialog-view.js +62 -0
- package/dist/esm/views/provider-tabbed-dialog-view.js.map +1 -0
- package/dist/esm/views/rename-dialog-view.d.ts +3 -0
- package/dist/esm/views/rename-dialog-view.js +55 -0
- package/dist/esm/views/rename-dialog-view.js.map +1 -0
- package/dist/esm/views/select-interactive-state-dialog-view.d.ts +22 -0
- package/dist/esm/views/select-interactive-state-dialog-view.js +87 -0
- package/dist/esm/views/select-interactive-state-dialog-view.js.map +1 -0
- package/dist/esm/views/select-provider-dialog-tab-view.d.ts +2 -0
- package/dist/esm/views/select-provider-dialog-tab-view.js +11 -0
- package/dist/esm/views/select-provider-dialog-tab-view.js.map +1 -0
- package/dist/esm/views/share-dialog-status-view.d.ts +9 -0
- package/dist/esm/views/share-dialog-status-view.js +17 -0
- package/dist/esm/views/share-dialog-status-view.js.map +1 -0
- package/dist/esm/views/share-dialog-tabs-view.d.ts +45 -0
- package/dist/esm/views/share-dialog-tabs-view.js +83 -0
- package/dist/esm/views/share-dialog-tabs-view.js.map +1 -0
- package/dist/esm/views/share-dialog-view.d.ts +50 -0
- package/dist/esm/views/share-dialog-view.js +214 -0
- package/dist/esm/views/share-dialog-view.js.map +1 -0
- package/dist/esm/views/share-loading-view.d.ts +2 -0
- package/dist/esm/views/share-loading-view.js +9 -0
- package/dist/esm/views/share-loading-view.js.map +1 -0
- package/dist/esm/views/tabbed-panel-view.d.ts +3 -0
- package/dist/esm/views/tabbed-panel-view.js +74 -0
- package/dist/esm/views/tabbed-panel-view.js.map +1 -0
- package/dist/esm/views/url-tab-view.d.ts +3 -0
- package/dist/esm/views/url-tab-view.js +62 -0
- package/dist/esm/views/url-tab-view.js.map +1 -0
- package/dist/examples/all-providers-react-18.html +74 -0
- package/dist/examples/all-providers.html +61 -0
- package/dist/examples/auto-saving.html +50 -0
- package/dist/examples/client-logging-provider.html +107 -0
- package/dist/examples/close-file.html +63 -0
- package/dist/examples/deprecate-phase-one.html +60 -0
- package/dist/examples/deprecate-phase-three.html +60 -0
- package/dist/examples/deprecate-phase-two.html +60 -0
- package/dist/examples/enable-demo-extension.html +52 -0
- package/dist/examples/enable-lara-sharing.html +51 -0
- package/dist/examples/example-app/index.html +133 -0
- package/dist/examples/hide-hamburger-2.html +55 -0
- package/dist/examples/hide-hamburger.html +34 -0
- package/dist/examples/index.html +40 -0
- package/dist/examples/interactive-api-provider.html +27 -0
- package/dist/examples/language-menu.html +86 -0
- package/dist/examples/lara-provider.html +52 -0
- package/dist/examples/load-url-query-param.html +54 -0
- package/dist/examples/menu-madness.html +67 -0
- package/dist/examples/new-does-not-use-new-tab.html +47 -0
- package/dist/examples/no-flag-language-menu.html +86 -0
- package/dist/examples/no-frame.html +130 -0
- package/dist/examples/no-shared-google-drives.html +47 -0
- package/dist/examples/read-only-with-folders.html +120 -0
- package/dist/examples/show-close-confirm.html +47 -0
- package/dist/examples/splash-screen.html +70 -0
- package/dist/examples/view-no-frame-nowrap.html +167 -0
- package/dist/examples/view-no-frame.html +129 -0
- package/dist/favicon.ico +0 -0
- package/dist/fonts/CodapIvy.eot +0 -0
- package/dist/fonts/CodapIvy.svg +61 -0
- package/dist/fonts/CodapIvy.ttf +0 -0
- package/dist/fonts/CodapIvy.woff +0 -0
- package/dist/fonts/Montserrat-Bold.otf +0 -0
- package/dist/fonts/Montserrat-Regular.otf +0 -0
- package/dist/fonts/MuseoSans_500.otf +0 -0
- package/dist/fonts/MuseoSans_500_Italic.otf +0 -0
- package/dist/fonts/icon-menu.eot +0 -0
- package/dist/fonts/icon-menu.svg +24 -0
- package/dist/fonts/icon-menu.ttf +0 -0
- package/dist/fonts/icon-menu.woff +0 -0
- package/dist/img/bb-chrome/arrow-collapse.svg +8 -0
- package/dist/img/bb-chrome/arrow-expand.svg +8 -0
- package/dist/img/bb-chrome/bg-horiz.png +0 -0
- package/dist/img/bb-chrome/btn-nodeLink.svg +298 -0
- package/dist/img/bb-chrome/chevron-down.png +0 -0
- package/dist/img/bb-chrome/chevron-left.png +0 -0
- package/dist/img/bb-chrome/chevron-right.png +0 -0
- package/dist/img/bb-chrome/chevron-up.png +0 -0
- package/dist/img/bb-chrome/global-nav-bg.png +0 -0
- package/dist/img/bb-chrome/icon-checkmark.svg +10 -0
- package/dist/img/bb-chrome/slider.svg +286 -0
- package/dist/img/bb-chrome/spin.svg +54 -0
- package/dist/img/concord-logo.png +0 -0
- package/dist/img/debug/grid.jpg +0 -0
- package/dist/img/document-store-16.png +0 -0
- package/dist/img/earth.svg +48 -0
- package/dist/img/flags.png +0 -0
- package/dist/img/fullscreen-dark.svg +22 -0
- package/dist/img/fullscreen-exit-dark.svg +22 -0
- package/dist/img/fullscreen-exit.svg +22 -0
- package/dist/img/fullscreen.svg +22 -0
- package/dist/img/google-drive-16.png +0 -0
- package/dist/img/google-drive-logo.png +0 -0
- package/dist/img/loading.gif +0 -0
- package/dist/index.html +21 -0
- package/dist/js/app.js +3 -0
- package/dist/js/app.js.LICENSE.txt +287 -0
- package/dist/js/app.js.map +1 -0
- package/dist/js/globals.js +3 -0
- package/dist/js/globals.js.LICENSE.txt +52 -0
- package/dist/js/globals.js.map +1 -0
- package/license.md +21 -0
- package/package.json +127 -0
- package/readme.md +275 -0
|
@@ -0,0 +1,1391 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.CloudFileManagerClient = exports.CloudFileManagerClientEvent = void 0;
|
|
7
|
+
// TODO: This file was created by bulk-decaffeinate.
|
|
8
|
+
// Sanity-check the conversion and remove this comment.
|
|
9
|
+
/*
|
|
10
|
+
* decaffeinate suggestions:
|
|
11
|
+
* DS102: Remove unnecessary code created because of implicit returns
|
|
12
|
+
* DS207: Consider shorter variations of null checks
|
|
13
|
+
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
14
|
+
*/
|
|
15
|
+
const jquery_1 = __importDefault(require("jquery"));
|
|
16
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
17
|
+
const mime_1 = __importDefault(require("mime"));
|
|
18
|
+
const translate_1 = __importDefault(require("./utils/translate"));
|
|
19
|
+
const is_string_1 = __importDefault(require("./utils/is-string"));
|
|
20
|
+
const base64_js_1 = __importDefault(require("base64-js")); // https://github.com/beatgammit/base64-js
|
|
21
|
+
const get_query_param_1 = __importDefault(require("./utils/get-query-param"));
|
|
22
|
+
const app_options_1 = require("./app-options");
|
|
23
|
+
const ui_1 = require("./ui");
|
|
24
|
+
const localstorage_provider_1 = __importDefault(require("./providers/localstorage-provider"));
|
|
25
|
+
const readonly_provider_1 = __importDefault(require("./providers/readonly-provider"));
|
|
26
|
+
const google_drive_provider_1 = __importDefault(require("./providers/google-drive-provider"));
|
|
27
|
+
const interactive_api_provider_1 = __importDefault(require("./providers/interactive-api-provider"));
|
|
28
|
+
const lara_provider_1 = __importDefault(require("./providers/lara-provider"));
|
|
29
|
+
const document_store_provider_1 = __importDefault(require("./providers/document-store-provider"));
|
|
30
|
+
const s3_share_provider_1 = __importDefault(require("./providers/s3-share-provider"));
|
|
31
|
+
const s3_provider_1 = __importDefault(require("./providers/s3-provider"));
|
|
32
|
+
const local_file_provider_1 = __importDefault(require("./providers/local-file-provider"));
|
|
33
|
+
const post_message_provider_1 = __importDefault(require("./providers/post-message-provider"));
|
|
34
|
+
const url_provider_1 = __importDefault(require("./providers/url-provider"));
|
|
35
|
+
const test_provider_1 = __importDefault(require("./providers/test-provider"));
|
|
36
|
+
const provider_interface_1 = require("./providers/provider-interface");
|
|
37
|
+
const report_error_1 = require("./utils/report-error");
|
|
38
|
+
const lara_interactive_api_1 = require("@concord-consortium/lara-interactive-api");
|
|
39
|
+
let CLOUDFILEMANAGER_EVENT_ID = 0;
|
|
40
|
+
const CLOUDFILEMANAGER_EVENTS = {};
|
|
41
|
+
class CloudFileManagerClientEvent {
|
|
42
|
+
constructor(type, data, callback = null, state) {
|
|
43
|
+
this.type = type;
|
|
44
|
+
if (data == null) {
|
|
45
|
+
data = {};
|
|
46
|
+
}
|
|
47
|
+
this.data = data;
|
|
48
|
+
this.callback = callback;
|
|
49
|
+
if (state == null) {
|
|
50
|
+
state = {};
|
|
51
|
+
}
|
|
52
|
+
this.state = state;
|
|
53
|
+
CLOUDFILEMANAGER_EVENT_ID++;
|
|
54
|
+
this.id = CLOUDFILEMANAGER_EVENT_ID;
|
|
55
|
+
}
|
|
56
|
+
postMessage(iframe) {
|
|
57
|
+
if (this.callback) {
|
|
58
|
+
CLOUDFILEMANAGER_EVENTS[this.id] = this;
|
|
59
|
+
}
|
|
60
|
+
// remove client from data to avoid structured clone error in postMessage
|
|
61
|
+
const eventData = lodash_1.default.clone(this.data);
|
|
62
|
+
delete eventData.client;
|
|
63
|
+
const message = { type: "cfm::event", eventId: this.id, eventType: this.type, eventData };
|
|
64
|
+
return iframe.postMessage(message, "*");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
exports.CloudFileManagerClientEvent = CloudFileManagerClientEvent;
|
|
68
|
+
class CloudFileManagerClient {
|
|
69
|
+
constructor(options) {
|
|
70
|
+
this.shouldAutoSave = this.shouldAutoSave.bind(this);
|
|
71
|
+
this.state = { availableProviders: [] };
|
|
72
|
+
this._listeners = [];
|
|
73
|
+
this._resetState();
|
|
74
|
+
this._ui = new ui_1.CloudFileManagerUI(this);
|
|
75
|
+
this.providers = {};
|
|
76
|
+
this.urlProvider = new url_provider_1.default();
|
|
77
|
+
this.onUnload = this.onUnload.bind(this);
|
|
78
|
+
(0, lara_interactive_api_1.setOnUnload)(this.onUnload);
|
|
79
|
+
this.connectedPromise = new Promise((resolve, reject) => {
|
|
80
|
+
this.connectedPromiseResolver = {
|
|
81
|
+
resolve: () => {
|
|
82
|
+
resolve();
|
|
83
|
+
this.connectedPromiseResolver = null;
|
|
84
|
+
},
|
|
85
|
+
reject: () => {
|
|
86
|
+
reject();
|
|
87
|
+
this.connectedPromiseResolver = null;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
setAppOptions(appOptions) {
|
|
93
|
+
var _a, _b, _c, _d;
|
|
94
|
+
let providerName;
|
|
95
|
+
let Provider;
|
|
96
|
+
if (appOptions == null) {
|
|
97
|
+
appOptions = {};
|
|
98
|
+
}
|
|
99
|
+
this.appOptions = appOptions;
|
|
100
|
+
if (this.appOptions.wrapFileContent == null) {
|
|
101
|
+
this.appOptions.wrapFileContent = true;
|
|
102
|
+
}
|
|
103
|
+
provider_interface_1.CloudContent.wrapFileContent = this.appOptions.wrapFileContent;
|
|
104
|
+
if (this.appOptions.isClientContent)
|
|
105
|
+
provider_interface_1.cloudContentFactory.isClientContent = this.appOptions.isClientContent;
|
|
106
|
+
const allProviders = {};
|
|
107
|
+
// Determine the available providers. Note that order in the list can
|
|
108
|
+
// be significant in provider searches (e.g. @autoProvider).
|
|
109
|
+
const providerList = [
|
|
110
|
+
localstorage_provider_1.default,
|
|
111
|
+
readonly_provider_1.default,
|
|
112
|
+
google_drive_provider_1.default,
|
|
113
|
+
lara_provider_1.default,
|
|
114
|
+
interactive_api_provider_1.default,
|
|
115
|
+
document_store_provider_1.default,
|
|
116
|
+
local_file_provider_1.default,
|
|
117
|
+
post_message_provider_1.default,
|
|
118
|
+
s3_provider_1.default,
|
|
119
|
+
test_provider_1.default
|
|
120
|
+
];
|
|
121
|
+
for (Provider of providerList) {
|
|
122
|
+
if (Provider.Available()) {
|
|
123
|
+
allProviders[Provider.Name] = Provider;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// default to all providers if none specified
|
|
127
|
+
if (!this.appOptions.providers) {
|
|
128
|
+
this.appOptions.providers = [];
|
|
129
|
+
for (providerName of Object.keys(allProviders || {})) {
|
|
130
|
+
appOptions.providers.push(providerName);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// preset the extension if Available
|
|
134
|
+
provider_interface_1.CloudMetadata.Extension = this.appOptions.extension;
|
|
135
|
+
provider_interface_1.CloudMetadata.ReadableExtensions = this.appOptions.readableExtensions || [];
|
|
136
|
+
if (provider_interface_1.CloudMetadata.Extension) {
|
|
137
|
+
provider_interface_1.CloudMetadata.ReadableExtensions.push(provider_interface_1.CloudMetadata.Extension);
|
|
138
|
+
}
|
|
139
|
+
const readableMimetypes = this.appOptions.readableMimeTypes || [];
|
|
140
|
+
readableMimetypes.push(this.appOptions.mimeType);
|
|
141
|
+
// check the providers
|
|
142
|
+
const requestedProviders = this.appOptions.providers.slice();
|
|
143
|
+
if ((0, get_query_param_1.default)("saveSecondaryFileViaPostMessage")) {
|
|
144
|
+
requestedProviders.push('postMessage');
|
|
145
|
+
}
|
|
146
|
+
const isInteractiveApiRequested = requestedProviders.includes('interactiveApi');
|
|
147
|
+
const availableProviders = [];
|
|
148
|
+
let shareProvider = null;
|
|
149
|
+
for (let providerSpec of requestedProviders) {
|
|
150
|
+
const [providerName, providerOptions] = (0, is_string_1.default)(providerSpec)
|
|
151
|
+
? [providerSpec, {}]
|
|
152
|
+
: [providerSpec.name, providerSpec];
|
|
153
|
+
// merge in other options as needed
|
|
154
|
+
if (providerOptions.mimeType == null) {
|
|
155
|
+
providerOptions.mimeType = this.appOptions.mimeType;
|
|
156
|
+
}
|
|
157
|
+
providerOptions.readableMimetypes = readableMimetypes;
|
|
158
|
+
if (!providerName) {
|
|
159
|
+
this.alert("Invalid provider spec - must either be string or object with name property");
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
if ((0, app_options_1.isCustomClientProvider)(providerOptions)) {
|
|
163
|
+
allProviders[providerName] = providerOptions.createProvider(provider_interface_1.ProviderInterface);
|
|
164
|
+
}
|
|
165
|
+
if (allProviders[providerName]) {
|
|
166
|
+
Provider = allProviders[providerName];
|
|
167
|
+
// don't add providers that require configuration if no (or invalid) configuration provided
|
|
168
|
+
if (!Provider.hasValidOptions || Provider.hasValidOptions(providerOptions)) {
|
|
169
|
+
const provider = new Provider(providerOptions, this);
|
|
170
|
+
this.providers[providerName] = provider;
|
|
171
|
+
shareProvider = this._getShareProvider();
|
|
172
|
+
// also add to here in providers list so we can look it up when parsing url hash
|
|
173
|
+
if (provider.urlDisplayName) {
|
|
174
|
+
this.providers[provider.urlDisplayName] = provider;
|
|
175
|
+
}
|
|
176
|
+
availableProviders.push(provider);
|
|
177
|
+
// InteractiveApiProvider is a newer form of Lara provider
|
|
178
|
+
if (!isInteractiveApiRequested && (providerName === "lara")) {
|
|
179
|
+
const interactiveApiProvider = new interactive_api_provider_1.default(providerOptions, this);
|
|
180
|
+
this.providers.interactiveApi = interactiveApiProvider;
|
|
181
|
+
availableProviders.push(interactiveApiProvider);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
this.alert(`Unknown provider: ${providerName}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
this._setState({
|
|
191
|
+
availableProviders,
|
|
192
|
+
shareProvider
|
|
193
|
+
});
|
|
194
|
+
if (!this.appOptions.ui) {
|
|
195
|
+
this.appOptions.ui = {};
|
|
196
|
+
}
|
|
197
|
+
if (!this.appOptions.ui.windowTitleSuffix) {
|
|
198
|
+
this.appOptions.ui.windowTitleSuffix = document.title;
|
|
199
|
+
}
|
|
200
|
+
if (!this.appOptions.ui.windowTitleSeparator) {
|
|
201
|
+
this.appOptions.ui.windowTitleSeparator = ' - ';
|
|
202
|
+
}
|
|
203
|
+
this._setWindowTitle();
|
|
204
|
+
this._ui.init(this.appOptions.ui);
|
|
205
|
+
// check for autosave
|
|
206
|
+
if (this.appOptions.autoSaveInterval) {
|
|
207
|
+
this.autoSave(this.appOptions.autoSaveInterval);
|
|
208
|
+
}
|
|
209
|
+
// initialize the cloudContentFactory with all data we want in the envelope
|
|
210
|
+
provider_interface_1.cloudContentFactory.setEnvelopeMetadata({
|
|
211
|
+
cfmVersion: '__PACKAGE_VERSION__', // replaced by version number at build time
|
|
212
|
+
appName: this.appOptions.appName || "",
|
|
213
|
+
appVersion: this.appOptions.appVersion || "",
|
|
214
|
+
appBuildNum: this.appOptions.appBuildNum || ""
|
|
215
|
+
});
|
|
216
|
+
this.newFileOpensInNewTab = (_b = (_a = this.appOptions.ui) === null || _a === void 0 ? void 0 : _a.newFileOpensInNewTab) !== null && _b !== void 0 ? _b : true;
|
|
217
|
+
this.newFileAddsNewToQuery = (_c = this.appOptions.ui) === null || _c === void 0 ? void 0 : _c.newFileAddsNewToQuery;
|
|
218
|
+
if ((_d = this.appOptions.ui) === null || _d === void 0 ? void 0 : _d.confirmCloseIfDirty) {
|
|
219
|
+
this._setupConfirmOnClose();
|
|
220
|
+
}
|
|
221
|
+
return this._startPostMessageListener();
|
|
222
|
+
}
|
|
223
|
+
_getShareProvider() {
|
|
224
|
+
return new s3_share_provider_1.default(this, new s3_provider_1.default(this));
|
|
225
|
+
}
|
|
226
|
+
setProviderOptions(name, newOptions) {
|
|
227
|
+
for (let provider of this.state.availableProviders) {
|
|
228
|
+
if (provider.name === name) {
|
|
229
|
+
provider.options = { ...provider.options, newOptions };
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
connect() {
|
|
235
|
+
var _a;
|
|
236
|
+
(_a = this.connectedPromiseResolver) === null || _a === void 0 ? void 0 : _a.resolve();
|
|
237
|
+
return this._event('connected', { client: this });
|
|
238
|
+
}
|
|
239
|
+
//
|
|
240
|
+
// Called from CloudFileManager.clientConnect to process the URL parameters
|
|
241
|
+
// and initiate opening any document specified by URL parameters. The CFM
|
|
242
|
+
// hash params are processed here after which providers are given a chance
|
|
243
|
+
// to process any provider-specific URL parameters. Calls ready() if no
|
|
244
|
+
// initial document opening occurs.
|
|
245
|
+
//
|
|
246
|
+
processUrlParams() {
|
|
247
|
+
// process the hash params
|
|
248
|
+
let providerName;
|
|
249
|
+
const { hashParams } = this.appOptions;
|
|
250
|
+
if (hashParams.sharedContentId) {
|
|
251
|
+
return this.openSharedContent(hashParams.sharedContentId);
|
|
252
|
+
}
|
|
253
|
+
else if (hashParams.fileParams) {
|
|
254
|
+
if (hashParams.fileParams.indexOf("http") === 0) {
|
|
255
|
+
return this.openUrlFile(hashParams.fileParams);
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
let providerParams;
|
|
259
|
+
[providerName, providerParams] = hashParams.fileParams.split(':');
|
|
260
|
+
return this.openProviderFile(providerName, providerParams);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
else if (hashParams.copyParams) {
|
|
264
|
+
return this.openCopiedFile(hashParams.copyParams);
|
|
265
|
+
}
|
|
266
|
+
else if (hashParams.newInFolderParams) {
|
|
267
|
+
let folder;
|
|
268
|
+
[providerName, folder] = hashParams.newInFolderParams.split(':');
|
|
269
|
+
return this.createNewInFolder(providerName, folder);
|
|
270
|
+
}
|
|
271
|
+
else if (this.haveTempFile()) {
|
|
272
|
+
return this.openAndClearTempFile();
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
// give providers a chance to process url params
|
|
276
|
+
for (let provider of this.state.availableProviders) {
|
|
277
|
+
if (provider.handleUrlParams()) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
// if no providers handled it, then just signal ready()
|
|
282
|
+
return this.ready();
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
ready() {
|
|
286
|
+
return this._event('ready');
|
|
287
|
+
}
|
|
288
|
+
rendered() {
|
|
289
|
+
return this._event('rendered', { client: this });
|
|
290
|
+
}
|
|
291
|
+
listen(listener) {
|
|
292
|
+
if (listener) {
|
|
293
|
+
return this._listeners.push(listener);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
log(event, eventData) {
|
|
297
|
+
this._event('log', { logEvent: event, logEventData: eventData });
|
|
298
|
+
if (this.appOptions.log) {
|
|
299
|
+
return this.appOptions.log(event, eventData);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
autoProvider(capability) {
|
|
303
|
+
for (let provider of this.state.availableProviders) {
|
|
304
|
+
if (provider.canAuto(capability)) {
|
|
305
|
+
return provider;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
appendMenuItem(item) {
|
|
310
|
+
this._ui.appendMenuItem(item);
|
|
311
|
+
return this;
|
|
312
|
+
}
|
|
313
|
+
prependMenuItem(item) {
|
|
314
|
+
this._ui.prependMenuItem(item);
|
|
315
|
+
return this;
|
|
316
|
+
}
|
|
317
|
+
replaceMenuItem(key, item) {
|
|
318
|
+
this._ui.replaceMenuItem(key, item);
|
|
319
|
+
return this;
|
|
320
|
+
}
|
|
321
|
+
insertMenuItemBefore(key, item) {
|
|
322
|
+
this._ui.insertMenuItemBefore(key, item);
|
|
323
|
+
return this;
|
|
324
|
+
}
|
|
325
|
+
insertMenuItemAfter(key, item) {
|
|
326
|
+
this._ui.insertMenuItemAfter(key, item);
|
|
327
|
+
return this;
|
|
328
|
+
}
|
|
329
|
+
setMenuBarInfo(info) {
|
|
330
|
+
return this._ui.setMenuBarInfo(info);
|
|
331
|
+
}
|
|
332
|
+
newFile(callback = null) {
|
|
333
|
+
this._closeCurrentFile();
|
|
334
|
+
this._resetState();
|
|
335
|
+
window.location.hash = "";
|
|
336
|
+
return this._event('newedFile', { content: "" }, callback);
|
|
337
|
+
}
|
|
338
|
+
newFileDialog(callback = null) {
|
|
339
|
+
if (this.newFileOpensInNewTab) {
|
|
340
|
+
return window.open(this.getCurrentUrl(this.newFileAddsNewToQuery ? "#new" : null), '_blank');
|
|
341
|
+
}
|
|
342
|
+
else if (this.state.dirty) {
|
|
343
|
+
if (this._autoSaveInterval && this.state.metadata) {
|
|
344
|
+
this.save();
|
|
345
|
+
return this.newFile(callback);
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
return this.confirm((0, translate_1.default)('~CONFIRM.NEW_FILE'), () => this.newFile(callback));
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
return this.newFile(callback);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
openFile(metadata, callback = null) {
|
|
356
|
+
var _a;
|
|
357
|
+
if ((_a = metadata === null || metadata === void 0 ? void 0 : metadata.provider) === null || _a === void 0 ? void 0 : _a.can(provider_interface_1.ECapabilities.load, metadata)) {
|
|
358
|
+
this._event('willOpenFile', { op: "openFile" });
|
|
359
|
+
return metadata.provider.load(metadata, (err, content) => {
|
|
360
|
+
if (err) {
|
|
361
|
+
return this.alert(err, () => this.ready());
|
|
362
|
+
}
|
|
363
|
+
// should wait to close current file until client signals open is complete
|
|
364
|
+
this._closeCurrentFile();
|
|
365
|
+
content = this._filterLoadedContent(content);
|
|
366
|
+
this._fileOpened(content, metadata, { openedContent: content.clone() }, this._getHashParams(metadata));
|
|
367
|
+
if (typeof callback === 'function') {
|
|
368
|
+
callback(content, metadata);
|
|
369
|
+
}
|
|
370
|
+
return metadata.provider.fileOpened(content, metadata);
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
return this.openFileDialog(callback);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
openFileDialog(callback = null) {
|
|
378
|
+
const showDialog = () => {
|
|
379
|
+
return this._ui.openFileDialog((metadata) => {
|
|
380
|
+
return this.openFile(metadata, callback);
|
|
381
|
+
});
|
|
382
|
+
};
|
|
383
|
+
if (!this.state.dirty) {
|
|
384
|
+
return showDialog();
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
return this.confirm((0, translate_1.default)('~CONFIRM.OPEN_FILE'), showDialog);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
closeFile(callback = null) {
|
|
391
|
+
this._closeCurrentFile();
|
|
392
|
+
this._resetState();
|
|
393
|
+
window.location.hash = "";
|
|
394
|
+
this._event('closedFile', { content: "" });
|
|
395
|
+
return (typeof callback === 'function' ? callback() : undefined);
|
|
396
|
+
}
|
|
397
|
+
closeFileDialog(callback = null) {
|
|
398
|
+
if (!this.state.dirty) {
|
|
399
|
+
return this.closeFile(callback);
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
return this.confirm((0, translate_1.default)('~CONFIRM.CLOSE_FILE'), () => this.closeFile(callback));
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
importData(data, callback = null) {
|
|
406
|
+
this._event('importedData', data);
|
|
407
|
+
return (typeof callback === 'function' ? callback(data) : undefined);
|
|
408
|
+
}
|
|
409
|
+
importDataDialog(callback = null) {
|
|
410
|
+
return this._ui.importDataDialog((data) => {
|
|
411
|
+
return this.importData(data, callback);
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
readLocalFile(file, callback = null) {
|
|
415
|
+
const reader = new FileReader();
|
|
416
|
+
reader.onload = loaded => typeof callback === 'function' ? callback({ name: file.name, content: loaded.target.result }) : undefined;
|
|
417
|
+
return reader.readAsText(file);
|
|
418
|
+
}
|
|
419
|
+
openLocalFile(file, callback = null) {
|
|
420
|
+
this._event('willOpenFile', { op: "openLocalFile" });
|
|
421
|
+
return this.readLocalFile(file, (data) => {
|
|
422
|
+
let content = provider_interface_1.cloudContentFactory.createEnvelopedCloudContent(data.content);
|
|
423
|
+
content = this._filterLoadedContent(content);
|
|
424
|
+
const metadata = new provider_interface_1.CloudMetadata({
|
|
425
|
+
name: data.name,
|
|
426
|
+
type: provider_interface_1.CloudMetadata.File
|
|
427
|
+
});
|
|
428
|
+
this._fileOpened(content, metadata, { openedContent: content.clone() });
|
|
429
|
+
return (typeof callback === 'function' ? callback(content, metadata) : undefined);
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
importLocalFile(file, callback = null) {
|
|
433
|
+
return this.readLocalFile(file, (data) => {
|
|
434
|
+
return this.importData(data, callback);
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
openSharedContent(id) {
|
|
438
|
+
const { shareProvider } = this.state;
|
|
439
|
+
this._event('willOpenFile', { op: "openSharedContent" });
|
|
440
|
+
if (shareProvider.loadSharedContent) {
|
|
441
|
+
shareProvider.loadSharedContent(id, (err, content, metadata) => {
|
|
442
|
+
if (err) {
|
|
443
|
+
this.alert(err, () => this.ready());
|
|
444
|
+
}
|
|
445
|
+
else {
|
|
446
|
+
content = this._filterLoadedContent(content);
|
|
447
|
+
this._fileOpened(content, metadata, { overwritable: false, openedContent: content.clone() });
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
// must be called as a result of user action (e.g. click) to avoid popup blockers
|
|
453
|
+
parseUrlAuthorizeAndOpen() {
|
|
454
|
+
var _a;
|
|
455
|
+
if (((_a = this.appOptions.hashParams) === null || _a === void 0 ? void 0 : _a.fileParams) != null) {
|
|
456
|
+
const [providerName, providerParams] = this.appOptions.hashParams.fileParams.split(':');
|
|
457
|
+
const provider = this.providers[providerName];
|
|
458
|
+
if (provider) {
|
|
459
|
+
return provider.authorize(() => {
|
|
460
|
+
return this.openProviderFile(providerName, providerParams);
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Disassociates the current document from its provider.
|
|
467
|
+
*
|
|
468
|
+
* This is important specifically for autosaving providers. When authenticated
|
|
469
|
+
* state is lost we must not continue to autosave.
|
|
470
|
+
*/
|
|
471
|
+
disconnectCurrentFile() {
|
|
472
|
+
console.warn('Closing file (rejected reauth)');
|
|
473
|
+
if (this.state.metadata) {
|
|
474
|
+
this.state.metadata.provider = null;
|
|
475
|
+
}
|
|
476
|
+
this._setState({ saving: null, saved: null });
|
|
477
|
+
window.location.hash = "";
|
|
478
|
+
this._event('ready');
|
|
479
|
+
}
|
|
480
|
+
confirmAuthorizeAndOpen(provider, providerParams) {
|
|
481
|
+
const rejectCallback = () => this.disconnectCurrentFile();
|
|
482
|
+
// trigger authorize() from confirmation dialog to avoid popup blockers
|
|
483
|
+
return this.confirm((0, translate_1.default)("~CONFIRM.AUTHORIZE_OPEN"), () => {
|
|
484
|
+
return provider.authorize(() => {
|
|
485
|
+
this._event('willOpenFile', { op: "confirmAuthorizeAndOpen" });
|
|
486
|
+
return provider.openSaved(providerParams, (err, content, metadata) => {
|
|
487
|
+
if (err) {
|
|
488
|
+
return this.alert(err);
|
|
489
|
+
}
|
|
490
|
+
content = this._filterLoadedContent(content);
|
|
491
|
+
this._fileOpened(content, metadata, { openedContent: content.clone() }, this._getHashParams(metadata));
|
|
492
|
+
return provider.fileOpened(content, metadata);
|
|
493
|
+
});
|
|
494
|
+
});
|
|
495
|
+
}, rejectCallback);
|
|
496
|
+
}
|
|
497
|
+
openProviderFileWhenConnected(providerName, providerParams) {
|
|
498
|
+
this.connectedPromise.then(() => this.openProviderFile(providerName, providerParams));
|
|
499
|
+
}
|
|
500
|
+
openProviderFile(providerName, providerParams) {
|
|
501
|
+
const provider = this.providers[providerName];
|
|
502
|
+
if (provider) {
|
|
503
|
+
return provider.authorized((isAuthorized) => {
|
|
504
|
+
// we can open the document without authorization in some cases
|
|
505
|
+
if (isAuthorized || !provider.isAuthorizationRequired()) {
|
|
506
|
+
this._event('willOpenFile', { op: "openProviderFile" });
|
|
507
|
+
return provider.openSaved(providerParams, (err, content, metadata) => {
|
|
508
|
+
if (err) {
|
|
509
|
+
return this.alert(err, () => this.ready());
|
|
510
|
+
}
|
|
511
|
+
// if we just opened the file, it doesn't need to be saved until the contents are changed unless
|
|
512
|
+
// it requires conversion from an older version
|
|
513
|
+
content = this._filterLoadedContent(content);
|
|
514
|
+
const additionalState = { openedContent: content.clone(), dirty: content.requiresConversion() };
|
|
515
|
+
this._fileOpened(content, metadata, additionalState, this._getHashParams(metadata));
|
|
516
|
+
return provider.fileOpened(content, metadata);
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
else {
|
|
520
|
+
return this.confirmAuthorizeAndOpen(provider, providerParams);
|
|
521
|
+
}
|
|
522
|
+
}, { forceAuthorization: true }); // force authorization for Google Drive
|
|
523
|
+
}
|
|
524
|
+
else {
|
|
525
|
+
return this.alert((0, translate_1.default)("~ALERT.NO_PROVIDER"), () => this.ready());
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
openUrlFile(url) {
|
|
529
|
+
return this.urlProvider.openFileFromUrl(url, (err, content, metadata) => {
|
|
530
|
+
this._event('willOpenFile', { op: "openUrlFile" });
|
|
531
|
+
if (err) {
|
|
532
|
+
return this.alert(err, () => this.ready());
|
|
533
|
+
}
|
|
534
|
+
content = this._filterLoadedContent(content);
|
|
535
|
+
return this._fileOpened(content, metadata, { openedContent: content.clone() }, this._getHashParams(metadata));
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
createNewInFolder(providerName, folder) {
|
|
539
|
+
const provider = this.providers[providerName];
|
|
540
|
+
if (provider && provider.can(provider_interface_1.ECapabilities.setFolder, this.state.metadata)) {
|
|
541
|
+
if ((this.state.metadata == null)) {
|
|
542
|
+
this.state.metadata = new provider_interface_1.CloudMetadata({
|
|
543
|
+
type: provider_interface_1.CloudMetadata.File,
|
|
544
|
+
provider
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
this.state.metadata.parent = new provider_interface_1.CloudMetadata({
|
|
548
|
+
type: provider_interface_1.CloudMetadata.Folder,
|
|
549
|
+
providerData: {
|
|
550
|
+
id: folder
|
|
551
|
+
}
|
|
552
|
+
});
|
|
553
|
+
this._ui.editInitialFilename();
|
|
554
|
+
}
|
|
555
|
+
return this._event('newedFile', { content: "" });
|
|
556
|
+
}
|
|
557
|
+
setInitialFilename(filename) {
|
|
558
|
+
this.state.metadata.rename(filename);
|
|
559
|
+
return this.save();
|
|
560
|
+
}
|
|
561
|
+
isSaveInProgress() {
|
|
562
|
+
return (this.state.saving != null);
|
|
563
|
+
}
|
|
564
|
+
confirmAuthorizeAndSave(stringContent, callback) {
|
|
565
|
+
let rejectCallback = () => { this.disconnectCurrentFile(); };
|
|
566
|
+
// trigger authorize() from confirmation dialog to avoid popup blockers
|
|
567
|
+
return this.confirm((0, translate_1.default)("~CONFIRM.AUTHORIZE_SAVE"), () => {
|
|
568
|
+
return this.state.metadata.provider.authorize(() => {
|
|
569
|
+
return this.saveFile(stringContent, this.state.metadata, callback);
|
|
570
|
+
});
|
|
571
|
+
}, rejectCallback);
|
|
572
|
+
}
|
|
573
|
+
save(callback = null) {
|
|
574
|
+
return this._event('getContent', { shared: this._sharedMetadata() }, (stringContent) => {
|
|
575
|
+
return this.saveContent(stringContent, callback);
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
saveContent(stringContent, callback = null) {
|
|
579
|
+
var _a;
|
|
580
|
+
const provider = ((_a = this.state.metadata) === null || _a === void 0 ? void 0 : _a.provider) || this.autoProvider(provider_interface_1.ECapabilities.save);
|
|
581
|
+
if (provider != null) {
|
|
582
|
+
return provider.authorized((isAuthorized) => {
|
|
583
|
+
// we can save the document without authorization in some cases
|
|
584
|
+
if (isAuthorized || !provider.isAuthorizationRequired()) {
|
|
585
|
+
return this.saveFile(stringContent, this.state.metadata, callback);
|
|
586
|
+
}
|
|
587
|
+
else {
|
|
588
|
+
return this.confirmAuthorizeAndSave(stringContent, callback);
|
|
589
|
+
}
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
else {
|
|
593
|
+
return this.saveFileDialog(stringContent, callback);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
saveFile(stringContent, metadata, callback = null) {
|
|
597
|
+
var _a;
|
|
598
|
+
const readonly = metadata && !metadata.overwritable; // only check if metadata exists
|
|
599
|
+
const resaveable = (_a = metadata === null || metadata === void 0 ? void 0 : metadata.provider) === null || _a === void 0 ? void 0 : _a.can(provider_interface_1.ECapabilities.resave, metadata);
|
|
600
|
+
// must be able to 'resave' to save silently, i.e. without save dialog
|
|
601
|
+
if (!readonly && resaveable) {
|
|
602
|
+
return this.saveFileNoDialog(stringContent, metadata, callback);
|
|
603
|
+
}
|
|
604
|
+
else {
|
|
605
|
+
return this.saveFileDialog(stringContent, callback);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
saveFileNoDialog(stringContent, metadata, callback = null) {
|
|
609
|
+
var _a, _b;
|
|
610
|
+
this._setState({
|
|
611
|
+
saving: metadata
|
|
612
|
+
});
|
|
613
|
+
let currentContent = this._createOrUpdateCurrentContent(stringContent, metadata);
|
|
614
|
+
currentContent = ((_b = (_a = this.appOptions).contentSaveFilter) === null || _b === void 0 ? void 0 : _b.call(_a, currentContent)) || currentContent;
|
|
615
|
+
return metadata.provider.save(currentContent, metadata, (err, statusCode, savedContent) => {
|
|
616
|
+
let failures;
|
|
617
|
+
if (err) {
|
|
618
|
+
if (statusCode === 401 || statusCode === 403 || statusCode === 404) {
|
|
619
|
+
// disable autosave while the confirmation dialog is showing
|
|
620
|
+
metadata.autoSaveDisabled = true;
|
|
621
|
+
this._setState({ metadata, saving: null });
|
|
622
|
+
return this.confirmAuthorizeAndSave(stringContent, callback);
|
|
623
|
+
}
|
|
624
|
+
else {
|
|
625
|
+
this._setState({ saving: null });
|
|
626
|
+
failures = this.state.failures;
|
|
627
|
+
if (!failures) {
|
|
628
|
+
failures = 1;
|
|
629
|
+
}
|
|
630
|
+
else {
|
|
631
|
+
failures++;
|
|
632
|
+
}
|
|
633
|
+
if (failures === 1) {
|
|
634
|
+
this._setState({ failures, showingSaveAlert: true });
|
|
635
|
+
let error = err.toString();
|
|
636
|
+
if (this.isAutoSaving()) {
|
|
637
|
+
error = `${error}<br><br>${(0, translate_1.default)("~FILE_STATUS.CONTINUE_SAVE")}`;
|
|
638
|
+
}
|
|
639
|
+
return this.alert(error, () => {
|
|
640
|
+
this._setState({ showingSaveAlert: false });
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
else {
|
|
644
|
+
this._setState({ failures });
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
else {
|
|
649
|
+
if (this.state.showingSaveAlert) {
|
|
650
|
+
this.hideAlert();
|
|
651
|
+
}
|
|
652
|
+
this._setState({ failures: 0, showingSaveAlert: false });
|
|
653
|
+
if (this.state.metadata !== metadata) {
|
|
654
|
+
this._closeCurrentFile();
|
|
655
|
+
}
|
|
656
|
+
// reenable autosave on save success if this isn't a local file save
|
|
657
|
+
if (metadata.autoSaveDisabled != null) {
|
|
658
|
+
delete metadata.autoSaveDisabled;
|
|
659
|
+
}
|
|
660
|
+
this._fileChanged('savedFile', currentContent, metadata, { saved: true }, this._getHashParams(metadata));
|
|
661
|
+
return (typeof callback === 'function' ? callback(currentContent, metadata, savedContent) : undefined);
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
}
|
|
665
|
+
saveFileDialog(stringContent = null, callback = null) {
|
|
666
|
+
return this._ui.saveFileDialog((metadata) => {
|
|
667
|
+
return this._dialogSave(stringContent, metadata, callback);
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
saveFileAsDialog(stringContent = null, callback = null) {
|
|
671
|
+
return this._ui.saveFileAsDialog((metadata) => {
|
|
672
|
+
return this._dialogSave(stringContent, metadata, callback);
|
|
673
|
+
});
|
|
674
|
+
}
|
|
675
|
+
createCopy(stringContent = null, callback = null) {
|
|
676
|
+
const saveAndOpenCopy = (stringContent) => {
|
|
677
|
+
var _a;
|
|
678
|
+
return this.saveCopiedFile(stringContent, (_a = this.state.metadata) === null || _a === void 0 ? void 0 : _a.name, (err, copyParams) => {
|
|
679
|
+
if (err) {
|
|
680
|
+
return (typeof callback === 'function' ? callback(err) : undefined);
|
|
681
|
+
}
|
|
682
|
+
window.open(this.getCurrentUrl(`#copy=${copyParams}`));
|
|
683
|
+
return (typeof callback === 'function' ? callback(copyParams) : undefined);
|
|
684
|
+
});
|
|
685
|
+
};
|
|
686
|
+
if (stringContent == null) {
|
|
687
|
+
return this._event('getContent', {}, (stringContent) => saveAndOpenCopy(stringContent));
|
|
688
|
+
}
|
|
689
|
+
else {
|
|
690
|
+
return saveAndOpenCopy(stringContent);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
saveCopiedFile(stringContent, name, callback) {
|
|
694
|
+
try {
|
|
695
|
+
const prefix = 'cfm-copy::';
|
|
696
|
+
let maxCopyNumber = 0;
|
|
697
|
+
for (let key of Object.keys(window.localStorage || {})) {
|
|
698
|
+
if (key.substr(0, prefix.length) === prefix) {
|
|
699
|
+
const copyNumber = parseInt(key.substr(prefix.length), 10);
|
|
700
|
+
maxCopyNumber = Math.max(maxCopyNumber, copyNumber);
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
maxCopyNumber++;
|
|
704
|
+
const value = JSON.stringify({
|
|
705
|
+
name: (name === null || name === void 0 ? void 0 : name.length) ? `Copy of ${name}` : "Copy of Untitled Document",
|
|
706
|
+
stringContent
|
|
707
|
+
});
|
|
708
|
+
window.localStorage.setItem(`${prefix}${maxCopyNumber}`, value);
|
|
709
|
+
return (typeof callback === 'function' ? callback(null, maxCopyNumber) : undefined);
|
|
710
|
+
}
|
|
711
|
+
catch (e) {
|
|
712
|
+
// CODAP style overrides
|
|
713
|
+
const divStyle = "text-align: left";
|
|
714
|
+
const paragraphStyle = "margin: 10px 0;";
|
|
715
|
+
const listStyle = "margin: 10px 10px 10px 30px; padding: 0;";
|
|
716
|
+
const message = `
|
|
717
|
+
<div style="${divStyle}">
|
|
718
|
+
<p style="${paragraphStyle}">The document is either too large to copy within the app, or your browser does not allow local storage.</p>
|
|
719
|
+
|
|
720
|
+
<p style="${paragraphStyle}">To copy this file you must duplicate it outside the app using these steps:</p>
|
|
721
|
+
|
|
722
|
+
<ol style="${listStyle}">
|
|
723
|
+
<li>Save the document.</li>
|
|
724
|
+
<li>Duplicate it using Google Drive or your local file system.</li>
|
|
725
|
+
<li>Open or import the newly duplicated document.</li>
|
|
726
|
+
</ol>
|
|
727
|
+
</div>
|
|
728
|
+
`;
|
|
729
|
+
return this.alert(message, "Copy Error");
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
openCopiedFile(copyParams) {
|
|
733
|
+
this._event('willOpenFile', { op: "openCopiedFile" });
|
|
734
|
+
try {
|
|
735
|
+
const key = `cfm-copy::${copyParams}`;
|
|
736
|
+
const copied = JSON.parse(window.localStorage.getItem(key));
|
|
737
|
+
let content = provider_interface_1.cloudContentFactory.createEnvelopedCloudContent(copied.stringContent);
|
|
738
|
+
content = this._filterLoadedContent(content);
|
|
739
|
+
const metadata = new provider_interface_1.CloudMetadata({
|
|
740
|
+
name: copied.name,
|
|
741
|
+
type: provider_interface_1.CloudMetadata.File
|
|
742
|
+
});
|
|
743
|
+
window.location.hash = "";
|
|
744
|
+
this._fileOpened(content, metadata, { dirty: true, openedContent: content.clone() });
|
|
745
|
+
return window.localStorage.removeItem(key);
|
|
746
|
+
}
|
|
747
|
+
catch (e) {
|
|
748
|
+
(0, report_error_1.reportError)("Unable to load copied file");
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
haveTempFile() {
|
|
752
|
+
try {
|
|
753
|
+
const key = "cfm-tempfile";
|
|
754
|
+
return !!(JSON.parse(window.localStorage.getItem(key)));
|
|
755
|
+
}
|
|
756
|
+
catch (e) {
|
|
757
|
+
return false;
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
saveTempFile(callback) {
|
|
761
|
+
return this._event('getContent', { shared: this._sharedMetadata() }, (stringContent) => {
|
|
762
|
+
var _a;
|
|
763
|
+
const currentContent = this._createOrUpdateCurrentContent(stringContent);
|
|
764
|
+
try {
|
|
765
|
+
const key = "cfm-tempfile";
|
|
766
|
+
const name = (_a = this.state.metadata) === null || _a === void 0 ? void 0 : _a.name;
|
|
767
|
+
const value = JSON.stringify({ name, stringContent });
|
|
768
|
+
window.localStorage.setItem(key, value);
|
|
769
|
+
const metadata = new provider_interface_1.CloudMetadata({
|
|
770
|
+
name,
|
|
771
|
+
type: provider_interface_1.CloudMetadata.File
|
|
772
|
+
});
|
|
773
|
+
this._fileChanged('savedFile', currentContent, metadata, { saved: true }, "");
|
|
774
|
+
return callback === null || callback === void 0 ? void 0 : callback(null);
|
|
775
|
+
}
|
|
776
|
+
catch (e) {
|
|
777
|
+
return callback === null || callback === void 0 ? void 0 : callback("Unable to temporarily save copied file");
|
|
778
|
+
}
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
openAndClearTempFile() {
|
|
782
|
+
this._event('willOpenFile', { op: "openAndClearTempFile" });
|
|
783
|
+
try {
|
|
784
|
+
const key = "cfm-tempfile";
|
|
785
|
+
const { name, stringContent } = JSON.parse(window.localStorage.getItem(key));
|
|
786
|
+
let content = provider_interface_1.cloudContentFactory.createEnvelopedCloudContent(stringContent);
|
|
787
|
+
content = this._filterLoadedContent(content);
|
|
788
|
+
const metadata = new provider_interface_1.CloudMetadata({
|
|
789
|
+
name,
|
|
790
|
+
type: provider_interface_1.CloudMetadata.File
|
|
791
|
+
});
|
|
792
|
+
this._fileOpened(content, metadata, { dirty: true, openedContent: content.clone() });
|
|
793
|
+
return window.localStorage.removeItem(key);
|
|
794
|
+
}
|
|
795
|
+
catch (e) {
|
|
796
|
+
(0, report_error_1.reportError)("Unable to load temp file");
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
_sharedMetadata() {
|
|
800
|
+
var _a;
|
|
801
|
+
return ((_a = this.state.currentContent) === null || _a === void 0 ? void 0 : _a.getSharedMetadata()) || {};
|
|
802
|
+
}
|
|
803
|
+
shareGetLink() {
|
|
804
|
+
return this._ui.shareDialog(this);
|
|
805
|
+
}
|
|
806
|
+
shareUpdate() {
|
|
807
|
+
return this.share(() => this.alert(((0, translate_1.default)("~SHARE_UPDATE.MESSAGE")), ((0, translate_1.default)("~SHARE_UPDATE.TITLE"))));
|
|
808
|
+
}
|
|
809
|
+
toggleShare(callback) {
|
|
810
|
+
if (this.isShared()) {
|
|
811
|
+
return this.unshare(callback);
|
|
812
|
+
}
|
|
813
|
+
else {
|
|
814
|
+
return this.share(callback);
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
isShared() {
|
|
818
|
+
var _a;
|
|
819
|
+
const currentContent = (_a = this.state) === null || _a === void 0 ? void 0 : _a.currentContent;
|
|
820
|
+
if (currentContent) {
|
|
821
|
+
const unshared = currentContent.get("isUnshared");
|
|
822
|
+
if (!unshared) {
|
|
823
|
+
const sharedDocumentId = currentContent.get("sharedDocumentId");
|
|
824
|
+
const sharedDocumentUrl = currentContent.get("sharedDocumentUrl");
|
|
825
|
+
return (sharedDocumentId || sharedDocumentUrl);
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
return false;
|
|
829
|
+
}
|
|
830
|
+
canEditShared() {
|
|
831
|
+
const accessKeys = (this.state.currentContent != null ? this.state.currentContent.get("accessKeys") : undefined) || {};
|
|
832
|
+
const shareEditKey = this.state.currentContent != null ? this.state.currentContent.get("shareEditKey") : undefined;
|
|
833
|
+
return (shareEditKey || accessKeys.readWrite) && !(this.state.currentContent != null ? this.state.currentContent.get("isUnshared") : undefined);
|
|
834
|
+
}
|
|
835
|
+
setShareState(shared, callback) {
|
|
836
|
+
if (this.state.shareProvider) {
|
|
837
|
+
const sharingMetadata = this.state.shareProvider.getSharingMetadata(shared);
|
|
838
|
+
return this._event('getContent', { shared: sharingMetadata }, (stringContent) => {
|
|
839
|
+
this._setState({ sharing: shared });
|
|
840
|
+
const sharedContent = provider_interface_1.cloudContentFactory.createEnvelopedCloudContent(stringContent);
|
|
841
|
+
sharedContent.addMetadata(sharingMetadata);
|
|
842
|
+
const currentContent = this._createOrUpdateCurrentContent(stringContent, this.state.metadata);
|
|
843
|
+
sharedContent.set('docName', currentContent.get('docName'));
|
|
844
|
+
// save the current name at the top level so it is displayed when the shared file is loaded
|
|
845
|
+
if (this.state.metadata) {
|
|
846
|
+
sharedContent.getClientContent().name = this.state.metadata.name;
|
|
847
|
+
}
|
|
848
|
+
if (shared) {
|
|
849
|
+
currentContent.remove('isUnshared');
|
|
850
|
+
}
|
|
851
|
+
else {
|
|
852
|
+
currentContent.set('isUnshared', true);
|
|
853
|
+
}
|
|
854
|
+
return this.state.shareProvider.share(shared, currentContent, sharedContent, this.state.metadata, (err, sharedContentId) => {
|
|
855
|
+
if (err) {
|
|
856
|
+
return this.alert(err);
|
|
857
|
+
}
|
|
858
|
+
return callback === null || callback === void 0 ? void 0 : callback(null, sharedContentId, currentContent);
|
|
859
|
+
});
|
|
860
|
+
});
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
share(callback) {
|
|
864
|
+
if (!this.state.metadata) {
|
|
865
|
+
// PJ, 07/10/2020: Without these lines the sharing process will fail (it looks for filename and later tries to
|
|
866
|
+
// update metadata object). Apparently, there's an assumption that metadata already exists. It can initialized
|
|
867
|
+
// in a few random places, but a new document that has never been renamed won't have this object available.
|
|
868
|
+
this.state.metadata = new provider_interface_1.CloudMetadata({
|
|
869
|
+
name: (0, translate_1.default)("~MENUBAR.UNTITLED_DOCUMENT"),
|
|
870
|
+
type: provider_interface_1.CloudMetadata.File
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
return this.setShareState(true, (err, sharedContentId, currentContent) => {
|
|
874
|
+
this._fileChanged('sharedFile', currentContent, this.state.metadata);
|
|
875
|
+
return callback === null || callback === void 0 ? void 0 : callback(null, sharedContentId);
|
|
876
|
+
});
|
|
877
|
+
}
|
|
878
|
+
unshare(callback) {
|
|
879
|
+
return this.setShareState(false, (err, sharedContentId, currentContent) => {
|
|
880
|
+
this._fileChanged('unsharedFile', currentContent, this.state.metadata);
|
|
881
|
+
return callback === null || callback === void 0 ? void 0 : callback(null);
|
|
882
|
+
});
|
|
883
|
+
}
|
|
884
|
+
revertToShared(callback = null) {
|
|
885
|
+
var _a, _b, _c;
|
|
886
|
+
// Look for sharedDocumentUrl or Url first:
|
|
887
|
+
const id = ((_a = this.state.currentContent) === null || _a === void 0 ? void 0 : _a.get("sharedDocumentUrl"))
|
|
888
|
+
|| ((_b = this.state.currentContent) === null || _b === void 0 ? void 0 : _b.get("url"))
|
|
889
|
+
|| ((_c = this.state.currentContent) === null || _c === void 0 ? void 0 : _c.get("sharedDocumentId"));
|
|
890
|
+
if (id && (this.state.shareProvider != null)) {
|
|
891
|
+
return this.state.shareProvider.loadSharedContent(id, (err, content, metadata) => {
|
|
892
|
+
let docName;
|
|
893
|
+
if (err) {
|
|
894
|
+
return this.alert(err);
|
|
895
|
+
}
|
|
896
|
+
content = this._filterLoadedContent(content);
|
|
897
|
+
this.state.currentContent.copyMetadataTo(content);
|
|
898
|
+
if (!metadata.name && (docName = content.get('docName'))) {
|
|
899
|
+
metadata.name = docName;
|
|
900
|
+
}
|
|
901
|
+
this._fileOpened(content, metadata, { dirty: true, openedContent: content.clone() });
|
|
902
|
+
return callback === null || callback === void 0 ? void 0 : callback(null);
|
|
903
|
+
});
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
revertToSharedDialog(callback = null) {
|
|
907
|
+
if ((this.state.currentContent != null ? this.state.currentContent.get("sharedDocumentId") : undefined) && (this.state.shareProvider != null)) {
|
|
908
|
+
return this.confirm((0, translate_1.default)("~CONFIRM.REVERT_TO_SHARED_VIEW"), () => this.revertToShared(callback));
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
downloadDialog(callback = null) {
|
|
912
|
+
// should share metadata be included in downloaded local files?
|
|
913
|
+
return this._event('getContent', { shared: this._sharedMetadata() }, (content) => {
|
|
914
|
+
var _a;
|
|
915
|
+
const envelopedContent = provider_interface_1.cloudContentFactory.createEnvelopedCloudContent(content);
|
|
916
|
+
if (this.state.currentContent != null) {
|
|
917
|
+
this.state.currentContent.copyMetadataTo(envelopedContent);
|
|
918
|
+
}
|
|
919
|
+
return this._ui.downloadDialog((_a = this.state.metadata) === null || _a === void 0 ? void 0 : _a.name, envelopedContent, callback);
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
getDownloadBlob(content, includeShareInfo, mimeType) {
|
|
923
|
+
var _a;
|
|
924
|
+
let contentToSave;
|
|
925
|
+
if (mimeType == null) {
|
|
926
|
+
mimeType = 'text/plain';
|
|
927
|
+
}
|
|
928
|
+
if (typeof content === "string") {
|
|
929
|
+
if (mimeType.indexOf("image") >= 0) {
|
|
930
|
+
contentToSave = base64_js_1.default.toByteArray(content);
|
|
931
|
+
}
|
|
932
|
+
else {
|
|
933
|
+
contentToSave = content;
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
else if (includeShareInfo) {
|
|
937
|
+
contentToSave = JSON.stringify(content.getContent());
|
|
938
|
+
}
|
|
939
|
+
else { // not includeShareInfo
|
|
940
|
+
// clone the document so we can delete the share info and not affect the original
|
|
941
|
+
const json = content.clone().getContent();
|
|
942
|
+
delete json.sharedDocumentId;
|
|
943
|
+
delete json.sharedDocumentUrl;
|
|
944
|
+
delete json.shareEditKey;
|
|
945
|
+
delete json.isUnshared;
|
|
946
|
+
delete json.accessKeys;
|
|
947
|
+
// CODAP moves the keys into its own namespace
|
|
948
|
+
if (((_a = json.metadata) === null || _a === void 0 ? void 0 : _a.shared) != null) {
|
|
949
|
+
delete json.metadata.shared;
|
|
950
|
+
}
|
|
951
|
+
contentToSave = JSON.stringify(json);
|
|
952
|
+
}
|
|
953
|
+
return new Blob([contentToSave], { type: mimeType });
|
|
954
|
+
}
|
|
955
|
+
getDownloadUrl(content, includeShareInfo, mimeType) {
|
|
956
|
+
if (mimeType == null) {
|
|
957
|
+
mimeType = 'text/plain';
|
|
958
|
+
}
|
|
959
|
+
const wURL = window.URL || window.webkitURL;
|
|
960
|
+
if (wURL) {
|
|
961
|
+
return wURL.createObjectURL(this.getDownloadBlob(content, includeShareInfo, mimeType));
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
rename(metadata, newName, callback) {
|
|
965
|
+
var _a;
|
|
966
|
+
const { dirty } = this.state;
|
|
967
|
+
const _rename = (metadata) => {
|
|
968
|
+
var _a;
|
|
969
|
+
if (this.state.currentContent != null) {
|
|
970
|
+
this.state.currentContent.addMetadata({ docName: metadata.name });
|
|
971
|
+
}
|
|
972
|
+
this._fileChanged('renamedFile', this.state.currentContent, metadata, { dirty }, this._getHashParams(metadata));
|
|
973
|
+
const done = () => typeof callback === 'function' ? callback(newName) : undefined;
|
|
974
|
+
const readOnlyProvider = ((_a = metadata === null || metadata === void 0 ? void 0 : metadata.provider) === null || _a === void 0 ? void 0 : _a.name) === readonly_provider_1.default.Name;
|
|
975
|
+
if (!readOnlyProvider && ((metadata === null || metadata === void 0 ? void 0 : metadata.provider) || this.autoProvider(provider_interface_1.ECapabilities.save))) {
|
|
976
|
+
// autosave renamed file if it has already been saved or can be autosaved
|
|
977
|
+
this.save(done);
|
|
978
|
+
}
|
|
979
|
+
else {
|
|
980
|
+
done();
|
|
981
|
+
}
|
|
982
|
+
};
|
|
983
|
+
if (newName !== (this.state.metadata != null ? this.state.metadata.name : undefined)) {
|
|
984
|
+
if ((_a = metadata === null || metadata === void 0 ? void 0 : metadata.provider) === null || _a === void 0 ? void 0 : _a.can(provider_interface_1.ECapabilities.rename, metadata)) {
|
|
985
|
+
return this.state.metadata.provider.rename(this.state.metadata, newName, (err, metadata) => {
|
|
986
|
+
if (err) {
|
|
987
|
+
return this.alert(err);
|
|
988
|
+
}
|
|
989
|
+
return _rename(metadata);
|
|
990
|
+
});
|
|
991
|
+
}
|
|
992
|
+
else {
|
|
993
|
+
if (metadata) {
|
|
994
|
+
metadata.rename(newName);
|
|
995
|
+
}
|
|
996
|
+
else {
|
|
997
|
+
metadata = new provider_interface_1.CloudMetadata({
|
|
998
|
+
name: newName,
|
|
999
|
+
type: provider_interface_1.CloudMetadata.File
|
|
1000
|
+
});
|
|
1001
|
+
}
|
|
1002
|
+
return _rename(metadata);
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
renameDialog(callback = null) {
|
|
1007
|
+
return this._ui.renameDialog(this.state.metadata != null ? this.state.metadata.name : undefined, (newName) => {
|
|
1008
|
+
return this.rename(this.state.metadata, newName, callback);
|
|
1009
|
+
});
|
|
1010
|
+
}
|
|
1011
|
+
revertToLastOpened(callback = null) {
|
|
1012
|
+
this._event('willOpenFile', { op: "revertToLastOpened" });
|
|
1013
|
+
if ((this.state.openedContent != null) && this.state.metadata) {
|
|
1014
|
+
return this._fileOpened(this.state.openedContent, this.state.metadata, { openedContent: this.state.openedContent.clone() });
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
revertToLastOpenedDialog(callback = null) {
|
|
1018
|
+
if ((this.state.openedContent != null) && this.state.metadata) {
|
|
1019
|
+
return this.confirm((0, translate_1.default)('~CONFIRM.REVERT_TO_LAST_OPENED'), () => this.revertToLastOpened(callback));
|
|
1020
|
+
}
|
|
1021
|
+
else {
|
|
1022
|
+
return (typeof callback === 'function' ? callback('No initial opened version was found for the currently active file') : undefined);
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
saveSecondaryFileAsDialog(stringContent, extension, mimeType, callback) {
|
|
1026
|
+
// set the mimeType if not given with the extension
|
|
1027
|
+
const extensionMimeType = mime_1.default.getType(extension);
|
|
1028
|
+
if (extension && !mimeType && extensionMimeType) {
|
|
1029
|
+
mimeType = extensionMimeType;
|
|
1030
|
+
}
|
|
1031
|
+
const provider = this.autoProvider(provider_interface_1.ECapabilities['export']);
|
|
1032
|
+
if (provider) {
|
|
1033
|
+
const metadata = { provider, extension, mimeType };
|
|
1034
|
+
return this.saveSecondaryFile(stringContent, metadata, callback);
|
|
1035
|
+
}
|
|
1036
|
+
else {
|
|
1037
|
+
const data = { content: stringContent, extension, mimeType };
|
|
1038
|
+
return this._ui.saveSecondaryFileAsDialog(data, (metadata) => {
|
|
1039
|
+
// replace defaults
|
|
1040
|
+
if (extension) {
|
|
1041
|
+
metadata.filename = provider_interface_1.CloudMetadata.newExtension(metadata.filename, extension);
|
|
1042
|
+
}
|
|
1043
|
+
if (mimeType) {
|
|
1044
|
+
metadata.mimeType = mimeType;
|
|
1045
|
+
}
|
|
1046
|
+
return this.saveSecondaryFile(stringContent, metadata, callback);
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
// Saves a file to backend, but does not update current metadata.
|
|
1051
|
+
// Used e.g. when exporting .csv files from CODAP
|
|
1052
|
+
saveSecondaryFile(stringContent, metadata, callback = null) {
|
|
1053
|
+
var _a;
|
|
1054
|
+
if ((_a = metadata === null || metadata === void 0 ? void 0 : metadata.provider) === null || _a === void 0 ? void 0 : _a.can(provider_interface_1.ECapabilities["export"], metadata)) {
|
|
1055
|
+
return metadata.provider.saveAsExport(stringContent, metadata, (err, statusCode) => {
|
|
1056
|
+
return err ? this.alert(err) : callback === null || callback === void 0 ? void 0 : callback(stringContent, metadata);
|
|
1057
|
+
});
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
dirty(isDirty = true) {
|
|
1061
|
+
this._setState({
|
|
1062
|
+
dirty: isDirty,
|
|
1063
|
+
saved: this.state.saved && !isDirty
|
|
1064
|
+
});
|
|
1065
|
+
if (window.self !== window.top) {
|
|
1066
|
+
// post to parent and not top window (not a bug even though we test for self inst top above)
|
|
1067
|
+
return window.parent.postMessage({ type: "cfm::setDirty", isDirty }, "*");
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
shouldAutoSave() {
|
|
1071
|
+
var _a;
|
|
1072
|
+
const { metadata } = this.state;
|
|
1073
|
+
return (this.state.dirty
|
|
1074
|
+
&& !(metadata === null || metadata === void 0 ? void 0 : metadata.autoSaveDisabled)
|
|
1075
|
+
&& !this.isSaveInProgress()
|
|
1076
|
+
&& ((_a = metadata === null || metadata === void 0 ? void 0 : metadata.provider) === null || _a === void 0 ? void 0 : _a.can(provider_interface_1.ECapabilities.resave, metadata)));
|
|
1077
|
+
}
|
|
1078
|
+
autoSave(interval) {
|
|
1079
|
+
if (this._autoSaveInterval) {
|
|
1080
|
+
clearInterval(this._autoSaveInterval);
|
|
1081
|
+
}
|
|
1082
|
+
// in case the caller uses milliseconds
|
|
1083
|
+
if (interval > 1000) {
|
|
1084
|
+
interval = Math.round(interval / 1000);
|
|
1085
|
+
}
|
|
1086
|
+
if (interval > 0) {
|
|
1087
|
+
return this._autoSaveInterval = window.setInterval(() => { if (this.shouldAutoSave()) {
|
|
1088
|
+
return this.save();
|
|
1089
|
+
} }, interval * 1000);
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
isAutoSaving() {
|
|
1093
|
+
return (this._autoSaveInterval != null);
|
|
1094
|
+
}
|
|
1095
|
+
changeLanguage(newLangCode, callback) {
|
|
1096
|
+
var _a, _b;
|
|
1097
|
+
if (callback) {
|
|
1098
|
+
const postSave = (err) => {
|
|
1099
|
+
if (err) {
|
|
1100
|
+
this.alert(err);
|
|
1101
|
+
return this.confirm((0, translate_1.default)('~CONFIRM.CHANGE_LANGUAGE'), () => callback(newLangCode));
|
|
1102
|
+
}
|
|
1103
|
+
else {
|
|
1104
|
+
return callback(newLangCode);
|
|
1105
|
+
}
|
|
1106
|
+
};
|
|
1107
|
+
if ((_b = (_a = this.state.metadata) === null || _a === void 0 ? void 0 : _a.provider) === null || _b === void 0 ? void 0 : _b.can(provider_interface_1.ECapabilities.save)) {
|
|
1108
|
+
return this.save((err) => postSave(err));
|
|
1109
|
+
}
|
|
1110
|
+
else {
|
|
1111
|
+
return this.saveTempFile(postSave);
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
showBlockingModal(modalProps) {
|
|
1116
|
+
return this._ui.showBlockingModal(modalProps);
|
|
1117
|
+
}
|
|
1118
|
+
hideBlockingModal() {
|
|
1119
|
+
return this._ui.hideBlockingModal();
|
|
1120
|
+
}
|
|
1121
|
+
getCurrentUrl(hashString) {
|
|
1122
|
+
return `${window.location.origin}${window.location.pathname}${window.location.search}${hashString || ""}`;
|
|
1123
|
+
}
|
|
1124
|
+
// Takes an array of strings representing url parameters to be removed from the URL.
|
|
1125
|
+
// Removes the specified parameters from the URL and then uses the history API's
|
|
1126
|
+
// pushState() method to update the URL without reloading the page.
|
|
1127
|
+
// Adapted from http://stackoverflow.com/a/11654436.
|
|
1128
|
+
removeQueryParams(params) {
|
|
1129
|
+
let url = window.location.href;
|
|
1130
|
+
const hash = url.split('#');
|
|
1131
|
+
for (let key of params) {
|
|
1132
|
+
const re = new RegExp(`([?&])${key}=.*?(&|#|$)(.*)`, "g");
|
|
1133
|
+
if (re.test(url)) {
|
|
1134
|
+
hash[0] = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, '');
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
url = hash[0] + ((hash[1] != null) ? `#${hash[1]}` : '');
|
|
1138
|
+
if (url !== window.location.href) {
|
|
1139
|
+
return history.pushState({ originalUrl: window.location.href }, '', url);
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
confirm(message, callback, rejectCallback) {
|
|
1143
|
+
return this.confirmDialog({ message, callback, rejectCallback });
|
|
1144
|
+
}
|
|
1145
|
+
confirmDialog(params) {
|
|
1146
|
+
return this._ui.confirmDialog(params);
|
|
1147
|
+
}
|
|
1148
|
+
alert(message, titleOrCallback, callback) {
|
|
1149
|
+
if (lodash_1.default.isFunction(titleOrCallback)) {
|
|
1150
|
+
callback = titleOrCallback;
|
|
1151
|
+
titleOrCallback = null;
|
|
1152
|
+
}
|
|
1153
|
+
return this._ui.alertDialog(message, (titleOrCallback || (0, translate_1.default)("~CLIENT_ERROR.TITLE")), callback);
|
|
1154
|
+
}
|
|
1155
|
+
hideAlert() {
|
|
1156
|
+
this._ui.hideAlertDialog();
|
|
1157
|
+
}
|
|
1158
|
+
selectInteractiveStateDialog(props, callback) {
|
|
1159
|
+
this._event("requiresUserInteraction");
|
|
1160
|
+
this._ui.selectInteractiveStateDialog({ ...props, onSelect: callback });
|
|
1161
|
+
}
|
|
1162
|
+
async onUnload(options) {
|
|
1163
|
+
if (options.unloading) {
|
|
1164
|
+
return new Promise(resolve => {
|
|
1165
|
+
var _a;
|
|
1166
|
+
// only save if the provider is set - when using linked interactives the provider is not set when
|
|
1167
|
+
// the linked interactive changed and the version choice dialog is showing
|
|
1168
|
+
if ((_a = this.state.metadata) === null || _a === void 0 ? void 0 : _a.provider) {
|
|
1169
|
+
this.save((content, metadata, savedContent) => {
|
|
1170
|
+
// providers can save a different format for the content
|
|
1171
|
+
// for example the interactiveApi provider can save attachments in which case the savedContent
|
|
1172
|
+
// will be an object pointing at the attachment
|
|
1173
|
+
resolve(savedContent || content);
|
|
1174
|
+
});
|
|
1175
|
+
}
|
|
1176
|
+
else {
|
|
1177
|
+
// signal that nothing needs to be saved
|
|
1178
|
+
resolve(undefined);
|
|
1179
|
+
}
|
|
1180
|
+
});
|
|
1181
|
+
}
|
|
1182
|
+
return Promise.resolve(undefined);
|
|
1183
|
+
}
|
|
1184
|
+
_dialogSave(stringContent, metadata, callback) {
|
|
1185
|
+
if (stringContent != null) {
|
|
1186
|
+
return this.saveFileNoDialog(stringContent, metadata, callback);
|
|
1187
|
+
}
|
|
1188
|
+
else {
|
|
1189
|
+
return this._event('getContent', { shared: this._sharedMetadata() }, (stringContent) => {
|
|
1190
|
+
return this.saveFileNoDialog(stringContent, metadata, callback);
|
|
1191
|
+
});
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
// The purpose of this seems to be to definitely set whether or not the content
|
|
1195
|
+
// can be overwritten? Will mutate metadata:
|
|
1196
|
+
_updateMetaDataOverwritable(metadata) {
|
|
1197
|
+
if (metadata != null) {
|
|
1198
|
+
metadata.overwritable = (metadata.overwritable != null)
|
|
1199
|
+
? metadata.overwritable
|
|
1200
|
+
: true;
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
_fileChanged(type, content, metadata, additionalState, hashParams = null) {
|
|
1204
|
+
if (additionalState == null) {
|
|
1205
|
+
additionalState = {};
|
|
1206
|
+
}
|
|
1207
|
+
this._updateMetaDataOverwritable(metadata);
|
|
1208
|
+
this._updateState(content, metadata, additionalState, hashParams);
|
|
1209
|
+
return this._event(type, { content: (content != null ? content.getClientContent() : undefined), shared: this._sharedMetadata() });
|
|
1210
|
+
}
|
|
1211
|
+
_fileOpened(content, metadata, additionalState, hashParams = null) {
|
|
1212
|
+
var _a, _b;
|
|
1213
|
+
if (additionalState == null) {
|
|
1214
|
+
additionalState = {};
|
|
1215
|
+
}
|
|
1216
|
+
const eventData = { content: (_b = (_a = content === null || content === void 0 ? void 0 : content.getClientContent) === null || _a === void 0 ? void 0 : _a.call(content)) !== null && _b !== void 0 ? _b : content };
|
|
1217
|
+
// update state before sending 'openedFile' events so that 'openedFile' listeners that
|
|
1218
|
+
// reference state have the updated state values
|
|
1219
|
+
this._updateState(content, metadata, additionalState, hashParams);
|
|
1220
|
+
// add metadata contentType to event for CODAP to load via postMessage API (for SageModeler standalone)
|
|
1221
|
+
const contentType = metadata.mimeType || metadata.contentType;
|
|
1222
|
+
eventData.metadata = { contentType, url: metadata.url, filename: metadata.filename };
|
|
1223
|
+
return this._event('openedFile', eventData, (iError, iSharedMetadata) => {
|
|
1224
|
+
if (iError) {
|
|
1225
|
+
return this.alert(iError, () => this.ready());
|
|
1226
|
+
}
|
|
1227
|
+
this._updateMetaDataOverwritable(metadata);
|
|
1228
|
+
if (!this.appOptions.wrapFileContent) {
|
|
1229
|
+
content.addMetadata(iSharedMetadata);
|
|
1230
|
+
}
|
|
1231
|
+
// and then update state again for the metadata and content changes
|
|
1232
|
+
this._updateState(content, metadata, additionalState, hashParams);
|
|
1233
|
+
return this.ready();
|
|
1234
|
+
});
|
|
1235
|
+
}
|
|
1236
|
+
_updateState(content, metadata, additionalState = {}, hashParams = null) {
|
|
1237
|
+
const state = {
|
|
1238
|
+
currentContent: content,
|
|
1239
|
+
metadata,
|
|
1240
|
+
saving: null,
|
|
1241
|
+
saved: false,
|
|
1242
|
+
dirty: !additionalState.saved && (content === null || content === void 0 ? void 0 : content.requiresConversion()),
|
|
1243
|
+
...additionalState
|
|
1244
|
+
};
|
|
1245
|
+
this._setWindowTitle(metadata === null || metadata === void 0 ? void 0 : metadata.name);
|
|
1246
|
+
if (hashParams !== null) {
|
|
1247
|
+
window.location.hash = hashParams;
|
|
1248
|
+
}
|
|
1249
|
+
return this._setState(state);
|
|
1250
|
+
}
|
|
1251
|
+
_event(type, data, eventCallback = null) {
|
|
1252
|
+
var _a;
|
|
1253
|
+
if (data == null) {
|
|
1254
|
+
data = {};
|
|
1255
|
+
}
|
|
1256
|
+
const event = new CloudFileManagerClientEvent(type, data, eventCallback, this.state);
|
|
1257
|
+
for (let listener of this._listeners) {
|
|
1258
|
+
listener(event);
|
|
1259
|
+
}
|
|
1260
|
+
// Workaround to fix https://www.pivotaltracker.com/story/show/162392580
|
|
1261
|
+
// CODAP will fail on the renamedFile message because we don't send the state with
|
|
1262
|
+
// the postMessage events and CODAP examines the state to get the new name.
|
|
1263
|
+
// I tried sending the state but that causes CODAP to replace its state which breaks other things.
|
|
1264
|
+
// A permanent fix for this would be to send the new filename outside of the state metadata.
|
|
1265
|
+
const skipPostMessage = type === "renamedFile";
|
|
1266
|
+
if (((_a = this.appOptions) === null || _a === void 0 ? void 0 : _a.sendPostMessageClientEvents) && this.iframe && !skipPostMessage) {
|
|
1267
|
+
return event.postMessage(this.iframe.contentWindow);
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
_setState(newState) {
|
|
1271
|
+
this.state = { ...this.state, ...newState };
|
|
1272
|
+
return this._event('stateChanged');
|
|
1273
|
+
}
|
|
1274
|
+
_resetState() {
|
|
1275
|
+
return this._setState({
|
|
1276
|
+
openedContent: null,
|
|
1277
|
+
currentContent: null,
|
|
1278
|
+
metadata: null,
|
|
1279
|
+
dirty: false,
|
|
1280
|
+
saving: null,
|
|
1281
|
+
saved: false,
|
|
1282
|
+
failures: 0
|
|
1283
|
+
});
|
|
1284
|
+
}
|
|
1285
|
+
_closeCurrentFile() {
|
|
1286
|
+
var _a;
|
|
1287
|
+
const { metadata } = this.state;
|
|
1288
|
+
if ((_a = metadata === null || metadata === void 0 ? void 0 : metadata.provider) === null || _a === void 0 ? void 0 : _a.can(provider_interface_1.ECapabilities.close, metadata)) {
|
|
1289
|
+
return metadata.provider.close(metadata);
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
_createOrUpdateCurrentContent(stringContent, metadata = null) {
|
|
1293
|
+
let currentContent;
|
|
1294
|
+
if (this.state.currentContent != null) {
|
|
1295
|
+
({ currentContent } = this.state);
|
|
1296
|
+
currentContent.setText(stringContent);
|
|
1297
|
+
}
|
|
1298
|
+
else {
|
|
1299
|
+
currentContent = provider_interface_1.cloudContentFactory.createEnvelopedCloudContent(stringContent);
|
|
1300
|
+
}
|
|
1301
|
+
if (metadata != null) {
|
|
1302
|
+
currentContent.addMetadata({ docName: metadata.name });
|
|
1303
|
+
}
|
|
1304
|
+
return currentContent;
|
|
1305
|
+
}
|
|
1306
|
+
_setWindowTitle(name) {
|
|
1307
|
+
var _a;
|
|
1308
|
+
if ((_a = this.appOptions) === null || _a === void 0 ? void 0 : _a.appSetsWindowTitle) {
|
|
1309
|
+
return;
|
|
1310
|
+
}
|
|
1311
|
+
const { ui } = this.appOptions;
|
|
1312
|
+
if (ui) {
|
|
1313
|
+
const { windowTitleSeparator, windowTitleSuffix } = ui;
|
|
1314
|
+
if (windowTitleSuffix) {
|
|
1315
|
+
const displayName = (name || "").length > 0
|
|
1316
|
+
? name
|
|
1317
|
+
: (0, translate_1.default)("~MENUBAR.UNTITLED_DOCUMENT");
|
|
1318
|
+
document.title = `${displayName}${windowTitleSeparator}${windowTitleSuffix}`;
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
_getHashParams(metadata) {
|
|
1323
|
+
var _a, _b;
|
|
1324
|
+
const canOpenSaved = ((_a = metadata === null || metadata === void 0 ? void 0 : metadata.provider) === null || _a === void 0 ? void 0 : _a.canOpenSaved()) || false;
|
|
1325
|
+
let openSavedParams = canOpenSaved ? (_b = metadata === null || metadata === void 0 ? void 0 : metadata.provider) === null || _b === void 0 ? void 0 : _b.getOpenSavedParams(metadata) : null;
|
|
1326
|
+
if (canOpenSaved && (openSavedParams != null) && (typeof openSavedParams === "string")) {
|
|
1327
|
+
return `#file=${metadata.provider.urlDisplayName || metadata.provider.name}:${encodeURIComponent(openSavedParams)}`;
|
|
1328
|
+
}
|
|
1329
|
+
else if ((metadata === null || metadata === void 0 ? void 0 : metadata.provider) instanceof url_provider_1.default && (window.location.hash.indexOf("#file=http") === 0)) {
|
|
1330
|
+
return window.location.hash; // leave it alone
|
|
1331
|
+
}
|
|
1332
|
+
else {
|
|
1333
|
+
return "";
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
_startPostMessageListener() {
|
|
1337
|
+
return (0, jquery_1.default)(window).on('message', e => {
|
|
1338
|
+
var _a, _b;
|
|
1339
|
+
const oe = e.originalEvent;
|
|
1340
|
+
const data = oe.data || {};
|
|
1341
|
+
const reply = function (type, params) {
|
|
1342
|
+
if (params == null) {
|
|
1343
|
+
params = {};
|
|
1344
|
+
}
|
|
1345
|
+
const message = lodash_1.default.merge({}, params, { type });
|
|
1346
|
+
return oe.source.postMessage(message, oe.origin);
|
|
1347
|
+
};
|
|
1348
|
+
switch (data === null || data === void 0 ? void 0 : data.type) {
|
|
1349
|
+
case 'cfm::getCommands':
|
|
1350
|
+
return reply('cfm::commands', { commands: ['cfm::autosave', 'cfm::event', 'cfm::event:reply', 'cfm::setDirty', 'cfm::iframedClientConnected'] });
|
|
1351
|
+
case 'cfm::autosave':
|
|
1352
|
+
if (this.shouldAutoSave()) {
|
|
1353
|
+
return this.save(() => reply('cfm::autosaved', { saved: true }));
|
|
1354
|
+
}
|
|
1355
|
+
else {
|
|
1356
|
+
return reply('cfm::autosaved', { saved: false });
|
|
1357
|
+
}
|
|
1358
|
+
case 'cfm::event':
|
|
1359
|
+
return this._event(data.eventType, data.eventData, function () {
|
|
1360
|
+
const callbackArgs = JSON.stringify(Array.prototype.slice.call(arguments));
|
|
1361
|
+
return reply('cfm::event:reply', { eventId: data.eventId, callbackArgs });
|
|
1362
|
+
});
|
|
1363
|
+
case 'cfm::event:reply': {
|
|
1364
|
+
const event = CLOUDFILEMANAGER_EVENTS[data.eventId];
|
|
1365
|
+
const callbackData = JSON.parse((data === null || data === void 0 ? void 0 : data.callbackArgs) || null);
|
|
1366
|
+
return (_a = event === null || event === void 0 ? void 0 : event.callback) === null || _a === void 0 ? void 0 : _a.apply(this, callbackData);
|
|
1367
|
+
}
|
|
1368
|
+
case 'cfm::setDirty':
|
|
1369
|
+
return this.dirty(data.isDirty);
|
|
1370
|
+
case 'cfm::iframedClientConnected':
|
|
1371
|
+
(_b = this.connectedPromiseResolver) === null || _b === void 0 ? void 0 : _b.resolve();
|
|
1372
|
+
return this.processUrlParams();
|
|
1373
|
+
}
|
|
1374
|
+
});
|
|
1375
|
+
}
|
|
1376
|
+
_setupConfirmOnClose() {
|
|
1377
|
+
return (0, jquery_1.default)(window).on('beforeunload', e => {
|
|
1378
|
+
if (this.state.dirty) {
|
|
1379
|
+
// different browsers trigger the confirm in different ways
|
|
1380
|
+
e.preventDefault();
|
|
1381
|
+
return e.returnValue = true;
|
|
1382
|
+
}
|
|
1383
|
+
});
|
|
1384
|
+
}
|
|
1385
|
+
_filterLoadedContent(content) {
|
|
1386
|
+
var _a, _b;
|
|
1387
|
+
return ((_b = (_a = this.appOptions).contentLoadFilter) === null || _b === void 0 ? void 0 : _b.call(_a, content)) || content;
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
exports.CloudFileManagerClient = CloudFileManagerClient;
|
|
1391
|
+
//# sourceMappingURL=client.js.map
|