expo-clipboard 4.4.0 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +14 -1
- package/android/build.gradle +11 -8
- package/build/web/ClipboardModule.d.ts.map +1 -1
- package/build/web/ClipboardModule.js +1 -1
- package/build/web/ClipboardModule.js.map +1 -1
- package/ios/NSAttributedString+utilities.swift +3 -0
- package/ios/Tests/ClipboardModuleSpec.swift +4 -3
- package/ios/Tests/MockNSAttributedString.swift +40 -0
- package/package.json +2 -2
- package/src/web/ClipboardModule.ts +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,16 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 4.6.0 — 2023-09-15
|
|
14
|
+
|
|
15
|
+
_This version does not introduce any user-facing changes._
|
|
16
|
+
|
|
17
|
+
## 4.5.0 — 2023-09-04
|
|
18
|
+
|
|
19
|
+
### 🎉 New features
|
|
20
|
+
|
|
21
|
+
- Added support for React Native 0.73. ([#24018](https://github.com/expo/expo/pull/24018) by [@kudo](https://github.com/kudo))
|
|
22
|
+
|
|
13
23
|
## 4.4.0 — 2023-08-02
|
|
14
24
|
|
|
15
25
|
_This version does not introduce any user-facing changes._
|
package/README.md
CHANGED
|
@@ -13,12 +13,25 @@
|
|
|
13
13
|
|
|
14
14
|
Please refer to the [API documentation for the latest stable release](https://docs.expo.dev/versions/latest/sdk/clipboard/).
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
|
|
17
|
+
## Installation in bare React Native projects
|
|
18
|
+
|
|
19
|
+
For bare React Native projects, ensure you've [installed and configured the `expo` package](https://docs.expo.dev/bare/installing-expo-modules/).
|
|
20
|
+
|
|
21
|
+
### Add the package to your npm dependencies
|
|
17
22
|
|
|
18
23
|
```
|
|
19
24
|
npx expo install expo-clipboard
|
|
20
25
|
```
|
|
21
26
|
|
|
27
|
+
### Configure for iOS
|
|
28
|
+
|
|
29
|
+
Run `npx pod-install` after installing the library.
|
|
30
|
+
|
|
31
|
+
### Configure for Android
|
|
32
|
+
|
|
33
|
+
No additional set up necessary.
|
|
34
|
+
|
|
22
35
|
## Contributing
|
|
23
36
|
|
|
24
37
|
Contributions are very welcome! Please refer to guidelines described in the [contributing guide](https://github.com/expo/expo#contributing).
|
package/android/build.gradle
CHANGED
|
@@ -3,7 +3,7 @@ apply plugin: 'kotlin-android'
|
|
|
3
3
|
apply plugin: 'maven-publish'
|
|
4
4
|
|
|
5
5
|
group = 'host.exp.exponent'
|
|
6
|
-
version = '4.
|
|
6
|
+
version = '4.6.0'
|
|
7
7
|
|
|
8
8
|
buildscript {
|
|
9
9
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
@@ -53,13 +53,16 @@ afterEvaluate {
|
|
|
53
53
|
android {
|
|
54
54
|
compileSdkVersion safeExtGet("compileSdkVersion", 33)
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
|
|
57
|
+
if (agpVersion.tokenize('.')[0].toInteger() < 8) {
|
|
58
|
+
compileOptions {
|
|
59
|
+
sourceCompatibility JavaVersion.VERSION_11
|
|
60
|
+
targetCompatibility JavaVersion.VERSION_11
|
|
61
|
+
}
|
|
60
62
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
kotlinOptions {
|
|
64
|
+
jvmTarget = JavaVersion.VERSION_11.majorVersion
|
|
65
|
+
}
|
|
63
66
|
}
|
|
64
67
|
|
|
65
68
|
namespace "expo.modules.clipboard"
|
|
@@ -67,7 +70,7 @@ android {
|
|
|
67
70
|
minSdkVersion safeExtGet("minSdkVersion", 21)
|
|
68
71
|
targetSdkVersion safeExtGet("targetSdkVersion", 33)
|
|
69
72
|
versionCode 3
|
|
70
|
-
versionName '4.
|
|
73
|
+
versionName '4.6.0'
|
|
71
74
|
}
|
|
72
75
|
lintOptions {
|
|
73
76
|
abortOnError false
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClipboardModule.d.ts","sourceRoot":"","sources":["../../src/web/ClipboardModule.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ClipboardModule.d.ts","sourceRoot":"","sources":["../../src/web/ClipboardModule.ts"],"names":[],"mappings":"AAeA,OAAO,EACL,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAEjB,MAAM,oBAAoB,CAAC;;;4BAMI,gBAAgB,GAAG,QAAQ,MAAM,CAAC;oBA6ChD,MAAM,GAAG,OAAO;yBAcL,MAAM,WAAW,gBAAgB,GAAG,QAAQ,OAAO,CAAC;sBAkCvD,QAAQ,OAAO,CAAC;4BAGV,eAAe,GAAG,QAAQ,cAAc,GAAG,IAAI,CAAC;+BA0B7C,MAAM,GAAG,QAAQ,IAAI,CAAC;qBAkBhC,QAAQ,OAAO,CAAC;4BAGf,IAAI;+BACD,IAAI;;AApJjC,wBAqJE"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { StringFormat, } from '../Clipboard.types';
|
|
2
1
|
import { ClipboardUnavailableException, CopyFailureException, NoPermissionException, PasteFailureException, } from './Exceptions';
|
|
3
2
|
import { base64toBlob, blobToBase64Async, findHtmlInClipboardAsync, findImageInClipboardAsync, getImageSizeFromBlobAsync, htmlToPlainText, isClipboardPermissionDeniedAsync, } from './Utils';
|
|
3
|
+
import { StringFormat, } from '../Clipboard.types';
|
|
4
4
|
export default {
|
|
5
5
|
get name() {
|
|
6
6
|
return 'ExpoClipboard';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClipboardModule.js","sourceRoot":"","sources":["../../src/web/ClipboardModule.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ClipboardImage,\n GetImageOptions,\n GetStringOptions,\n SetStringOptions,\n StringFormat,\n} from '../Clipboard.types';\nimport {\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';\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"]}
|
|
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"]}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import MobileCoreServices
|
|
4
4
|
|
|
5
5
|
extension NSAttributedString {
|
|
6
|
+
@objc
|
|
6
7
|
convenience init(htmlString: String) throws {
|
|
7
8
|
let initOptions: [DocumentReadingOptionKey: Any] = [
|
|
8
9
|
.documentType: NSAttributedString.DocumentType.html
|
|
@@ -10,6 +11,7 @@ extension NSAttributedString {
|
|
|
10
11
|
try self.init(data: Data(htmlString.utf8), options: initOptions, documentAttributes: nil)
|
|
11
12
|
}
|
|
12
13
|
|
|
14
|
+
@objc
|
|
13
15
|
var rtfData: Data? {
|
|
14
16
|
let range = NSRange(location: 0, length: self.length)
|
|
15
17
|
let attributes: [DocumentAttributeKey: Any] = [
|
|
@@ -19,6 +21,7 @@ extension NSAttributedString {
|
|
|
19
21
|
return try? self.data(from: range, documentAttributes: attributes)
|
|
20
22
|
}
|
|
21
23
|
|
|
24
|
+
@objc
|
|
22
25
|
var htmlString: String? {
|
|
23
26
|
do {
|
|
24
27
|
let range = NSRange(location: 0, length: self.length)
|
|
@@ -11,7 +11,7 @@ class ClipboardModuleSpec: ExpoSpec {
|
|
|
11
11
|
let holder = ModuleHolder(appContext: appContext, module: ClipboardModule(appContext: appContext))
|
|
12
12
|
|
|
13
13
|
func testModuleFunction<T>(_ functionName: String, args: [Any], _ block: @escaping (T?) -> Void) {
|
|
14
|
-
waitUntil { done in
|
|
14
|
+
waitUntil(timeout: .seconds(3)) { done in
|
|
15
15
|
holder.call(function: functionName, args: args) { result in
|
|
16
16
|
let value = try! result.get()
|
|
17
17
|
expect(value).to(beAKindOf(T?.self))
|
|
@@ -22,7 +22,7 @@ class ClipboardModuleSpec: ExpoSpec {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
func expectModuleFunctionThrows<T>(_ functionName: String, args: [Any], exception: T.Type) where T: Exception {
|
|
25
|
-
waitUntil { done in
|
|
25
|
+
waitUntil(timeout: .seconds(3)) { done in
|
|
26
26
|
holder.call(function: functionName, args: args) { result in
|
|
27
27
|
expect(result).to(beFailure(exception: exception))
|
|
28
28
|
done()
|
|
@@ -32,6 +32,7 @@ class ClipboardModuleSpec: ExpoSpec {
|
|
|
32
32
|
|
|
33
33
|
beforeSuite {
|
|
34
34
|
swizzleGeneralPasteboard()
|
|
35
|
+
swizzleNSAttributedString()
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
// MARK: - Strings
|
|
@@ -305,7 +306,7 @@ class ClipboardModuleSpec: ExpoSpec {
|
|
|
305
306
|
}
|
|
306
307
|
|
|
307
308
|
// TODO: (barthap) Replace this with built-in beFailure() when upgraded to Nimble 10.0
|
|
308
|
-
func beFailure<Success, Failure, T: Exception>(exception: T.Type) -> Predicate<Result<Success, Failure>> {
|
|
309
|
+
func beFailure<Success, Failure, T: Exception>(exception: T.Type) -> Nimble.Predicate<Result<Success, Failure>> {
|
|
309
310
|
return Predicate.simple("be \(exception)") { actualExpression in
|
|
310
311
|
guard let actual = try actualExpression.evaluate(),
|
|
311
312
|
case let .failure(error) = actual,
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Copyright 2018-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
import Foundation
|
|
4
|
+
@testable import ExpoClipboard
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
A mocked `NSAttributedString+utilities` for unit tests
|
|
8
|
+
`NSAttributedString` HTML processor requires main thread and it is slow. It may break unit test occasionally.
|
|
9
|
+
This mocked version just returns the raw string.
|
|
10
|
+
*/
|
|
11
|
+
class MockNSAttributedString: NSAttributedString {
|
|
12
|
+
convenience init(htmlString: String) throws {
|
|
13
|
+
self.init(string: htmlString)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
override var rtfData: Data? {
|
|
17
|
+
return try? self.data(from: NSRange(location: 0, length: self.length))
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
override var htmlString: String? {
|
|
21
|
+
return self.string
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
func swizzleNSAttributedString() {
|
|
26
|
+
// swiftlint:disable force_unwrapping
|
|
27
|
+
method_exchangeImplementations(
|
|
28
|
+
class_getInstanceMethod(NSAttributedString.self, #selector(NSAttributedString.init(htmlString:)))!,
|
|
29
|
+
class_getInstanceMethod(MockNSAttributedString.self, #selector(MockNSAttributedString.init(htmlString:)))!
|
|
30
|
+
)
|
|
31
|
+
method_exchangeImplementations(
|
|
32
|
+
class_getInstanceMethod(NSAttributedString.self, #selector(getter: NSAttributedString.rtfData))!,
|
|
33
|
+
class_getInstanceMethod(MockNSAttributedString.self, #selector(getter: MockNSAttributedString.rtfData))!
|
|
34
|
+
)
|
|
35
|
+
method_exchangeImplementations(
|
|
36
|
+
class_getInstanceMethod(NSAttributedString.self, #selector(getter: NSAttributedString.htmlString))!,
|
|
37
|
+
class_getInstanceMethod(MockNSAttributedString.self, #selector(getter: MockNSAttributedString.htmlString))!
|
|
38
|
+
)
|
|
39
|
+
// swiftlint:enable force_unwrapping
|
|
40
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-clipboard",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.6.0",
|
|
4
4
|
"description": "ExpoClipboard standalone module",
|
|
5
5
|
"main": "build/Clipboard.js",
|
|
6
6
|
"types": "build/Clipboard.d.ts",
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"jest": {
|
|
40
40
|
"preset": "expo-module-scripts/universal"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "ee2c866ba3c7fbc35ff2a3e896041cf15d3bd7c5"
|
|
43
43
|
}
|
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ClipboardImage,
|
|
3
|
-
GetImageOptions,
|
|
4
|
-
GetStringOptions,
|
|
5
|
-
SetStringOptions,
|
|
6
|
-
StringFormat,
|
|
7
|
-
} from '../Clipboard.types';
|
|
8
1
|
import {
|
|
9
2
|
ClipboardUnavailableException,
|
|
10
3
|
CopyFailureException,
|
|
@@ -20,6 +13,13 @@ import {
|
|
|
20
13
|
htmlToPlainText,
|
|
21
14
|
isClipboardPermissionDeniedAsync,
|
|
22
15
|
} from './Utils';
|
|
16
|
+
import {
|
|
17
|
+
ClipboardImage,
|
|
18
|
+
GetImageOptions,
|
|
19
|
+
GetStringOptions,
|
|
20
|
+
SetStringOptions,
|
|
21
|
+
StringFormat,
|
|
22
|
+
} from '../Clipboard.types';
|
|
23
23
|
|
|
24
24
|
export default {
|
|
25
25
|
get name(): string {
|