DataTransfer.js 4.4 KB

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