function validate_aria_attribute_value(attribute, name, schema, value) {
	const type = schema.type;

	if (value === null) return;
	if (value === true) value = '';

	if (type === 'boolean' && value !== 'true' && value !== 'false') {
		w.a11y_incorrect_aria_attribute_type_boolean(attribute, name);
	} else if (type === 'integer' && (value === '' || !Number.isInteger(+value))) {
		w.a11y_incorrect_aria_attribute_type_integer(attribute, name);
	} else if (type === 'number' && (value === '' || isNaN(+value))) {
		w.a11y_incorrect_aria_attribute_type(attribute, name, 'number');
	} else if ((type === 'string' || type === 'id') && value === '') {
		w.a11y_incorrect_aria_attribute_type(attribute, name, 'non-empty string');
	} else if (type === 'idlist' && value === '') {
		w.a11y_incorrect_aria_attribute_type_idlist(attribute, name);
	} else if (type === 'token') {
		const values = (schema.values ?? []).map((value) => value.toString());
		if (!values.includes(value.toLowerCase())) {
			w.a11y_incorrect_aria_attribute_type_token(
				attribute,
				name,
				list(values.map((v) => `"${v}"`))
			);
		}
	} else if (type === 'tokenlist') {
		const values = (schema.values ?? []).map((value) => value.toString());
		if (
			value
				.toLowerCase()
				.split(regex_whitespaces)
				.some((value) => !values.includes(value))
		) {
			w.a11y_incorrect_aria_attribute_type_tokenlist(
				attribute,
				name,
				list(values.map((v) => `"${v}"`))
			);
		}
	} else if (type === 'tristate' && value !== 'true' && value !== 'false' && value !== 'mixed') {
		w.a11y_incorrect_aria_attribute_type_tristate(attribute, name);
	}
}
@param {AST.Attribute} attribute
@param {ARIAProperty} name
@param {ARIAPropertyDefinition} schema
@param {string | true | null} value