ui.file_manager.file_uploader.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. /**
  2. * DevExtreme (ui/file_manager/ui.file_manager.file_uploader.js)
  3. * Version: 19.1.16
  4. * Build date: Tue Oct 18 2022
  5. *
  6. * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
  7. * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
  8. */
  9. "use strict";
  10. function _typeof(obj) {
  11. "@babel/helpers - typeof";
  12. return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(obj) {
  13. return typeof obj
  14. } : function(obj) {
  15. return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj
  16. }, _typeof(obj)
  17. }
  18. var _renderer = require("../../core/renderer");
  19. var _renderer2 = _interopRequireDefault(_renderer);
  20. var _extend = require("../../core/utils/extend");
  21. var _events_engine = require("../../events/core/events_engine");
  22. var _events_engine2 = _interopRequireDefault(_events_engine);
  23. var _deferred = require("../../core/utils/deferred");
  24. var _ui = require("../widget/ui.widget");
  25. var _ui2 = _interopRequireDefault(_ui);
  26. var _button = require("../button");
  27. var _button2 = _interopRequireDefault(_button);
  28. var _progress_bar = require("../progress_bar");
  29. var _progress_bar2 = _interopRequireDefault(_progress_bar);
  30. var _popup = require("../popup");
  31. var _popup2 = _interopRequireDefault(_popup);
  32. function _interopRequireDefault(obj) {
  33. return obj && obj.__esModule ? obj : {
  34. "default": obj
  35. }
  36. }
  37. function _classCallCheck(instance, Constructor) {
  38. if (!(instance instanceof Constructor)) {
  39. throw new TypeError("Cannot call a class as a function")
  40. }
  41. }
  42. function _defineProperties(target, props) {
  43. for (var i = 0; i < props.length; i++) {
  44. var descriptor = props[i];
  45. descriptor.enumerable = descriptor.enumerable || false;
  46. descriptor.configurable = true;
  47. if ("value" in descriptor) {
  48. descriptor.writable = true
  49. }
  50. Object.defineProperty(target, descriptor.key, descriptor)
  51. }
  52. }
  53. function _createClass(Constructor, protoProps, staticProps) {
  54. if (protoProps) {
  55. _defineProperties(Constructor.prototype, protoProps)
  56. }
  57. if (staticProps) {
  58. _defineProperties(Constructor, staticProps)
  59. }
  60. Object.defineProperty(Constructor, "prototype", {
  61. writable: false
  62. });
  63. return Constructor
  64. }
  65. function _get() {
  66. if ("undefined" !== typeof Reflect && Reflect.get) {
  67. _get = Reflect.get.bind()
  68. } else {
  69. _get = function(target, property, receiver) {
  70. var base = _superPropBase(target, property);
  71. if (!base) {
  72. return
  73. }
  74. var desc = Object.getOwnPropertyDescriptor(base, property);
  75. if (desc.get) {
  76. return desc.get.call(arguments.length < 3 ? target : receiver)
  77. }
  78. return desc.value
  79. }
  80. }
  81. return _get.apply(this, arguments)
  82. }
  83. function _superPropBase(object, property) {
  84. while (!Object.prototype.hasOwnProperty.call(object, property)) {
  85. object = _getPrototypeOf(object);
  86. if (null === object) {
  87. break
  88. }
  89. }
  90. return object
  91. }
  92. function _inherits(subClass, superClass) {
  93. if ("function" !== typeof superClass && null !== superClass) {
  94. throw new TypeError("Super expression must either be null or a function")
  95. }
  96. subClass.prototype = Object.create(superClass && superClass.prototype, {
  97. constructor: {
  98. value: subClass,
  99. writable: true,
  100. configurable: true
  101. }
  102. });
  103. Object.defineProperty(subClass, "prototype", {
  104. writable: false
  105. });
  106. if (superClass) {
  107. _setPrototypeOf(subClass, superClass)
  108. }
  109. }
  110. function _setPrototypeOf(o, p) {
  111. _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function(o, p) {
  112. o.__proto__ = p;
  113. return o
  114. };
  115. return _setPrototypeOf(o, p)
  116. }
  117. function _createSuper(Derived) {
  118. var hasNativeReflectConstruct = _isNativeReflectConstruct();
  119. return function() {
  120. var result, Super = _getPrototypeOf(Derived);
  121. if (hasNativeReflectConstruct) {
  122. var NewTarget = _getPrototypeOf(this).constructor;
  123. result = Reflect.construct(Super, arguments, NewTarget)
  124. } else {
  125. result = Super.apply(this, arguments)
  126. }
  127. return _possibleConstructorReturn(this, result)
  128. }
  129. }
  130. function _possibleConstructorReturn(self, call) {
  131. if (call && ("object" === _typeof(call) || "function" === typeof call)) {
  132. return call
  133. } else {
  134. if (void 0 !== call) {
  135. throw new TypeError("Derived constructors may only return object or undefined")
  136. }
  137. }
  138. return _assertThisInitialized(self)
  139. }
  140. function _assertThisInitialized(self) {
  141. if (void 0 === self) {
  142. throw new ReferenceError("this hasn't been initialised - super() hasn't been called")
  143. }
  144. return self
  145. }
  146. function _isNativeReflectConstruct() {
  147. if ("undefined" === typeof Reflect || !Reflect.construct) {
  148. return false
  149. }
  150. if (Reflect.construct.sham) {
  151. return false
  152. }
  153. if ("function" === typeof Proxy) {
  154. return true
  155. }
  156. try {
  157. Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {}));
  158. return true
  159. } catch (e) {
  160. return false
  161. }
  162. }
  163. function _getPrototypeOf(o) {
  164. _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function(o) {
  165. return o.__proto__ || Object.getPrototypeOf(o)
  166. };
  167. return _getPrototypeOf(o)
  168. }
  169. var FILE_MANAGER_FILE_UPLOADER_CLASS = "dx-filemanager-fileuploader";
  170. var FILE_MANAGER_FILE_UPLOADER_FILE_INPUT_CLASS = FILE_MANAGER_FILE_UPLOADER_CLASS + "-fileinput";
  171. var FILE_MANAGER_PROGRESS_PANEL = "dx-filemanager-progresspanel";
  172. var FILE_MANAGER_PROGRESS_BOX = "dx-filemanager-progressbox";
  173. var FILE_MANAGER_PROGRESS_BOX_TITLE = FILE_MANAGER_PROGRESS_BOX + "-title";
  174. var FILE_MANAGER_PROGRESS_BOX_PROGRESS_BAR = FILE_MANAGER_PROGRESS_BOX + "-progressbar";
  175. var FILE_MANAGER_PROGRESS_BOX_CANCEL_BUTTON = FILE_MANAGER_PROGRESS_BOX + "-cancel-button";
  176. var FileManagerFileUploader = function(_Widget) {
  177. _inherits(FileManagerFileUploader, _Widget);
  178. var _super = _createSuper(FileManagerFileUploader);
  179. function FileManagerFileUploader() {
  180. _classCallCheck(this, FileManagerFileUploader);
  181. return _super.apply(this, arguments)
  182. }
  183. _createClass(FileManagerFileUploader, [{
  184. key: "_initMarkup",
  185. value: function() {
  186. this._initActions();
  187. this._progressPanel = this._createComponent((0, _renderer2.default)("<div>"), FileManagerUploadProgressPanel, {});
  188. this.$element().addClass(FILE_MANAGER_FILE_UPLOADER_CLASS).append(this._progressPanel.$element());
  189. this._renderFileInput();
  190. _get(_getPrototypeOf(FileManagerFileUploader.prototype), "_initMarkup", this).call(this)
  191. }
  192. }, {
  193. key: "_renderFileInput",
  194. value: function() {
  195. this._$fileInput = (0, _renderer2.default)("<input>").attr("type", "file").prop({
  196. multiple: "multiple",
  197. tabIndex: -1
  198. }).addClass(FILE_MANAGER_FILE_UPLOADER_FILE_INPUT_CLASS);
  199. _events_engine2.default.on(this._$fileInput, "change", this._onFileInputChange.bind(this));
  200. _events_engine2.default.on(this._$fileInput, "click", function(e) {
  201. e.stopPropagation();
  202. return true
  203. });
  204. this.$element().append(this._$fileInput)
  205. }
  206. }, {
  207. key: "_onFileInputChange",
  208. value: function() {
  209. var files = this._$fileInput.prop("files");
  210. if (0 === files.length) {
  211. return
  212. }
  213. _events_engine2.default.off(this._$fileInput, "change");
  214. _events_engine2.default.off(this._$fileInput, "click");
  215. var $fileInput = this._$fileInput;
  216. this._uploadFiles(files).always(function() {
  217. setTimeout(function() {
  218. $fileInput.remove()
  219. })
  220. });
  221. this._renderFileInput()
  222. }
  223. }, {
  224. key: "_uploadFiles",
  225. value: function(files) {
  226. var _this = this;
  227. if (0 === files.length) {
  228. return
  229. }
  230. var progressBoxTitle = "Uploading ".concat(files.length, " files");
  231. var progressBox = this._progressPanel.addProgressBox(progressBoxTitle, null);
  232. var controllerGetter = this.option("getController");
  233. var session = new FileManagerUploadSession({
  234. controller: controllerGetter(),
  235. onProgress: function(value) {
  236. return progressBox.updateProgress(100 * value)
  237. },
  238. onError: function(reason) {
  239. return _this._raiseOnErrorOccurred(reason)
  240. }
  241. });
  242. progressBox.option("onCancel", function() {
  243. return session.cancelUpload()
  244. });
  245. var deferreds = session.uploadFiles(files);
  246. return _deferred.when.apply(null, deferreds).then(function() {
  247. this._progressPanel.removeProgressBox(progressBox);
  248. var results = [].slice.call(arguments);
  249. if (results.some(function(res) {
  250. return res.success
  251. })) {
  252. this._onFilesUploaded()
  253. }
  254. }.bind(this))
  255. }
  256. }, {
  257. key: "tryUpload",
  258. value: function() {
  259. this._$fileInput.click()
  260. }
  261. }, {
  262. key: "_onFilesUploaded",
  263. value: function() {
  264. this._actions.onFilesUploaded()
  265. }
  266. }, {
  267. key: "_raiseOnErrorOccurred",
  268. value: function(args) {
  269. this._actions.onErrorOccurred({
  270. info: args
  271. })
  272. }
  273. }, {
  274. key: "_initActions",
  275. value: function() {
  276. this._actions = {
  277. onFilesUploaded: this._createActionByOption("onFilesUploaded"),
  278. onErrorOccurred: this._createActionByOption("onErrorOccurred")
  279. }
  280. }
  281. }, {
  282. key: "_getDefaultOptions",
  283. value: function() {
  284. return (0, _extend.extend)(_get(_getPrototypeOf(FileManagerFileUploader.prototype), "_getDefaultOptions", this).call(this), {
  285. getController: null,
  286. onFilesUploaded: null,
  287. onErrorOccurred: null
  288. })
  289. }
  290. }, {
  291. key: "_optionChanged",
  292. value: function(args) {
  293. var name = args.name;
  294. switch (name) {
  295. case "getController":
  296. this.repaint();
  297. break;
  298. case "onFilesUploaded":
  299. case "onErrorOccurred":
  300. this._actions[name] = this._createActionByOption(name);
  301. break;
  302. default:
  303. _get(_getPrototypeOf(FileManagerFileUploader.prototype), "_optionChanged", this).call(this, args)
  304. }
  305. }
  306. }]);
  307. return FileManagerFileUploader
  308. }(_ui2.default);
  309. var FileManagerUploadSession = function() {
  310. function FileManagerUploadSession(options) {
  311. _classCallCheck(this, FileManagerUploadSession);
  312. this._controller = options.controller;
  313. this._onProgressHandler = options.onProgress;
  314. this._onErrorHandler = options.onError;
  315. this._canceled = false
  316. }
  317. _createClass(FileManagerUploadSession, [{
  318. key: "uploadFiles",
  319. value: function(files) {
  320. var progressInfo = {
  321. uploadedBytesCount: 0,
  322. totalBytesCount: 0
  323. };
  324. for (var j = 0; j < files.length; j++) {
  325. progressInfo.totalBytesCount += files[j].size
  326. }
  327. var result = [];
  328. for (var i = 0; i < files.length; i++) {
  329. var deferred = this._uploadFile(files[i], progressInfo);
  330. result.push(deferred)
  331. }
  332. return result
  333. }
  334. }, {
  335. key: "cancelUpload",
  336. value: function() {
  337. this._canceled = true
  338. }
  339. }, {
  340. key: "_uploadFile",
  341. value: function(file, progressInfo) {
  342. var _this2 = this;
  343. var state = this._createUploadingState(file);
  344. return this._controller.initiateUpload(state).then(function() {
  345. return _this2._uploadChunks(state, progressInfo)
  346. }).then(function() {
  347. return _this2._finalizeUpload(state)
  348. }, function(reason) {
  349. if (reason && reason.canceled) {
  350. return _this2._abortUpload(state)
  351. } else {
  352. return _this2._handleError(reason, file)
  353. }
  354. }).catch(function(reason) {
  355. return _this2._handleError(reason, file)
  356. })
  357. }
  358. }, {
  359. key: "_uploadChunks",
  360. value: function(state, progressInfo) {
  361. var _this3 = this;
  362. if (this._canceled) {
  363. var reason = this._createResultInfo(state.file.name, false, true);
  364. return (new _deferred.Deferred).reject(reason).promise()
  365. }
  366. var chunk = this._getChunk(state);
  367. if (!chunk) {
  368. return (new _deferred.Deferred).resolve().promise()
  369. }
  370. return this._controller.uploadChunk(state, chunk).done(function() {
  371. state.uploadedBytesCount += chunk.size;
  372. state.uploadedChunksCount++;
  373. progressInfo.uploadedBytesCount += chunk.size;
  374. _this3._raiseOnProgress(progressInfo)
  375. }).then(function() {
  376. return _this3._uploadChunks(state, progressInfo)
  377. })
  378. }
  379. }, {
  380. key: "_getChunk",
  381. value: function(state) {
  382. var bytesLeft = state.file.size - state.uploadedBytesCount;
  383. if (0 === bytesLeft) {
  384. return null
  385. }
  386. var chunkSize = Math.min(bytesLeft, this._controller.chunkSize);
  387. var blob = state.file.slice(state.uploadedBytesCount, state.uploadedBytesCount + chunkSize);
  388. return {
  389. index: state.uploadedChunksCount,
  390. size: chunkSize,
  391. blob: blob
  392. }
  393. }
  394. }, {
  395. key: "_finalizeUpload",
  396. value: function(state) {
  397. var _this4 = this;
  398. return this._controller.finalizeUpload(state).then(function() {
  399. return _this4._createResultInfo(state.file.name, true)
  400. })
  401. }
  402. }, {
  403. key: "_abortUpload",
  404. value: function(state) {
  405. var _this5 = this;
  406. return this._controller.abortUpload(state).then(function() {
  407. return _this5._createResultInfo(state.file.name, false, true)
  408. })
  409. }
  410. }, {
  411. key: "_handleError",
  412. value: function(error, file) {
  413. var result = this._createResultInfo(file.name, false, false, error);
  414. this._onErrorHandler(result);
  415. return result
  416. }
  417. }, {
  418. key: "_raiseOnProgress",
  419. value: function(info) {
  420. var value = 0 !== info.totalBytesCount ? info.uploadedBytesCount / info.totalBytesCount : 1;
  421. this._onProgressHandler(value)
  422. }
  423. }, {
  424. key: "_createUploadingState",
  425. value: function(file) {
  426. var chunkCount = Math.ceil(file.size / this._controller.chunkSize);
  427. return {
  428. file: file,
  429. uploadedBytesCount: 0,
  430. uploadedChunksCount: 0,
  431. totalChunkCount: chunkCount,
  432. customData: {}
  433. }
  434. }
  435. }, {
  436. key: "_createResultInfo",
  437. value: function(fileName, success, canceled, error) {
  438. return {
  439. fileName: fileName,
  440. success: success || false,
  441. canceled: canceled || false,
  442. error: error || null
  443. }
  444. }
  445. }]);
  446. return FileManagerUploadSession
  447. }();
  448. var FileManagerUploadProgressPanel = function(_Widget2) {
  449. _inherits(FileManagerUploadProgressPanel, _Widget2);
  450. var _super2 = _createSuper(FileManagerUploadProgressPanel);
  451. function FileManagerUploadProgressPanel() {
  452. _classCallCheck(this, FileManagerUploadProgressPanel);
  453. return _super2.apply(this, arguments)
  454. }
  455. _createClass(FileManagerUploadProgressPanel, [{
  456. key: "_init",
  457. value: function() {
  458. this._progressBoxCount = 0;
  459. _get(_getPrototypeOf(FileManagerUploadProgressPanel.prototype), "_init", this).call(this)
  460. }
  461. }, {
  462. key: "_initMarkup",
  463. value: function() {
  464. this._popup = this._createComponent(this.$element(), _popup2.default, {
  465. width: 200,
  466. height: 145,
  467. position: "right bottom",
  468. showTitle: false,
  469. visible: false,
  470. shading: false,
  471. deferRendering: false,
  472. closeOnOutsideClick: false,
  473. contentTemplate: this._getPopupContentTemplate.bind(this)
  474. });
  475. _get(_getPrototypeOf(FileManagerUploadProgressPanel.prototype), "_initMarkup", this).call(this)
  476. }
  477. }, {
  478. key: "addProgressBox",
  479. value: function(title, onCancel) {
  480. var progressBox = this._createComponent((0, _renderer2.default)("<div>"), FileManagerUploadProgressBox, {
  481. title: title,
  482. onCancel: onCancel
  483. });
  484. this._$container.append(progressBox.$element());
  485. if (0 === this._progressBoxCount) {
  486. this._popup.show()
  487. }
  488. this._progressBoxCount++;
  489. return progressBox
  490. }
  491. }, {
  492. key: "removeProgressBox",
  493. value: function(progressBox) {
  494. if (1 === this._progressBoxCount) {
  495. this._popup.hide()
  496. }
  497. this._progressBoxCount--;
  498. progressBox.dispose();
  499. progressBox.$element().remove()
  500. }
  501. }, {
  502. key: "_getPopupContentTemplate",
  503. value: function() {
  504. this._$container = (0, _renderer2.default)("<div>").addClass(FILE_MANAGER_PROGRESS_PANEL);
  505. return this._$container
  506. }
  507. }]);
  508. return FileManagerUploadProgressPanel
  509. }(_ui2.default);
  510. var FileManagerUploadProgressBox = function(_Widget3) {
  511. _inherits(FileManagerUploadProgressBox, _Widget3);
  512. var _super3 = _createSuper(FileManagerUploadProgressBox);
  513. function FileManagerUploadProgressBox() {
  514. _classCallCheck(this, FileManagerUploadProgressBox);
  515. return _super3.apply(this, arguments)
  516. }
  517. _createClass(FileManagerUploadProgressBox, [{
  518. key: "_initMarkup",
  519. value: function() {
  520. this._createOnCancelAction();
  521. var titleText = this.option("title");
  522. var $title = (0, _renderer2.default)("<span>").text(titleText).addClass(FILE_MANAGER_PROGRESS_BOX_TITLE);
  523. this._cancelButton = this._createComponent((0, _renderer2.default)("<div>"), _button2.default, {
  524. text: "Cancel",
  525. onClick: this._onCancelButtonClick.bind(this)
  526. });
  527. this._cancelButton.$element().addClass(FILE_MANAGER_PROGRESS_BOX_CANCEL_BUTTON);
  528. this._progressBar = this._createComponent((0, _renderer2.default)("<div>"), _progress_bar2.default, {
  529. min: 0,
  530. max: 100,
  531. width: "100%",
  532. showStatus: false
  533. });
  534. this._progressBar.$element().addClass(FILE_MANAGER_PROGRESS_BOX_PROGRESS_BAR);
  535. this.$element().addClass(FILE_MANAGER_PROGRESS_BOX);
  536. this.$element().append($title, this._progressBar.$element(), this._cancelButton.$element());
  537. _get(_getPrototypeOf(FileManagerUploadProgressBox.prototype), "_initMarkup", this).call(this)
  538. }
  539. }, {
  540. key: "updateProgress",
  541. value: function(value) {
  542. this._progressBar.option("value", value)
  543. }
  544. }, {
  545. key: "_onCancelButtonClick",
  546. value: function() {
  547. this._cancelButton.option({
  548. disabled: true,
  549. text: "Canceling..."
  550. });
  551. this._onCancelAction()
  552. }
  553. }, {
  554. key: "_createOnCancelAction",
  555. value: function() {
  556. this._onCancelAction = this._createActionByOption("onCancel")
  557. }
  558. }, {
  559. key: "_getDefaultOptions",
  560. value: function() {
  561. return (0, _extend.extend)(_get(_getPrototypeOf(FileManagerUploadProgressBox.prototype), "_getDefaultOptions", this).call(this), {
  562. title: "",
  563. onCancel: null
  564. })
  565. }
  566. }, {
  567. key: "_optionChanged",
  568. value: function(args) {
  569. var name = args.name;
  570. switch (name) {
  571. case "title":
  572. this.repaint();
  573. break;
  574. case "onCancel":
  575. this._createOnCancelAction();
  576. break;
  577. default:
  578. _get(_getPrototypeOf(FileManagerUploadProgressBox.prototype), "_optionChanged", this).call(this, args)
  579. }
  580. }
  581. }]);
  582. return FileManagerUploadProgressBox
  583. }(_ui2.default);
  584. module.exports = FileManagerFileUploader;