DataTransfer.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import { createFileList } from './FileList.js';
  2. function _define_property(obj, key, value) {
  3. if (key in obj) {
  4. Object.defineProperty(obj, key, {
  5. value: value,
  6. enumerable: true,
  7. configurable: true,
  8. writable: true
  9. });
  10. } else {
  11. obj[key] = value;
  12. }
  13. return obj;
  14. }
  15. // DataTransfer is not implemented in jsdom.
  16. // DataTransfer with FileList is being created by the browser on certain events.
  17. class DataTransferItemStub {
  18. getAsFile() {
  19. return this.file;
  20. }
  21. getAsString(callback) {
  22. if (typeof this.data === 'string') {
  23. callback(this.data);
  24. }
  25. }
  26. /* istanbul ignore next */ webkitGetAsEntry() {
  27. throw new Error('not implemented');
  28. }
  29. constructor(dataOrFile, type){
  30. _define_property(this, "kind", undefined);
  31. _define_property(this, "type", undefined);
  32. _define_property(this, "file", null);
  33. _define_property(this, "data", undefined);
  34. if (typeof dataOrFile === 'string') {
  35. this.kind = 'string';
  36. this.type = String(type);
  37. this.data = dataOrFile;
  38. } else {
  39. this.kind = 'file';
  40. this.type = dataOrFile.type;
  41. this.file = dataOrFile;
  42. }
  43. }
  44. }
  45. class DataTransferItemListStub extends Array {
  46. add(...args) {
  47. const item = new DataTransferItemStub(args[0], args[1]);
  48. this.push(item);
  49. return item;
  50. }
  51. clear() {
  52. this.splice(0, this.length);
  53. }
  54. remove(index) {
  55. this.splice(index, 1);
  56. }
  57. }
  58. function getTypeMatcher(type, exact) {
  59. const [group, sub] = type.split('/');
  60. const isGroup = !sub || sub === '*';
  61. return (item)=>{
  62. return exact ? item.type === (isGroup ? group : type) : isGroup ? item.type.startsWith(`${group}/`) : item.type === group;
  63. };
  64. }
  65. function createDataTransferStub(window) {
  66. return new class DataTransferStub {
  67. getData(format) {
  68. var _this_items_find;
  69. const match = (_this_items_find = this.items.find(getTypeMatcher(format, true))) !== null && _this_items_find !== undefined ? _this_items_find : this.items.find(getTypeMatcher(format, false));
  70. let text = '';
  71. match === null || match === undefined ? undefined : match.getAsString((t)=>{
  72. text = t;
  73. });
  74. return text;
  75. }
  76. setData(format, data) {
  77. const matchIndex = this.items.findIndex(getTypeMatcher(format, true));
  78. const item = new DataTransferItemStub(data, format);
  79. if (matchIndex >= 0) {
  80. this.items.splice(matchIndex, 1, item);
  81. } else {
  82. this.items.push(item);
  83. }
  84. }
  85. clearData(format) {
  86. if (format) {
  87. const matchIndex = this.items.findIndex(getTypeMatcher(format, true));
  88. if (matchIndex >= 0) {
  89. this.items.remove(matchIndex);
  90. }
  91. } else {
  92. this.items.clear();
  93. }
  94. }
  95. get types() {
  96. const t = [];
  97. if (this.files.length) {
  98. t.push('Files');
  99. }
  100. this.items.forEach((i)=>t.push(i.type));
  101. Object.freeze(t);
  102. return t;
  103. }
  104. /* istanbul ignore next */ setDragImage() {}
  105. constructor(){
  106. _define_property(this, "dropEffect", 'none');
  107. _define_property(this, "effectAllowed", 'uninitialized');
  108. _define_property(this, "items", new DataTransferItemListStub());
  109. _define_property(this, "files", createFileList(window, []));
  110. }
  111. }();
  112. }
  113. function createDataTransfer(window, files = []) {
  114. // Use real DataTransfer if available
  115. const dt = typeof window.DataTransfer === 'undefined' ? createDataTransferStub(window) : /* istanbul ignore next */ new window.DataTransfer();
  116. Object.defineProperty(dt, 'files', {
  117. get: ()=>createFileList(window, files)
  118. });
  119. return dt;
  120. }
  121. async function getBlobFromDataTransferItem(window, item) {
  122. if (item.kind === 'file') {
  123. return item.getAsFile();
  124. }
  125. return new window.Blob([
  126. await new Promise((r)=>item.getAsString(r))
  127. ], {
  128. type: item.type
  129. });
  130. }
  131. export { createDataTransfer, getBlobFromDataTransferItem };