1{"version":3,"file":"ClipboardModule.js","sourceRoot":"","sources":["../../src/web/ClipboardModule.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n  ClipboardUnavailableException,\n  CopyFailureException,\n  NoPermissionException,\n  PasteFailureException,\n} from './Exceptions';\nimport {\n  base64toBlob,\n  blobToBase64Async,\n  findHtmlInClipboardAsync,\n  findImageInClipboardAsync,\n  getImageSizeFromBlobAsync,\n  htmlToPlainText,\n  isClipboardPermissionDeniedAsync,\n} from './Utils';\nimport {\n  ClipboardImage,\n  GetImageOptions,\n  GetStringOptions,\n  SetStringOptions,\n  StringFormat,\n} from '../Clipboard.types';\n\nexport default {\n  get name(): string {\n    return 'ExpoClipboard';\n  },\n  async getStringAsync(options: GetStringOptions): Promise<string> {\n    if (!navigator.clipboard) {\n      throw new ClipboardUnavailableException();\n    }\n\n    try {\n      switch (options.preferredFormat) {\n        case StringFormat.HTML: {\n          // Try reading HTML first\n          const clipboardItems = await navigator.clipboard.read();\n          const blob = await findHtmlInClipboardAsync(clipboardItems);\n          if (!blob) {\n            // Fall back to plain text\n            return await navigator.clipboard.readText();\n          }\n          return await new Response(blob).text();\n        }\n        default: {\n          let text = await navigator.clipboard.readText();\n          if (!text || text === '') {\n            // If there's no direct plain text, try reading HTML\n            const clipboardItems = await navigator.clipboard.read();\n            const blob = await findHtmlInClipboardAsync(clipboardItems);\n            const blobText = await blob?.text();\n            text = htmlToPlainText(blobText ?? '');\n          }\n          return text;\n        }\n      }\n    } catch (e) {\n      // it might fail, because user denied permission\n      if (e.name === 'NotAllowedError' || (await isClipboardPermissionDeniedAsync())) {\n        throw new NoPermissionException();\n      }\n\n      try {\n        // Internet Explorer\n        // @ts-ignore\n        return window.clipboardData.getData('Text');\n      } catch {\n        return Promise.reject(new Error('Unable to retrieve item from clipboard'));\n      }\n    }\n  },\n  // TODO: (barthap) The `setString` was deprecated in SDK 45. Remove this function in a few SDK cycles.\n  setString(text: string): boolean {\n    const textField = document.createElement('textarea');\n    textField.textContent = text;\n    document.body.appendChild(textField);\n    textField.select();\n    try {\n      document.execCommand('copy');\n      return true;\n    } catch {\n      return false;\n    } finally {\n      document.body.removeChild(textField);\n    }\n  },\n  async setStringAsync(text: string, options: SetStringOptions): Promise<boolean> {\n    switch (options.inputFormat) {\n      case StringFormat.HTML: {\n        if (!navigator.clipboard) {\n          throw new ClipboardUnavailableException();\n        }\n\n        try {\n          const clipboardItemInput = createHtmlClipboardItem(text);\n          await navigator.clipboard.write([clipboardItemInput]);\n          return true;\n        } catch (e) {\n          // it might fail, because user denied permission\n          if (e.name === 'NotAllowedError' || (await isClipboardPermissionDeniedAsync())) {\n            throw new NoPermissionException();\n          }\n          throw new CopyFailureException(e.message);\n        }\n      }\n      default: {\n        try {\n          if (!navigator.clipboard) {\n            throw new Error();\n          }\n          await navigator.clipboard.writeText(text);\n          return true;\n        } catch {\n          // we can fall back to legacy behavior in any kind of failure\n          // including navigator.clipboard unavailability\n          return this.setString(text);\n        }\n      }\n    }\n  },\n  async hasStringAsync(): Promise<boolean> {\n    return await clipboardHasTypesAsync(['text/plain', 'text/html']);\n  },\n  async getImageAsync(_options: GetImageOptions): Promise<ClipboardImage | null> {\n    if (!navigator.clipboard) {\n      throw new ClipboardUnavailableException();\n    }\n\n    try {\n      const clipboardItems = await navigator.clipboard.read();\n      const blob = await findImageInClipboardAsync(clipboardItems);\n      if (!blob) {\n        return null;\n      }\n\n      const [data, size] = await Promise.all([\n        blobToBase64Async(blob),\n        getImageSizeFromBlobAsync(blob),\n      ]);\n\n      return { data, size };\n    } catch (e) {\n      // it might fail, because user denied permission\n      if (e.name === 'NotAllowedError' || (await isClipboardPermissionDeniedAsync())) {\n        throw new NoPermissionException();\n      }\n      throw new PasteFailureException(e.message);\n    }\n  },\n  async setImageAsync(base64image: string): Promise<void> {\n    if (!navigator.clipboard) {\n      throw new ClipboardUnavailableException();\n    }\n\n    try {\n      // we set it always to `image/png` because it's the only format supported by the clipboard\n      // but it seems to work even when provided jpeg data\n      const blob = base64toBlob(base64image, 'image/png');\n      await navigator.clipboard.write([\n        new ClipboardItem({\n          [blob.type]: blob,\n        }),\n      ]);\n    } catch (err: any) {\n      throw new CopyFailureException(err.message);\n    }\n  },\n  async hasImageAsync(): Promise<boolean> {\n    return await clipboardHasTypesAsync(['image/png', 'image/jpeg']);\n  },\n  addClipboardListener(): void {},\n  removeClipboardListener(): void {},\n};\n\n/**\n * Resolves to true if clipboard has one of provided {@link types}.\n * @throws `ClipboardUnavailableException` if AsyncClipboard API is not available\n * @throws `NoPermissionException` if user denied permission\n */\nasync function clipboardHasTypesAsync(types: string[]): Promise<boolean> {\n  if (!navigator.clipboard) {\n    throw new ClipboardUnavailableException();\n  }\n\n  try {\n    const clipboardItems = await navigator.clipboard.read();\n    return clipboardItems.flatMap((item) => item.types).some((type) => types.includes(type));\n  } catch (e) {\n    // it might fail, because user denied permission\n    if (e.name === 'NotAllowedError' || (await isClipboardPermissionDeniedAsync())) {\n      throw new NoPermissionException();\n    }\n    throw e;\n  }\n}\n\nfunction createHtmlClipboardItem(htmlString: string): ClipboardItem {\n  return new ClipboardItem({\n    // @ts-ignore `Blob` from `lib.dom.d.ts` and the one from `@types/react-native` differ\n    'text/html': new Blob([htmlString], { type: 'text/html' }),\n    // @ts-ignore `Blob` from `lib.dom.d.ts` and the one from `@types/react-native` differ\n    'text/plain': new Blob([htmlToPlainText(htmlString)], { type: 'text/plain' }),\n  });\n}\n"]}