mirror of
https://github.com/divkit/divkit.git
synced 2026-06-06 20:07:59 +00:00
Filter action url
commit_hash:fb613bcfef9a1aa33090dacc0cebc1e81d4762e9
This commit is contained in:
@@ -22987,6 +22987,7 @@
|
||||
"visual-editor/src/lib/utils/capitalize.ts":"divkit/public/visual-editor/src/lib/utils/capitalize.ts",
|
||||
"visual-editor/src/lib/utils/checkDivjson.test.ts":"divkit/public/visual-editor/src/lib/utils/checkDivjson.test.ts",
|
||||
"visual-editor/src/lib/utils/checkDivjson.ts":"divkit/public/visual-editor/src/lib/utils/checkDivjson.ts",
|
||||
"visual-editor/src/lib/utils/checkValue.ts":"divkit/public/visual-editor/src/lib/utils/checkValue.ts",
|
||||
"visual-editor/src/lib/utils/colors.test.ts":"divkit/public/visual-editor/src/lib/utils/colors.test.ts",
|
||||
"visual-editor/src/lib/utils/colors.ts":"divkit/public/visual-editor/src/lib/utils/colors.ts",
|
||||
"visual-editor/src/lib/utils/componentIcon.ts":"divkit/public/visual-editor/src/lib/utils/componentIcon.ts",
|
||||
|
||||
@@ -62,6 +62,12 @@ export interface CardLocale {
|
||||
text: Record<string, string>;
|
||||
}
|
||||
|
||||
export type StringValueFilter = RegExp | ((value: string) => boolean);
|
||||
|
||||
export interface ValueFilters {
|
||||
actionUrl?: StringValueFilter;
|
||||
}
|
||||
|
||||
export interface EditorOptions {
|
||||
node: HTMLElement;
|
||||
shadowRoot?: ShadowRoot;
|
||||
@@ -148,6 +154,7 @@ export interface DivProEditorOptions {
|
||||
/* @deprecated */
|
||||
errorFileLimit?: number;
|
||||
fileLimits?: FileLimits;
|
||||
valueFilters?: ValueFilters;
|
||||
rootConfigurable?: boolean;
|
||||
customFontFaces?: FontFaceDesc[];
|
||||
directionSelector?: boolean;
|
||||
@@ -193,6 +200,7 @@ export const DivProEditor = {
|
||||
state.direction.set(opts.direction || 'ltr');
|
||||
state.safeAreaEmulation = opts.safeAreaEmulation;
|
||||
state.safeAreaEmulationEnabled.set(Boolean(opts.safeAreaEmulation));
|
||||
state.valueFilters = opts.valueFilters;
|
||||
|
||||
if (Array.isArray(json?.card?.variables)) {
|
||||
const localPalette = json.card.variables.find((it?: JsonVariable) => it?.type === 'dict' && it.name === 'local_palette');
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
import { formatFileSize } from '../../utils/formatFileSize';
|
||||
import { calcFileSizeMod, getFileSize } from '../../utils/fileSize';
|
||||
import type { VideoSource } from '../../utils/video';
|
||||
import type { StringValueFilter } from '../../../lib';
|
||||
import { checkStringValue } from '../../utils/checkValue';
|
||||
|
||||
export let id: string = '';
|
||||
export let value: string | number | undefined;
|
||||
@@ -34,6 +36,7 @@
|
||||
export let size: 'medium' | 'small' = 'medium';
|
||||
export let width: 'auto' | 'small' = 'auto';
|
||||
export let pattern: string | null = null;
|
||||
export let filter: StringValueFilter | undefined = undefined;
|
||||
export let error = '';
|
||||
export let title = '';
|
||||
export let generateFromVideo: VideoSource[] | undefined = undefined;
|
||||
@@ -54,11 +57,18 @@
|
||||
let elem: HTMLElement;
|
||||
let subtypeError = false;
|
||||
let requiredError = false;
|
||||
let filterError = false;
|
||||
let isFocused = false;
|
||||
let currentSize: number | undefined = undefined;
|
||||
let sizeLabelWidth = 0;
|
||||
let customButtonsWidth = 0;
|
||||
|
||||
function validateValue(value: string | number | undefined): void {
|
||||
requiredError = !value && required;
|
||||
|
||||
filterError = !checkStringValue(value, filter);
|
||||
}
|
||||
|
||||
function updateInternalValue(
|
||||
subtype: string,
|
||||
value: string | number | undefined,
|
||||
@@ -80,7 +90,7 @@
|
||||
|
||||
loadFileSize();
|
||||
|
||||
requiredError = !internalValue && required;
|
||||
validateValue(internalValue);
|
||||
}
|
||||
|
||||
$: updateInternalValue(subtype, value, defaultValue);
|
||||
@@ -135,7 +145,7 @@
|
||||
|
||||
loadFileSize();
|
||||
|
||||
requiredError = !value && required;
|
||||
validateValue(value);
|
||||
|
||||
dispatch('change', {
|
||||
value
|
||||
@@ -194,7 +204,7 @@
|
||||
class:text_inline-label={Boolean(inlineLabel)}
|
||||
class:text_button={hasButton}
|
||||
class:text_disabled={disabled}
|
||||
class:text_error={Boolean(error || subtypeError || requiredError)}
|
||||
class:text_error={Boolean(error || subtypeError || requiredError || filterError)}
|
||||
title={error}
|
||||
aria-label={title}
|
||||
data-custom-tooltip={title}
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
const { l10n, lang } = getContext<LanguageContext>(LANGUAGE_CTX);
|
||||
const { state } = getContext<AppContext>(APP_CTX);
|
||||
const { customActions } = state;
|
||||
const { customActions, valueFilters } = state;
|
||||
|
||||
$: if (isShown && !readOnly && callback) {
|
||||
if (!value.log_url) {
|
||||
@@ -224,6 +224,7 @@
|
||||
<Text
|
||||
bind:value={value.url}
|
||||
disabled={readOnly}
|
||||
filter={valueFilters?.actionUrl}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -22,27 +22,31 @@
|
||||
import { LANGUAGE_CTX, type LanguageContext } from '../../ctx/languageContext';
|
||||
import { parseAction } from '../../data/actions';
|
||||
import { APP_CTX, type AppContext } from '../../ctx/appContext';
|
||||
import { checkStringValue } from '../../utils/checkValue';
|
||||
|
||||
export let value: Action;
|
||||
|
||||
const { l10n, lang } = getContext<LanguageContext>(LANGUAGE_CTX);
|
||||
const { state, actions2Dialog } = getContext<AppContext>(APP_CTX);
|
||||
const { customActions, readOnly } = state;
|
||||
const { customActions, readOnly, valueFilters } = state;
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
let elem: HTMLElement;
|
||||
let type = '';
|
||||
let text = '';
|
||||
let hasError = false;
|
||||
|
||||
function updateVal(value: Action): void {
|
||||
const parsed = parseAction(value, $customActions);
|
||||
|
||||
type = '';
|
||||
hasError = false;
|
||||
|
||||
if (parsed.type === 'url') {
|
||||
type = $l10n('actions-url');
|
||||
text = parsed.url || '';
|
||||
hasError = !checkStringValue(parsed.url, valueFilters?.actionUrl);
|
||||
} else if (parsed.type.startsWith('typed:')) {
|
||||
if (parsed.type === 'typed:focus_element') {
|
||||
type = $l10n('actions.focus_element');
|
||||
@@ -133,6 +137,7 @@
|
||||
<button
|
||||
class="actions2-item"
|
||||
class:actions2-item_readonly={$readOnly}
|
||||
class:actions2-item_error={hasError}
|
||||
bind:this={elem}
|
||||
on:click={onClick}
|
||||
>
|
||||
@@ -164,11 +169,15 @@
|
||||
background: var(--fill-transparent-1);
|
||||
}
|
||||
|
||||
.actions2-item:not(.actions2-item_readonly):hover {
|
||||
.actions2-item_error {
|
||||
border-color: var(--accent-red);
|
||||
}
|
||||
|
||||
.actions2-item:not(.actions2-item_readonly):not(.actions2-item_error):hover {
|
||||
border-color: var(--fill-transparent-4);
|
||||
}
|
||||
|
||||
.actions2-item:not(.actions2-item_readonly):focus-visible {
|
||||
.actions2-item:not(.actions2-item_readonly):not(.actions2-item_error):focus-visible {
|
||||
outline: none;
|
||||
border-color: var(--accent-purple);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { parseExpression, walkExpression } from '@divkitframework/divkit/client-
|
||||
import type { PaletteItem } from './palette';
|
||||
import { parseVariableValue, type JsonVariable, type Variable } from './customVariables';
|
||||
import { type JsonTimer, type Timer } from './timers';
|
||||
import type { ActionDesc, EditorError, FileLimits, GetTranslationKey, Locale, SafeAreaEmulation, Source, TankerMeta } from '../../lib';
|
||||
import type { ActionDesc, EditorError, FileLimits, GetTranslationKey, Locale, SafeAreaEmulation, Source, TankerMeta, ValueFilters } from '../../lib';
|
||||
import type { TreeLeaf } from '../ctx/tree';
|
||||
import type { BaseCommand } from './commands/base';
|
||||
import { namedTemplates } from './templates';
|
||||
@@ -152,6 +152,8 @@ export class State {
|
||||
safeAreaEmulation?: SafeAreaEmulation;
|
||||
safeAreaEmulationEnabled = writable(false);
|
||||
|
||||
valueFilters?: ValueFilters;
|
||||
|
||||
private getTranslationKey: GetTranslationKey | undefined;
|
||||
|
||||
lang: Writable<Locale> = writable('en');
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import type { StringValueFilter } from '../../lib';
|
||||
|
||||
export function checkStringValue(
|
||||
value: string | number | undefined,
|
||||
filter?: StringValueFilter
|
||||
): boolean {
|
||||
if (!value) {
|
||||
return true;
|
||||
} else if (typeof filter === 'function') {
|
||||
return filter(String(value));
|
||||
} else if (filter instanceof RegExp) {
|
||||
return filter.test(String(value));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user