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
Boxiang Sun
gitlab-ce
Commits
dab60475
Commit
dab60475
authored
Apr 07, 2017
by
Luke "Jared" Bennett
Committed by
Jacob Schatz
Apr 07, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update droplab
parent
780a8968
Changes
36
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
36 changed files
with
2585 additions
and
1622 deletions
+2585
-1622
.babelrc
.babelrc
+0
-1
app/assets/javascripts/droplab/constants.js
app/assets/javascripts/droplab/constants.js
+11
-0
app/assets/javascripts/droplab/drop_down.js
app/assets/javascripts/droplab/drop_down.js
+137
-0
app/assets/javascripts/droplab/drop_lab.js
app/assets/javascripts/droplab/drop_lab.js
+152
-0
app/assets/javascripts/droplab/droplab.js
app/assets/javascripts/droplab/droplab.js
+0
-741
app/assets/javascripts/droplab/droplab_ajax.js
app/assets/javascripts/droplab/droplab_ajax.js
+0
-103
app/assets/javascripts/droplab/droplab_ajax_filter.js
app/assets/javascripts/droplab/droplab_ajax_filter.js
+0
-164
app/assets/javascripts/droplab/droplab_filter.js
app/assets/javascripts/droplab/droplab_filter.js
+0
-76
app/assets/javascripts/droplab/hook.js
app/assets/javascripts/droplab/hook.js
+22
-0
app/assets/javascripts/droplab/hook_button.js
app/assets/javascripts/droplab/hook_button.js
+65
-0
app/assets/javascripts/droplab/hook_input.js
app/assets/javascripts/droplab/hook_input.js
+119
-0
app/assets/javascripts/droplab/keyboard.js
app/assets/javascripts/droplab/keyboard.js
+113
-0
app/assets/javascripts/droplab/plugins/ajax.js
app/assets/javascripts/droplab/plugins/ajax.js
+65
-0
app/assets/javascripts/droplab/plugins/ajax_filter.js
app/assets/javascripts/droplab/plugins/ajax_filter.js
+133
-0
app/assets/javascripts/droplab/plugins/filter.js
app/assets/javascripts/droplab/plugins/filter.js
+95
-0
app/assets/javascripts/droplab/plugins/input_setter.js
app/assets/javascripts/droplab/plugins/input_setter.js
+52
-0
app/assets/javascripts/droplab/utils.js
app/assets/javascripts/droplab/utils.js
+38
-0
app/assets/javascripts/filtered_search/dropdown_hint.js
app/assets/javascripts/filtered_search/dropdown_hint.js
+5
-5
app/assets/javascripts/filtered_search/dropdown_non_user.js
app/assets/javascripts/filtered_search/dropdown_non_user.js
+15
-7
app/assets/javascripts/filtered_search/dropdown_user.js
app/assets/javascripts/filtered_search/dropdown_user.js
+12
-5
app/assets/javascripts/filtered_search/filtered_search_dropdown.js
...s/javascripts/filtered_search/filtered_search_dropdown.js
+1
-1
app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js
...ripts/filtered_search/filtered_search_dropdown_manager.js
+1
-1
app/assets/javascripts/filtered_search/filtered_search_manager.js
...ts/javascripts/filtered_search/filtered_search_manager.js
+1
-1
app/assets/javascripts/main.js
app/assets/javascripts/main.js
+0
-6
app/assets/stylesheets/framework/filters.scss
app/assets/stylesheets/framework/filters.scss
+2
-4
app/views/shared/issuable/_search_bar.html.haml
app/views/shared/issuable/_search_bar.html.haml
+1
-1
spec/features/issues/filtered_search/dropdown_hint_spec.rb
spec/features/issues/filtered_search/dropdown_hint_spec.rb
+6
-8
spec/features/issues/filtered_search/dropdown_label_spec.rb
spec/features/issues/filtered_search/dropdown_label_spec.rb
+14
-17
spec/features/issues/filtered_search/dropdown_milestone_spec.rb
...eatures/issues/filtered_search/dropdown_milestone_spec.rb
+7
-7
spec/features/issues/filtered_search/search_bar_spec.rb
spec/features/issues/filtered_search/search_bar_spec.rb
+10
-8
spec/javascripts/droplab/constants_spec.js
spec/javascripts/droplab/constants_spec.js
+29
-0
spec/javascripts/droplab/drop_down_spec.js
spec/javascripts/droplab/drop_down_spec.js
+578
-0
spec/javascripts/droplab/hook_spec.js
spec/javascripts/droplab/hook_spec.js
+82
-0
spec/javascripts/droplab/plugins/input_setter_spec.js
spec/javascripts/droplab/plugins/input_setter_spec.js
+246
-0
spec/javascripts/filtered_search/dropdown_user_spec.js
spec/javascripts/filtered_search/dropdown_user_spec.js
+4
-4
yarn.lock
yarn.lock
+569
-462
No files found.
.babelrc
View file @
dab60475
...
@@ -8,7 +8,6 @@
...
@@ -8,7 +8,6 @@
"plugins": [
"plugins": [
["istanbul", {
["istanbul", {
"exclude": [
"exclude": [
"app/assets/javascripts/droplab/**/*",
"spec/javascripts/**/*"
"spec/javascripts/**/*"
]
]
}],
}],
...
...
app/assets/javascripts/droplab/constants.js
0 → 100644
View file @
dab60475
const
DATA_TRIGGER
=
'
data-dropdown-trigger
'
;
const
DATA_DROPDOWN
=
'
data-dropdown
'
;
const
SELECTED_CLASS
=
'
droplab-item-selected
'
;
const
ACTIVE_CLASS
=
'
droplab-item-active
'
;
export
{
DATA_TRIGGER
,
DATA_DROPDOWN
,
SELECTED_CLASS
,
ACTIVE_CLASS
,
};
app/assets/javascripts/droplab/drop_down.js
0 → 100644
View file @
dab60475
/* eslint-disable */
import
utils
from
'
./utils
'
;
import
{
SELECTED_CLASS
}
from
'
./constants
'
;
var
DropDown
=
function
(
list
)
{
this
.
currentIndex
=
0
;
this
.
hidden
=
true
;
this
.
list
=
typeof
list
===
'
string
'
?
document
.
querySelector
(
list
)
:
list
;
this
.
items
=
[];
this
.
eventWrapper
=
{};
this
.
getItems
();
this
.
initTemplateString
();
this
.
addEvents
();
this
.
initialState
=
list
.
innerHTML
;
};
Object
.
assign
(
DropDown
.
prototype
,
{
getItems
:
function
()
{
this
.
items
=
[].
slice
.
call
(
this
.
list
.
querySelectorAll
(
'
li
'
));
return
this
.
items
;
},
initTemplateString
:
function
()
{
var
items
=
this
.
items
||
this
.
getItems
();
var
templateString
=
''
;
if
(
items
.
length
>
0
)
templateString
=
items
[
items
.
length
-
1
].
outerHTML
;
this
.
templateString
=
templateString
;
return
this
.
templateString
;
},
clickEvent
:
function
(
e
)
{
var
selected
=
utils
.
closest
(
e
.
target
,
'
LI
'
);
if
(
!
selected
)
return
;
this
.
addSelectedClass
(
selected
);
e
.
preventDefault
();
this
.
hide
();
var
listEvent
=
new
CustomEvent
(
'
click.dl
'
,
{
detail
:
{
list
:
this
,
selected
:
selected
,
data
:
e
.
target
.
dataset
,
},
});
this
.
list
.
dispatchEvent
(
listEvent
);
},
addSelectedClass
:
function
(
selected
)
{
this
.
removeSelectedClasses
();
selected
.
classList
.
add
(
SELECTED_CLASS
);
},
removeSelectedClasses
:
function
()
{
const
items
=
this
.
items
||
this
.
getItems
();
items
.
forEach
(
item
=>
item
.
classList
.
remove
(
SELECTED_CLASS
));
},
addEvents
:
function
()
{
this
.
eventWrapper
.
clickEvent
=
this
.
clickEvent
.
bind
(
this
)
this
.
list
.
addEventListener
(
'
click
'
,
this
.
eventWrapper
.
clickEvent
);
},
toggle
:
function
()
{
this
.
hidden
?
this
.
show
()
:
this
.
hide
();
},
setData
:
function
(
data
)
{
this
.
data
=
data
;
this
.
render
(
data
);
},
addData
:
function
(
data
)
{
this
.
data
=
(
this
.
data
||
[]).
concat
(
data
);
this
.
render
(
this
.
data
);
},
render
:
function
(
data
)
{
const
children
=
data
?
data
.
map
(
this
.
renderChildren
.
bind
(
this
))
:
[];
const
renderableList
=
this
.
list
.
querySelector
(
'
ul[data-dynamic]
'
)
||
this
.
list
;
renderableList
.
innerHTML
=
children
.
join
(
''
);
},
renderChildren
:
function
(
data
)
{
var
html
=
utils
.
t
(
this
.
templateString
,
data
);
var
template
=
document
.
createElement
(
'
div
'
);
template
.
innerHTML
=
html
;
this
.
setImagesSrc
(
template
);
template
.
firstChild
.
style
.
display
=
data
.
droplab_hidden
?
'
none
'
:
'
block
'
;
return
template
.
firstChild
.
outerHTML
;
},
setImagesSrc
:
function
(
template
)
{
const
images
=
[].
slice
.
call
(
template
.
querySelectorAll
(
'
img[data-src]
'
));
images
.
forEach
((
image
)
=>
{
image
.
src
=
image
.
getAttribute
(
'
data-src
'
);
image
.
removeAttribute
(
'
data-src
'
);
});
},
show
:
function
()
{
if
(
!
this
.
hidden
)
return
;
this
.
list
.
style
.
display
=
'
block
'
;
this
.
currentIndex
=
0
;
this
.
hidden
=
false
;
},
hide
:
function
()
{
if
(
this
.
hidden
)
return
;
this
.
list
.
style
.
display
=
'
none
'
;
this
.
currentIndex
=
0
;
this
.
hidden
=
true
;
},
toggle
:
function
()
{
this
.
hidden
?
this
.
show
()
:
this
.
hide
();
},
destroy
:
function
()
{
this
.
hide
();
this
.
list
.
removeEventListener
(
'
click
'
,
this
.
eventWrapper
.
clickEvent
);
}
});
export
default
DropDown
;
app/assets/javascripts/droplab/drop_lab.js
0 → 100644
View file @
dab60475
/* eslint-disable */
import
HookButton
from
'
./hook_button
'
;
import
HookInput
from
'
./hook_input
'
;
import
utils
from
'
./utils
'
;
import
Keyboard
from
'
./keyboard
'
;
import
{
DATA_TRIGGER
}
from
'
./constants
'
;
var
DropLab
=
function
()
{
this
.
ready
=
false
;
this
.
hooks
=
[];
this
.
queuedData
=
[];
this
.
config
=
{};
this
.
eventWrapper
=
{};
};
Object
.
assign
(
DropLab
.
prototype
,
{
loadStatic
:
function
(){
var
dropdownTriggers
=
[].
slice
.
apply
(
document
.
querySelectorAll
(
`[
${
DATA_TRIGGER
}
]`
));
this
.
addHooks
(
dropdownTriggers
);
},
addData
:
function
()
{
var
args
=
[].
slice
.
apply
(
arguments
);
this
.
applyArgs
(
args
,
'
_addData
'
);
},
setData
:
function
()
{
var
args
=
[].
slice
.
apply
(
arguments
);
this
.
applyArgs
(
args
,
'
_setData
'
);
},
destroy
:
function
()
{
this
.
hooks
.
forEach
(
hook
=>
hook
.
destroy
());
this
.
hooks
=
[];
this
.
removeEvents
();
},
applyArgs
:
function
(
args
,
methodName
)
{
if
(
this
.
ready
)
return
this
[
methodName
].
apply
(
this
,
args
);
this
.
queuedData
=
this
.
queuedData
||
[];
this
.
queuedData
.
push
(
args
);
},
_addData
:
function
(
trigger
,
data
)
{
this
.
_processData
(
trigger
,
data
,
'
addData
'
);
},
_setData
:
function
(
trigger
,
data
)
{
this
.
_processData
(
trigger
,
data
,
'
setData
'
);
},
_processData
:
function
(
trigger
,
data
,
methodName
)
{
this
.
hooks
.
forEach
((
hook
)
=>
{
if
(
Array
.
isArray
(
trigger
))
hook
.
list
[
methodName
](
trigger
);
if
(
hook
.
trigger
.
id
===
trigger
)
hook
.
list
[
methodName
](
data
);
});
},
addEvents
:
function
()
{
this
.
eventWrapper
.
documentClicked
=
this
.
documentClicked
.
bind
(
this
)
document
.
addEventListener
(
'
click
'
,
this
.
eventWrapper
.
documentClicked
);
},
documentClicked
:
function
(
e
)
{
let
thisTag
=
e
.
target
;
if
(
thisTag
.
tagName
!==
'
UL
'
)
thisTag
=
utils
.
closest
(
thisTag
,
'
UL
'
);
if
(
utils
.
isDropDownParts
(
thisTag
,
this
.
hooks
)
||
utils
.
isDropDownParts
(
e
.
target
,
this
.
hooks
))
return
;
this
.
hooks
.
forEach
(
hook
=>
hook
.
list
.
hide
());
},
removeEvents
:
function
(){
document
.
removeEventListener
(
'
click
'
,
this
.
eventWrapper
.
documentClicked
);
},
changeHookList
:
function
(
trigger
,
list
,
plugins
,
config
)
{
const
availableTrigger
=
typeof
trigger
===
'
string
'
?
document
.
getElementById
(
trigger
)
:
trigger
;
this
.
hooks
.
forEach
((
hook
,
i
)
=>
{
hook
.
list
.
list
.
dataset
.
dropdownActive
=
false
;
if
(
hook
.
trigger
!==
availableTrigger
)
return
;
hook
.
destroy
();
this
.
hooks
.
splice
(
i
,
1
);
this
.
addHook
(
availableTrigger
,
list
,
plugins
,
config
);
});
},
addHook
:
function
(
hook
,
list
,
plugins
,
config
)
{
const
availableHook
=
typeof
hook
===
'
string
'
?
document
.
querySelector
(
hook
)
:
hook
;
let
availableList
;
if
(
typeof
list
===
'
string
'
)
{
availableList
=
document
.
querySelector
(
list
);
}
else
if
(
list
instanceof
Element
)
{
availableList
=
list
;
}
else
{
availableList
=
document
.
querySelector
(
hook
.
dataset
[
utils
.
toCamelCase
(
DATA_TRIGGER
)]);
}
availableList
.
dataset
.
dropdownActive
=
true
;
const
HookObject
=
availableHook
.
tagName
===
'
INPUT
'
?
HookInput
:
HookButton
;
this
.
hooks
.
push
(
new
HookObject
(
availableHook
,
availableList
,
plugins
,
config
));
return
this
;
},
addHooks
:
function
(
hooks
,
plugins
,
config
)
{
hooks
.
forEach
(
hook
=>
this
.
addHook
(
hook
,
null
,
plugins
,
config
));
return
this
;
},
setConfig
:
function
(
obj
){
this
.
config
=
obj
;
},
fireReady
:
function
()
{
const
readyEvent
=
new
CustomEvent
(
'
ready.dl
'
,
{
detail
:
{
dropdown
:
this
,
},
});
document
.
dispatchEvent
(
readyEvent
);
this
.
ready
=
true
;
},
init
:
function
(
hook
,
list
,
plugins
,
config
)
{
hook
?
this
.
addHook
(
hook
,
list
,
plugins
,
config
)
:
this
.
loadStatic
();
this
.
addEvents
();
Keyboard
();
this
.
fireReady
();
this
.
queuedData
.
forEach
(
data
=>
this
.
addData
(
data
));
this
.
queuedData
=
[];
return
this
;
},
});
export
default
DropLab
;
app/assets/javascripts/droplab/droplab.js
deleted
100644 → 0
View file @
780a8968
This diff is collapsed.
Click to expand it.
app/assets/javascripts/droplab/droplab_ajax.js
deleted
100644 → 0
View file @
780a8968
/* eslint-disable */
(
function
(
f
){
if
(
typeof
exports
===
"
object
"
&&
typeof
module
!==
"
undefined
"
){
module
.
exports
=
f
()}
else
if
(
typeof
define
===
"
function
"
&&
define
.
amd
){
define
([],
f
)}
else
{
var
g
;
if
(
typeof
window
!==
"
undefined
"
){
g
=
window
}
else
if
(
typeof
global
!==
"
undefined
"
){
g
=
global
}
else
if
(
typeof
self
!==
"
undefined
"
){
g
=
self
}
else
{
g
=
this
}
g
=
(
g
.
droplab
||
(
g
.
droplab
=
{}));
g
=
(
g
.
ajax
||
(
g
.
ajax
=
{}));
g
=
(
g
.
datasource
||
(
g
.
datasource
=
{}));
g
.
js
=
f
()}})(
function
(){
var
define
,
module
,
exports
;
return
(
function
e
(
t
,
n
,
r
){
function
s
(
o
,
u
){
if
(
!
n
[
o
]){
if
(
!
t
[
o
]){
var
a
=
typeof
require
==
"
function
"
&&
require
;
if
(
!
u
&&
a
)
return
a
(
o
,
!
0
);
if
(
i
)
return
i
(
o
,
!
0
);
var
f
=
new
Error
(
"
Cannot find module '
"
+
o
+
"
'
"
);
throw
f
.
code
=
"
MODULE_NOT_FOUND
"
,
f
}
var
l
=
n
[
o
]
=
{
exports
:{}};
t
[
o
][
0
].
call
(
l
.
exports
,
function
(
e
){
var
n
=
t
[
o
][
1
][
e
];
return
s
(
n
?
n
:
e
)},
l
,
l
.
exports
,
e
,
t
,
n
,
r
)}
return
n
[
o
].
exports
}
var
i
=
typeof
require
==
"
function
"
&&
require
;
for
(
var
o
=
0
;
o
<
r
.
length
;
o
++
)
s
(
r
[
o
]);
return
s
})({
1
:[
function
(
require
,
module
,
exports
){
/* global droplab */
require
(
'
../window
'
)(
function
(
w
){
function
droplabAjaxException
(
message
)
{
this
.
message
=
message
;
}
w
.
droplabAjax
=
{
_loadUrlData
:
function
_loadUrlData
(
url
)
{
var
self
=
this
;
return
new
Promise
(
function
(
resolve
,
reject
)
{
var
xhr
=
new
XMLHttpRequest
;
xhr
.
open
(
'
GET
'
,
url
,
true
);
xhr
.
onreadystatechange
=
function
()
{
if
(
xhr
.
readyState
===
XMLHttpRequest
.
DONE
)
{
if
(
xhr
.
status
===
200
)
{
var
data
=
JSON
.
parse
(
xhr
.
responseText
);
self
.
cache
[
url
]
=
data
;
return
resolve
(
data
);
}
else
{
return
reject
([
xhr
.
responseText
,
xhr
.
status
]);
}
}
};
xhr
.
send
();
});
},
_loadData
:
function
_loadData
(
data
,
config
,
self
)
{
if
(
config
.
loadingTemplate
)
{
var
dataLoadingTemplate
=
self
.
hook
.
list
.
list
.
querySelector
(
'
[data-loading-template]
'
);
if
(
dataLoadingTemplate
)
{
dataLoadingTemplate
.
outerHTML
=
self
.
listTemplate
;
}
}
if
(
!
self
.
destroyed
)
{
self
.
hook
.
list
[
config
.
method
].
call
(
self
.
hook
.
list
,
data
);
}
},
init
:
function
init
(
hook
)
{
var
self
=
this
;
self
.
destroyed
=
false
;
self
.
cache
=
self
.
cache
||
{};
var
config
=
hook
.
config
.
droplabAjax
;
this
.
hook
=
hook
;
if
(
!
config
||
!
config
.
endpoint
||
!
config
.
method
)
{
return
;
}
if
(
config
.
method
!==
'
setData
'
&&
config
.
method
!==
'
addData
'
)
{
return
;
}
if
(
config
.
loadingTemplate
)
{
var
dynamicList
=
hook
.
list
.
list
.
querySelector
(
'
[data-dynamic]
'
);
var
loadingTemplate
=
document
.
createElement
(
'
div
'
);
loadingTemplate
.
innerHTML
=
config
.
loadingTemplate
;
loadingTemplate
.
setAttribute
(
'
data-loading-template
'
,
''
);
this
.
listTemplate
=
dynamicList
.
outerHTML
;
dynamicList
.
outerHTML
=
loadingTemplate
.
outerHTML
;
}
if
(
self
.
cache
[
config
.
endpoint
])
{
self
.
_loadData
(
self
.
cache
[
config
.
endpoint
],
config
,
self
);
}
else
{
this
.
_loadUrlData
(
config
.
endpoint
)
.
then
(
function
(
d
)
{
self
.
_loadData
(
d
,
config
,
self
);
},
function
(
xhrError
)
{
// TODO: properly handle errors due to XHR cancellation
return
;
}).
catch
(
function
(
e
)
{
throw
new
droplabAjaxException
(
e
.
message
||
e
);
});
}
},
destroy
:
function
()
{
var
dynamicList
=
this
.
hook
.
list
.
list
.
querySelector
(
'
[data-dynamic]
'
);
this
.
destroyed
=
true
;
if
(
this
.
listTemplate
&&
dynamicList
)
{
dynamicList
.
outerHTML
=
this
.
listTemplate
;
}
}
};
});
},{
"
../window
"
:
2
}],
2
:[
function
(
require
,
module
,
exports
){
module
.
exports
=
function
(
callback
)
{
return
(
function
()
{
callback
(
this
);
}).
call
(
null
);
};
},{}]},{},[
1
])(
1
)
});
app/assets/javascripts/droplab/droplab_ajax_filter.js
deleted
100644 → 0
View file @
780a8968
/* eslint-disable */
(
function
(
f
){
if
(
typeof
exports
===
"
object
"
&&
typeof
module
!==
"
undefined
"
){
module
.
exports
=
f
()}
else
if
(
typeof
define
===
"
function
"
&&
define
.
amd
){
define
([],
f
)}
else
{
var
g
;
if
(
typeof
window
!==
"
undefined
"
){
g
=
window
}
else
if
(
typeof
global
!==
"
undefined
"
){
g
=
global
}
else
if
(
typeof
self
!==
"
undefined
"
){
g
=
self
}
else
{
g
=
this
}
g
=
(
g
.
droplab
||
(
g
.
droplab
=
{}));
g
=
(
g
.
ajax
||
(
g
.
ajax
=
{}));
g
=
(
g
.
datasource
||
(
g
.
datasource
=
{}));
g
.
js
=
f
()}})(
function
(){
var
define
,
module
,
exports
;
return
(
function
e
(
t
,
n
,
r
){
function
s
(
o
,
u
){
if
(
!
n
[
o
]){
if
(
!
t
[
o
]){
var
a
=
typeof
require
==
"
function
"
&&
require
;
if
(
!
u
&&
a
)
return
a
(
o
,
!
0
);
if
(
i
)
return
i
(
o
,
!
0
);
var
f
=
new
Error
(
"
Cannot find module '
"
+
o
+
"
'
"
);
throw
f
.
code
=
"
MODULE_NOT_FOUND
"
,
f
}
var
l
=
n
[
o
]
=
{
exports
:{}};
t
[
o
][
0
].
call
(
l
.
exports
,
function
(
e
){
var
n
=
t
[
o
][
1
][
e
];
return
s
(
n
?
n
:
e
)},
l
,
l
.
exports
,
e
,
t
,
n
,
r
)}
return
n
[
o
].
exports
}
var
i
=
typeof
require
==
"
function
"
&&
require
;
for
(
var
o
=
0
;
o
<
r
.
length
;
o
++
)
s
(
r
[
o
]);
return
s
})({
1
:[
function
(
require
,
module
,
exports
){
/* global droplab */
require
(
'
../window
'
)(
function
(
w
){
w
.
droplabAjaxFilter
=
{
init
:
function
(
hook
)
{
this
.
destroyed
=
false
;
this
.
hook
=
hook
;
this
.
notLoading
();
this
.
debounceTriggerWrapper
=
this
.
debounceTrigger
.
bind
(
this
);
this
.
hook
.
trigger
.
addEventListener
(
'
keydown.dl
'
,
this
.
debounceTriggerWrapper
);
this
.
hook
.
trigger
.
addEventListener
(
'
focus
'
,
this
.
debounceTriggerWrapper
);
this
.
trigger
(
true
);
},
notLoading
:
function
notLoading
()
{
this
.
loading
=
false
;
},
debounceTrigger
:
function
debounceTrigger
(
e
)
{
var
NON_CHARACTER_KEYS
=
[
16
,
17
,
18
,
20
,
37
,
38
,
39
,
40
,
91
,
93
];
var
invalidKeyPressed
=
NON_CHARACTER_KEYS
.
indexOf
(
e
.
detail
.
which
||
e
.
detail
.
keyCode
)
>
-
1
;
var
focusEvent
=
e
.
type
===
'
focus
'
;
if
(
invalidKeyPressed
||
this
.
loading
)
{
return
;
}
if
(
this
.
timeout
)
{
clearTimeout
(
this
.
timeout
);
}
this
.
timeout
=
setTimeout
(
this
.
trigger
.
bind
(
this
,
focusEvent
),
200
);
},
trigger
:
function
trigger
(
getEntireList
)
{
var
config
=
this
.
hook
.
config
.
droplabAjaxFilter
;
var
searchValue
=
this
.
trigger
.
value
;
if
(
!
config
||
!
config
.
endpoint
||
!
config
.
searchKey
)
{
return
;
}
if
(
config
.
searchValueFunction
)
{
searchValue
=
config
.
searchValueFunction
();
}
if
(
config
.
loadingTemplate
&&
this
.
hook
.
list
.
data
===
undefined
||
this
.
hook
.
list
.
data
.
length
===
0
)
{
var
dynamicList
=
this
.
hook
.
list
.
list
.
querySelector
(
'
[data-dynamic]
'
);
var
loadingTemplate
=
document
.
createElement
(
'
div
'
);
loadingTemplate
.
innerHTML
=
config
.
loadingTemplate
;
loadingTemplate
.
setAttribute
(
'
data-loading-template
'
,
true
);
this
.
listTemplate
=
dynamicList
.
outerHTML
;
dynamicList
.
outerHTML
=
loadingTemplate
.
outerHTML
;
}
if
(
getEntireList
)
{
searchValue
=
''
;
}
if
(
config
.
searchKey
===
searchValue
)
{
return
this
.
list
.
show
();
}
this
.
loading
=
true
;
var
params
=
config
.
params
||
{};
params
[
config
.
searchKey
]
=
searchValue
;
var
self
=
this
;
self
.
cache
=
self
.
cache
||
{};
var
url
=
config
.
endpoint
+
this
.
buildParams
(
params
);
var
urlCachedData
=
self
.
cache
[
url
];
if
(
urlCachedData
)
{
self
.
_loadData
(
urlCachedData
,
config
,
self
);
}
else
{
this
.
_loadUrlData
(
url
)
.
then
(
function
(
data
)
{
self
.
_loadData
(
data
,
config
,
self
);
},
function
(
xhrError
)
{
// TODO: properly handle errors due to XHR cancellation
return
;
});
}
},
_loadUrlData
:
function
_loadUrlData
(
url
)
{
var
self
=
this
;
return
new
Promise
(
function
(
resolve
,
reject
)
{
var
xhr
=
new
XMLHttpRequest
;
xhr
.
open
(
'
GET
'
,
url
,
true
);
xhr
.
onreadystatechange
=
function
()
{
if
(
xhr
.
readyState
===
XMLHttpRequest
.
DONE
)
{
if
(
xhr
.
status
===
200
)
{
var
data
=
JSON
.
parse
(
xhr
.
responseText
);
self
.
cache
[
url
]
=
data
;
return
resolve
(
data
);
}
else
{
return
reject
([
xhr
.
responseText
,
xhr
.
status
]);
}
}
};
xhr
.
send
();
});
},
_loadData
:
function
_loadData
(
data
,
config
,
self
)
{
if
(
config
.
loadingTemplate
&&
self
.
hook
.
list
.
data
===
undefined
||
self
.
hook
.
list
.
data
.
length
===
0
)
{
const
dataLoadingTemplate
=
self
.
hook
.
list
.
list
.
querySelector
(
'
[data-loading-template]
'
);
if
(
dataLoadingTemplate
)
{
dataLoadingTemplate
.
outerHTML
=
self
.
listTemplate
;
}
}
if
(
!
self
.
destroyed
)
{
var
hookListChildren
=
self
.
hook
.
list
.
list
.
children
;
var
onlyDynamicList
=
hookListChildren
.
length
===
1
&&
hookListChildren
[
0
].
hasAttribute
(
'
data-dynamic
'
);
if
(
onlyDynamicList
&&
data
.
length
===
0
)
{
self
.
hook
.
list
.
hide
();
}
self
.
hook
.
list
.
setData
.
call
(
self
.
hook
.
list
,
data
);
}
self
.
notLoading
();
self
.
hook
.
list
.
currentIndex
=
0
;
},
buildParams
:
function
(
params
)
{
if
(
!
params
)
return
''
;
var
paramsArray
=
Object
.
keys
(
params
).
map
(
function
(
param
)
{
return
param
+
'
=
'
+
(
params
[
param
]
||
''
);
});
return
'
?
'
+
paramsArray
.
join
(
'
&
'
);
},
destroy
:
function
destroy
()
{
if
(
this
.
timeout
)
{
clearTimeout
(
this
.
timeout
);
}
this
.
destroyed
=
true
;
this
.
hook
.
trigger
.
removeEventListener
(
'
keydown.dl
'
,
this
.
debounceTriggerWrapper
);
this
.
hook
.
trigger
.
removeEventListener
(
'
focus
'
,
this
.
debounceTriggerWrapper
);
}
};
});
},{
"
../window
"
:
2
}],
2
:[
function
(
require
,
module
,
exports
){
module
.
exports
=
function
(
callback
)
{
return
(
function
()
{
callback
(
this
);
}).
call
(
null
);
};
},{}]},{},[
1
])(
1
)
});
app/assets/javascripts/droplab/droplab_filter.js
deleted
100644 → 0
View file @
780a8968
/* eslint-disable */
(
function
(
f
){
if
(
typeof
exports
===
"
object
"
&&
typeof
module
!==
"
undefined
"
){
module
.
exports
=
f
()}
else
if
(
typeof
define
===
"
function
"
&&
define
.
amd
){
define
([],
f
)}
else
{
var
g
;
if
(
typeof
window
!==
"
undefined
"
){
g
=
window
}
else
if
(
typeof
global
!==
"
undefined
"
){
g
=
global
}
else
if
(
typeof
self
!==
"
undefined
"
){
g
=
self
}
else
{
g
=
this
}
g
=
(
g
.
droplab
||
(
g
.
droplab
=
{}));
g
=
(
g
.
filter
||
(
g
.
filter
=
{}));
g
.
js
=
f
()}})(
function
(){
var
define
,
module
,
exports
;
return
(
function
e
(
t
,
n
,
r
){
function
s
(
o
,
u
){
if
(
!
n
[
o
]){
if
(
!
t
[
o
]){
var
a
=
typeof
require
==
"
function
"
&&
require
;
if
(
!
u
&&
a
)
return
a
(
o
,
!
0
);
if
(
i
)
return
i
(
o
,
!
0
);
var
f
=
new
Error
(
"
Cannot find module '
"
+
o
+
"
'
"
);
throw
f
.
code
=
"
MODULE_NOT_FOUND
"
,
f
}
var
l
=
n
[
o
]
=
{
exports
:{}};
t
[
o
][
0
].
call
(
l
.
exports
,
function
(
e
){
var
n
=
t
[
o
][
1
][
e
];
return
s
(
n
?
n
:
e
)},
l
,
l
.
exports
,
e
,
t
,
n
,
r
)}
return
n
[
o
].
exports
}
var
i
=
typeof
require
==
"
function
"
&&
require
;
for
(
var
o
=
0
;
o
<
r
.
length
;
o
++
)
s
(
r
[
o
]);
return
s
})({
1
:[
function
(
require
,
module
,
exports
){
/* global droplab */
require
(
'
../window
'
)(
function
(
w
){
w
.
droplabFilter
=
{
keydownWrapper
:
function
(
e
){
var
hiddenCount
=
0
;
var
dataHiddenCount
=
0
;
var
list
=
e
.
detail
.
hook
.
list
;
var
data
=
list
.
data
;
var
value
=
e
.
detail
.
hook
.
trigger
.
value
.
toLowerCase
();
var
config
=
e
.
detail
.
hook
.
config
.
droplabFilter
;
var
matches
=
[];
var
filterFunction
;
// will only work on dynamically set data
if
(
!
data
){
return
;
}
if
(
config
&&
config
.
filterFunction
&&
typeof
config
.
filterFunction
===
'
function
'
)
{
filterFunction
=
config
.
filterFunction
;
}
else
{
filterFunction
=
function
(
o
){
// cheap string search
o
.
droplab_hidden
=
o
[
config
.
template
].
toLowerCase
().
indexOf
(
value
)
===
-
1
;
return
o
;
};
}
dataHiddenCount
=
data
.
filter
(
function
(
o
)
{
return
!
o
.
droplab_hidden
;
}).
length
;
matches
=
data
.
map
(
function
(
o
)
{
return
filterFunction
(
o
,
value
);
});
hiddenCount
=
matches
.
filter
(
function
(
o
)
{
return
!
o
.
droplab_hidden
;
}).
length
;
if
(
dataHiddenCount
!==
hiddenCount
)
{
list
.
render
(
matches
);
list
.
currentIndex
=
0
;
}
},
init
:
function
init
(
hookInput
)
{
var
config
=
hookInput
.
config
.
droplabFilter
;
if
(
!
config
||
(
!
config
.
template
&&
!
config
.
filterFunction
))
{
return
;
}
this
.
hookInput
=
hookInput
;
this
.
hookInput
.
trigger
.
addEventListener
(
'
keyup.dl
'
,
this
.
keydownWrapper
);
this
.
hookInput
.
trigger
.
addEventListener
(
'
mousedown.dl
'
,
this
.
keydownWrapper
);
},
destroy
:
function
destroy
(){
this
.
hookInput
.
trigger
.
removeEventListener
(
'
keyup.dl
'
,
this
.
keydownWrapper
);
this
.
hookInput
.
trigger
.
removeEventListener
(
'
mousedown.dl
'
,
this
.
keydownWrapper
);
}
};
});
},{
"
../window
"
:
2
}],
2
:[
function
(
require
,
module
,
exports
){
module
.
exports
=
function
(
callback
)
{
return
(
function
()
{
callback
(
this
);
}).
call
(
null
);
};
},{}]},{},[
1
])(
1
)
});
app/assets/javascripts/droplab/hook.js
0 → 100644
View file @
dab60475
/* eslint-disable */
import
DropDown
from
'
./drop_down
'
;
var
Hook
=
function
(
trigger
,
list
,
plugins
,
config
){
this
.
trigger
=
trigger
;
this
.
list
=
new
DropDown
(
list
);
this
.
type
=
'
Hook
'
;
this
.
event
=
'
click
'
;
this
.
plugins
=
plugins
||
[];
this
.
config
=
config
||
{};
this
.
id
=
trigger
.
id
;
};
Object
.
assign
(
Hook
.
prototype
,
{
addEvents
:
function
(){},
constructor
:
Hook
,
});
export
default
Hook
;
app/assets/javascripts/droplab/hook_button.js
0 → 100644
View file @
dab60475
/* eslint-disable */
import
Hook
from
'
./hook
'
;
var
HookButton
=
function
(
trigger
,
list
,
plugins
,
config
)
{
Hook
.
call
(
this
,
trigger
,
list
,
plugins
,
config
);
this
.
type
=
'
button
'
;
this
.
event
=
'
click
'
;
this
.
eventWrapper
=
{};
this
.
addEvents
();
this
.
addPlugins
();
};
HookButton
.
prototype
=
Object
.
create
(
Hook
.
prototype
);
Object
.
assign
(
HookButton
.
prototype
,
{
addPlugins
:
function
()
{
this
.
plugins
.
forEach
(
plugin
=>
plugin
.
init
(
this
));
},
clicked
:
function
(
e
){
var
buttonEvent
=
new
CustomEvent
(
'
click.dl
'
,
{
detail
:
{
hook
:
this
,
},
bubbles
:
true
,
cancelable
:
true
});
e
.
target
.
dispatchEvent
(
buttonEvent
);
this
.
list
.
toggle
();
},
addEvents
:
function
(){
this
.
eventWrapper
.
clicked
=
this
.
clicked
.
bind
(
this
);
this
.
trigger
.
addEventListener
(
'
click
'
,
this
.
eventWrapper
.
clicked
);
},
removeEvents
:
function
(){
this
.
trigger
.
removeEventListener
(
'
click
'
,
this
.
eventWrapper
.
clicked
);
},
restoreInitialState
:
function
()
{
this
.
list
.
list
.
innerHTML
=
this
.
list
.
initialState
;
},
removePlugins
:
function
()
{
this
.
plugins
.
forEach
(
plugin
=>
plugin
.
destroy
());
},
destroy
:
function
()
{
this
.
restoreInitialState
();
this
.
removeEvents
();
this
.
removePlugins
();
},
constructor
:
HookButton
,
});
export
default
HookButton
;
app/assets/javascripts/droplab/hook_input.js
0 → 100644
View file @
dab60475
/* eslint-disable */
import
Hook
from
'
./hook
'
;
var
HookInput
=
function
(
trigger
,
list
,
plugins
,
config
)
{
Hook
.
call
(
this
,
trigger
,
list
,
plugins
,
config
);
this
.
type
=
'
input
'
;
this
.
event
=
'
input
'
;
this
.
eventWrapper
=
{};
this
.
addEvents
();
this
.
addPlugins
();
};
Object
.
assign
(
HookInput
.
prototype
,
{
addPlugins
:
function
()
{
this
.
plugins
.
forEach
(
plugin
=>
plugin
.
init
(
this
));
},
addEvents
:
function
(){
this
.
eventWrapper
.
mousedown
=
this
.
mousedown
.
bind
(
this
);
this
.
eventWrapper
.
input
=
this
.
input
.
bind
(
this
);
this
.
eventWrapper
.
keyup
=
this
.
keyup
.
bind
(
this
);
this
.
eventWrapper
.
keydown
=
this
.
keydown
.
bind
(
this
);
this
.
trigger
.
addEventListener
(
'
mousedown
'
,
this
.
eventWrapper
.
mousedown
);
this
.
trigger
.
addEventListener
(
'
input
'
,
this
.
eventWrapper
.
input
);
this
.
trigger
.
addEventListener
(
'
keyup
'
,
this
.
eventWrapper
.
keyup
);
this
.
trigger
.
addEventListener
(
'
keydown
'
,
this
.
eventWrapper
.
keydown
);
},
removeEvents
:
function
()
{
this
.
hasRemovedEvents
=
true
;
this
.
trigger
.
removeEventListener
(
'
mousedown
'
,
this
.
eventWrapper
.
mousedown
);
this
.
trigger
.
removeEventListener
(
'
input
'
,
this
.
eventWrapper
.
input
);
this
.
trigger
.
removeEventListener
(
'
keyup
'
,
this
.
eventWrapper
.
keyup
);
this
.
trigger
.
removeEventListener
(
'
keydown
'
,
this
.
eventWrapper
.
keydown
);
},
input
:
function
(
e
)
{
if
(
this
.
hasRemovedEvents
)
return
;
this
.
list
.
show
();
const
inputEvent
=
new
CustomEvent
(
'
input.dl
'
,
{
detail
:
{
hook
:
this
,
text
:
e
.
target
.
value
,
},
bubbles
:
true
,
cancelable
:
true
});
e
.
target
.
dispatchEvent
(
inputEvent
);
},
mousedown
:
function
(
e
)
{
if
(
this
.
hasRemovedEvents
)
return
;
const
mouseEvent
=
new
CustomEvent
(
'
mousedown.dl
'
,
{
detail
:
{
hook
:
this
,
text
:
e
.
target
.
value
,
},
bubbles
:
true
,
cancelable
:
true
,
});
e
.
target
.
dispatchEvent
(
mouseEvent
);
},
keyup
:
function
(
e
)
{
if
(
this
.
hasRemovedEvents
)
return
;
this
.
keyEvent
(
e
,
'
keyup.dl
'
);
},
keydown
:
function
(
e
)
{
if
(
this
.
hasRemovedEvents
)
return
;
this
.
keyEvent
(
e
,
'
keydown.dl
'
);
},
keyEvent
:
function
(
e
,
eventName
)
{
this
.
list
.
show
();
const
keyEvent
=
new
CustomEvent
(
eventName
,
{
detail
:
{
hook
:
this
,
text
:
e
.
target
.
value
,
which
:
e
.
which
,
key
:
e
.
key
,
},
bubbles
:
true
,
cancelable
:
true
,
});
e
.
target
.
dispatchEvent
(
keyEvent
);
},
restoreInitialState
:
function
()
{
this
.
list
.
list
.
innerHTML
=
this
.
list
.
initialState
;
},
removePlugins
:
function
()
{
this
.
plugins
.
forEach
(
plugin
=>
plugin
.
destroy
());
},
destroy
:
function
()
{
this
.
restoreInitialState
();
this
.
removeEvents
();
this
.
removePlugins
();
this
.
list
.
destroy
();
}
});
export
default
HookInput
;
app/assets/javascripts/droplab/keyboard.js
0 → 100644
View file @
dab60475
/* eslint-disable */
import
{
ACTIVE_CLASS
}
from
'
./constants
'
;
const
Keyboard
=
function
()
{
var
currentKey
;
var
currentFocus
;
var
isUpArrow
=
false
;
var
isDownArrow
=
false
;
var
removeHighlight
=
function
removeHighlight
(
list
)
{
var
itemElements
=
Array
.
prototype
.
slice
.
call
(
list
.
list
.
querySelectorAll
(
'
li:not(.divider)
'
),
0
);
var
listItems
=
[];
for
(
var
i
=
0
;
i
<
itemElements
.
length
;
i
++
)
{
var
listItem
=
itemElements
[
i
];
listItem
.
classList
.
remove
(
ACTIVE_CLASS
);
if
(
listItem
.
style
.
display
!==
'
none
'
)
{
listItems
.
push
(
listItem
);
}
}
return
listItems
;
};
var
setMenuForArrows
=
function
setMenuForArrows
(
list
)
{
var
listItems
=
removeHighlight
(
list
);
if
(
list
.
currentIndex
>
0
){
if
(
!
listItems
[
list
.
currentIndex
-
1
]){
list
.
currentIndex
=
list
.
currentIndex
-
1
;
}
if
(
listItems
[
list
.
currentIndex
-
1
])
{
var
el
=
listItems
[
list
.
currentIndex
-
1
];
var
filterDropdownEl
=
el
.
closest
(
'
.filter-dropdown
'
);
el
.
classList
.
add
(
ACTIVE_CLASS
);
if
(
filterDropdownEl
)
{
var
filterDropdownBottom
=
filterDropdownEl
.
offsetHeight
;
var
elOffsetTop
=
el
.
offsetTop
-
30
;
if
(
elOffsetTop
>
filterDropdownBottom
)
{
filterDropdownEl
.
scrollTop
=
elOffsetTop
-
filterDropdownBottom
;
}
}
}
}
};
var
mousedown
=
function
mousedown
(
e
)
{
var
list
=
e
.
detail
.
hook
.
list
;
removeHighlight
(
list
);
list
.
show
();
list
.
currentIndex
=
0
;
isUpArrow
=
false
;
isDownArrow
=
false
;
};
var
selectItem
=
function
selectItem
(
list
)
{
var
listItems
=
removeHighlight
(
list
);
var
currentItem
=
listItems
[
list
.
currentIndex
-
1
];
var
listEvent
=
new
CustomEvent
(
'
click.dl
'
,
{
detail
:
{
list
:
list
,
selected
:
currentItem
,
data
:
currentItem
.
dataset
,
},
});
list
.
list
.
dispatchEvent
(
listEvent
);
list
.
hide
();
}
var
keydown
=
function
keydown
(
e
){
var
typedOn
=
e
.
target
;
var
list
=
e
.
detail
.
hook
.
list
;
var
currentIndex
=
list
.
currentIndex
;
isUpArrow
=
false
;
isDownArrow
=
false
;
if
(
e
.
detail
.
which
){
currentKey
=
e
.
detail
.
which
;
if
(
currentKey
===
13
){
selectItem
(
e
.
detail
.
hook
.
list
);
return
;
}
if
(
currentKey
===
38
)
{
isUpArrow
=
true
;
}
if
(
currentKey
===
40
)
{
isDownArrow
=
true
;
}
}
else
if
(
e
.
detail
.
key
)
{
currentKey
=
e
.
detail
.
key
;
if
(
currentKey
===
'
Enter
'
){
selectItem
(
e
.
detail
.
hook
.
list
);
return
;
}
if
(
currentKey
===
'
ArrowUp
'
)
{
isUpArrow
=
true
;
}
if
(
currentKey
===
'
ArrowDown
'
)
{
isDownArrow
=
true
;
}
}
if
(
isUpArrow
){
currentIndex
--
;
}
if
(
isDownArrow
){
currentIndex
++
;
}
if
(
currentIndex
<
0
){
currentIndex
=
0
;
}
list
.
currentIndex
=
currentIndex
;
setMenuForArrows
(
e
.
detail
.
hook
.
list
);
};
document
.
addEventListener
(
'
mousedown.dl
'
,
mousedown
);
document
.
addEventListener
(
'
keydown.dl
'
,
keydown
);
};
export
default
Keyboard
;
app/assets/javascripts/droplab/plugins/ajax.js
0 → 100644
View file @
dab60475
/* eslint-disable */
const
Ajax
=
{
_loadUrlData
:
function
_loadUrlData
(
url
)
{
var
self
=
this
;
return
new
Promise
(
function
(
resolve
,
reject
)
{
var
xhr
=
new
XMLHttpRequest
;
xhr
.
open
(
'
GET
'
,
url
,
true
);
xhr
.
onreadystatechange
=
function
()
{
if
(
xhr
.
readyState
===
XMLHttpRequest
.
DONE
)
{
if
(
xhr
.
status
===
200
)
{
var
data
=
JSON
.
parse
(
xhr
.
responseText
);
self
.
cache
[
url
]
=
data
;
return
resolve
(
data
);
}
else
{
return
reject
([
xhr
.
responseText
,
xhr
.
status
]);
}
}
};
xhr
.
send
();
});
},
_loadData
:
function
_loadData
(
data
,
config
,
self
)
{
if
(
config
.
loadingTemplate
)
{
var
dataLoadingTemplate
=
self
.
hook
.
list
.
list
.
querySelector
(
'
[data-loading-template]
'
);
if
(
dataLoadingTemplate
)
dataLoadingTemplate
.
outerHTML
=
self
.
listTemplate
;
}
if
(
!
self
.
destroyed
)
self
.
hook
.
list
[
config
.
method
].
call
(
self
.
hook
.
list
,
data
);
},
init
:
function
init
(
hook
)
{
var
self
=
this
;
self
.
destroyed
=
false
;
self
.
cache
=
self
.
cache
||
{};
var
config
=
hook
.
config
.
Ajax
;
this
.
hook
=
hook
;
if
(
!
config
||
!
config
.
endpoint
||
!
config
.
method
)
{
return
;
}
if
(
config
.
method
!==
'
setData
'
&&
config
.
method
!==
'
addData
'
)
{
return
;
}
if
(
config
.
loadingTemplate
)
{
var
dynamicList
=
hook
.
list
.
list
.
querySelector
(
'
[data-dynamic]
'
);
var
loadingTemplate
=
document
.
createElement
(
'
div
'
);
loadingTemplate
.
innerHTML
=
config
.
loadingTemplate
;
loadingTemplate
.
setAttribute
(
'
data-loading-template
'
,
''
);
this
.
listTemplate
=
dynamicList
.
outerHTML
;
dynamicList
.
outerHTML
=
loadingTemplate
.
outerHTML
;
}
if
(
self
.
cache
[
config
.
endpoint
])
{
self
.
_loadData
(
self
.
cache
[
config
.
endpoint
],
config
,
self
);
}
else
{
this
.
_loadUrlData
(
config
.
endpoint
)
.
then
(
function
(
d
)
{
self
.
_loadData
(
d
,
config
,
self
);
},
config
.
onError
).
catch
(
config
.
onError
);
}
},
destroy
:
function
()
{
this
.
destroyed
=
true
;
}
};
export
default
Ajax
;
app/assets/javascripts/droplab/plugins/ajax_filter.js
0 → 100644
View file @
dab60475
/* eslint-disable */
const
AjaxFilter
=
{
init
:
function
(
hook
)
{
this
.
destroyed
=
false
;
this
.
hook
=
hook
;
this
.
notLoading
();
this
.
eventWrapper
=
{};
this
.
eventWrapper
.
debounceTrigger
=
this
.
debounceTrigger
.
bind
(
this
);
this
.
hook
.
trigger
.
addEventListener
(
'
keydown.dl
'
,
this
.
eventWrapper
.
debounceTrigger
);
this
.
hook
.
trigger
.
addEventListener
(
'
focus
'
,
this
.
eventWrapper
.
debounceTrigger
);
this
.
trigger
(
true
);
},
notLoading
:
function
notLoading
()
{
this
.
loading
=
false
;
},
debounceTrigger
:
function
debounceTrigger
(
e
)
{
var
NON_CHARACTER_KEYS
=
[
16
,
17
,
18
,
20
,
37
,
38
,
39
,
40
,
91
,
93
];
var
invalidKeyPressed
=
NON_CHARACTER_KEYS
.
indexOf
(
e
.
detail
.
which
||
e
.
detail
.
keyCode
)
>
-
1
;
var
focusEvent
=
e
.
type
===
'
focus
'
;
if
(
invalidKeyPressed
||
this
.
loading
)
{
return
;
}
if
(
this
.
timeout
)
{
clearTimeout
(
this
.
timeout
);
}
this
.
timeout
=
setTimeout
(
this
.
trigger
.
bind
(
this
,
focusEvent
),
200
);
},
trigger
:
function
trigger
(
getEntireList
)
{
var
config
=
this
.
hook
.
config
.
AjaxFilter
;
var
searchValue
=
this
.
trigger
.
value
;
if
(
!
config
||
!
config
.
endpoint
||
!
config
.
searchKey
)
{
return
;
}
if
(
config
.
searchValueFunction
)
{
searchValue
=
config
.
searchValueFunction
();
}
if
(
config
.
loadingTemplate
&&
this
.
hook
.
list
.
data
===
undefined
||
this
.
hook
.
list
.
data
.
length
===
0
)
{
var
dynamicList
=
this
.
hook
.
list
.
list
.
querySelector
(
'
[data-dynamic]
'
);
var
loadingTemplate
=
document
.
createElement
(
'
div
'
);
loadingTemplate
.
innerHTML
=
config
.
loadingTemplate
;
loadingTemplate
.
setAttribute
(
'
data-loading-template
'
,
true
);
this
.
listTemplate
=
dynamicList
.
outerHTML
;
dynamicList
.
outerHTML
=
loadingTemplate
.
outerHTML
;
}
if
(
getEntireList
)
{
searchValue
=
''
;
}
if
(
config
.
searchKey
===
searchValue
)
{
return
this
.
list
.
show
();
}
this
.
loading
=
true
;
var
params
=
config
.
params
||
{};
params
[
config
.
searchKey
]
=
searchValue
;
var
self
=
this
;
self
.
cache
=
self
.
cache
||
{};
var
url
=
config
.
endpoint
+
this
.
buildParams
(
params
);
var
urlCachedData
=
self
.
cache
[
url
];
if
(
urlCachedData
)
{
self
.
_loadData
(
urlCachedData
,
config
,
self
);
}
else
{
this
.
_loadUrlData
(
url
)
.
then
(
function
(
data
)
{
self
.
_loadData
(
data
,
config
,
self
);
},
config
.
onError
).
catch
(
config
.
onError
);
}
},
_loadUrlData
:
function
_loadUrlData
(
url
)
{
var
self
=
this
;
return
new
Promise
(
function
(
resolve
,
reject
)
{
var
xhr
=
new
XMLHttpRequest
;
xhr
.
open
(
'
GET
'
,
url
,
true
);
xhr
.
onreadystatechange
=
function
()
{
if
(
xhr
.
readyState
===
XMLHttpRequest
.
DONE
)
{
if
(
xhr
.
status
===
200
)
{
var
data
=
JSON
.
parse
(
xhr
.
responseText
);
self
.
cache
[
url
]
=
data
;
return
resolve
(
data
);
}
else
{
return
reject
([
xhr
.
responseText
,
xhr
.
status
]);
}
}
};
xhr
.
send
();
});
},
_loadData
:
function
_loadData
(
data
,
config
,
self
)
{
const
list
=
self
.
hook
.
list
;
if
(
config
.
loadingTemplate
&&
list
.
data
===
undefined
||
list
.
data
.
length
===
0
)
{
const
dataLoadingTemplate
=
list
.
list
.
querySelector
(
'
[data-loading-template]
'
);
if
(
dataLoadingTemplate
)
{
dataLoadingTemplate
.
outerHTML
=
self
.
listTemplate
;
}
}
if
(
!
self
.
destroyed
)
{
var
hookListChildren
=
list
.
list
.
children
;
var
onlyDynamicList
=
hookListChildren
.
length
===
1
&&
hookListChildren
[
0
].
hasAttribute
(
'
data-dynamic
'
);
if
(
onlyDynamicList
&&
data
.
length
===
0
)
{
list
.
hide
();
}
list
.
setData
.
call
(
list
,
data
);
}
self
.
notLoading
();
list
.
currentIndex
=
0
;
},
buildParams
:
function
(
params
)
{
if
(
!
params
)
return
''
;
var
paramsArray
=
Object
.
keys
(
params
).
map
(
function
(
param
)
{
return
param
+
'
=
'
+
(
params
[
param
]
||
''
);
});
return
'
?
'
+
paramsArray
.
join
(
'
&
'
);
},
destroy
:
function
destroy
()
{
if
(
this
.
timeout
)
clearTimeout
(
this
.
timeout
);
this
.
destroyed
=
true
;
this
.
hook
.
trigger
.
removeEventListener
(
'
keydown.dl
'
,
this
.
eventWrapper
.
debounceTrigger
);
this
.
hook
.
trigger
.
removeEventListener
(
'
focus
'
,
this
.
eventWrapper
.
debounceTrigger
);
}
};
export
default
AjaxFilter
;
app/assets/javascripts/droplab/plugins/filter.js
0 → 100644
View file @
dab60475
/* eslint-disable */
const
Filter
=
{
keydown
:
function
(
e
){
if
(
this
.
destroyed
)
return
;
var
hiddenCount
=
0
;
var
dataHiddenCount
=
0
;
var
list
=
e
.
detail
.
hook
.
list
;
var
data
=
list
.
data
;
var
value
=
e
.
detail
.
hook
.
trigger
.
value
.
toLowerCase
();
var
config
=
e
.
detail
.
hook
.
config
.
Filter
;
var
matches
=
[];
var
filterFunction
;
// will only work on dynamically set data
if
(
!
data
){
return
;
}
if
(
config
&&
config
.
filterFunction
&&
typeof
config
.
filterFunction
===
'
function
'
)
{
filterFunction
=
config
.
filterFunction
;
}
else
{
filterFunction
=
function
(
o
){
// cheap string search
o
.
droplab_hidden
=
o
[
config
.
template
].
toLowerCase
().
indexOf
(
value
)
===
-
1
;
return
o
;
};
}
dataHiddenCount
=
data
.
filter
(
function
(
o
)
{
return
!
o
.
droplab_hidden
;
}).
length
;
matches
=
data
.
map
(
function
(
o
)
{
return
filterFunction
(
o
,
value
);
});
hiddenCount
=
matches
.
filter
(
function
(
o
)
{
return
!
o
.
droplab_hidden
;
}).
length
;
if
(
dataHiddenCount
!==
hiddenCount
)
{
list
.
setData
(
matches
);
list
.
currentIndex
=
0
;
}
},
debounceKeydown
:
function
debounceKeydown
(
e
)
{
if
([
13
,
// enter
16
,
// shift
17
,
// ctrl
18
,
// alt
20
,
// caps lock
37
,
// left arrow
38
,
// up arrow
39
,
// right arrow
40
,
// down arrow
91
,
// left window
92
,
// right window
93
,
// select
].
indexOf
(
e
.
detail
.
which
||
e
.
detail
.
keyCode
)
>
-
1
)
return
;
if
(
this
.
timeout
)
clearTimeout
(
this
.
timeout
);
this
.
timeout
=
setTimeout
(
this
.
keydown
.
bind
(
this
,
e
),
200
);
},
init
:
function
init
(
hook
)
{
var
config
=
hook
.
config
.
Filter
;
if
(
!
config
||
!
config
.
template
)
return
;
this
.
hook
=
hook
;
this
.
destroyed
=
false
;
this
.
eventWrapper
=
{};
this
.
eventWrapper
.
debounceKeydown
=
this
.
debounceKeydown
.
bind
(
this
);
this
.
hook
.
trigger
.
addEventListener
(
'
keydown.dl
'
,
this
.
eventWrapper
.
debounceKeydown
);
this
.
hook
.
trigger
.
addEventListener
(
'
mousedown.dl
'
,
this
.
eventWrapper
.
debounceKeydown
);
this
.
debounceKeydown
({
detail
:
{
hook
:
this
.
hook
}
});
},
destroy
:
function
destroy
()
{
if
(
this
.
timeout
)
clearTimeout
(
this
.
timeout
);
this
.
destroyed
=
true
;
this
.
hook
.
trigger
.
removeEventListener
(
'
keydown.dl
'
,
this
.
eventWrapper
.
debounceKeydown
);
this
.
hook
.
trigger
.
removeEventListener
(
'
mousedown.dl
'
,
this
.
eventWrapper
.
debounceKeydown
);
}
};
export
default
Filter
;
app/assets/javascripts/droplab/plugins/input_setter.js
0 → 100644
View file @
dab60475
/* eslint-disable */
const
InputSetter
=
{
init
(
hook
)
{
this
.
hook
=
hook
;
this
.
destroyed
=
false
;
this
.
config
=
hook
.
config
.
InputSetter
||
(
this
.
hook
.
config
.
InputSetter
=
{});
this
.
eventWrapper
=
{};
this
.
addEvents
();
},
addEvents
()
{
this
.
eventWrapper
.
setInputs
=
this
.
setInputs
.
bind
(
this
);
this
.
hook
.
list
.
list
.
addEventListener
(
'
click.dl
'
,
this
.
eventWrapper
.
setInputs
);
},
removeEvents
()
{
this
.
hook
.
list
.
list
.
removeEventListener
(
'
click.dl
'
,
this
.
eventWrapper
.
setInputs
);
},
setInputs
(
e
)
{
if
(
this
.
destroyed
)
return
;
const
selectedItem
=
e
.
detail
.
selected
;
if
(
!
Array
.
isArray
(
this
.
config
))
this
.
config
=
[
this
.
config
];
this
.
config
.
forEach
(
config
=>
this
.
setInput
(
config
,
selectedItem
));
},
setInput
(
config
,
selectedItem
)
{
const
input
=
config
.
input
||
this
.
hook
.
trigger
;
const
newValue
=
selectedItem
.
getAttribute
(
config
.
valueAttribute
);
const
inputAttribute
=
config
.
inputAttribute
;
if
(
!
newValue
)
return
;
if
(
input
.
hasAttribute
(
inputAttribute
))
return
input
.
setAttribute
(
inputAttribute
,
newValue
);
if
(
input
.
tagName
===
'
INPUT
'
)
return
input
.
value
=
newValue
;
return
input
.
textContent
=
newValue
;
},
destroy
()
{
this
.
destroyed
=
true
;
this
.
removeEvents
();
},
};
export
default
InputSetter
;
app/assets/javascripts/droplab/utils.js
0 → 100644
View file @
dab60475
/* eslint-disable */
import
{
DATA_TRIGGER
,
DATA_DROPDOWN
}
from
'
./constants
'
;
const
utils
=
{
toCamelCase
(
attr
)
{
return
this
.
camelize
(
attr
.
split
(
'
-
'
).
slice
(
1
).
join
(
'
'
));
},
t
(
s
,
d
)
{
for
(
const
p
in
d
)
{
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
d
,
p
))
{
s
=
s
.
replace
(
new
RegExp
(
`{{
${
p
}
}}`
,
'
g
'
),
d
[
p
]);
}
}
return
s
;
},
camelize
(
str
)
{
return
str
.
replace
(
/
(?:
^
\w
|
[
A-Z
]
|
\b\w)
/g
,
(
letter
,
index
)
=>
{
return
index
===
0
?
letter
.
toLowerCase
()
:
letter
.
toUpperCase
();
}).
replace
(
/
\s
+/g
,
''
);
},
closest
(
thisTag
,
stopTag
)
{
while
(
thisTag
&&
thisTag
.
tagName
!==
stopTag
&&
thisTag
.
tagName
!==
'
HTML
'
)
{
thisTag
=
thisTag
.
parentNode
;
}
return
thisTag
;
},
isDropDownParts
(
target
)
{
if
(
!
target
||
target
.
tagName
===
'
HTML
'
)
return
false
;
return
target
.
hasAttribute
(
DATA_TRIGGER
)
||
target
.
hasAttribute
(
DATA_DROPDOWN
);
},
};
export
default
utils
;
app/assets/javascripts/filtered_search/dropdown_hint.js
View file @
dab60475
require
(
'
./filtered_search_dropdown
'
)
;
import
Filter
from
'
~/droplab/plugins/filter
'
;
/* global droplabFilter */
require
(
'
./filtered_search_dropdown
'
);
(()
=>
{
(()
=>
{
class
DropdownHint
extends
gl
.
FilteredSearchDropdown
{
class
DropdownHint
extends
gl
.
FilteredSearchDropdown
{
constructor
(
droplab
,
dropdown
,
input
,
filter
)
{
constructor
(
droplab
,
dropdown
,
input
,
filter
)
{
super
(
droplab
,
dropdown
,
input
,
filter
);
super
(
droplab
,
dropdown
,
input
,
filter
);
this
.
config
=
{
this
.
config
=
{
droplab
Filter
:
{
Filter
:
{
template
:
'
hint
'
,
template
:
'
hint
'
,
filterFunction
:
gl
.
DropdownUtils
.
filterHint
.
bind
(
null
,
input
),
filterFunction
:
gl
.
DropdownUtils
.
filterHint
.
bind
(
null
,
input
),
},
},
...
@@ -69,12 +69,12 @@ require('./filtered_search_dropdown');
...
@@ -69,12 +69,12 @@ require('./filtered_search_dropdown');
}
}
});
});
this
.
droplab
.
changeHookList
(
this
.
hookId
,
this
.
dropdown
,
[
droplab
Filter
],
this
.
config
);
this
.
droplab
.
changeHookList
(
this
.
hookId
,
this
.
dropdown
,
[
Filter
],
this
.
config
);
this
.
droplab
.
setData
(
this
.
hookId
,
dropdownData
);
this
.
droplab
.
setData
(
this
.
hookId
,
dropdownData
);
}
}
init
()
{
init
()
{
this
.
droplab
.
addHook
(
this
.
input
,
this
.
dropdown
,
[
droplab
Filter
],
this
.
config
).
init
();
this
.
droplab
.
addHook
(
this
.
input
,
this
.
dropdown
,
[
Filter
],
this
.
config
).
init
();
}
}
}
}
...
...
app/assets/javascripts/filtered_search/dropdown_non_user.js
View file @
dab60475
require
(
'
./filtered_search_dropdown
'
);
/* global Flash */
import
Ajax
from
'
~/droplab/plugins/ajax
'
;
import
Filter
from
'
~/droplab/plugins/filter
'
;
/* global droplabAjax */
require
(
'
./filtered_search_dropdown
'
);
/* global droplabFilter */
(()
=>
{
(()
=>
{
class
DropdownNonUser
extends
gl
.
FilteredSearchDropdown
{
class
DropdownNonUser
extends
gl
.
FilteredSearchDropdown
{
...
@@ -9,13 +11,19 @@ require('./filtered_search_dropdown');
...
@@ -9,13 +11,19 @@ require('./filtered_search_dropdown');
super
(
droplab
,
dropdown
,
input
,
filter
);
super
(
droplab
,
dropdown
,
input
,
filter
);
this
.
symbol
=
symbol
;
this
.
symbol
=
symbol
;
this
.
config
=
{
this
.
config
=
{
droplab
Ajax
:
{
Ajax
:
{
endpoint
,
endpoint
,
method
:
'
setData
'
,
method
:
'
setData
'
,
loadingTemplate
:
this
.
loadingTemplate
,
loadingTemplate
:
this
.
loadingTemplate
,
onError
()
{
/* eslint-disable no-new */
new
Flash
(
'
An error occured fetching the dropdown data.
'
);
/* eslint-enable no-new */
},
},
},
droplab
Filter
:
{
Filter
:
{
filterFunction
:
gl
.
DropdownUtils
.
filterWithSymbol
.
bind
(
null
,
this
.
symbol
,
input
),
filterFunction
:
gl
.
DropdownUtils
.
filterWithSymbol
.
bind
(
null
,
this
.
symbol
,
input
),
template
:
'
title
'
,
},
},
};
};
}
}
...
@@ -29,13 +37,13 @@ require('./filtered_search_dropdown');
...
@@ -29,13 +37,13 @@ require('./filtered_search_dropdown');
renderContent
(
forceShowList
=
false
)
{
renderContent
(
forceShowList
=
false
)
{
this
.
droplab
this
.
droplab
.
changeHookList
(
this
.
hookId
,
this
.
dropdown
,
[
droplabAjax
,
droplab
Filter
],
this
.
config
);
.
changeHookList
(
this
.
hookId
,
this
.
dropdown
,
[
Ajax
,
Filter
],
this
.
config
);
super
.
renderContent
(
forceShowList
);
super
.
renderContent
(
forceShowList
);
}
}
init
()
{
init
()
{
this
.
droplab
this
.
droplab
.
addHook
(
this
.
input
,
this
.
dropdown
,
[
droplabAjax
,
droplab
Filter
],
this
.
config
).
init
();
.
addHook
(
this
.
input
,
this
.
dropdown
,
[
Ajax
,
Filter
],
this
.
config
).
init
();
}
}
}
}
...
...
app/assets/javascripts/filtered_search/dropdown_user.js
View file @
dab60475
require
(
'
./filtered_search_dropdown
'
);
/* global Flash */
import
AjaxFilter
from
'
~/droplab/plugins/ajax_filter
'
;
/* global droplabAjaxFilter */
require
(
'
./filtered_search_dropdown
'
);
(()
=>
{
(()
=>
{
class
DropdownUser
extends
gl
.
FilteredSearchDropdown
{
class
DropdownUser
extends
gl
.
FilteredSearchDropdown
{
constructor
(
droplab
,
dropdown
,
input
,
filter
)
{
constructor
(
droplab
,
dropdown
,
input
,
filter
)
{
super
(
droplab
,
dropdown
,
input
,
filter
);
super
(
droplab
,
dropdown
,
input
,
filter
);
this
.
config
=
{
this
.
config
=
{
droplab
AjaxFilter
:
{
AjaxFilter
:
{
endpoint
:
`
${
gon
.
relative_url_root
||
''
}
/autocomplete/users.json`
,
endpoint
:
`
${
gon
.
relative_url_root
||
''
}
/autocomplete/users.json`
,
searchKey
:
'
search
'
,
searchKey
:
'
search
'
,
params
:
{
params
:
{
...
@@ -18,6 +20,11 @@ require('./filtered_search_dropdown');
...
@@ -18,6 +20,11 @@ require('./filtered_search_dropdown');
},
},
searchValueFunction
:
this
.
getSearchInput
.
bind
(
this
),
searchValueFunction
:
this
.
getSearchInput
.
bind
(
this
),
loadingTemplate
:
this
.
loadingTemplate
,
loadingTemplate
:
this
.
loadingTemplate
,
onError
()
{
/* eslint-disable no-new */
new
Flash
(
'
An error occured fetching the dropdown data.
'
);
/* eslint-enable no-new */
},
},
},
};
};
}
}
...
@@ -28,7 +35,7 @@ require('./filtered_search_dropdown');
...
@@ -28,7 +35,7 @@ require('./filtered_search_dropdown');
}
}
renderContent
(
forceShowList
=
false
)
{
renderContent
(
forceShowList
=
false
)
{
this
.
droplab
.
changeHookList
(
this
.
hookId
,
this
.
dropdown
,
[
droplab
AjaxFilter
],
this
.
config
);
this
.
droplab
.
changeHookList
(
this
.
hookId
,
this
.
dropdown
,
[
AjaxFilter
],
this
.
config
);
super
.
renderContent
(
forceShowList
);
super
.
renderContent
(
forceShowList
);
}
}
...
@@ -56,7 +63,7 @@ require('./filtered_search_dropdown');
...
@@ -56,7 +63,7 @@ require('./filtered_search_dropdown');
}
}
init
()
{
init
()
{
this
.
droplab
.
addHook
(
this
.
input
,
this
.
dropdown
,
[
droplab
AjaxFilter
],
this
.
config
).
init
();
this
.
droplab
.
addHook
(
this
.
input
,
this
.
dropdown
,
[
AjaxFilter
],
this
.
config
).
init
();
}
}
}
}
...
...
app/assets/javascripts/filtered_search/filtered_search_dropdown.js
View file @
dab60475
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
class
FilteredSearchDropdown
{
class
FilteredSearchDropdown
{
constructor
(
droplab
,
dropdown
,
input
,
filter
)
{
constructor
(
droplab
,
dropdown
,
input
,
filter
)
{
this
.
droplab
=
droplab
;
this
.
droplab
=
droplab
;
this
.
hookId
=
input
&&
input
.
getAttribute
(
'
data-id
'
)
;
this
.
hookId
=
input
&&
input
.
id
;
this
.
input
=
input
;
this
.
input
=
input
;
this
.
filter
=
filter
;
this
.
filter
=
filter
;
this
.
dropdown
=
dropdown
;
this
.
dropdown
=
dropdown
;
...
...
app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js
View file @
dab60475
/* global DropLab */
import
DropLab
from
'
~/droplab/drop_lab
'
;
import
FilteredSearchContainer
from
'
./container
'
;
import
FilteredSearchContainer
from
'
./container
'
;
(()
=>
{
(()
=>
{
...
...
app/assets/javascripts/filtered_search/filtered_search_manager.js
View file @
dab60475
...
@@ -154,7 +154,7 @@ import eventHub from './event_hub';
...
@@ -154,7 +154,7 @@ import eventHub from './event_hub';
if
(
e
.
keyCode
===
13
)
{
if
(
e
.
keyCode
===
13
)
{
const
dropdown
=
this
.
dropdownManager
.
mapping
[
this
.
dropdownManager
.
currentDropdown
];
const
dropdown
=
this
.
dropdownManager
.
mapping
[
this
.
dropdownManager
.
currentDropdown
];
const
dropdownEl
=
dropdown
.
element
;
const
dropdownEl
=
dropdown
.
element
;
const
activeElements
=
dropdownEl
.
querySelectorAll
(
'
.drop
down
-active
'
);
const
activeElements
=
dropdownEl
.
querySelectorAll
(
'
.drop
lab-item
-active
'
);
e
.
preventDefault
();
e
.
preventDefault
();
...
...
app/assets/javascripts/main.js
View file @
dab60475
...
@@ -75,12 +75,6 @@ import './u2f/error';
...
@@ -75,12 +75,6 @@ import './u2f/error';
import
'
./u2f/register
'
;
import
'
./u2f/register
'
;
import
'
./u2f/util
'
;
import
'
./u2f/util
'
;
// droplab
import
'
./droplab/droplab
'
;
import
'
./droplab/droplab_ajax
'
;
import
'
./droplab/droplab_ajax_filter
'
;
import
'
./droplab/droplab_filter
'
;
// everything else
// everything else
import
'
./abuse_reports
'
;
import
'
./abuse_reports
'
;
import
'
./activities
'
;
import
'
./activities
'
;
...
...
app/assets/stylesheets/framework/filters.scss
View file @
dab60475
...
@@ -446,10 +446,8 @@
...
@@ -446,10 +446,8 @@
}
}
}
}
.filter-dropdown-item.dropdown-active
{
.filter-dropdown-item.droplab-item-active
.btn
{
.btn
{
@extend
%filter-dropdown-item-btn-hover
;
@extend
%filter-dropdown-item-btn-hover
;
}
}
}
.filter-dropdown-loading
{
.filter-dropdown-loading
{
...
...
app/views/shared/issuable/_search_bar.html.haml
View file @
dab60475
...
@@ -23,7 +23,7 @@
...
@@ -23,7 +23,7 @@
.scroll-container
.scroll-container
%ul
.tokens-container.list-unstyled
%ul
.tokens-container.list-unstyled
%li
.input-token
%li
.input-token
%input
.form-control.filtered-search
{
placeholder:
'Search or filter results...'
,
data:
{
id:
"filtered-search-#{type.to_s}"
,
'project-id'
=>
@project
.
id
,
'username-params'
=>
@users
.
to_json
(
only:
[
:id
,
:username
]),
'base-endpoint'
=>
namespace_project_path
(
@project
.
namespace
,
@project
)
}
}
%input
.form-control.filtered-search
{
id:
"filtered-search-#{type.to_s}"
,
placeholder:
'Search or filter results...'
,
data:
{
'project-id'
=>
@project
.
id
,
'username-params'
=>
@users
.
to_json
(
only:
[
:id
,
:username
]),
'base-endpoint'
=>
namespace_project_path
(
@project
.
namespace
,
@project
)
}
}
=
icon
(
'filter'
)
=
icon
(
'filter'
)
%button
.clear-search.hidden
{
type:
'button'
}
%button
.clear-search.hidden
{
type:
'button'
}
=
icon
(
'times'
)
=
icon
(
'times'
)
...
...
spec/features/issues/filtered_search/dropdown_hint_spec.rb
View file @
dab60475
require
'rails_helper'
require
'rails_helper'
describe
'Dropdown hint'
,
js:
true
,
feature:
tru
e
do
describe
'Dropdown hint'
,
:js
,
:featur
e
do
include
FilteredSearchHelpers
include
FilteredSearchHelpers
include
WaitForAjax
include
WaitForAjax
...
@@ -9,10 +9,6 @@ describe 'Dropdown hint', js: true, feature: true do
...
@@ -9,10 +9,6 @@ describe 'Dropdown hint', js: true, feature: true do
let
(
:filtered_search
)
{
find
(
'.filtered-search'
)
}
let
(
:filtered_search
)
{
find
(
'.filtered-search'
)
}
let
(
:js_dropdown_hint
)
{
'#js-dropdown-hint'
}
let
(
:js_dropdown_hint
)
{
'#js-dropdown-hint'
}
def
dropdown_hint_size
page
.
all
(
'#js-dropdown-hint .filter-dropdown .filter-dropdown-item'
).
size
end
def
click_hint
(
text
)
def
click_hint
(
text
)
find
(
'#js-dropdown-hint .filter-dropdown .filter-dropdown-item'
,
text:
text
).
click
find
(
'#js-dropdown-hint .filter-dropdown .filter-dropdown-item'
,
text:
text
).
click
end
end
...
@@ -46,14 +42,16 @@ describe 'Dropdown hint', js: true, feature: true do
...
@@ -46,14 +42,16 @@ describe 'Dropdown hint', js: true, feature: true do
it
'does not filter `Press Enter or click to search`'
do
it
'does not filter `Press Enter or click to search`'
do
filtered_search
.
set
(
'randomtext'
)
filtered_search
.
set
(
'randomtext'
)
expect
(
page
).
to
have_css
(
js_dropdown_hint
,
text:
'Press Enter or click to search'
,
visible:
false
)
hint_dropdown
=
find
(
js_dropdown_hint
)
expect
(
dropdown_hint_size
).
to
eq
(
0
)
expect
(
hint_dropdown
).
to
have_content
(
'Press Enter or click to search'
)
expect
(
hint_dropdown
).
to
have_selector
(
'.filter-dropdown .filter-dropdown-item'
,
count:
0
)
end
end
it
'filters with text'
do
it
'filters with text'
do
filtered_search
.
set
(
'a'
)
filtered_search
.
set
(
'a'
)
expect
(
dropdown_hint_size
).
to
eq
(
3
)
expect
(
find
(
js_dropdown_hint
)).
to
have_selector
(
'.filter-dropdown .filter-dropdown-item'
,
count:
3
)
end
end
end
end
...
...
spec/features/issues/filtered_search/dropdown_label_spec.rb
View file @
dab60475
...
@@ -28,10 +28,6 @@ describe 'Dropdown label', js: true, feature: true do
...
@@ -28,10 +28,6 @@ describe 'Dropdown label', js: true, feature: true do
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
text
).
click
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
text
).
click
end
end
def
dropdown_label_size
filter_dropdown
.
all
(
'.filter-dropdown-item'
).
size
end
def
clear_search_field
def
clear_search_field
find
(
'.filtered-search-box .clear-search'
).
click
find
(
'.filtered-search-box .clear-search'
).
click
end
end
...
@@ -81,7 +77,7 @@ describe 'Dropdown label', js: true, feature: true do
...
@@ -81,7 +77,7 @@ describe 'Dropdown label', js: true, feature: true do
filtered_search
.
set
(
'label:'
)
filtered_search
.
set
(
'label:'
)
expect
(
filter_dropdown
).
to
have_content
(
bug_label
.
title
)
expect
(
filter_dropdown
).
to
have_content
(
bug_label
.
title
)
expect
(
dropdown_label_size
).
to
eq
(
1
)
expect
(
filter_dropdown
).
to
have_selector
(
'.filter-dropdown-item'
,
count:
1
)
end
end
end
end
...
@@ -97,7 +93,8 @@ describe 'Dropdown label', js: true, feature: true do
...
@@ -97,7 +93,8 @@ describe 'Dropdown label', js: true, feature: true do
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
bug_label
.
title
)).
to
be_visible
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
bug_label
.
title
)).
to
be_visible
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
uppercase_label
.
title
)).
to
be_visible
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
uppercase_label
.
title
)).
to
be_visible
expect
(
dropdown_label_size
).
to
eq
(
2
)
expect
(
filter_dropdown
).
to
have_selector
(
'.filter-dropdown-item'
,
count:
2
)
clear_search_field
clear_search_field
init_label_search
init_label_search
...
@@ -106,14 +103,14 @@ describe 'Dropdown label', js: true, feature: true do
...
@@ -106,14 +103,14 @@ describe 'Dropdown label', js: true, feature: true do
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
bug_label
.
title
)).
to
be_visible
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
bug_label
.
title
)).
to
be_visible
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
uppercase_label
.
title
)).
to
be_visible
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
uppercase_label
.
title
)).
to
be_visible
expect
(
dropdown_label_size
).
to
eq
(
2
)
expect
(
filter_dropdown
).
to
have_selector
(
'.filter-dropdown-item'
,
count:
2
)
end
end
it
'filters by multiple words with or without symbol'
do
it
'filters by multiple words with or without symbol'
do
filtered_search
.
send_keys
(
'Hig'
)
filtered_search
.
send_keys
(
'Hig'
)
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
two_words_label
.
title
)).
to
be_visible
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
two_words_label
.
title
)).
to
be_visible
expect
(
dropdown_label_size
).
to
eq
(
1
)
expect
(
filter_dropdown
).
to
have_selector
(
'.filter-dropdown-item'
,
count:
1
)
clear_search_field
clear_search_field
init_label_search
init_label_search
...
@@ -121,14 +118,14 @@ describe 'Dropdown label', js: true, feature: true do
...
@@ -121,14 +118,14 @@ describe 'Dropdown label', js: true, feature: true do
filtered_search
.
send_keys
(
'~Hig'
)
filtered_search
.
send_keys
(
'~Hig'
)
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
two_words_label
.
title
)).
to
be_visible
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
two_words_label
.
title
)).
to
be_visible
expect
(
dropdown_label_size
).
to
eq
(
1
)
expect
(
filter_dropdown
).
to
have_selector
(
'.filter-dropdown-item'
,
count:
1
)
end
end
it
'filters by multiple words containing single quotes with or without symbol'
do
it
'filters by multiple words containing single quotes with or without symbol'
do
filtered_search
.
send_keys
(
'won\'t'
)
filtered_search
.
send_keys
(
'won\'t'
)
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
wont_fix_single_label
.
title
)).
to
be_visible
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
wont_fix_single_label
.
title
)).
to
be_visible
expect
(
dropdown_label_size
).
to
eq
(
1
)
expect
(
filter_dropdown
).
to
have_selector
(
'.filter-dropdown-item'
,
count:
1
)
clear_search_field
clear_search_field
init_label_search
init_label_search
...
@@ -136,14 +133,14 @@ describe 'Dropdown label', js: true, feature: true do
...
@@ -136,14 +133,14 @@ describe 'Dropdown label', js: true, feature: true do
filtered_search
.
send_keys
(
'~won\'t'
)
filtered_search
.
send_keys
(
'~won\'t'
)
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
wont_fix_single_label
.
title
)).
to
be_visible
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
wont_fix_single_label
.
title
)).
to
be_visible
expect
(
dropdown_label_size
).
to
eq
(
1
)
expect
(
filter_dropdown
).
to
have_selector
(
'.filter-dropdown-item'
,
count:
1
)
end
end
it
'filters by multiple words containing double quotes with or without symbol'
do
it
'filters by multiple words containing double quotes with or without symbol'
do
filtered_search
.
send_keys
(
'won"t'
)
filtered_search
.
send_keys
(
'won"t'
)
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
wont_fix_label
.
title
)).
to
be_visible
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
wont_fix_label
.
title
)).
to
be_visible
expect
(
dropdown_label_size
).
to
eq
(
1
)
expect
(
filter_dropdown
).
to
have_selector
(
'.filter-dropdown-item'
,
count:
1
)
clear_search_field
clear_search_field
init_label_search
init_label_search
...
@@ -151,14 +148,14 @@ describe 'Dropdown label', js: true, feature: true do
...
@@ -151,14 +148,14 @@ describe 'Dropdown label', js: true, feature: true do
filtered_search
.
send_keys
(
'~won"t'
)
filtered_search
.
send_keys
(
'~won"t'
)
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
wont_fix_label
.
title
)).
to
be_visible
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
wont_fix_label
.
title
)).
to
be_visible
expect
(
dropdown_label_size
).
to
eq
(
1
)
expect
(
filter_dropdown
).
to
have_selector
(
'.filter-dropdown-item'
,
count:
1
)
end
end
it
'filters by special characters with or without symbol'
do
it
'filters by special characters with or without symbol'
do
filtered_search
.
send_keys
(
'^+'
)
filtered_search
.
send_keys
(
'^+'
)
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
special_label
.
title
)).
to
be_visible
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
special_label
.
title
)).
to
be_visible
expect
(
dropdown_label_size
).
to
eq
(
1
)
expect
(
filter_dropdown
).
to
have_selector
(
'.filter-dropdown-item'
,
count:
1
)
clear_search_field
clear_search_field
init_label_search
init_label_search
...
@@ -166,7 +163,7 @@ describe 'Dropdown label', js: true, feature: true do
...
@@ -166,7 +163,7 @@ describe 'Dropdown label', js: true, feature: true do
filtered_search
.
send_keys
(
'~^+'
)
filtered_search
.
send_keys
(
'~^+'
)
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
special_label
.
title
)).
to
be_visible
expect
(
filter_dropdown
.
find
(
'.filter-dropdown-item'
,
text:
special_label
.
title
)).
to
be_visible
expect
(
dropdown_label_size
).
to
eq
(
1
)
expect
(
filter_dropdown
).
to
have_selector
(
'.filter-dropdown-item'
,
count:
1
)
end
end
end
end
...
@@ -280,13 +277,13 @@ describe 'Dropdown label', js: true, feature: true do
...
@@ -280,13 +277,13 @@ describe 'Dropdown label', js: true, feature: true do
create
(
:label
,
project:
project
,
title:
'bug-label'
)
create
(
:label
,
project:
project
,
title:
'bug-label'
)
init_label_search
init_label_search
expect
(
dropdown_label_size
).
to
eq
(
1
)
expect
(
filter_dropdown
).
to
have_selector
(
'.filter-dropdown-item'
,
count:
1
)
create
(
:label
,
project:
project
)
create
(
:label
,
project:
project
)
clear_search_field
clear_search_field
init_label_search
init_label_search
expect
(
dropdown_label_size
).
to
eq
(
1
)
expect
(
filter_dropdown
).
to
have_selector
(
'.filter-dropdown-item'
,
count:
1
)
end
end
end
end
end
end
spec/features/issues/filtered_search/dropdown_milestone_spec.rb
View file @
dab60475
...
@@ -65,7 +65,7 @@ describe 'Dropdown milestone', :feature, :js do
...
@@ -65,7 +65,7 @@ describe 'Dropdown milestone', :feature, :js do
it
'should load all the milestones when opened'
do
it
'should load all the milestones when opened'
do
filtered_search
.
set
(
'milestone:'
)
filtered_search
.
set
(
'milestone:'
)
expect
(
dropdown_milestone_size
).
to
be
>
0
expect
(
filter_dropdown
).
to
have_selector
(
'.filter-dropdown .filter-dropdown-item'
,
count:
6
)
end
end
end
end
...
@@ -84,37 +84,37 @@ describe 'Dropdown milestone', :feature, :js do
...
@@ -84,37 +84,37 @@ describe 'Dropdown milestone', :feature, :js do
it
'filters by name'
do
it
'filters by name'
do
filtered_search
.
send_keys
(
'v1'
)
filtered_search
.
send_keys
(
'v1'
)
expect
(
dropdown_milestone_size
).
to
eq
(
1
)
expect
(
filter_dropdown
).
to
have_selector
(
'.filter-dropdown .filter-dropdown-item'
,
count:
1
)
end
end
it
'filters by case insensitive name'
do
it
'filters by case insensitive name'
do
filtered_search
.
send_keys
(
'V1'
)
filtered_search
.
send_keys
(
'V1'
)
expect
(
dropdown_milestone_size
).
to
eq
(
1
)
expect
(
filter_dropdown
).
to
have_selector
(
'.filter-dropdown .filter-dropdown-item'
,
count:
1
)
end
end
it
'filters by name with symbol'
do
it
'filters by name with symbol'
do
filtered_search
.
send_keys
(
'%v1'
)
filtered_search
.
send_keys
(
'%v1'
)
expect
(
dropdown_milestone_size
).
to
eq
(
1
)
expect
(
filter_dropdown
).
to
have_selector
(
'.filter-dropdown .filter-dropdown-item'
,
count:
1
)
end
end
it
'filters by case insensitive name with symbol'
do
it
'filters by case insensitive name with symbol'
do
filtered_search
.
send_keys
(
'%V1'
)
filtered_search
.
send_keys
(
'%V1'
)
expect
(
dropdown_milestone_size
).
to
eq
(
1
)
expect
(
filter_dropdown
).
to
have_selector
(
'.filter-dropdown .filter-dropdown-item'
,
count:
1
)
end
end
it
'filters by special characters'
do
it
'filters by special characters'
do
filtered_search
.
send_keys
(
'(+'
)
filtered_search
.
send_keys
(
'(+'
)
expect
(
dropdown_milestone_size
).
to
eq
(
1
)
expect
(
filter_dropdown
).
to
have_selector
(
'.filter-dropdown .filter-dropdown-item'
,
count:
1
)
end
end
it
'filters by special characters with symbol'
do
it
'filters by special characters with symbol'
do
filtered_search
.
send_keys
(
'%(+'
)
filtered_search
.
send_keys
(
'%(+'
)
expect
(
dropdown_milestone_size
).
to
eq
(
1
)
expect
(
filter_dropdown
).
to
have_selector
(
'.filter-dropdown .filter-dropdown-item'
,
count:
1
)
end
end
end
end
...
...
spec/features/issues/filtered_search/search_bar_spec.rb
View file @
dab60475
...
@@ -26,7 +26,7 @@ describe 'Search bar', js: true, feature: true do
...
@@ -26,7 +26,7 @@ describe 'Search bar', js: true, feature: true do
filtered_search
.
native
.
send_keys
(
:down
)
filtered_search
.
native
.
send_keys
(
:down
)
page
.
within
'#js-dropdown-hint'
do
page
.
within
'#js-dropdown-hint'
do
expect
(
page
).
to
have_selector
(
'.drop
down
-active'
)
expect
(
page
).
to
have_selector
(
'.drop
lab-item
-active'
)
end
end
end
end
...
@@ -79,28 +79,30 @@ describe 'Search bar', js: true, feature: true do
...
@@ -79,28 +79,30 @@ describe 'Search bar', js: true, feature: true do
filtered_search
.
set
(
'author'
)
filtered_search
.
set
(
'author'
)
expect
(
page
.
all
(
'#js-dropdown-hint .filter-dropdown .filter-dropdown-item'
).
size
).
to
eq
(
1
)
expect
(
find
(
'#js-dropdown-hint'
)).
to
have_selector
(
'.filter-dropdown .filter-dropdown-item'
,
count:
1
)
find
(
'.filtered-search-box .clear-search'
).
click
find
(
'.filtered-search-box .clear-search'
).
click
filtered_search
.
click
filtered_search
.
click
expect
(
page
.
all
(
'#js-dropdown-hint .filter-dropdown .filter-dropdown-item'
).
size
).
to
eq
(
original_size
)
expect
(
find
(
'#js-dropdown-hint'
)).
to
have_selector
(
'.filter-dropdown .filter-dropdown-item'
,
count:
original_size
)
end
end
it
'resets the dropdown filters'
do
it
'resets the dropdown filters'
do
filtered_search
.
click
hint_offset
=
get_left_style
(
find
(
'#js-dropdown-hint'
)[
'style'
])
filtered_search
.
set
(
'a'
)
filtered_search
.
set
(
'a'
)
hint_style
=
page
.
find
(
'#js-dropdown-hint'
)[
'style'
]
hint_offset
=
get_left_style
(
hint_style
)
filtered_search
.
set
(
'author:'
)
filtered_search
.
set
(
'author:'
)
expect
(
page
.
all
(
'#js-dropdown-hint .filter-dropdown .filter-dropdown-item'
).
size
).
to
eq
(
0
)
find
(
'#js-dropdown-hint'
,
visible:
false
)
find
(
'.filtered-search-box .clear-search'
).
click
find
(
'.filtered-search-box .clear-search'
).
click
filtered_search
.
click
filtered_search
.
click
expect
(
page
.
all
(
'#js-dropdown-hint .filter-dropdown .filter-dropdown-item'
).
size
).
to
be
>
0
expect
(
find
(
'#js-dropdown-hint'
)).
to
have_selector
(
'.filter-dropdown .filter-dropdown-item'
,
count:
4
)
expect
(
get_left_style
(
page
.
find
(
'#js-dropdown-hint'
)[
'style'
])).
to
eq
(
hint_offset
)
expect
(
get_left_style
(
find
(
'#js-dropdown-hint'
)[
'style'
])).
to
eq
(
hint_offset
)
end
end
end
end
end
end
spec/javascripts/droplab/constants_spec.js
0 → 100644
View file @
dab60475
/* eslint-disable */
import
*
as
constants
from
'
~/droplab/constants
'
;
describe
(
'
constants
'
,
function
()
{
describe
(
'
DATA_TRIGGER
'
,
function
()
{
it
(
'
should be `data-dropdown-trigger`
'
,
function
()
{
expect
(
constants
.
DATA_TRIGGER
).
toBe
(
'
data-dropdown-trigger
'
);
});
});
describe
(
'
DATA_DROPDOWN
'
,
function
()
{
it
(
'
should be `data-dropdown`
'
,
function
()
{
expect
(
constants
.
DATA_DROPDOWN
).
toBe
(
'
data-dropdown
'
);
});
});
describe
(
'
SELECTED_CLASS
'
,
function
()
{
it
(
'
should be `droplab-item-selected`
'
,
function
()
{
expect
(
constants
.
SELECTED_CLASS
).
toBe
(
'
droplab-item-selected
'
);
});
});
describe
(
'
ACTIVE_CLASS
'
,
function
()
{
it
(
'
should be `droplab-item-active`
'
,
function
()
{
expect
(
constants
.
ACTIVE_CLASS
).
toBe
(
'
droplab-item-active
'
);
});
});
});
spec/javascripts/droplab/drop_down_spec.js
0 → 100644
View file @
dab60475
This diff is collapsed.
Click to expand it.
spec/javascripts/droplab/hook_spec.js
0 → 100644
View file @
dab60475
/* eslint-disable */
import
Hook
from
'
~/droplab/hook
'
;
import
*
as
dropdownSrc
from
'
~/droplab/drop_down
'
;
describe
(
'
Hook
'
,
function
()
{
describe
(
'
class constructor
'
,
function
()
{
beforeEach
(
function
()
{
this
.
trigger
=
{
id
:
'
id
'
};
this
.
list
=
{};
this
.
plugins
=
{};
this
.
config
=
{};
this
.
dropdown
=
{};
spyOn
(
dropdownSrc
,
'
default
'
).
and
.
returnValue
(
this
.
dropdown
);
this
.
hook
=
new
Hook
(
this
.
trigger
,
this
.
list
,
this
.
plugins
,
this
.
config
);
});
it
(
'
should set .trigger
'
,
function
()
{
expect
(
this
.
hook
.
trigger
).
toBe
(
this
.
trigger
);
});
it
(
'
should set .list
'
,
function
()
{
expect
(
this
.
hook
.
list
).
toBe
(
this
.
dropdown
);
});
it
(
'
should call DropDown constructor
'
,
function
()
{
expect
(
dropdownSrc
.
default
).
toHaveBeenCalledWith
(
this
.
list
);
});
it
(
'
should set .type
'
,
function
()
{
expect
(
this
.
hook
.
type
).
toBe
(
'
Hook
'
);
});
it
(
'
should set .event
'
,
function
()
{
expect
(
this
.
hook
.
event
).
toBe
(
'
click
'
);
});
it
(
'
should set .plugins
'
,
function
()
{
expect
(
this
.
hook
.
plugins
).
toBe
(
this
.
plugins
);
});
it
(
'
should set .config
'
,
function
()
{
expect
(
this
.
hook
.
config
).
toBe
(
this
.
config
);
});
it
(
'
should set .id
'
,
function
()
{
expect
(
this
.
hook
.
id
).
toBe
(
this
.
trigger
.
id
);
});
describe
(
'
if config argument is undefined
'
,
function
()
{
beforeEach
(
function
()
{
this
.
config
=
undefined
;
this
.
hook
=
new
Hook
(
this
.
trigger
,
this
.
list
,
this
.
plugins
,
this
.
config
);
});
it
(
'
should set .config to an empty object
'
,
function
()
{
expect
(
this
.
hook
.
config
).
toEqual
({});
});
});
describe
(
'
if plugins argument is undefined
'
,
function
()
{
beforeEach
(
function
()
{
this
.
plugins
=
undefined
;
this
.
hook
=
new
Hook
(
this
.
trigger
,
this
.
list
,
this
.
plugins
,
this
.
config
);
});
it
(
'
should set .plugins to an empty array
'
,
function
()
{
expect
(
this
.
hook
.
plugins
).
toEqual
([]);
});
});
});
describe
(
'
addEvents
'
,
function
()
{
it
(
'
should exist
'
,
function
()
{
expect
(
Hook
.
prototype
.
hasOwnProperty
(
'
addEvents
'
)).
toBe
(
true
);
});
});
});
spec/javascripts/droplab/plugins/input_setter_spec.js
0 → 100644
View file @
dab60475
/* eslint-disable */
import
InputSetter
from
'
~/droplab/plugins/input_setter
'
;
describe
(
'
InputSetter
'
,
function
()
{
describe
(
'
init
'
,
function
()
{
beforeEach
(
function
()
{
this
.
config
=
{
InputSetter
:
{}
};
this
.
hook
=
{
config
:
this
.
config
};
this
.
inputSetter
=
jasmine
.
createSpyObj
(
'
inputSetter
'
,
[
'
addEvents
'
]);
InputSetter
.
init
.
call
(
this
.
inputSetter
,
this
.
hook
);
});
it
(
'
should set .hook
'
,
function
()
{
expect
(
this
.
inputSetter
.
hook
).
toBe
(
this
.
hook
);
});
it
(
'
should set .config
'
,
function
()
{
expect
(
this
.
inputSetter
.
config
).
toBe
(
this
.
config
.
InputSetter
);
});
it
(
'
should set .eventWrapper
'
,
function
()
{
expect
(
this
.
inputSetter
.
eventWrapper
).
toEqual
({});
});
it
(
'
should call .addEvents
'
,
function
()
{
expect
(
this
.
inputSetter
.
addEvents
).
toHaveBeenCalled
();
});
describe
(
'
if config.InputSetter is not set
'
,
function
()
{
beforeEach
(
function
()
{
this
.
config
=
{
InputSetter
:
undefined
};
this
.
hook
=
{
config
:
this
.
config
};
InputSetter
.
init
.
call
(
this
.
inputSetter
,
this
.
hook
);
});
it
(
'
should set .config to an empty object
'
,
function
()
{
expect
(
this
.
inputSetter
.
config
).
toEqual
({});
});
it
(
'
should set hook.config to an empty object
'
,
function
()
{
expect
(
this
.
hook
.
config
.
InputSetter
).
toEqual
({});
});
})
});
describe
(
'
addEvents
'
,
function
()
{
beforeEach
(
function
()
{
this
.
hook
=
{
list
:
{
list
:
jasmine
.
createSpyObj
(
'
list
'
,
[
'
addEventListener
'
])
}
};
this
.
inputSetter
=
{
eventWrapper
:
{},
hook
:
this
.
hook
,
setInputs
:
()
=>
{}
};
InputSetter
.
addEvents
.
call
(
this
.
inputSetter
);
});
it
(
'
should set .eventWrapper.setInputs
'
,
function
()
{
expect
(
this
.
inputSetter
.
eventWrapper
.
setInputs
).
toEqual
(
jasmine
.
any
(
Function
));
});
it
(
'
should call .addEventListener
'
,
function
()
{
expect
(
this
.
hook
.
list
.
list
.
addEventListener
)
.
toHaveBeenCalledWith
(
'
click.dl
'
,
this
.
inputSetter
.
eventWrapper
.
setInputs
);
});
});
describe
(
'
removeEvents
'
,
function
()
{
beforeEach
(
function
()
{
this
.
hook
=
{
list
:
{
list
:
jasmine
.
createSpyObj
(
'
list
'
,
[
'
removeEventListener
'
])
}
};
this
.
eventWrapper
=
jasmine
.
createSpyObj
(
'
eventWrapper
'
,
[
'
setInputs
'
]);
this
.
inputSetter
=
{
eventWrapper
:
this
.
eventWrapper
,
hook
:
this
.
hook
};
InputSetter
.
removeEvents
.
call
(
this
.
inputSetter
);
});
it
(
'
should call .removeEventListener
'
,
function
()
{
expect
(
this
.
hook
.
list
.
list
.
removeEventListener
)
.
toHaveBeenCalledWith
(
'
click.dl
'
,
this
.
eventWrapper
.
setInputs
);
});
});
describe
(
'
setInputs
'
,
function
()
{
beforeEach
(
function
()
{
this
.
event
=
{
detail
:
{
selected
:
{}
}
};
this
.
config
=
[
0
,
1
];
this
.
inputSetter
=
{
config
:
this
.
config
,
setInput
:
()
=>
{}
};
spyOn
(
this
.
inputSetter
,
'
setInput
'
);
InputSetter
.
setInputs
.
call
(
this
.
inputSetter
,
this
.
event
);
});
it
(
'
should call .setInput for each config element
'
,
function
()
{
const
allArgs
=
this
.
inputSetter
.
setInput
.
calls
.
allArgs
();
expect
(
allArgs
.
length
).
toEqual
(
2
);
allArgs
.
forEach
((
args
,
i
)
=>
{
expect
(
args
[
0
]).
toBe
(
this
.
config
[
i
]);
expect
(
args
[
1
]).
toBe
(
this
.
event
.
detail
.
selected
);
});
});
describe
(
'
if config isnt an array
'
,
function
()
{
beforeEach
(
function
()
{
this
.
inputSetter
=
{
config
:
{},
setInput
:
()
=>
{}
};
InputSetter
.
setInputs
.
call
(
this
.
inputSetter
,
this
.
event
);
});
it
(
'
should set .config to an array with .config as the first element
'
,
function
()
{
expect
(
this
.
inputSetter
.
config
).
toEqual
([{}]);
});
});
});
describe
(
'
setInput
'
,
function
()
{
beforeEach
(
function
()
{
this
.
selectedItem
=
{
getAttribute
:
()
=>
{}
};
this
.
input
=
{
value
:
'
oldValue
'
,
tagName
:
'
INPUT
'
,
hasAttribute
:
()
=>
{}
};
this
.
config
=
{
valueAttribute
:
{},
input
:
this
.
input
};
this
.
inputSetter
=
{
hook
:
{
trigger
:
{}
}
};
this
.
newValue
=
'
newValue
'
;
spyOn
(
this
.
selectedItem
,
'
getAttribute
'
).
and
.
returnValue
(
this
.
newValue
);
spyOn
(
this
.
input
,
'
hasAttribute
'
).
and
.
returnValue
(
false
);
InputSetter
.
setInput
.
call
(
this
.
inputSetter
,
this
.
config
,
this
.
selectedItem
);
});
it
(
'
should call .getAttribute
'
,
function
()
{
expect
(
this
.
selectedItem
.
getAttribute
).
toHaveBeenCalledWith
(
this
.
config
.
valueAttribute
);
});
it
(
'
should call .hasAttribute
'
,
function
()
{
expect
(
this
.
input
.
hasAttribute
).
toHaveBeenCalledWith
(
undefined
);
});
it
(
'
should set the value of the input
'
,
function
()
{
expect
(
this
.
input
.
value
).
toBe
(
this
.
newValue
);
});
describe
(
'
if there is no newValue
'
,
function
()
{
beforeEach
(
function
()
{
this
.
newValue
=
''
;
this
.
inputSetter
=
{
hook
:
{
trigger
:
{}
}
};
this
.
config
=
{
valueAttribute
:
{},
input
:
this
.
input
};
this
.
input
=
{
value
:
'
oldValue
'
,
tagName
:
'
INPUT
'
};
this
.
selectedItem
=
{
getAttribute
:
()
=>
{}
};
InputSetter
.
setInput
.
call
(
this
.
inputSetter
,
this
.
config
,
this
.
selectedItem
);
});
it
(
'
should not set the value of the input
'
,
function
()
{
expect
(
this
.
input
.
value
).
toBe
(
'
oldValue
'
);
})
});
describe
(
'
if no config.input is provided
'
,
function
()
{
beforeEach
(
function
()
{
this
.
config
=
{
valueAttribute
:
{}
};
this
.
trigger
=
{
value
:
'
oldValue
'
,
tagName
:
'
INPUT
'
,
hasAttribute
:
()
=>
{}
};
this
.
inputSetter
=
{
hook
:
{
trigger
:
this
.
trigger
}
};
InputSetter
.
setInput
.
call
(
this
.
inputSetter
,
this
.
config
,
this
.
selectedItem
);
});
it
(
'
should set the value of the hook.trigger
'
,
function
()
{
expect
(
this
.
trigger
.
value
).
toBe
(
this
.
newValue
);
});
});
describe
(
'
if the input tag is not INPUT
'
,
function
()
{
beforeEach
(
function
()
{
this
.
input
=
{
textContent
:
'
oldValue
'
,
tagName
:
'
SPAN
'
,
hasAttribute
:
()
=>
{}
};
this
.
config
=
{
valueAttribute
:
{},
input
:
this
.
input
};
InputSetter
.
setInput
.
call
(
this
.
inputSetter
,
this
.
config
,
this
.
selectedItem
);
});
it
(
'
should set the textContent of the input
'
,
function
()
{
expect
(
this
.
input
.
textContent
).
toBe
(
this
.
newValue
);
});
describe
(
'
if there is no new value
'
,
function
()
{
beforeEach
(
function
()
{
this
.
selectedItem
=
{
getAttribute
:
()
=>
{}
};
this
.
input
=
{
textContent
:
'
oldValue
'
,
tagName
:
'
INPUT
'
,
hasAttribute
:
()
=>
{}
};
this
.
config
=
{
valueAttribute
:
{},
input
:
this
.
input
};
this
.
inputSetter
=
{
hook
:
{
trigger
:
{}
}
};
this
.
newValue
=
'
newValue
'
;
spyOn
(
this
.
selectedItem
,
'
getAttribute
'
).
and
.
returnValue
(
this
.
newValue
);
InputSetter
.
setInput
.
call
(
this
.
inputSetter
,
this
.
config
,
this
.
selectedItem
);
});
it
(
'
should not set the value of the input
'
,
function
()
{
expect
(
this
.
input
.
textContent
).
toBe
(
'
oldValue
'
);
});
});
});
describe
(
'
if there is an inputAttribute
'
,
function
()
{
beforeEach
(
function
()
{
this
.
selectedItem
=
{
getAttribute
:
()
=>
{}
};
this
.
input
=
{
id
:
'
oldValue
'
,
hasAttribute
:
()
=>
{},
setAttribute
:
()
=>
{}
};
this
.
inputSetter
=
{
hook
:
{
trigger
:
{}
}
};
this
.
newValue
=
'
newValue
'
;
this
.
inputAttribute
=
'
id
'
;
this
.
config
=
{
valueAttribute
:
{},
input
:
this
.
input
,
inputAttribute
:
this
.
inputAttribute
,
};
spyOn
(
this
.
selectedItem
,
'
getAttribute
'
).
and
.
returnValue
(
this
.
newValue
);
spyOn
(
this
.
input
,
'
hasAttribute
'
).
and
.
returnValue
(
true
);
spyOn
(
this
.
input
,
'
setAttribute
'
);
InputSetter
.
setInput
.
call
(
this
.
inputSetter
,
this
.
config
,
this
.
selectedItem
);
});
it
(
'
should call setAttribute
'
,
function
()
{
expect
(
this
.
input
.
setAttribute
).
toHaveBeenCalledWith
(
this
.
inputAttribute
,
this
.
newValue
);
});
it
(
'
should not set the value or textContent of the input
'
,
function
()
{
expect
(
this
.
input
.
value
).
not
.
toBe
(
'
newValue
'
);
expect
(
this
.
input
.
textContent
).
not
.
toBe
(
'
newValue
'
);
});
});
});
describe
(
'
destroy
'
,
function
()
{
beforeEach
(
function
()
{
this
.
inputSetter
=
jasmine
.
createSpyObj
(
'
inputSetter
'
,
[
'
removeEvents
'
]);
InputSetter
.
destroy
.
call
(
this
.
inputSetter
);
});
it
(
'
should call .removeEvents
'
,
function
()
{
expect
(
this
.
inputSetter
.
removeEvents
).
toHaveBeenCalled
();
});
});
});
spec/javascripts/filtered_search/dropdown_user_spec.js
View file @
dab60475
...
@@ -33,7 +33,7 @@ require('~/filtered_search/dropdown_user');
...
@@ -33,7 +33,7 @@ require('~/filtered_search/dropdown_user');
});
});
});
});
describe
(
'
config
droplab
AjaxFilter
\'
s endpoint
'
,
()
=>
{
describe
(
'
config AjaxFilter
\'
s endpoint
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(()
=>
{
spyOn
(
gl
.
DropdownUser
.
prototype
,
'
bindEvents
'
).
and
.
callFake
(()
=>
{});
spyOn
(
gl
.
DropdownUser
.
prototype
,
'
bindEvents
'
).
and
.
callFake
(()
=>
{});
spyOn
(
gl
.
DropdownUser
.
prototype
,
'
getProjectId
'
).
and
.
callFake
(()
=>
{});
spyOn
(
gl
.
DropdownUser
.
prototype
,
'
getProjectId
'
).
and
.
callFake
(()
=>
{});
...
@@ -45,13 +45,13 @@ require('~/filtered_search/dropdown_user');
...
@@ -45,13 +45,13 @@ require('~/filtered_search/dropdown_user');
};
};
const
dropdown
=
new
gl
.
DropdownUser
();
const
dropdown
=
new
gl
.
DropdownUser
();
expect
(
dropdown
.
config
.
droplab
AjaxFilter
.
endpoint
).
toBe
(
'
/autocomplete/users.json
'
);
expect
(
dropdown
.
config
.
AjaxFilter
.
endpoint
).
toBe
(
'
/autocomplete/users.json
'
);
});
});
it
(
'
should return endpoint when relative_url_root is undefined
'
,
()
=>
{
it
(
'
should return endpoint when relative_url_root is undefined
'
,
()
=>
{
const
dropdown
=
new
gl
.
DropdownUser
();
const
dropdown
=
new
gl
.
DropdownUser
();
expect
(
dropdown
.
config
.
droplab
AjaxFilter
.
endpoint
).
toBe
(
'
/autocomplete/users.json
'
);
expect
(
dropdown
.
config
.
AjaxFilter
.
endpoint
).
toBe
(
'
/autocomplete/users.json
'
);
});
});
it
(
'
should return endpoint with relative url when available
'
,
()
=>
{
it
(
'
should return endpoint with relative url when available
'
,
()
=>
{
...
@@ -60,7 +60,7 @@ require('~/filtered_search/dropdown_user');
...
@@ -60,7 +60,7 @@ require('~/filtered_search/dropdown_user');
};
};
const
dropdown
=
new
gl
.
DropdownUser
();
const
dropdown
=
new
gl
.
DropdownUser
();
expect
(
dropdown
.
config
.
droplab
AjaxFilter
.
endpoint
).
toBe
(
'
/gitlab_directory/autocomplete/users.json
'
);
expect
(
dropdown
.
config
.
AjaxFilter
.
endpoint
).
toBe
(
'
/gitlab_directory/autocomplete/users.json
'
);
});
});
afterEach
(()
=>
{
afterEach
(()
=>
{
...
...
yarn.lock
View file @
dab60475
This diff is collapsed.
Click to expand it.
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