BigW Consortium Gitlab
Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
gitlab-ce
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Forest Godfrey
gitlab-ce
Commits
efeaf3bd
Commit
efeaf3bd
authored
Oct 11, 2017
by
Filipa Lacerda
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'ph-gl-form-js-modules' into 'master'
Moves form related JS modules out of global See merge request gitlab-org/gitlab-ce!14780
parents
e39aef73
556ef5ed
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
214 additions
and
232 deletions
+214
-232
dispatcher.js
app/assets/javascripts/dispatcher.js
+11
-9
gl_field_error.js
app/assets/javascripts/gl_field_error.js
+1
-4
gl_field_errors.js
app/assets/javascripts/gl_field_errors.js
+16
-20
gl_form.js
app/assets/javascripts/gl_form.js
+80
-85
notes.js
app/assets/javascripts/notes.js
+3
-2
pipeline_schedule_form_bundle.js
...ripts/pipeline_schedules/pipeline_schedule_form_bundle.js
+2
-1
field.vue
...sets/javascripts/vue_shared/components/markdown/field.vue
+2
-1
gl_field_errors_spec.js
spec/javascripts/gl_field_errors_spec.js
+89
-91
gl_form_spec.js
spec/javascripts/gl_form_spec.js
+1
-8
notes_spec.js
spec/javascripts/notes_spec.js
+9
-11
No files found.
app/assets/javascripts/dispatcher.js
View file @
efeaf3bd
...
...
@@ -80,6 +80,8 @@ import initChangesDropdown from './init_changes_dropdown';
import
AbuseReports
from
'./abuse_reports'
;
import
{
ajaxGet
,
convertPermissionToBoolean
}
from
'./lib/utils/common_utils'
;
import
AjaxLoadingSpinner
from
'./ajax_loading_spinner'
;
import
GlFieldErrors
from
'./gl_field_errors'
;
import
GLForm
from
'./gl_form'
;
import
U2FAuthenticate
from
'./u2f/authenticate'
;
(
function
()
{
...
...
@@ -231,7 +233,7 @@ import U2FAuthenticate from './u2f/authenticate';
case
'groups:milestones:update'
:
new
ZenMode
();
new
gl
.
DueDateSelectors
();
new
gl
.
GLForm
(
$
(
'.milestone-form'
),
true
);
new
GLForm
(
$
(
'.milestone-form'
),
true
);
break
;
case
'projects:compare:show'
:
new
gl
.
Diff
();
...
...
@@ -248,7 +250,7 @@ import U2FAuthenticate from './u2f/authenticate';
case
'projects:issues:new'
:
case
'projects:issues:edit'
:
shortcut_handler
=
new
ShortcutsNavigation
();
new
gl
.
GLForm
(
$
(
'.issue-form'
),
true
);
new
GLForm
(
$
(
'.issue-form'
),
true
);
new
IssuableForm
(
$
(
'.issue-form'
));
new
LabelsSelect
();
new
MilestoneSelect
();
...
...
@@ -272,7 +274,7 @@ import U2FAuthenticate from './u2f/authenticate';
case
'projects:merge_requests:edit'
:
new
gl
.
Diff
();
shortcut_handler
=
new
ShortcutsNavigation
();
new
gl
.
GLForm
(
$
(
'.merge-request-form'
),
true
);
new
GLForm
(
$
(
'.merge-request-form'
),
true
);
new
IssuableForm
(
$
(
'.merge-request-form'
));
new
LabelsSelect
();
new
MilestoneSelect
();
...
...
@@ -281,7 +283,7 @@ import U2FAuthenticate from './u2f/authenticate';
break
;
case
'projects:tags:new'
:
new
ZenMode
();
new
gl
.
GLForm
(
$
(
'.tag-form'
),
true
);
new
GLForm
(
$
(
'.tag-form'
),
true
);
new
RefSelectDropdown
(
$
(
'.js-branch-select'
));
break
;
case
'projects:snippets:show'
:
...
...
@@ -291,17 +293,17 @@ import U2FAuthenticate from './u2f/authenticate';
case
'projects:snippets:edit'
:
case
'projects:snippets:create'
:
case
'projects:snippets:update'
:
new
gl
.
GLForm
(
$
(
'.snippet-form'
),
true
);
new
GLForm
(
$
(
'.snippet-form'
),
true
);
break
;
case
'snippets:new'
:
case
'snippets:edit'
:
case
'snippets:create'
:
case
'snippets:update'
:
new
gl
.
GLForm
(
$
(
'.snippet-form'
),
false
);
new
GLForm
(
$
(
'.snippet-form'
),
false
);
break
;
case
'projects:releases:edit'
:
new
ZenMode
();
new
gl
.
GLForm
(
$
(
'.release-form'
),
true
);
new
GLForm
(
$
(
'.release-form'
),
true
);
break
;
case
'projects:merge_requests:show'
:
new
gl
.
Diff
();
...
...
@@ -607,7 +609,7 @@ import U2FAuthenticate from './u2f/authenticate';
new
Wikis
();
shortcut_handler
=
new
ShortcutsWiki
();
new
ZenMode
();
new
gl
.
GLForm
(
$
(
'.wiki-form'
),
true
);
new
GLForm
(
$
(
'.wiki-form'
),
true
);
break
;
case
'snippets'
:
shortcut_handler
=
new
ShortcutsNavigation
();
...
...
@@ -658,7 +660,7 @@ import U2FAuthenticate from './u2f/authenticate';
Dispatcher
.
prototype
.
initFieldErrors
=
function
()
{
$
(
'.gl-show-field-errors'
).
each
((
i
,
form
)
=>
{
new
gl
.
GlFieldErrors
(
form
);
new
GlFieldErrors
(
form
);
});
};
...
...
app/assets/javascripts/gl_field_error.js
View file @
efeaf3bd
...
...
@@ -54,7 +54,7 @@ const inputErrorClass = 'gl-field-error-outline';
const
errorAnchorSelector
=
'.gl-field-error-anchor'
;
const
ignoreInputSelector
=
'.gl-field-error-ignore'
;
class
GlFieldError
{
export
default
class
GlFieldError
{
constructor
({
input
,
formErrors
})
{
this
.
inputElement
=
$
(
input
);
this
.
inputDomElement
=
this
.
inputElement
.
get
(
0
);
...
...
@@ -159,6 +159,3 @@ class GlFieldError {
this
.
fieldErrorElement
.
hide
();
}
}
window
.
gl
=
window
.
gl
||
{};
window
.
gl
.
GlFieldError
=
GlFieldError
;
app/assets/javascripts/gl_field_errors.js
View file @
efeaf3bd
/* eslint-disable comma-dangle, class-methods-use-this, max-len, space-before-function-paren, arrow-parens, no-param-reassign */
import
'./gl_field_error'
;
import
GlFieldError
from
'./gl_field_error'
;
const
customValidationFlag
=
'gl-field-error-ignore'
;
class
GlFieldErrors
{
export
default
class
GlFieldErrors
{
constructor
(
form
)
{
this
.
form
=
$
(
form
);
this
.
state
=
{
inputs
:
[],
valid
:
false
valid
:
false
,
};
this
.
initValidators
();
}
initValidators
()
{
initValidators
()
{
// register selectors here as needed
const
validateSelectors
=
[
':text'
,
':password'
,
'[type=email]'
]
.
map
(
(
selector
)
=>
`input
${
selector
}
`
).
join
(
','
);
.
map
(
selector
=>
`input
${
selector
}
`
).
join
(
','
);
this
.
state
.
inputs
=
this
.
form
.
find
(
validateSelectors
).
toArray
()
.
filter
(
(
input
)
=>
!
input
.
classList
.
contains
(
customValidationFlag
))
.
map
(
(
input
)
=>
new
window
.
gl
.
GlFieldError
({
input
,
formErrors
:
this
}));
.
filter
(
input
=>
!
input
.
classList
.
contains
(
customValidationFlag
))
.
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
* because Safari & iOS quietly allow form submission when form is invalid
* and prevents disabling of invalid submit button by application.js */
catchInvalidFormSubmit
(
event
)
{
const
$form
=
$
(
e
vent
.
currentTarget
);
static
catchInvalidFormSubmit
(
e
)
{
const
$form
=
$
(
e
.
currentTarget
);
if
(
!
$form
.
attr
(
'novalidate'
))
{
if
(
!
e
vent
.
currentTarget
.
checkValidity
())
{
e
vent
.
preventDefault
();
e
vent
.
stopPropagation
();
if
(
!
e
.
currentTarget
.
checkValidity
())
{
e
.
preventDefault
();
e
.
stopPropagation
();
}
}
}
...
...
@@ -50,11 +48,9 @@ class GlFieldErrors {
});
}
focusOnFirstInvalid
()
{
const
firstInvalid
=
this
.
state
.
inputs
.
filter
((
input
)
=>
!
input
.
inputDomElement
.
validity
.
valid
)[
0
];
focusOnFirstInvalid
()
{
const
firstInvalid
=
this
.
state
.
inputs
.
filter
(
input
=>
!
input
.
inputDomElement
.
validity
.
valid
)[
0
];
firstInvalid
.
inputElement
.
focus
();
}
}
window
.
gl
=
window
.
gl
||
{};
window
.
gl
.
GlFieldErrors
=
GlFieldErrors
;
app/assets/javascripts/gl_form.js
View file @
efeaf3bd
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-new, max-len */
/* global GitLab */
/* global DropzoneInput */
/* global autosize */
import
GfmAutoComplete
from
'./gfm_auto_complete'
;
window
.
gl
=
window
.
gl
||
{};
function
GLForm
(
form
,
enableGFM
=
false
)
{
this
.
form
=
form
;
this
.
textarea
=
this
.
form
.
find
(
'textarea.js-gfm-input'
);
this
.
enableGFM
=
enableGFM
;
// Before we start, we should clean up any previous data for this form
this
.
destroy
();
// Setup the form
this
.
setupForm
();
this
.
form
.
data
(
'gl-form'
,
this
);
}
GLForm
.
prototype
.
destroy
=
function
()
{
// Clean form listeners
this
.
clearEventListeners
();
if
(
this
.
autoComplete
)
{
this
.
autoComplete
.
destroy
();
export
default
class
GLForm
{
constructor
(
form
,
enableGFM
=
false
)
{
this
.
form
=
form
;
this
.
textarea
=
this
.
form
.
find
(
'textarea.js-gfm-input'
);
this
.
enableGFM
=
enableGFM
;
// Before we start, we should clean up any previous data for this form
this
.
destroy
();
// Setup the form
this
.
setupForm
();
this
.
form
.
data
(
'gl-form'
,
this
);
}
return
this
.
form
.
data
(
'gl-form'
,
null
);
};
GLForm
.
prototype
.
setupForm
=
function
()
{
var
isNewForm
;
isNewForm
=
this
.
form
.
is
(
':not(.gfm-form)'
);
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
);
autosize
(
this
.
textarea
);
destroy
()
{
// Clean form listeners
this
.
clearEventListeners
();
if
(
this
.
autoComplete
)
{
this
.
autoComplete
.
destroy
();
}
this
.
form
.
data
(
'gl-form'
,
null
);
}
// 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
()
{
this
.
textarea
.
off
(
'autosize:resized'
)
.
on
(
'autosize:resized'
,
this
.
setHeightData
.
bind
(
this
));
setupForm
()
{
const
isNewForm
=
this
.
form
.
is
(
':not(.gfm-form)'
);
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'
)
.
on
(
'mouseup.autosize'
,
this
.
destroyAutosize
.
bind
(
this
));
setupAutosize
()
{
this
.
textarea
.
off
(
'autosize:resized'
)
.
on
(
'autosize:resized'
,
this
.
setHeightData
.
bind
(
this
));
setTimeout
(()
=>
{
autosize
(
this
.
textarea
);
this
.
textarea
.
css
(
'resize'
,
'vertical'
);
},
0
);
};
this
.
textarea
.
off
(
'mouseup.autosize'
)
.
on
(
'mouseup.autosize'
,
this
.
destroyAutosize
.
bind
(
this
));
GLForm
.
prototype
.
setHeightData
=
function
()
{
this
.
textarea
.
data
(
'height'
,
this
.
textarea
.
outerHeight
());
};
setTimeout
(()
=>
{
autosize
(
this
.
textarea
);
this
.
textarea
.
css
(
'resize'
,
'vertical'
);
},
0
);
}
GLForm
.
prototype
.
destroyAutosize
=
function
()
{
const
outerHeight
=
this
.
textarea
.
outerHeight
();
setHeightData
()
{
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
);
this
.
textarea
.
outerHeight
(
outerHeight
);
this
.
textarea
.
css
(
'max-height'
,
window
.
outerHeight
);
};
autosize
.
destroy
(
this
.
textarea
);
GLForm
.
prototype
.
clearEventListeners
=
function
()
{
this
.
textarea
.
off
(
'focus'
);
this
.
textarea
.
off
(
'blur'
);
return
gl
.
text
.
removeListeners
(
this
.
form
);
};
this
.
textarea
.
data
(
'height'
,
outerHeight
);
this
.
textarea
.
outerHeight
(
outerHeight
);
this
.
textarea
.
css
(
'max-height'
,
window
.
outerHeight
);
}
GLForm
.
prototype
.
addEventListeners
=
function
()
{
this
.
textarea
.
on
(
'focus'
,
function
()
{
return
$
(
this
).
closest
(
'.md-area'
).
addClass
(
'is-focused'
);
});
return
this
.
textarea
.
on
(
'blur'
,
function
()
{
return
$
(
this
).
closest
(
'.md-area'
).
removeClass
(
'is-focused'
);
});
};
clearEventListeners
()
{
this
.
textarea
.
off
(
'focus'
);
this
.
textarea
.
off
(
'blur'
);
gl
.
text
.
removeListeners
(
this
.
form
);
}
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 @
efeaf3bd
...
...
@@ -19,6 +19,7 @@ import 'vendor/jquery.atwho';
import
AjaxCache
from
'~/lib/utils/ajax_cache'
;
import
Flash
from
'./flash'
;
import
CommentTypeToggle
from
'./comment_type_toggle'
;
import
GLForm
from
'./gl_form'
;
import
loadAwardsHandler
from
'./awards_handler'
;
import
'./autosave'
;
import
'./dropzone_input'
;
...
...
@@ -557,7 +558,7 @@ export default class Notes {
*/
setupNoteForm
(
form
)
{
var
textarea
,
key
;
new
gl
.
GLForm
(
form
,
this
.
enableGFM
);
this
.
glForm
=
new
GLForm
(
form
,
this
.
enableGFM
);
textarea
=
form
.
find
(
'.js-note-text'
);
key
=
[
'Note'
,
...
...
@@ -1152,7 +1153,7 @@ export default class Notes {
var
targetId
=
$originalContentEl
.
data
(
'target-id'
);
var
targetType
=
$originalContentEl
.
data
(
'target-type'
);
new
gl
.
GLForm
(
$editForm
.
find
(
'form'
),
this
.
enableGFM
);
this
.
glForm
=
new
GLForm
(
$editForm
.
find
(
'form'
),
this
.
enableGFM
);
$editForm
.
find
(
'form'
)
.
attr
(
'action'
,
postUrl
)
...
...
app/assets/javascripts/pipeline_schedules/pipeline_schedule_form_bundle.js
View file @
efeaf3bd
import
Vue
from
'vue'
;
import
Translate
from
'../vue_shared/translate'
;
import
GlFieldErrors
from
'../gl_field_errors'
;
import
intervalPatternInput
from
'./components/interval_pattern_input.vue'
;
import
TimezoneDropdown
from
'./components/timezone_dropdown'
;
import
TargetBranchDropdown
from
'./components/target_branch_dropdown'
;
...
...
@@ -39,7 +40,7 @@ document.addEventListener('DOMContentLoaded', () => {
gl
.
timezoneDropdown
=
new
TimezoneDropdown
();
gl
.
targetBranchDropdown
=
new
TargetBranchDropdown
();
gl
.
pipelineScheduleFieldErrors
=
new
gl
.
GlFieldErrors
(
formElement
);
gl
.
pipelineScheduleFieldErrors
=
new
GlFieldErrors
(
formElement
);
setupPipelineVariableList
(
$
(
'.js-pipeline-variable-list'
));
});
app/assets/javascripts/vue_shared/components/markdown/field.vue
View file @
efeaf3bd
<
script
>
import
Flash
from
'../../../flash'
;
import
GLForm
from
'../../../gl_form'
;
import
markdownHeader
from
'./header.vue'
;
import
markdownToolbar
from
'./toolbar.vue'
;
...
...
@@ -85,7 +86,7 @@
/*
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
()
{
const
glForm
=
$
(
this
.
$refs
[
'gl-form'
]).
data
(
'gl-form'
);
...
...
spec/javascripts/gl_field_errors_spec.js
View file @
efeaf3bd
/* 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'
);
describe
(
'GL Style Field Errors'
,
function
()
{
beforeEach
(
function
()
{
loadFixtures
(
'static/gl_field_errors.html.raw'
);
const
$form
=
this
.
$form
=
$
(
'form.gl-show-field-errors'
);
this
.
fieldErrors
=
new
global
.
GlFieldErrors
(
$form
);
});
beforeEach
(
function
()
{
loadFixtures
(
'static/gl_field_errors.html.raw'
);
const
$form
=
this
.
$form
=
$
(
'form.gl-show-field-errors'
);
this
.
fieldErrors
=
new
GlFieldErrors
(
$form
);
});
it
(
'should select the correct input elements'
,
function
()
{
expect
(
this
.
$form
).
toBeDefined
();
expect
(
this
.
$form
.
length
).
toBe
(
1
);
expect
(
this
.
fieldErrors
).
toBeDefined
();
const
inputs
=
this
.
fieldErrors
.
state
.
inputs
;
expect
(
inputs
.
length
).
toBe
(
4
);
});
it
(
'should select the correct input elements'
,
function
()
{
expect
(
this
.
$form
).
toBeDefined
();
expect
(
this
.
$form
.
length
).
toBe
(
1
);
expect
(
this
.
fieldErrors
).
toBeDefined
();
const
inputs
=
this
.
fieldErrors
.
state
.
inputs
;
expect
(
inputs
.
length
).
toBe
(
4
);
});
it
(
'should ignore elements with custom error handling'
,
function
()
{
const
customErrorFlag
=
'gl-field-error-ignore'
;
const
customErrorElem
=
$
(
`.
${
customErrorFlag
}
`
);
it
(
'should ignore elements with custom error handling'
,
function
()
{
const
customErrorFlag
=
'gl-field-error-ignore'
;
const
customErrorElem
=
$
(
`.
${
customErrorFlag
}
`
);
expect
(
customErrorElem
.
length
).
toBe
(
1
);
expect
(
customErrorElem
.
length
).
toBe
(
1
);
const
customErrors
=
this
.
fieldErrors
.
state
.
inputs
.
filter
((
input
)
=>
{
return
input
.
inputElement
.
hasClass
(
customErrorFlag
);
});
expect
(
customErrors
.
length
).
toBe
(
0
);
const
customErrors
=
this
.
fieldErrors
.
state
.
inputs
.
filter
((
input
)
=>
{
return
input
.
inputElement
.
hasClass
(
customErrorFlag
);
});
expect
(
customErrors
.
length
).
toBe
(
0
);
});
it
(
'should not show any errors before submit attempt'
,
function
()
{
this
.
$form
.
find
(
'.email'
).
val
(
'not-a-valid-email'
).
keyup
();
this
.
$form
.
find
(
'.text-required'
).
val
(
''
).
keyup
();
this
.
$form
.
find
(
'.alphanumberic'
).
val
(
'?---*'
).
keyup
();
it
(
'should not show any errors before submit attempt'
,
function
()
{
this
.
$form
.
find
(
'.email'
).
val
(
'not-a-valid-email'
).
keyup
();
this
.
$form
.
find
(
'.text-required'
).
val
(
''
).
keyup
();
this
.
$form
.
find
(
'.alphanumberic'
).
val
(
'?---*'
).
keyup
();
const
errorsShown
=
this
.
$form
.
find
(
'.gl-field-error-outline'
);
expect
(
errorsShown
.
length
).
toBe
(
0
);
});
const
errorsShown
=
this
.
$form
.
find
(
'.gl-field-error-outline'
);
expect
(
errorsShown
.
length
).
toBe
(
0
);
});
it
(
'should show errors when input valid is submitted'
,
function
()
{
this
.
$form
.
find
(
'.email'
).
val
(
'not-a-valid-email'
).
keyup
();
this
.
$form
.
find
(
'.text-required'
).
val
(
''
).
keyup
();
this
.
$form
.
find
(
'.alphanumberic'
).
val
(
'?---*'
).
keyup
();
it
(
'should show errors when input valid is submitted'
,
function
()
{
this
.
$form
.
find
(
'.email'
).
val
(
'not-a-valid-email'
).
keyup
();
this
.
$form
.
find
(
'.text-required'
).
val
(
''
).
keyup
();
this
.
$form
.
find
(
'.alphanumberic'
).
val
(
'?---*'
).
keyup
();
this
.
$form
.
submit
();
this
.
$form
.
submit
();
const
errorsShown
=
this
.
$form
.
find
(
'.gl-field-error-outline'
);
expect
(
errorsShown
.
length
).
toBe
(
4
);
});
const
errorsShown
=
this
.
$form
.
find
(
'.gl-field-error-outline'
);
expect
(
errorsShown
.
length
).
toBe
(
4
);
});
it
(
'should properly track validity state on input after invalid submission attempt'
,
function
()
{
this
.
$form
.
submit
();
const
emailInputModel
=
this
.
fieldErrors
.
state
.
inputs
[
1
];
const
fieldState
=
emailInputModel
.
state
;
const
emailInputElement
=
emailInputModel
.
inputElement
;
// No input
expect
(
emailInputElement
).
toHaveClass
(
'gl-field-error-outline'
);
expect
(
fieldState
.
empty
).
toBe
(
true
);
expect
(
fieldState
.
valid
).
toBe
(
false
);
// Then invalid input
emailInputElement
.
val
(
'not-a-valid-email'
).
keyup
();
expect
(
emailInputElement
).
toHaveClass
(
'gl-field-error-outline'
);
expect
(
fieldState
.
empty
).
toBe
(
false
);
expect
(
fieldState
.
valid
).
toBe
(
false
);
// Then valid input
emailInputElement
.
val
(
'email@gitlab.com'
).
keyup
();
expect
(
emailInputElement
).
not
.
toHaveClass
(
'gl-field-error-outline'
);
expect
(
fieldState
.
empty
).
toBe
(
false
);
expect
(
fieldState
.
valid
).
toBe
(
true
);
// Then invalid input
emailInputElement
.
val
(
'not-a-valid-email'
).
keyup
();
expect
(
emailInputElement
).
toHaveClass
(
'gl-field-error-outline'
);
expect
(
fieldState
.
empty
).
toBe
(
false
);
expect
(
fieldState
.
valid
).
toBe
(
false
);
// Then empty input
emailInputElement
.
val
(
''
).
keyup
();
expect
(
emailInputElement
).
toHaveClass
(
'gl-field-error-outline'
);
expect
(
fieldState
.
empty
).
toBe
(
true
);
expect
(
fieldState
.
valid
).
toBe
(
false
);
// Then valid input
emailInputElement
.
val
(
'email@gitlab.com'
).
keyup
();
expect
(
emailInputElement
).
not
.
toHaveClass
(
'gl-field-error-outline'
);
expect
(
fieldState
.
empty
).
toBe
(
false
);
expect
(
fieldState
.
valid
).
toBe
(
true
);
});
it
(
'should properly track validity state on input after invalid submission attempt'
,
function
()
{
this
.
$form
.
submit
();
const
emailInputModel
=
this
.
fieldErrors
.
state
.
inputs
[
1
];
const
fieldState
=
emailInputModel
.
state
;
const
emailInputElement
=
emailInputModel
.
inputElement
;
// No input
expect
(
emailInputElement
).
toHaveClass
(
'gl-field-error-outline'
);
expect
(
fieldState
.
empty
).
toBe
(
true
);
expect
(
fieldState
.
valid
).
toBe
(
false
);
// Then invalid input
emailInputElement
.
val
(
'not-a-valid-email'
).
keyup
();
expect
(
emailInputElement
).
toHaveClass
(
'gl-field-error-outline'
);
expect
(
fieldState
.
empty
).
toBe
(
false
);
expect
(
fieldState
.
valid
).
toBe
(
false
);
// Then valid input
emailInputElement
.
val
(
'email@gitlab.com'
).
keyup
();
expect
(
emailInputElement
).
not
.
toHaveClass
(
'gl-field-error-outline'
);
expect
(
fieldState
.
empty
).
toBe
(
false
);
expect
(
fieldState
.
valid
).
toBe
(
true
);
// Then invalid input
emailInputElement
.
val
(
'not-a-valid-email'
).
keyup
();
expect
(
emailInputElement
).
toHaveClass
(
'gl-field-error-outline'
);
expect
(
fieldState
.
empty
).
toBe
(
false
);
expect
(
fieldState
.
valid
).
toBe
(
false
);
// Then empty input
emailInputElement
.
val
(
''
).
keyup
();
expect
(
emailInputElement
).
toHaveClass
(
'gl-field-error-outline'
);
expect
(
fieldState
.
empty
).
toBe
(
true
);
expect
(
fieldState
.
valid
).
toBe
(
false
);
// Then valid input
emailInputElement
.
val
(
'email@gitlab.com'
).
keyup
();
expect
(
emailInputElement
).
not
.
toHaveClass
(
'gl-field-error-outline'
);
expect
(
fieldState
.
empty
).
toBe
(
false
);
expect
(
fieldState
.
valid
).
toBe
(
true
);
});
it
(
'should properly infer error messages'
,
function
()
{
this
.
$form
.
submit
();
const
trackedInputs
=
this
.
fieldErrors
.
state
.
inputs
;
const
inputHasTitle
=
trackedInputs
[
1
];
const
hasTitleErrorElem
=
inputHasTitle
.
inputElement
.
siblings
(
'.gl-field-error'
);
const
inputNoTitle
=
trackedInputs
[
2
];
const
noTitleErrorElem
=
inputNoTitle
.
inputElement
.
siblings
(
'.gl-field-error'
);
it
(
'should properly infer error messages'
,
function
()
{
this
.
$form
.
submit
();
const
trackedInputs
=
this
.
fieldErrors
.
state
.
inputs
;
const
inputHasTitle
=
trackedInputs
[
1
];
const
hasTitleErrorElem
=
inputHasTitle
.
inputElement
.
siblings
(
'.gl-field-error'
);
const
inputNoTitle
=
trackedInputs
[
2
];
const
noTitleErrorElem
=
inputNoTitle
.
inputElement
.
siblings
(
'.gl-field-error'
);
expect
(
noTitleErrorElem
.
text
()).
toBe
(
'This field is required.'
);
expect
(
hasTitleErrorElem
.
text
()).
toBe
(
'Please provide a valid email address.'
);
});
expect
(
noTitleErrorElem
.
text
()).
toBe
(
'This field is required.'
);
expect
(
hasTitleErrorElem
.
text
()).
toBe
(
'Please provide a valid email address.'
);
});
})
(
window
.
gl
||
(
window
.
gl
=
{}))
;
});
spec/javascripts/gl_form_spec.js
View file @
efeaf3bd
import
autosize
from
'vendor/autosize'
;
import
'~/gl_form'
;
import
GLForm
from
'~/gl_form'
;
import
'~/lib/utils/text_utility'
;
import
'~/lib/utils/common_utils'
;
window
.
autosize
=
autosize
;
describe
(
'GLForm'
,
()
=>
{
const
global
=
window
.
gl
||
(
window
.
gl
=
{});
const
GLForm
=
global
.
GLForm
;
it
(
'should be defined in the global scope'
,
()
=>
{
expect
(
GLForm
).
toBeDefined
();
});
describe
(
'when instantiated'
,
function
()
{
beforeEach
((
done
)
=>
{
this
.
form
=
$
(
'<form class="gfm-form"><textarea class="js-gfm-input"></form>'
);
...
...
spec/javascripts/notes_spec.js
View file @
efeaf3bd
...
...
@@ -426,19 +426,17 @@ import '~/notes';
});
describe
(
'putEditFormInPlace'
,
()
=>
{
it
(
'should call gl.GLForm with GFM parameter passed through'
,
()
=>
{
spyOn
(
gl
,
'GLForm'
);
it
(
'should call GLForm with GFM parameter passed through'
,
()
=>
{
const
notes
=
new
Notes
(
''
,
[]);
const
$el
=
$
(
`
<div>
<form></form>
</div>
`
);
const
$el
=
jasmine
.
createSpyObj
(
'$form'
,
[
'find'
,
'closest'
]);
$el
.
find
.
and
.
returnValue
(
$
(
'<div>'
));
$el
.
closest
.
and
.
returnValue
(
$
(
'<div>'
));
notes
.
putEditFormInPlace
(
$el
);
Notes
.
prototype
.
putEditFormInPlace
.
call
({
getEditFormSelector
:
()
=>
''
,
enableGFM
:
true
},
$el
);
expect
(
gl
.
GLForm
).
toHaveBeenCalledWith
(
jasmine
.
any
(
Object
),
true
);
expect
(
notes
.
glForm
.
enableGFM
).
toBeTruthy
();
});
});
...
...
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