kopia lustrzana https://github.com/wagtail/wagtail
107 wiersze
3.2 KiB
TypeScript
107 wiersze
3.2 KiB
TypeScript
import { Controller } from '@hotwired/stimulus';
|
|
import { slugify } from '../utils/slugify';
|
|
import { urlify } from '../utils/urlify';
|
|
|
|
type SlugMethods = 'slugify' | 'urlify';
|
|
|
|
/**
|
|
* Adds ability to slugify the value of an input element.
|
|
*
|
|
* @example
|
|
* <input type="text" name="slug" data-controller="w-slug" data-action="blur->w-slug#slugify" />
|
|
*/
|
|
export class SlugController extends Controller<HTMLInputElement> {
|
|
static values = {
|
|
allowUnicode: { default: false, type: Boolean },
|
|
};
|
|
|
|
declare allowUnicodeValue: boolean;
|
|
|
|
/**
|
|
* Allow for a comparison value to be provided so that a dispatched event can be
|
|
* prevented. This provides a way for other events to interact with this controller
|
|
* to block further updates if a value is not in sync.
|
|
* By default it will compare to the slugify method, this can be overridden by providing
|
|
* either a Stimulus param value on the element or the event's detail.
|
|
*/
|
|
compare(
|
|
event: CustomEvent<{ compareAs?: SlugMethods; value: string }> & {
|
|
params?: { compareAs?: SlugMethods };
|
|
},
|
|
) {
|
|
// do not attempt to compare if the current field is empty
|
|
if (!this.element.value) {
|
|
return true;
|
|
}
|
|
|
|
const compareAs =
|
|
event.detail?.compareAs || event.params?.compareAs || 'slugify';
|
|
|
|
const compareValue = this[compareAs](
|
|
{ detail: { value: event.detail?.value || '' } },
|
|
true,
|
|
);
|
|
|
|
const currentValue = this.element.value;
|
|
|
|
const valuesAreSame = compareValue.trim() === currentValue.trim();
|
|
|
|
if (!valuesAreSame) {
|
|
event?.preventDefault();
|
|
}
|
|
|
|
return valuesAreSame;
|
|
}
|
|
|
|
/**
|
|
* Basic slugify of a string, updates the controlled element's value
|
|
* or can be used to simply return the transformed value.
|
|
* If a custom event with detail.value is provided, that value will be used
|
|
* instead of the field's value.
|
|
*/
|
|
slugify(
|
|
event: CustomEvent<{ value: string }> | { detail: { value: string } },
|
|
ignoreUpdate = false,
|
|
) {
|
|
const allowUnicode = this.allowUnicodeValue;
|
|
const { value = this.element.value } = event?.detail || {};
|
|
const newValue = slugify(value.trim(), { allowUnicode });
|
|
|
|
if (!ignoreUpdate) {
|
|
this.element.value = newValue;
|
|
}
|
|
|
|
return newValue;
|
|
}
|
|
|
|
/**
|
|
* Advanced slugify of a string, updates the controlled element's value
|
|
* or can be used to simply return the transformed value.
|
|
*
|
|
* The urlify (Django port) function performs extra processing on the string &
|
|
* is more suitable for creating a slug from the title, rather than sanitising manually.
|
|
* If the urlify util returns an empty string it will fall back to the slugify method.
|
|
*
|
|
* If a custom event with detail.value is provided, that value will be used
|
|
* instead of the field's value.
|
|
*/
|
|
urlify(
|
|
event: CustomEvent<{ value: string }> | { detail: { value: string } },
|
|
ignoreUpdate = false,
|
|
) {
|
|
const allowUnicode = this.allowUnicodeValue;
|
|
const { value = this.element.value } = event?.detail || {};
|
|
const trimmedValue = value.trim();
|
|
|
|
const newValue =
|
|
urlify(trimmedValue, { allowUnicode }) ||
|
|
this.slugify({ detail: { value: trimmedValue } }, true);
|
|
|
|
if (!ignoreUpdate) {
|
|
this.element.value = newValue;
|
|
}
|
|
|
|
return newValue;
|
|
}
|
|
}
|