diff --git a/.mapping.json b/.mapping.json index 89c46e957..ce6017cb6 100644 --- a/.mapping.json +++ b/.mapping.json @@ -11988,6 +11988,7 @@ "client/web/divkit/package.json":"divkit/public/client/web/divkit/package.json", "client/web/divkit/server/package.json":"divkit/public/client/web/divkit/server/package.json", "client/web/divkit/src/actions/array.ts":"divkit/public/client/web/divkit/src/actions/array.ts", + "client/web/divkit/src/actions/copyToClipboard.ts":"divkit/public/client/web/divkit/src/actions/copyToClipboard.ts", "client/web/divkit/src/client-devtool.ts":"divkit/public/client/web/divkit/src/client-devtool.ts", "client/web/divkit/src/client.ts":"divkit/public/client/web/divkit/src/client.ts", "client/web/divkit/src/components.js":"divkit/public/client/web/divkit/src/components.js", diff --git a/client/web/divkit/src/actions/copyToClipboard.ts b/client/web/divkit/src/actions/copyToClipboard.ts new file mode 100644 index 000000000..47f85f136 --- /dev/null +++ b/client/web/divkit/src/actions/copyToClipboard.ts @@ -0,0 +1,43 @@ +import type { ActionCopyToClipboard, WrappedError } from '../../typings/common'; +import type { MaybeMissing } from '../expressions/json'; +import { wrapError } from '../utils/wrapError'; + +export function copyToClipboard( + logError: (error: WrappedError) => void, + actionTyped: MaybeMissing +): void { + if (!( + actionTyped.content && (actionTyped.content.type === 'text' || actionTyped.content.type === 'url') && + typeof actionTyped.content.value === 'string' + )) { + logError(wrapError(new Error('Incorrect action'), { + additional: { + action: actionTyped + } + })); + return; + } + + if (!( + typeof navigator !== 'undefined' && + 'clipboard' in navigator && + navigator.clipboard && + 'write' in navigator.clipboard && + typeof navigator.clipboard.writeText === 'function' + )) { + logError(wrapError(new Error('Clipboard is unavailable'), { + additional: { + action: actionTyped + } + })); + return; + } + + navigator.clipboard.writeText(actionTyped.content.value).catch(err => { + logError(wrapError(new Error('Failed to copy to the clipboard'), { + additional: { + originalError: String(err) + } + })); + }); +} diff --git a/client/web/divkit/src/components/Root.svelte b/client/web/divkit/src/components/Root.svelte index f21ab8104..44a0d5c3d 100644 --- a/client/web/divkit/src/components/Root.svelte +++ b/client/web/divkit/src/components/Root.svelte @@ -72,6 +72,7 @@ import { getUrlSchema, isBuiltinSchema } from '../utils/url'; import { TimersController } from '../utils/timers'; import { arrayInsert, arrayRemove } from '../actions/array'; + import { copyToClipboard } from '../actions/copyToClipboard'; export let id: string; export let json: Partial = {}; @@ -772,6 +773,9 @@ case 'array_remove_value': arrayRemove(variables, logError, actionTyped); break; + case 'copy_to_clipboard': + copyToClipboard(logError, actionTyped); + break; default: { logError(wrapError(new Error('Unknown type of action'), { additional: { diff --git a/client/web/divkit/typings/common.d.ts b/client/web/divkit/typings/common.d.ts index 62caeab8d..eba1744c7 100644 --- a/client/web/divkit/typings/common.d.ts +++ b/client/web/divkit/typings/common.d.ts @@ -160,7 +160,25 @@ export interface ActionArrayInsertValue { value: TypedValue; } -export type TypedAction = ActionSetVariable | ActionArrayRemoveValue | ActionArrayInsertValue; +export interface CopyToClipboardContentText { + type: 'text'; + value: string; +} + +export interface CopyToClipboardContentUrl { + type: 'url'; + value: string; +} + +export type CopyToClipboardContent = CopyToClipboardContentText | CopyToClipboardContentUrl; + +export interface ActionCopyToClipboard { + type: 'copy_to_clipboard'; + content: CopyToClipboardContent; +} + +export type TypedAction = ActionSetVariable | ActionArrayRemoveValue | ActionArrayInsertValue | + ActionCopyToClipboard; export interface Action { log_id: string; diff --git a/schema/div-action-typed.json b/schema/div-action-typed.json index bc81b4323..cb74710c7 100644 --- a/schema/div-action-typed.json +++ b/schema/div-action-typed.json @@ -16,11 +16,7 @@ ] }, { - "$ref": "div-action-copy-to-clipboard.json", - "platforms": [ - "android", - "ios" - ] + "$ref": "div-action-copy-to-clipboard.json" } ] } diff --git a/test_data/regression_test_data/index.json b/test_data/regression_test_data/index.json index 108e12388..431e975bc 100644 --- a/test_data/regression_test_data/index.json +++ b/test_data/regression_test_data/index.json @@ -5,10 +5,6 @@ "tags": [ "DivAction" ], - "platforms": [ - "android", - "ios" - ], "steps": [ "Tap to copy url button and paste clipboard to input", "Tap to copy string button and paste clipboard to input"