Add styling for invalid form field values (#1870)

* Add styling for invalid form field values

* Apply to all multiple email address fields. Use pattern attr to do better validation

* Simplify and correct the email address regex
This commit is contained in:
Daniel LaLiberte 2022-05-17 15:01:03 -04:00 коммит произвёл GitHub
Родитель 1a758c9b98
Коммит e5f1b48d31
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 35 добавлений и 17 удалений

Просмотреть файл

@ -55,6 +55,21 @@ SUMMARY_PLACEHOLDER_TXT = (
'Write it from a web developer\'s point of view.\n\n'
'Follow the example link below for more guidance.')
# Patterns from https://www.oreilly.com/library/view/regular-expressions-cookbook/9781449327453/ch04s01.html
# Removing single quote ('), backtick (`), and pipe (|) since they are risky unless properly escaped everywhere.
# Also removing ! and % because they have special meaning for some older email routing systems.
USER_REGEX = '[A-Za-z0-9_#$&*+/=?{}~^.-]+'
DOMAIN_REGEX = '(([A-Za-z0-9-]+\.)+[A-Za-z]{2,6})'
EMAIL_ADDRESS_REGEX = USER_REGEX + '@' + DOMAIN_REGEX
EMAIL_ADDRESSES_REGEX = EMAIL_ADDRESS_REGEX + '([ ]*,[ ]*' + EMAIL_ADDRESS_REGEX + ')*'
MULTI_EMAIL_FIELD_ATTRS = {
'title':"Enter one or more comma-separated complete email addresses.",
'multiple': True,
'placeholder': 'user1@domain.com, user2@chromium.org',
'pattern': EMAIL_ADDRESSES_REGEX
}
# We define all form fields here so that they can be include in one or more
# stage-specific fields without repeating the details and help text.
@ -88,8 +103,7 @@ ALL_FIELDS = {
'owner': MultiEmailField(
required=True, label='Feature owners',
widget=forms.EmailInput(
attrs={'multiple': True, 'placeholder': 'email,email'}),
widget=forms.EmailInput(attrs=MULTI_EMAIL_FIELD_ATTRS),
help_text=('Comma separated list of full email addresses. '
'Prefer @chromium.org.')),
@ -188,10 +202,9 @@ ALL_FIELDS = {
help_text=('The spec document has details in a specification language '
'such as Web IDL, or there is an exsting MDN page.')),
'spec_mentors': forms.EmailField(
'spec_mentors': MultiEmailField(
required=False, label='Spec mentor',
widget=forms.EmailInput(
attrs={'multiple': True, 'placeholder': 'email'}),
widget=forms.EmailInput(attrs=MULTI_EMAIL_FIELD_ATTRS),
help_text=
('Experienced <a target="_blank" '
'href="https://www.chromium.org/blink/spec-mentors">'
@ -521,25 +534,22 @@ ALL_FIELDS = {
'<a href="go/finch" targe="_blank">Finch experiment</a>, '
'link to it here.')),
'i2e_lgtms': forms.EmailField(
'i2e_lgtms': MultiEmailField(
required=False, label='Intent to Experiment LGTM by',
widget=forms.EmailInput(
attrs={'multiple': True, 'placeholder': 'email'}),
widget=forms.EmailInput(attrs=MULTI_EMAIL_FIELD_ATTRS),
help_text=('Full email address of API owner who LGTM\'d the '
'Intent to Experiment email thread.')),
'i2s_lgtms': forms.EmailField(
'i2s_lgtms': MultiEmailField(
required=False, label='Intent to Ship LGTMs by',
widget=forms.EmailInput(
attrs={'multiple': True, 'placeholder': 'email, email, email'}),
widget=forms.EmailInput(attrs=MULTI_EMAIL_FIELD_ATTRS),
help_text=('Comma separated list of '
'full email addresses of API owners who LGTM\'d '
'the Intent to Ship email thread.')),
'r4dt_lgtms': forms.EmailField( # Sets i2e_lgtms field.
'r4dt_lgtms': MultiEmailField( # Sets i2e_lgtms field.
required=False, label='Request for Deprecation Trial LGTM by',
widget=forms.EmailInput(
attrs={'multiple': True, 'placeholder': 'email'}),
widget=forms.EmailInput(attrs=MULTI_EMAIL_FIELD_ATTRS),
help_text=('Full email addresses of API owners who LGTM\'d '
'the Request for Deprecation Trial email thread.')),
@ -640,10 +650,9 @@ ALL_FIELDS = {
choices=[(x, x) for x in models.BlinkComponent.fetch_all_components()],
initial=[models.BlinkComponent.DEFAULT_COMPONENT]),
'devrel': forms.EmailField(
'devrel': MultiEmailField(
required=False, label='Developer relations emails',
widget=forms.EmailInput(
attrs={'multiple': True, 'placeholder': 'email, email'}),
widget=forms.EmailInput(attrs=MULTI_EMAIL_FIELD_ATTRS),
help_text='Comma separated list of full email addresses.'),
'impl_status_chrome': forms.ChoiceField(

Просмотреть файл

@ -16,6 +16,7 @@ export const VARS = css`
--bar-shadow-color: rgba(0, 0, 0, .065);
--bar-border-color: #D4D4D4;
--error-border-color: #FF0000;
--chromium-color-dark: #366597;
--chromium-color-medium: #85b4df;

Просмотреть файл

@ -12,6 +12,7 @@ $nav-link-color: #444;
$bar-shadow-color: rgba(0, 0, 0, .065);
$bar-border-color: #D4D4D4;
$error-border-color: #FF0000;
$chromium-color-dark: #366597;
$chromium-color-medium: #85b4df;

Просмотреть файл

@ -56,6 +56,11 @@ table {
border: 1px solid $invalid-color;
}
input:not([type="submit"]):not([type="search"]):invalid:not(:focus) {
outline: 1px dotted var(--error-border-color);
background-color: #FFEDF5;
}
.errorlist {
color: red;
}

Просмотреть файл

@ -59,6 +59,7 @@ export const SHARED_STYLES = [
textarea {
border: 1px solid var(--bar-border-color);
}
input:not([type="submit"])[disabled],
textarea[disabled],
button[disabled] {

Просмотреть файл

@ -45,6 +45,7 @@ a:hover {
input:not([type="submit"]), textarea {
border: 1px solid $bar-border-color;
}
input:not([type="submit"])[disabled], textarea[disabled], button[disabled] {
opacity: 0.5;
}