wagtail/client/src/controllers/SlugController.ts

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;
}
}