paste.js 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. import { useEffect } from "react";
  2. const handle_paste_data = (clipboardData) =>
  3. new Promise((resolve, reject) => {
  4. const pasted_data = [];
  5. const n_items = clipboardData.items.length;
  6. const extract_data = (item) => {
  7. const type = item.type;
  8. if (item.kind === "string") {
  9. item.getAsString((data) => {
  10. pasted_data.push([type, data]);
  11. if (pasted_data.length === n_items) {
  12. resolve(pasted_data);
  13. }
  14. });
  15. } else if (item.kind === "file") {
  16. const file = item.getAsFile();
  17. const reader = new FileReader();
  18. reader.onload = (e) => {
  19. pasted_data.push([type, e.target.result]);
  20. if (pasted_data.length === n_items) {
  21. resolve(pasted_data);
  22. }
  23. };
  24. if (type.indexOf("text/") === 0) {
  25. reader.readAsText(file);
  26. } else {
  27. reader.readAsDataURL(file);
  28. }
  29. }
  30. };
  31. for (const item of clipboardData.items) {
  32. extract_data(item);
  33. }
  34. });
  35. export default function usePasteHandler(target_ids, event_actions, on_paste) {
  36. return useEffect(() => {
  37. const handle_paste = (_ev) => {
  38. event_actions.preventDefault && _ev.preventDefault();
  39. event_actions.stopPropagation && _ev.stopPropagation();
  40. handle_paste_data(_ev.clipboardData).then(on_paste);
  41. };
  42. const targets = target_ids
  43. .map((id) => document.getElementById(id))
  44. .filter((element) => !!element);
  45. if (target_ids.length === 0) {
  46. targets.push(document);
  47. }
  48. targets.forEach((target) =>
  49. target.addEventListener("paste", handle_paste, false),
  50. );
  51. return () => {
  52. targets.forEach((target) =>
  53. target.removeEventListener("paste", handle_paste, false),
  54. );
  55. };
  56. });
  57. }