Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Léo-Paul Géneau
gitlab-ce
Commits
44d3745e
Commit
44d3745e
authored
Oct 10, 2017
by
Phil Hughes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Moves form related JS modules out of global
parent
a30417e5
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
201 additions
and
210 deletions
+201
-210
app/assets/javascripts/dispatcher.js
app/assets/javascripts/dispatcher.js
+11
-9
app/assets/javascripts/gl_field_error.js
app/assets/javascripts/gl_field_error.js
+1
-4
app/assets/javascripts/gl_field_errors.js
app/assets/javascripts/gl_field_errors.js
+13
-17
app/assets/javascripts/gl_form.js
app/assets/javascripts/gl_form.js
+80
-85
app/assets/javascripts/notes.js
app/assets/javascripts/notes.js
+3
-2
app/assets/javascripts/pipeline_schedules/pipeline_schedule_form_bundle.js
...ripts/pipeline_schedules/pipeline_schedule_form_bundle.js
+2
-1
app/assets/javascripts/vue_shared/components/markdown/field.vue
...sets/javascripts/vue_shared/components/markdown/field.vue
+2
-1
spec/javascripts/gl_field_errors_spec.js
spec/javascripts/gl_field_errors_spec.js
+89
-91
No files found.
app/assets/javascripts/dispatcher.js
View file @
44d3745e
...
@@ -79,6 +79,8 @@ import initChangesDropdown from './init_changes_dropdown';
...
@@ -79,6 +79,8 @@ import initChangesDropdown from './init_changes_dropdown';
import
AbuseReports
from
'
./abuse_reports
'
;
import
AbuseReports
from
'
./abuse_reports
'
;
import
{
ajaxGet
,
convertPermissionToBoolean
}
from
'
./lib/utils/common_utils
'
;
import
{
ajaxGet
,
convertPermissionToBoolean
}
from
'
./lib/utils/common_utils
'
;
import
AjaxLoadingSpinner
from
'
./ajax_loading_spinner
'
;
import
AjaxLoadingSpinner
from
'
./ajax_loading_spinner
'
;
import
GlFieldErrors
from
'
./gl_field_errors
'
;
import
GLForm
from
'
./gl_form
'
;
import
U2FAuthenticate
from
'
./u2f/authenticate
'
;
import
U2FAuthenticate
from
'
./u2f/authenticate
'
;
(
function
()
{
(
function
()
{
...
@@ -230,7 +232,7 @@ import U2FAuthenticate from './u2f/authenticate';
...
@@ -230,7 +232,7 @@ import U2FAuthenticate from './u2f/authenticate';
case
'
groups:milestones:update
'
:
case
'
groups:milestones:update
'
:
new
ZenMode
();
new
ZenMode
();
new
gl
.
DueDateSelectors
();
new
gl
.
DueDateSelectors
();
new
gl
.
GLForm
(
$
(
'
.milestone-form
'
),
true
);
new
GLForm
(
$
(
'
.milestone-form
'
),
true
);
break
;
break
;
case
'
projects:compare:show
'
:
case
'
projects:compare:show
'
:
new
gl
.
Diff
();
new
gl
.
Diff
();
...
@@ -247,7 +249,7 @@ import U2FAuthenticate from './u2f/authenticate';
...
@@ -247,7 +249,7 @@ import U2FAuthenticate from './u2f/authenticate';
case
'
projects:issues:new
'
:
case
'
projects:issues:new
'
:
case
'
projects:issues:edit
'
:
case
'
projects:issues:edit
'
:
shortcut_handler
=
new
ShortcutsNavigation
();
shortcut_handler
=
new
ShortcutsNavigation
();
new
gl
.
GLForm
(
$
(
'
.issue-form
'
),
true
);
new
GLForm
(
$
(
'
.issue-form
'
),
true
);
new
IssuableForm
(
$
(
'
.issue-form
'
));
new
IssuableForm
(
$
(
'
.issue-form
'
));
new
LabelsSelect
();
new
LabelsSelect
();
new
MilestoneSelect
();
new
MilestoneSelect
();
...
@@ -271,7 +273,7 @@ import U2FAuthenticate from './u2f/authenticate';
...
@@ -271,7 +273,7 @@ import U2FAuthenticate from './u2f/authenticate';
case
'
projects:merge_requests:edit
'
:
case
'
projects:merge_requests:edit
'
:
new
gl
.
Diff
();
new
gl
.
Diff
();
shortcut_handler
=
new
ShortcutsNavigation
();
shortcut_handler
=
new
ShortcutsNavigation
();
new
gl
.
GLForm
(
$
(
'
.merge-request-form
'
),
true
);
new
GLForm
(
$
(
'
.merge-request-form
'
),
true
);
new
IssuableForm
(
$
(
'
.merge-request-form
'
));
new
IssuableForm
(
$
(
'
.merge-request-form
'
));
new
LabelsSelect
();
new
LabelsSelect
();
new
MilestoneSelect
();
new
MilestoneSelect
();
...
@@ -280,7 +282,7 @@ import U2FAuthenticate from './u2f/authenticate';
...
@@ -280,7 +282,7 @@ import U2FAuthenticate from './u2f/authenticate';
break
;
break
;
case
'
projects:tags:new
'
:
case
'
projects:tags:new
'
:
new
ZenMode
();
new
ZenMode
();
new
gl
.
GLForm
(
$
(
'
.tag-form
'
),
true
);
new
GLForm
(
$
(
'
.tag-form
'
),
true
);
new
RefSelectDropdown
(
$
(
'
.js-branch-select
'
));
new
RefSelectDropdown
(
$
(
'
.js-branch-select
'
));
break
;
break
;
case
'
projects:snippets:show
'
:
case
'
projects:snippets:show
'
:
...
@@ -290,17 +292,17 @@ import U2FAuthenticate from './u2f/authenticate';
...
@@ -290,17 +292,17 @@ import U2FAuthenticate from './u2f/authenticate';
case
'
projects:snippets:edit
'
:
case
'
projects:snippets:edit
'
:
case
'
projects:snippets:create
'
:
case
'
projects:snippets:create
'
:
case
'
projects:snippets:update
'
:
case
'
projects:snippets:update
'
:
new
gl
.
GLForm
(
$
(
'
.snippet-form
'
),
true
);
new
GLForm
(
$
(
'
.snippet-form
'
),
true
);
break
;
break
;
case
'
snippets:new
'
:
case
'
snippets:new
'
:
case
'
snippets:edit
'
:
case
'
snippets:edit
'
:
case
'
snippets:create
'
:
case
'
snippets:create
'
:
case
'
snippets:update
'
:
case
'
snippets:update
'
:
new
gl
.
GLForm
(
$
(
'
.snippet-form
'
),
false
);
new
GLForm
(
$
(
'
.snippet-form
'
),
false
);
break
;
break
;
case
'
projects:releases:edit
'
:
case
'
projects:releases:edit
'
:
new
ZenMode
();
new
ZenMode
();
new
gl
.
GLForm
(
$
(
'
.release-form
'
),
true
);
new
GLForm
(
$
(
'
.release-form
'
),
true
);
break
;
break
;
case
'
projects:merge_requests:show
'
:
case
'
projects:merge_requests:show
'
:
new
gl
.
Diff
();
new
gl
.
Diff
();
...
@@ -606,7 +608,7 @@ import U2FAuthenticate from './u2f/authenticate';
...
@@ -606,7 +608,7 @@ import U2FAuthenticate from './u2f/authenticate';
new
Wikis
();
new
Wikis
();
shortcut_handler
=
new
ShortcutsWiki
();
shortcut_handler
=
new
ShortcutsWiki
();
new
ZenMode
();
new
ZenMode
();
new
gl
.
GLForm
(
$
(
'
.wiki-form
'
),
true
);
new
GLForm
(
$
(
'
.wiki-form
'
),
true
);
break
;
break
;
case
'
snippets
'
:
case
'
snippets
'
:
shortcut_handler
=
new
ShortcutsNavigation
();
shortcut_handler
=
new
ShortcutsNavigation
();
...
@@ -657,7 +659,7 @@ import U2FAuthenticate from './u2f/authenticate';
...
@@ -657,7 +659,7 @@ import U2FAuthenticate from './u2f/authenticate';
Dispatcher
.
prototype
.
initFieldErrors
=
function
()
{
Dispatcher
.
prototype
.
initFieldErrors
=
function
()
{
$
(
'
.gl-show-field-errors
'
).
each
((
i
,
form
)
=>
{
$
(
'
.gl-show-field-errors
'
).
each
((
i
,
form
)
=>
{
new
gl
.
GlFieldErrors
(
form
);
new
GlFieldErrors
(
form
);
});
});
};
};
...
...
app/assets/javascripts/gl_field_error.js
View file @
44d3745e
...
@@ -54,7 +54,7 @@ const inputErrorClass = 'gl-field-error-outline';
...
@@ -54,7 +54,7 @@ const inputErrorClass = 'gl-field-error-outline';
const
errorAnchorSelector
=
'
.gl-field-error-anchor
'
;
const
errorAnchorSelector
=
'
.gl-field-error-anchor
'
;
const
ignoreInputSelector
=
'
.gl-field-error-ignore
'
;
const
ignoreInputSelector
=
'
.gl-field-error-ignore
'
;
class
GlFieldError
{
export
default
class
GlFieldError
{
constructor
({
input
,
formErrors
})
{
constructor
({
input
,
formErrors
})
{
this
.
inputElement
=
$
(
input
);
this
.
inputElement
=
$
(
input
);
this
.
inputDomElement
=
this
.
inputElement
.
get
(
0
);
this
.
inputDomElement
=
this
.
inputElement
.
get
(
0
);
...
@@ -159,6 +159,3 @@ class GlFieldError {
...
@@ -159,6 +159,3 @@ class GlFieldError {
this
.
fieldErrorElement
.
hide
();
this
.
fieldErrorElement
.
hide
();
}
}
}
}
window
.
gl
=
window
.
gl
||
{};
window
.
gl
.
GlFieldError
=
GlFieldError
;
app/assets/javascripts/gl_field_errors.js
View file @
44d3745e
/* eslint-disable comma-dangle, class-methods-use-this, max-len, space-before-function-paren, arrow-parens, no-param-reassign */
import
GlFieldError
from
'
./gl_field_error
'
;
import
'
./gl_field_error
'
;
const
customValidationFlag
=
'
gl-field-error-ignore
'
;
const
customValidationFlag
=
'
gl-field-error-ignore
'
;
class
GlFieldErrors
{
export
default
class
GlFieldErrors
{
constructor
(
form
)
{
constructor
(
form
)
{
this
.
form
=
$
(
form
);
this
.
form
=
$
(
form
);
this
.
state
=
{
this
.
state
=
{
inputs
:
[],
inputs
:
[],
valid
:
false
valid
:
false
,
};
};
this
.
initValidators
();
this
.
initValidators
();
}
}
initValidators
()
{
initValidators
()
{
// register selectors here as needed
// register selectors here as needed
const
validateSelectors
=
[
'
:text
'
,
'
:password
'
,
'
[type=email]
'
]
const
validateSelectors
=
[
'
:text
'
,
'
:password
'
,
'
[type=email]
'
]
.
map
(
(
selector
)
=>
`input
${
selector
}
`
).
join
(
'
,
'
);
.
map
(
selector
=>
`input
${
selector
}
`
).
join
(
'
,
'
);
this
.
state
.
inputs
=
this
.
form
.
find
(
validateSelectors
).
toArray
()
this
.
state
.
inputs
=
this
.
form
.
find
(
validateSelectors
).
toArray
()
.
filter
(
(
input
)
=>
!
input
.
classList
.
contains
(
customValidationFlag
))
.
filter
(
input
=>
!
input
.
classList
.
contains
(
customValidationFlag
))
.
map
(
(
input
)
=>
new
window
.
gl
.
GlFieldError
({
input
,
formErrors
:
this
}));
.
map
(
input
=>
new
GlFieldError
({
input
,
formErrors
:
this
}));
this
.
form
.
on
(
'
submit
'
,
thi
s
.
catchInvalidFormSubmit
);
this
.
form
.
on
(
'
submit
'
,
GlFieldError
s
.
catchInvalidFormSubmit
);
}
}
/* Neccessary to prevent intercept and override invalid form submit
/* Neccessary to prevent intercept and override invalid form submit
* because Safari & iOS quietly allow form submission when form is invalid
* because Safari & iOS quietly allow form submission when form is invalid
* and prevents disabling of invalid submit button by application.js */
* and prevents disabling of invalid submit button by application.js */
catchInvalidFormSubmit
(
event
)
{
static
catchInvalidFormSubmit
(
e
)
{
const
$form
=
$
(
e
vent
.
currentTarget
);
const
$form
=
$
(
e
.
currentTarget
);
if
(
!
$form
.
attr
(
'
novalidate
'
))
{
if
(
!
$form
.
attr
(
'
novalidate
'
))
{
if
(
!
event
.
currentTarget
.
checkValidity
())
{
if
(
!
event
.
currentTarget
.
checkValidity
())
{
...
@@ -50,11 +48,9 @@ class GlFieldErrors {
...
@@ -50,11 +48,9 @@ class GlFieldErrors {
});
});
}
}
focusOnFirstInvalid
()
{
focusOnFirstInvalid
()
{
const
firstInvalid
=
this
.
state
.
inputs
.
filter
((
input
)
=>
!
input
.
inputDomElement
.
validity
.
valid
)[
0
];
const
firstInvalid
=
this
.
state
.
inputs
.
filter
(
input
=>
!
input
.
inputDomElement
.
validity
.
valid
)[
0
];
firstInvalid
.
inputElement
.
focus
();
firstInvalid
.
inputElement
.
focus
();
}
}
}
}
window
.
gl
=
window
.
gl
||
{};
window
.
gl
.
GlFieldErrors
=
GlFieldErrors
;
app/assets/javascripts/gl_form.js
View file @
44d3745e
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-new, max-len */
/* global GitLab */
/* global DropzoneInput */
/* global DropzoneInput */
/* global autosize */
/* global autosize */
import
GfmAutoComplete
from
'
./gfm_auto_complete
'
;
import
GfmAutoComplete
from
'
./gfm_auto_complete
'
;
window
.
gl
=
window
.
gl
||
{};
export
default
class
GLForm
{
constructor
(
form
,
enableGFM
=
false
)
{
function
GLForm
(
form
,
enableGFM
=
false
)
{
this
.
form
=
form
;
this
.
form
=
form
;
this
.
textarea
=
this
.
form
.
find
(
'
textarea.js-gfm-input
'
);
this
.
textarea
=
this
.
form
.
find
(
'
textarea.js-gfm-input
'
);
this
.
enableGFM
=
enableGFM
;
this
.
enableGFM
=
enableGFM
;
// Before we start, we should clean up any previous data for this form
// Before we start, we should clean up any previous data for this form
this
.
destroy
();
this
.
destroy
();
// Setup the form
// Setup the form
this
.
setupForm
();
this
.
setupForm
();
this
.
form
.
data
(
'
gl-form
'
,
this
);
this
.
form
.
data
(
'
gl-form
'
,
this
);
}
GLForm
.
prototype
.
destroy
=
function
()
{
// Clean form listeners
this
.
clearEventListeners
();
if
(
this
.
autoComplete
)
{
this
.
autoComplete
.
destroy
();
}
}
return
this
.
form
.
data
(
'
gl-form
'
,
null
);
};
GLForm
.
prototype
.
setupForm
=
function
()
{
destroy
()
{
var
isNewForm
;
// Clean form listeners
isNewForm
=
this
.
form
.
is
(
'
:not(.gfm-form)
'
);
this
.
clearEventListeners
();
this
.
form
.
removeClass
(
'
js-new-note-form
'
);
if
(
this
.
autoComplete
)
{
if
(
isNewForm
)
{
this
.
autoComplete
.
destroy
();
this
.
form
.
find
(
'
.div-dropzone
'
).
remove
();
}
this
.
form
.
addClass
(
'
gfm-form
'
);
this
.
form
.
data
(
'
gl-form
'
,
null
);
// remove notify commit author checkbox for non-commit notes
gl
.
utils
.
disableButtonIfEmptyField
(
this
.
form
.
find
(
'
.js-note-text
'
),
this
.
form
.
find
(
'
.js-comment-button, .js-note-new-discussion
'
));
this
.
autoComplete
=
new
GfmAutoComplete
(
gl
.
GfmAutoComplete
&&
gl
.
GfmAutoComplete
.
dataSources
);
this
.
autoComplete
.
setup
(
this
.
form
.
find
(
'
.js-gfm-input
'
),
{
emojis
:
true
,
members
:
this
.
enableGFM
,
issues
:
this
.
enableGFM
,
milestones
:
this
.
enableGFM
,
mergeRequests
:
this
.
enableGFM
,
labels
:
this
.
enableGFM
,
});
new
DropzoneInput
(
this
.
form
);
autosize
(
this
.
textarea
);
}
}
// form and textarea event listeners
this
.
addEventListeners
();
gl
.
text
.
init
(
this
.
form
);
// hide discard button
this
.
form
.
find
(
'
.js-note-discard
'
).
hide
();
this
.
form
.
show
();
if
(
this
.
isAutosizeable
)
this
.
setupAutosize
();
};
GLForm
.
prototype
.
setupAutosize
=
function
()
{
setupForm
()
{
this
.
textarea
.
off
(
'
autosize:resized
'
)
const
isNewForm
=
this
.
form
.
is
(
'
:not(.gfm-form)
'
);
.
on
(
'
autosize:resized
'
,
this
.
setHeightData
.
bind
(
this
));
this
.
form
.
removeClass
(
'
js-new-note-form
'
);
if
(
isNewForm
)
{
this
.
form
.
find
(
'
.div-dropzone
'
).
remove
();
this
.
form
.
addClass
(
'
gfm-form
'
);
// remove notify commit author checkbox for non-commit notes
gl
.
utils
.
disableButtonIfEmptyField
(
this
.
form
.
find
(
'
.js-note-text
'
),
this
.
form
.
find
(
'
.js-comment-button, .js-note-new-discussion
'
));
this
.
autoComplete
=
new
GfmAutoComplete
(
gl
.
GfmAutoComplete
&&
gl
.
GfmAutoComplete
.
dataSources
);
this
.
autoComplete
.
setup
(
this
.
form
.
find
(
'
.js-gfm-input
'
),
{
emojis
:
true
,
members
:
this
.
enableGFM
,
issues
:
this
.
enableGFM
,
milestones
:
this
.
enableGFM
,
mergeRequests
:
this
.
enableGFM
,
labels
:
this
.
enableGFM
,
});
new
DropzoneInput
(
this
.
form
);
// eslint-disable-line no-new
autosize
(
this
.
textarea
);
}
// form and textarea event listeners
this
.
addEventListeners
();
gl
.
text
.
init
(
this
.
form
);
// hide discard button
this
.
form
.
find
(
'
.js-note-discard
'
).
hide
();
this
.
form
.
show
();
if
(
this
.
isAutosizeable
)
this
.
setupAutosize
();
}
this
.
textarea
.
off
(
'
mouseup.autosize
'
)
setupAutosize
()
{
.
on
(
'
mouseup.autosize
'
,
this
.
destroyAutosize
.
bind
(
this
));
this
.
textarea
.
off
(
'
autosize:resized
'
)
.
on
(
'
autosize:resized
'
,
this
.
setHeightData
.
bind
(
this
));
setTimeout
(()
=>
{
this
.
textarea
.
off
(
'
mouseup.autosize
'
)
autosize
(
this
.
textarea
);
.
on
(
'
mouseup.autosize
'
,
this
.
destroyAutosize
.
bind
(
this
));
this
.
textarea
.
css
(
'
resize
'
,
'
vertical
'
);
},
0
);
};
GLForm
.
prototype
.
setHeightData
=
function
()
{
setTimeout
(()
=>
{
this
.
textarea
.
data
(
'
height
'
,
this
.
textarea
.
outerHeight
());
autosize
(
this
.
textarea
);
};
this
.
textarea
.
css
(
'
resize
'
,
'
vertical
'
);
},
0
);
}
GLForm
.
prototype
.
destroyAutosize
=
function
()
{
setHeightData
()
{
const
outerHeight
=
this
.
textarea
.
outerHeight
();
this
.
textarea
.
data
(
'
height
'
,
this
.
textarea
.
outerHeight
());
}
if
(
this
.
textarea
.
data
(
'
height
'
)
===
outerHeight
)
return
;
destroyAutosize
()
{
const
outerHeight
=
this
.
textarea
.
outerHeight
();
autosize
.
destroy
(
this
.
textarea
)
;
if
(
this
.
textarea
.
data
(
'
height
'
)
===
outerHeight
)
return
;
this
.
textarea
.
data
(
'
height
'
,
outerHeight
);
autosize
.
destroy
(
this
.
textarea
);
this
.
textarea
.
outerHeight
(
outerHeight
);
this
.
textarea
.
css
(
'
max-height
'
,
window
.
outerHeight
);
};
GLForm
.
prototype
.
clearEventListeners
=
function
()
{
this
.
textarea
.
data
(
'
height
'
,
outerHeight
);
this
.
textarea
.
off
(
'
focus
'
);
this
.
textarea
.
outerHeight
(
outerHeight
);
this
.
textarea
.
off
(
'
blur
'
);
this
.
textarea
.
css
(
'
max-height
'
,
window
.
outerHeight
);
return
gl
.
text
.
removeListeners
(
this
.
form
);
}
};
GLForm
.
prototype
.
addEventListeners
=
function
()
{
clearEventListeners
()
{
this
.
textarea
.
on
(
'
focus
'
,
function
()
{
this
.
textarea
.
off
(
'
focus
'
);
return
$
(
this
).
closest
(
'
.md-area
'
).
addClass
(
'
is-focused
'
);
this
.
textarea
.
off
(
'
blur
'
);
});
gl
.
text
.
removeListeners
(
this
.
form
);
return
this
.
textarea
.
on
(
'
blur
'
,
function
()
{
}
return
$
(
this
).
closest
(
'
.md-area
'
).
removeClass
(
'
is-focused
'
);
});
};
window
.
gl
.
GLForm
=
GLForm
;
addEventListeners
()
{
this
.
textarea
.
on
(
'
focus
'
,
function
focusTextArea
()
{
$
(
this
).
closest
(
'
.md-area
'
).
addClass
(
'
is-focused
'
);
});
this
.
textarea
.
on
(
'
blur
'
,
function
blurTextArea
()
{
$
(
this
).
closest
(
'
.md-area
'
).
removeClass
(
'
is-focused
'
);
});
}
}
app/assets/javascripts/notes.js
View file @
44d3745e
...
@@ -19,6 +19,7 @@ import 'vendor/jquery.atwho';
...
@@ -19,6 +19,7 @@ import 'vendor/jquery.atwho';
import
AjaxCache
from
'
~/lib/utils/ajax_cache
'
;
import
AjaxCache
from
'
~/lib/utils/ajax_cache
'
;
import
Flash
from
'
./flash
'
;
import
Flash
from
'
./flash
'
;
import
CommentTypeToggle
from
'
./comment_type_toggle
'
;
import
CommentTypeToggle
from
'
./comment_type_toggle
'
;
import
GLForm
from
'
./gl_form
'
;
import
loadAwardsHandler
from
'
./awards_handler
'
;
import
loadAwardsHandler
from
'
./awards_handler
'
;
import
'
./autosave
'
;
import
'
./autosave
'
;
import
'
./dropzone_input
'
;
import
'
./dropzone_input
'
;
...
@@ -557,7 +558,7 @@ export default class Notes {
...
@@ -557,7 +558,7 @@ export default class Notes {
*/
*/
setupNoteForm
(
form
)
{
setupNoteForm
(
form
)
{
var
textarea
,
key
;
var
textarea
,
key
;
new
gl
.
GLForm
(
form
,
this
.
enableGFM
);
new
GLForm
(
form
,
this
.
enableGFM
);
textarea
=
form
.
find
(
'
.js-note-text
'
);
textarea
=
form
.
find
(
'
.js-note-text
'
);
key
=
[
key
=
[
'
Note
'
,
'
Note
'
,
...
@@ -1152,7 +1153,7 @@ export default class Notes {
...
@@ -1152,7 +1153,7 @@ export default class Notes {
var
targetId
=
$originalContentEl
.
data
(
'
target-id
'
);
var
targetId
=
$originalContentEl
.
data
(
'
target-id
'
);
var
targetType
=
$originalContentEl
.
data
(
'
target-type
'
);
var
targetType
=
$originalContentEl
.
data
(
'
target-type
'
);
new
gl
.
GLForm
(
$editForm
.
find
(
'
form
'
),
this
.
enableGFM
);
new
GLForm
(
$editForm
.
find
(
'
form
'
),
this
.
enableGFM
);
$editForm
.
find
(
'
form
'
)
$editForm
.
find
(
'
form
'
)
.
attr
(
'
action
'
,
postUrl
)
.
attr
(
'
action
'
,
postUrl
)
...
...
app/assets/javascripts/pipeline_schedules/pipeline_schedule_form_bundle.js
View file @
44d3745e
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
Translate
from
'
../vue_shared/translate
'
;
import
Translate
from
'
../vue_shared/translate
'
;
import
GlFieldErrors
from
'
../gl_field_errors
'
;
import
intervalPatternInput
from
'
./components/interval_pattern_input.vue
'
;
import
intervalPatternInput
from
'
./components/interval_pattern_input.vue
'
;
import
TimezoneDropdown
from
'
./components/timezone_dropdown
'
;
import
TimezoneDropdown
from
'
./components/timezone_dropdown
'
;
import
TargetBranchDropdown
from
'
./components/target_branch_dropdown
'
;
import
TargetBranchDropdown
from
'
./components/target_branch_dropdown
'
;
...
@@ -39,7 +40,7 @@ document.addEventListener('DOMContentLoaded', () => {
...
@@ -39,7 +40,7 @@ document.addEventListener('DOMContentLoaded', () => {
gl
.
timezoneDropdown
=
new
TimezoneDropdown
();
gl
.
timezoneDropdown
=
new
TimezoneDropdown
();
gl
.
targetBranchDropdown
=
new
TargetBranchDropdown
();
gl
.
targetBranchDropdown
=
new
TargetBranchDropdown
();
gl
.
pipelineScheduleFieldErrors
=
new
gl
.
GlFieldErrors
(
formElement
);
gl
.
pipelineScheduleFieldErrors
=
new
GlFieldErrors
(
formElement
);
setupPipelineVariableList
(
$
(
'
.js-pipeline-variable-list
'
));
setupPipelineVariableList
(
$
(
'
.js-pipeline-variable-list
'
));
});
});
app/assets/javascripts/vue_shared/components/markdown/field.vue
View file @
44d3745e
<
script
>
<
script
>
import
Flash
from
'
../../../flash
'
;
import
Flash
from
'
../../../flash
'
;
import
GLForm
from
'
../../../gl_form
'
;
import
markdownHeader
from
'
./header.vue
'
;
import
markdownHeader
from
'
./header.vue
'
;
import
markdownToolbar
from
'
./toolbar.vue
'
;
import
markdownToolbar
from
'
./toolbar.vue
'
;
...
@@ -85,7 +86,7 @@
...
@@ -85,7 +86,7 @@
/*
/*
GLForm class handles all the toolbar buttons
GLForm class handles all the toolbar buttons
*/
*/
return
new
gl
.
GLForm
(
$
(
this
.
$refs
[
'
gl-form
'
]),
true
);
return
new
GLForm
(
$
(
this
.
$refs
[
'
gl-form
'
]),
true
);
},
},
beforeDestroy
()
{
beforeDestroy
()
{
const
glForm
=
$
(
this
.
$refs
[
'
gl-form
'
]).
data
(
'
gl-form
'
);
const
glForm
=
$
(
this
.
$refs
[
'
gl-form
'
]).
data
(
'
gl-form
'
);
...
...
spec/javascripts/gl_field_errors_spec.js
View file @
44d3745e
/* eslint-disable space-before-function-paren, arrow-body-style */
/* eslint-disable space-before-function-paren, arrow-body-style */
import
'
~/gl_field_errors
'
;
import
GlFieldErrors
from
'
~/gl_field_errors
'
;
((
global
)
=>
{
describe
(
'
GL Style Field Errors
'
,
function
()
{
preloadFixtures
(
'
static/gl_field_errors.html.raw
'
);
preloadFixtures
(
'
static/gl_field_errors.html.raw
'
);
describe
(
'
GL Style Field Errors
'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
loadFixtures
(
'
static/gl_field_errors.html.raw
'
);
loadFixtures
(
'
static/gl_field_errors.html.raw
'
);
const
$form
=
this
.
$form
=
$
(
'
form.gl-show-field-errors
'
);
const
$form
=
this
.
$form
=
$
(
'
form.gl-show-field-errors
'
);
this
.
fieldErrors
=
new
GlFieldErrors
(
$form
);
this
.
fieldErrors
=
new
global
.
GlFieldErrors
(
$form
);
});
});
it
(
'
should select the correct input elements
'
,
function
()
{
it
(
'
should select the correct input elements
'
,
function
()
{
expect
(
this
.
$form
).
toBeDefined
();
expect
(
this
.
$form
).
toBeDefined
();
expect
(
this
.
$form
.
length
).
toBe
(
1
);
expect
(
this
.
$form
.
length
).
toBe
(
1
);
expect
(
this
.
fieldErrors
).
toBeDefined
();
expect
(
this
.
fieldErrors
).
toBeDefined
();
const
inputs
=
this
.
fieldErrors
.
state
.
inputs
;
const
inputs
=
this
.
fieldErrors
.
state
.
inputs
;
expect
(
inputs
.
length
).
toBe
(
4
);
expect
(
inputs
.
length
).
toBe
(
4
);
});
});
it
(
'
should ignore elements with custom error handling
'
,
function
()
{
it
(
'
should ignore elements with custom error handling
'
,
function
()
{
const
customErrorFlag
=
'
gl-field-error-ignore
'
;
const
customErrorFlag
=
'
gl-field-error-ignore
'
;
const
customErrorElem
=
$
(
`.
${
customErrorFlag
}
`
);
const
customErrorElem
=
$
(
`.
${
customErrorFlag
}
`
);
expect
(
customErrorElem
.
length
).
toBe
(
1
);
expect
(
customErrorElem
.
length
).
toBe
(
1
);
const
customErrors
=
this
.
fieldErrors
.
state
.
inputs
.
filter
((
input
)
=>
{
const
customErrors
=
this
.
fieldErrors
.
state
.
inputs
.
filter
((
input
)
=>
{
return
input
.
inputElement
.
hasClass
(
customErrorFlag
);
return
input
.
inputElement
.
hasClass
(
customErrorFlag
);
});
expect
(
customErrors
.
length
).
toBe
(
0
);
});
});
expect
(
customErrors
.
length
).
toBe
(
0
);
});
it
(
'
should not show any errors before submit attempt
'
,
function
()
{
it
(
'
should not show any errors before submit attempt
'
,
function
()
{
this
.
$form
.
find
(
'
.email
'
).
val
(
'
not-a-valid-email
'
).
keyup
();
this
.
$form
.
find
(
'
.email
'
).
val
(
'
not-a-valid-email
'
).
keyup
();
this
.
$form
.
find
(
'
.text-required
'
).
val
(
''
).
keyup
();
this
.
$form
.
find
(
'
.text-required
'
).
val
(
''
).
keyup
();
this
.
$form
.
find
(
'
.alphanumberic
'
).
val
(
'
?---*
'
).
keyup
();
this
.
$form
.
find
(
'
.alphanumberic
'
).
val
(
'
?---*
'
).
keyup
();
const
errorsShown
=
this
.
$form
.
find
(
'
.gl-field-error-outline
'
);
const
errorsShown
=
this
.
$form
.
find
(
'
.gl-field-error-outline
'
);
expect
(
errorsShown
.
length
).
toBe
(
0
);
expect
(
errorsShown
.
length
).
toBe
(
0
);
});
});
it
(
'
should show errors when input valid is submitted
'
,
function
()
{
it
(
'
should show errors when input valid is submitted
'
,
function
()
{
this
.
$form
.
find
(
'
.email
'
).
val
(
'
not-a-valid-email
'
).
keyup
();
this
.
$form
.
find
(
'
.email
'
).
val
(
'
not-a-valid-email
'
).
keyup
();
this
.
$form
.
find
(
'
.text-required
'
).
val
(
''
).
keyup
();
this
.
$form
.
find
(
'
.text-required
'
).
val
(
''
).
keyup
();
this
.
$form
.
find
(
'
.alphanumberic
'
).
val
(
'
?---*
'
).
keyup
();
this
.
$form
.
find
(
'
.alphanumberic
'
).
val
(
'
?---*
'
).
keyup
();
this
.
$form
.
submit
();
this
.
$form
.
submit
();
const
errorsShown
=
this
.
$form
.
find
(
'
.gl-field-error-outline
'
);
const
errorsShown
=
this
.
$form
.
find
(
'
.gl-field-error-outline
'
);
expect
(
errorsShown
.
length
).
toBe
(
4
);
expect
(
errorsShown
.
length
).
toBe
(
4
);
});
});
it
(
'
should properly track validity state on input after invalid submission attempt
'
,
function
()
{
it
(
'
should properly track validity state on input after invalid submission attempt
'
,
function
()
{
this
.
$form
.
submit
();
this
.
$form
.
submit
();
const
emailInputModel
=
this
.
fieldErrors
.
state
.
inputs
[
1
];
const
emailInputModel
=
this
.
fieldErrors
.
state
.
inputs
[
1
];
const
fieldState
=
emailInputModel
.
state
;
const
fieldState
=
emailInputModel
.
state
;
const
emailInputElement
=
emailInputModel
.
inputElement
;
const
emailInputElement
=
emailInputModel
.
inputElement
;
// No input
// No input
expect
(
emailInputElement
).
toHaveClass
(
'
gl-field-error-outline
'
);
expect
(
emailInputElement
).
toHaveClass
(
'
gl-field-error-outline
'
);
expect
(
fieldState
.
empty
).
toBe
(
true
);
expect
(
fieldState
.
empty
).
toBe
(
true
);
expect
(
fieldState
.
valid
).
toBe
(
false
);
expect
(
fieldState
.
valid
).
toBe
(
false
);
// Then invalid input
// Then invalid input
emailInputElement
.
val
(
'
not-a-valid-email
'
).
keyup
();
emailInputElement
.
val
(
'
not-a-valid-email
'
).
keyup
();
expect
(
emailInputElement
).
toHaveClass
(
'
gl-field-error-outline
'
);
expect
(
emailInputElement
).
toHaveClass
(
'
gl-field-error-outline
'
);
expect
(
fieldState
.
empty
).
toBe
(
false
);
expect
(
fieldState
.
empty
).
toBe
(
false
);
expect
(
fieldState
.
valid
).
toBe
(
false
);
expect
(
fieldState
.
valid
).
toBe
(
false
);
// Then valid input
// Then valid input
emailInputElement
.
val
(
'
email@gitlab.com
'
).
keyup
();
emailInputElement
.
val
(
'
email@gitlab.com
'
).
keyup
();
expect
(
emailInputElement
).
not
.
toHaveClass
(
'
gl-field-error-outline
'
);
expect
(
emailInputElement
).
not
.
toHaveClass
(
'
gl-field-error-outline
'
);
expect
(
fieldState
.
empty
).
toBe
(
false
);
expect
(
fieldState
.
empty
).
toBe
(
false
);
expect
(
fieldState
.
valid
).
toBe
(
true
);
expect
(
fieldState
.
valid
).
toBe
(
true
);
// Then invalid input
// Then invalid input
emailInputElement
.
val
(
'
not-a-valid-email
'
).
keyup
();
emailInputElement
.
val
(
'
not-a-valid-email
'
).
keyup
();
expect
(
emailInputElement
).
toHaveClass
(
'
gl-field-error-outline
'
);
expect
(
emailInputElement
).
toHaveClass
(
'
gl-field-error-outline
'
);
expect
(
fieldState
.
empty
).
toBe
(
false
);
expect
(
fieldState
.
empty
).
toBe
(
false
);
expect
(
fieldState
.
valid
).
toBe
(
false
);
expect
(
fieldState
.
valid
).
toBe
(
false
);
// Then empty input
// Then empty input
emailInputElement
.
val
(
''
).
keyup
();
emailInputElement
.
val
(
''
).
keyup
();
expect
(
emailInputElement
).
toHaveClass
(
'
gl-field-error-outline
'
);
expect
(
emailInputElement
).
toHaveClass
(
'
gl-field-error-outline
'
);
expect
(
fieldState
.
empty
).
toBe
(
true
);
expect
(
fieldState
.
empty
).
toBe
(
true
);
expect
(
fieldState
.
valid
).
toBe
(
false
);
expect
(
fieldState
.
valid
).
toBe
(
false
);
// Then valid input
// Then valid input
emailInputElement
.
val
(
'
email@gitlab.com
'
).
keyup
();
emailInputElement
.
val
(
'
email@gitlab.com
'
).
keyup
();
expect
(
emailInputElement
).
not
.
toHaveClass
(
'
gl-field-error-outline
'
);
expect
(
emailInputElement
).
not
.
toHaveClass
(
'
gl-field-error-outline
'
);
expect
(
fieldState
.
empty
).
toBe
(
false
);
expect
(
fieldState
.
empty
).
toBe
(
false
);
expect
(
fieldState
.
valid
).
toBe
(
true
);
expect
(
fieldState
.
valid
).
toBe
(
true
);
});
});
it
(
'
should properly infer error messages
'
,
function
()
{
it
(
'
should properly infer error messages
'
,
function
()
{
this
.
$form
.
submit
();
this
.
$form
.
submit
();
const
trackedInputs
=
this
.
fieldErrors
.
state
.
inputs
;
const
trackedInputs
=
this
.
fieldErrors
.
state
.
inputs
;
const
inputHasTitle
=
trackedInputs
[
1
];
const
inputHasTitle
=
trackedInputs
[
1
];
const
hasTitleErrorElem
=
inputHasTitle
.
inputElement
.
siblings
(
'
.gl-field-error
'
);
const
hasTitleErrorElem
=
inputHasTitle
.
inputElement
.
siblings
(
'
.gl-field-error
'
);
const
inputNoTitle
=
trackedInputs
[
2
];
const
inputNoTitle
=
trackedInputs
[
2
];
const
noTitleErrorElem
=
inputNoTitle
.
inputElement
.
siblings
(
'
.gl-field-error
'
);
const
noTitleErrorElem
=
inputNoTitle
.
inputElement
.
siblings
(
'
.gl-field-error
'
);
expect
(
noTitleErrorElem
.
text
()).
toBe
(
'
This field is required.
'
);
expect
(
noTitleErrorElem
.
text
()).
toBe
(
'
This field is required.
'
);
expect
(
hasTitleErrorElem
.
text
()).
toBe
(
'
Please provide a valid email address.
'
);
expect
(
hasTitleErrorElem
.
text
()).
toBe
(
'
Please provide a valid email address.
'
);
});
});
});
})
(
window
.
gl
||
(
window
.
gl
=
{}))
;
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment