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:
Родитель
1a758c9b98
Коммит
e5f1b48d31
|
@ -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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче