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
4d0db16f
Commit
4d0db16f
authored
Oct 10, 2018
by
Mike Greiling
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Prettify diff_notes diffs and droplab modules
parent
7fd4e21c
Changes
18
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
172 additions
and
136 deletions
+172
-136
app/assets/javascripts/diff_notes/components/comment_resolve_btn.js
.../javascripts/diff_notes/components/comment_resolve_btn.js
+17
-13
app/assets/javascripts/diff_notes/components/diff_note_avatars.js
...ts/javascripts/diff_notes/components/diff_note_avatars.js
+21
-7
app/assets/javascripts/diff_notes/components/jump_to_discussion.js
...s/javascripts/diff_notes/components/jump_to_discussion.js
+18
-17
app/assets/javascripts/diff_notes/components/resolve_count.js
...assets/javascripts/diff_notes/components/resolve_count.js
+5
-5
app/assets/javascripts/diff_notes/mixins/discussion.js
app/assets/javascripts/diff_notes/mixins/discussion.js
+5
-5
app/assets/javascripts/diff_notes/models/discussion.js
app/assets/javascripts/diff_notes/models/discussion.js
+9
-9
app/assets/javascripts/diff_notes/stores/comments.js
app/assets/javascripts/diff_notes/stores/comments.js
+7
-7
app/assets/javascripts/diffs/components/commit_item.vue
app/assets/javascripts/diffs/components/commit_item.vue
+3
-1
app/assets/javascripts/diffs/components/diff_file.vue
app/assets/javascripts/diffs/components/diff_file.vue
+4
-4
app/assets/javascripts/droplab/constants.js
app/assets/javascripts/droplab/constants.js
+1
-8
app/assets/javascripts/droplab/drop_down.js
app/assets/javascripts/droplab/drop_down.js
+2
-2
app/assets/javascripts/droplab/drop_lab.js
app/assets/javascripts/droplab/drop_lab.js
+3
-2
app/assets/javascripts/droplab/keyboard.js
app/assets/javascripts/droplab/keyboard.js
+31
-22
app/assets/javascripts/droplab/plugins/ajax.js
app/assets/javascripts/droplab/plugins/ajax.js
+2
-2
app/assets/javascripts/droplab/plugins/ajax_filter.js
app/assets/javascripts/droplab/plugins/ajax_filter.js
+10
-8
app/assets/javascripts/droplab/plugins/filter.js
app/assets/javascripts/droplab/plugins/filter.js
+21
-18
app/assets/javascripts/droplab/plugins/input_setter.js
app/assets/javascripts/droplab/plugins/input_setter.js
+2
-2
app/assets/javascripts/droplab/utils.js
app/assets/javascripts/droplab/utils.js
+11
-4
No files found.
app/assets/javascripts/diff_notes/components/comment_resolve_btn.js
View file @
4d0db16f
...
...
@@ -18,52 +18,56 @@ const CommentAndResolveBtn = Vue.extend({
};
},
computed
:
{
showButton
:
function
()
{
showButton
:
function
()
{
if
(
this
.
discussion
)
{
return
this
.
discussion
.
isResolvable
();
}
else
{
return
false
;
}
},
isDiscussionResolved
:
function
()
{
isDiscussionResolved
:
function
()
{
return
this
.
discussion
.
isResolved
();
},
buttonText
:
function
()
{
buttonText
:
function
()
{
if
(
this
.
isDiscussionResolved
)
{
if
(
this
.
textareaIsEmpty
)
{
return
"
Unresolve discussion
"
;
return
'
Unresolve discussion
'
;
}
else
{
return
"
Comment & unresolve discussion
"
;
return
'
Comment & unresolve discussion
'
;
}
}
else
{
if
(
this
.
textareaIsEmpty
)
{
return
"
Resolve discussion
"
;
return
'
Resolve discussion
'
;
}
else
{
return
"
Comment & resolve discussion
"
;
}
return
'
Comment & resolve discussion
'
;
}
}
},
},
created
()
{
if
(
this
.
discussionId
)
{
this
.
discussion
=
CommentsStore
.
state
[
this
.
discussionId
];
}
},
mounted
:
function
()
{
mounted
:
function
()
{
if
(
!
this
.
discussionId
)
return
;
const
$textarea
=
$
(
`.js-discussion-note-form[data-discussion-id=
${
this
.
discussionId
}
] .note-textarea`
);
const
$textarea
=
$
(
`.js-discussion-note-form[data-discussion-id=
${
this
.
discussionId
}
] .note-textarea`
,
);
this
.
textareaIsEmpty
=
$textarea
.
val
()
===
''
;
$textarea
.
on
(
'
input.comment-and-resolve-btn
'
,
()
=>
{
this
.
textareaIsEmpty
=
$textarea
.
val
()
===
''
;
});
},
destroyed
:
function
()
{
destroyed
:
function
()
{
if
(
!
this
.
discussionId
)
return
;
$
(
`.js-discussion-note-form[data-discussion-id=
${
this
.
discussionId
}
] .note-textarea`
).
off
(
'
input.comment-and-resolve-btn
'
);
}
$
(
`.js-discussion-note-form[data-discussion-id=
${
this
.
discussionId
}
] .note-textarea`
).
off
(
'
input.comment-and-resolve-btn
'
,
);
},
});
Vue
.
component
(
'
comment-and-resolve-btn
'
,
CommentAndResolveBtn
);
app/assets/javascripts/diff_notes/components/diff_note_avatars.js
View file @
4d0db16f
...
...
@@ -83,7 +83,11 @@ const DiffNoteAvatars = Vue.extend({
this
.
addNoCommentClass
();
this
.
setDiscussionVisible
();
this
.
lineType
=
$
(
this
.
$el
).
closest
(
'
.diff-line-num
'
).
hasClass
(
'
old_line
'
)
?
'
old
'
:
'
new
'
;
this
.
lineType
=
$
(
this
.
$el
)
.
closest
(
'
.diff-line-num
'
)
.
hasClass
(
'
old_line
'
)
?
'
old
'
:
'
new
'
;
});
$
(
document
).
on
(
'
toggle.comments
'
,
()
=>
{
...
...
@@ -113,20 +117,30 @@ const DiffNoteAvatars = Vue.extend({
addNoCommentClass
()
{
const
{
notesCount
}
=
this
;
$
(
this
.
$el
).
closest
(
'
.js-avatar-container
'
)
$
(
this
.
$el
)
.
closest
(
'
.js-avatar-container
'
)
.
toggleClass
(
'
no-comment-btn
'
,
notesCount
>
0
)
.
nextUntil
(
'
.js-avatar-container
'
)
.
toggleClass
(
'
no-comment-btn
'
,
notesCount
>
0
);
},
toggleDiscussionsToggleState
()
{
const
$notesHolders
=
$
(
this
.
$el
).
closest
(
'
.code
'
).
find
(
'
.notes_holder
'
);
const
$notesHolders
=
$
(
this
.
$el
)
.
closest
(
'
.code
'
)
.
find
(
'
.notes_holder
'
);
const
$visibleNotesHolders
=
$notesHolders
.
filter
(
'
:visible
'
);
const
$toggleDiffCommentsBtn
=
$
(
this
.
$el
).
closest
(
'
.diff-file
'
).
find
(
'
.js-toggle-diff-comments
'
);
const
$toggleDiffCommentsBtn
=
$
(
this
.
$el
)
.
closest
(
'
.diff-file
'
)
.
find
(
'
.js-toggle-diff-comments
'
);
$toggleDiffCommentsBtn
.
toggleClass
(
'
active
'
,
$notesHolders
.
length
===
$visibleNotesHolders
.
length
);
$toggleDiffCommentsBtn
.
toggleClass
(
'
active
'
,
$notesHolders
.
length
===
$visibleNotesHolders
.
length
,
);
},
setDiscussionVisible
()
{
this
.
isVisible
=
$
(
`.diffs .notes[data-discussion-id="
${
this
.
discussion
.
id
}
"]`
).
is
(
'
:visible
'
);
this
.
isVisible
=
$
(
`.diffs .notes[data-discussion-id="
${
this
.
discussion
.
id
}
"]`
).
is
(
'
:visible
'
,
);
},
getTooltipText
(
note
)
{
return
`
${
note
.
authorName
}
:
${
note
.
noteTruncated
}
`
;
...
...
app/assets/javascripts/diff_notes/components/jump_to_discussion.js
View file @
4d0db16f
...
...
@@ -14,24 +14,24 @@ const JumpToDiscussion = Vue.extend({
required
:
true
,
},
},
data
:
function
()
{
data
:
function
()
{
return
{
discussions
:
CommentsStore
.
state
,
discussion
:
{},
};
},
computed
:
{
buttonText
:
function
()
{
buttonText
:
function
()
{
if
(
this
.
discussionId
)
{
return
'
Jump to next unresolved discussion
'
;
}
else
{
return
'
Jump to first unresolved discussion
'
;
}
},
allResolved
:
function
()
{
allResolved
:
function
()
{
return
this
.
unresolvedDiscussionCount
===
0
;
},
showButton
:
function
()
{
showButton
:
function
()
{
if
(
this
.
discussionId
)
{
if
(
this
.
unresolvedDiscussionCount
>
1
)
{
return
true
;
...
...
@@ -42,7 +42,7 @@ const JumpToDiscussion = Vue.extend({
return
this
.
unresolvedDiscussionCount
>=
1
;
}
},
lastResolvedId
:
function
()
{
lastResolvedId
:
function
()
{
let
lastId
;
for
(
const
discussionId
in
this
.
discussions
)
{
const
discussion
=
this
.
discussions
[
discussionId
];
...
...
@@ -52,13 +52,13 @@ const JumpToDiscussion = Vue.extend({
}
}
return
lastId
;
}
}
,
},
created
()
{
this
.
discussion
=
this
.
discussions
[
this
.
discussionId
];
},
methods
:
{
jumpToNextUnresolvedDiscussion
:
function
()
{
jumpToNextUnresolvedDiscussion
:
function
()
{
let
discussionsSelector
;
let
discussionIdsInScope
;
let
firstUnresolvedDiscussionId
;
...
...
@@ -68,9 +68,11 @@ const JumpToDiscussion = Vue.extend({
let
jumpToFirstDiscussion
=
!
this
.
discussionId
;
const
discussionIdsForElements
=
function
(
elements
)
{
return
elements
.
map
(
function
()
{
return
elements
.
map
(
function
()
{
return
$
(
this
).
attr
(
'
data-discussion-id
'
);
}).
toArray
();
})
.
toArray
();
};
const
{
discussions
}
=
this
;
...
...
@@ -144,8 +146,7 @@ const JumpToDiscussion = Vue.extend({
if
(
!
discussion
.
isResolved
())
{
nextUnresolvedDiscussionId
=
discussionId
;
break
;
}
else
{
}
else
{
continue
;
}
}
...
...
@@ -175,9 +176,9 @@ const JumpToDiscussion = Vue.extend({
// Resolved discussions are hidden in the diffs tab by default.
// If they are marked unresolved on the notes tab, they will still be hidden on the diffs tab.
// When jumping between unresolved discussions on the diffs tab, we show them.
$target
.
closest
(
"
.content
"
).
show
();
$target
.
closest
(
'
.content
'
).
show
();
const
$notesHolder
=
$target
.
closest
(
"
tr.notes_holder
"
);
const
$notesHolder
=
$target
.
closest
(
'
tr.notes_holder
'
);
// Image diff discussions does not use notes_holder
// so we should keep original $target value in those cases
...
...
@@ -194,7 +195,7 @@ const JumpToDiscussion = Vue.extend({
prevEl
=
$target
.
prev
();
// If the discussion doesn't have 4 lines above it, we'll have to do with fewer.
if
(
!
prevEl
.
hasClass
(
"
line_holder
"
))
{
if
(
!
prevEl
.
hasClass
(
'
line_holder
'
))
{
break
;
}
...
...
@@ -203,9 +204,9 @@ const JumpToDiscussion = Vue.extend({
}
$
.
scrollTo
(
$target
,
{
offset
:
-
150
offset
:
-
150
,
});
}
}
,
},
});
...
...
app/assets/javascripts/diff_notes/components/resolve_count.js
View file @
4d0db16f
...
...
@@ -13,17 +13,17 @@ window.ResolveCount = Vue.extend({
required
:
true
,
},
},
data
:
function
()
{
data
:
function
()
{
return
{
discussions
:
CommentsStore
.
state
discussions
:
CommentsStore
.
state
,
};
},
computed
:
{
allResolved
:
function
()
{
allResolved
:
function
()
{
return
this
.
resolvedDiscussionCount
===
this
.
discussionCount
;
},
resolvedCountText
()
{
return
this
.
discussionCount
===
1
?
'
discussion
'
:
'
discussions
'
;
}
}
}
,
}
,
});
app/assets/javascripts/diff_notes/mixins/discussion.js
View file @
4d0db16f
...
...
@@ -2,10 +2,10 @@
const
DiscussionMixins
=
{
computed
:
{
discussionCount
:
function
()
{
discussionCount
:
function
()
{
return
Object
.
keys
(
this
.
discussions
).
length
;
},
resolvedDiscussionCount
:
function
()
{
resolvedDiscussionCount
:
function
()
{
let
resolvedCount
=
0
;
for
(
const
discussionId
in
this
.
discussions
)
{
...
...
@@ -18,7 +18,7 @@ const DiscussionMixins = {
return
resolvedCount
;
},
unresolvedDiscussionCount
:
function
()
{
unresolvedDiscussionCount
:
function
()
{
let
unresolvedCount
=
0
;
for
(
const
discussionId
in
this
.
discussions
)
{
...
...
@@ -30,8 +30,8 @@ const DiscussionMixins = {
}
return
unresolvedCount
;
}
}
}
,
}
,
};
export
default
DiscussionMixins
;
app/assets/javascripts/diff_notes/models/discussion.js
View file @
4d0db16f
...
...
@@ -6,22 +6,22 @@ import Vue from 'vue';
import
{
localTimeAgo
}
from
'
../../lib/utils/datetime_utility
'
;
class
DiscussionModel
{
constructor
(
discussionId
)
{
constructor
(
discussionId
)
{
this
.
id
=
discussionId
;
this
.
notes
=
{};
this
.
loading
=
false
;
this
.
canResolve
=
false
;
}
createNote
(
noteObj
)
{
createNote
(
noteObj
)
{
Vue
.
set
(
this
.
notes
,
noteObj
.
noteId
,
new
NoteModel
(
this
.
id
,
noteObj
));
}
deleteNote
(
noteId
)
{
deleteNote
(
noteId
)
{
Vue
.
delete
(
this
.
notes
,
noteId
);
}
getNote
(
noteId
)
{
getNote
(
noteId
)
{
return
this
.
notes
[
noteId
];
}
...
...
@@ -29,7 +29,7 @@ class DiscussionModel {
return
Object
.
keys
(
this
.
notes
).
length
;
}
isResolved
()
{
isResolved
()
{
for
(
const
noteId
in
this
.
notes
)
{
const
note
=
this
.
notes
[
noteId
];
...
...
@@ -40,7 +40,7 @@ class DiscussionModel {
return
true
;
}
resolveAllNotes
(
resolved_by
)
{
resolveAllNotes
(
resolved_by
)
{
for
(
const
noteId
in
this
.
notes
)
{
const
note
=
this
.
notes
[
noteId
];
...
...
@@ -51,7 +51,7 @@ class DiscussionModel {
}
}
unResolveAllNotes
()
{
unResolveAllNotes
()
{
for
(
const
noteId
in
this
.
notes
)
{
const
note
=
this
.
notes
[
noteId
];
...
...
@@ -62,7 +62,7 @@ class DiscussionModel {
}
}
updateHeadline
(
data
)
{
updateHeadline
(
data
)
{
const
discussionSelector
=
`.discussion[data-discussion-id="
${
this
.
id
}
"]`
;
const
$discussionHeadline
=
$
(
`
${
discussionSelector
}
.js-discussion-headline`
);
...
...
@@ -79,7 +79,7 @@ class DiscussionModel {
}
}
isResolvable
()
{
isResolvable
()
{
if
(
!
this
.
canResolve
)
{
return
false
;
}
...
...
app/assets/javascripts/diff_notes/stores/comments.js
View file @
4d0db16f
...
...
@@ -5,10 +5,10 @@ import Vue from 'vue';
window
.
CommentsStore
=
{
state
:
{},
get
:
function
(
discussionId
,
noteId
)
{
get
:
function
(
discussionId
,
noteId
)
{
return
this
.
state
[
discussionId
].
getNote
(
noteId
);
},
createDiscussion
:
function
(
discussionId
,
canResolve
)
{
createDiscussion
:
function
(
discussionId
,
canResolve
)
{
let
discussion
=
this
.
state
[
discussionId
];
if
(
!
this
.
state
[
discussionId
])
{
discussion
=
new
DiscussionModel
(
discussionId
);
...
...
@@ -21,18 +21,18 @@ window.CommentsStore = {
return
discussion
;
},
create
:
function
(
noteObj
)
{
create
:
function
(
noteObj
)
{
const
discussion
=
this
.
createDiscussion
(
noteObj
.
discussionId
);
discussion
.
createNote
(
noteObj
);
},
update
:
function
(
discussionId
,
noteId
,
resolved
,
resolved_by
)
{
update
:
function
(
discussionId
,
noteId
,
resolved
,
resolved_by
)
{
const
discussion
=
this
.
state
[
discussionId
];
const
note
=
discussion
.
getNote
(
noteId
);
note
.
resolved
=
resolved
;
note
.
resolved_by
=
resolved_by
;
},
delete
:
function
(
discussionId
,
noteId
)
{
delete
:
function
(
discussionId
,
noteId
)
{
const
discussion
=
this
.
state
[
discussionId
];
discussion
.
deleteNote
(
noteId
);
...
...
@@ -40,7 +40,7 @@ window.CommentsStore = {
Vue
.
delete
(
this
.
state
,
discussionId
);
}
},
unresolvedDiscussionIds
:
function
()
{
unresolvedDiscussionIds
:
function
()
{
const
ids
=
[];
for
(
const
discussionId
in
this
.
state
)
{
...
...
@@ -52,5 +52,5 @@ window.CommentsStore = {
}
return
ids
;
}
}
,
};
app/assets/javascripts/diffs/components/commit_item.vue
View file @
4d0db16f
...
...
@@ -43,7 +43,9 @@ export default {
return
(
this
.
commit
.
author
&&
this
.
commit
.
author
.
name
)
||
this
.
commit
.
authorName
;
},
authorUrl
()
{
return
(
this
.
commit
.
author
&&
this
.
commit
.
author
.
webUrl
)
||
`mailto:
${
this
.
commit
.
authorEmail
}
`
;
return
(
(
this
.
commit
.
author
&&
this
.
commit
.
author
.
webUrl
)
||
`mailto:
${
this
.
commit
.
authorEmail
}
`
);
},
authorAvatar
()
{
return
(
this
.
commit
.
author
&&
this
.
commit
.
author
.
avatarUrl
)
||
this
.
commit
.
authorGravatarUrl
;
...
...
app/assets/javascripts/diffs/components/diff_file.vue
View file @
4d0db16f
...
...
@@ -46,10 +46,10 @@ export default {
showExpandMessage
()
{
return
(
this
.
isCollapsed
||
!
this
.
file
.
highlightedDiffLines
&&
(
!
this
.
file
.
highlightedDiffLines
&&
!
this
.
isLoadingCollapsedDiff
&&
!
this
.
file
.
tooLarge
&&
this
.
file
.
text
this
.
file
.
text
)
);
},
showLoadingIcon
()
{
...
...
app/assets/javascripts/droplab/constants.js
View file @
4d0db16f
...
...
@@ -6,11 +6,4 @@ const IGNORE_CLASS = 'droplab-item-ignore';
// Matches `{{anything}}` and `{{ everything }}`.
const
TEMPLATE_REGEX
=
/
\{\{(
.+
?)\}\}
/g
;
export
{
DATA_TRIGGER
,
DATA_DROPDOWN
,
SELECTED_CLASS
,
ACTIVE_CLASS
,
TEMPLATE_REGEX
,
IGNORE_CLASS
,
};
export
{
DATA_TRIGGER
,
DATA_DROPDOWN
,
SELECTED_CLASS
,
ACTIVE_CLASS
,
TEMPLATE_REGEX
,
IGNORE_CLASS
};
app/assets/javascripts/droplab/drop_down.js
View file @
4d0db16f
...
...
@@ -2,7 +2,7 @@ import utils from './utils';
import
{
SELECTED_CLASS
,
IGNORE_CLASS
}
from
'
./constants
'
;
class
DropDown
{
constructor
(
list
,
config
=
{
})
{
constructor
(
list
,
config
=
{})
{
this
.
currentIndex
=
0
;
this
.
hidden
=
true
;
this
.
list
=
typeof
list
===
'
string
'
?
document
.
querySelector
(
list
)
:
list
;
...
...
@@ -157,7 +157,7 @@ class DropDown {
static
setImagesSrc
(
template
)
{
const
images
=
[...
template
.
querySelectorAll
(
'
img[data-src]
'
)];
images
.
forEach
(
(
image
)
=>
{
images
.
forEach
(
image
=>
{
const
img
=
image
;
img
.
src
=
img
.
getAttribute
(
'
data-src
'
);
...
...
app/assets/javascripts/droplab/drop_lab.js
View file @
4d0db16f
...
...
@@ -51,7 +51,7 @@ class DropLab {
}
processData
(
trigger
,
data
,
methodName
)
{
this
.
hooks
.
forEach
(
(
hook
)
=>
{
this
.
hooks
.
forEach
(
hook
=>
{
if
(
Array
.
isArray
(
trigger
))
hook
.
list
[
methodName
](
trigger
);
if
(
hook
.
trigger
.
id
===
trigger
)
hook
.
list
[
methodName
](
data
);
...
...
@@ -78,7 +78,8 @@ class DropLab {
}
changeHookList
(
trigger
,
list
,
plugins
,
config
)
{
const
availableTrigger
=
typeof
trigger
===
'
string
'
?
document
.
getElementById
(
trigger
)
:
trigger
;
const
availableTrigger
=
typeof
trigger
===
'
string
'
?
document
.
getElementById
(
trigger
)
:
trigger
;
this
.
hooks
.
forEach
((
hook
,
i
)
=>
{
const
aHook
=
hook
;
...
...
app/assets/javascripts/droplab/keyboard.js
View file @
4d0db16f
...
...
@@ -2,15 +2,18 @@
import
{
ACTIVE_CLASS
}
from
'
./constants
'
;
const
Keyboard
=
function
()
{
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):not(.hidden)
'
),
0
);
var
itemElements
=
Array
.
prototype
.
slice
.
call
(
list
.
list
.
querySelectorAll
(
'
li:not(.divider):not(.hidden)
'
),
0
,
);
var
listItems
=
[];
for
(
var
i
=
0
;
i
<
itemElements
.
length
;
i
++
)
{
for
(
var
i
=
0
;
i
<
itemElements
.
length
;
i
++
)
{
var
listItem
=
itemElements
[
i
];
listItem
.
classList
.
remove
(
ACTIVE_CLASS
);
...
...
@@ -23,13 +26,13 @@ const Keyboard = function () {
var
setMenuForArrows
=
function
setMenuForArrows
(
list
)
{
var
listItems
=
removeHighlight
(
list
);
if
(
list
.
currentIndex
>
0
)
{
if
(
!
listItems
[
list
.
currentIndex
-
1
])
{
list
.
currentIndex
=
list
.
currentIndex
-
1
;
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
];
if
(
listItems
[
list
.
currentIndex
-
1
])
{
var
el
=
listItems
[
list
.
currentIndex
-
1
];
var
filterDropdownEl
=
el
.
closest
(
'
.filter-dropdown
'
);
el
.
classList
.
add
(
ACTIVE_CLASS
);
...
...
@@ -55,7 +58,7 @@ const Keyboard = function () {
};
var
selectItem
=
function
selectItem
(
list
)
{
var
listItems
=
removeHighlight
(
list
);
var
currentItem
=
listItems
[
list
.
currentIndex
-
1
];
var
currentItem
=
listItems
[
list
.
currentIndex
-
1
];
var
listEvent
=
new
CustomEvent
(
'
click.dl
'
,
{
detail
:
{
list
:
list
,
...
...
@@ -65,43 +68,49 @@ const Keyboard = function () {
});
list
.
list
.
dispatchEvent
(
listEvent
);
list
.
hide
();
}
}
;
var
keydown
=
function
keydown
(
e
){
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
)
{
if
(
e
.
detail
.
which
)
{
currentKey
=
e
.
detail
.
which
;
if
(
currentKey
===
13
)
{
if
(
currentKey
===
13
)
{
selectItem
(
e
.
detail
.
hook
.
list
);
return
;
}
if
(
currentKey
===
38
)
{
if
(
currentKey
===
38
)
{
isUpArrow
=
true
;
}
if
(
currentKey
===
40
)
{
if
(
currentKey
===
40
)
{
isDownArrow
=
true
;
}
}
else
if
(
e
.
detail
.
key
)
{
}
else
if
(
e
.
detail
.
key
)
{
currentKey
=
e
.
detail
.
key
;
if
(
currentKey
===
'
Enter
'
)
{
if
(
currentKey
===
'
Enter
'
)
{
selectItem
(
e
.
detail
.
hook
.
list
);
return
;
}
if
(
currentKey
===
'
ArrowUp
'
)
{
if
(
currentKey
===
'
ArrowUp
'
)
{
isUpArrow
=
true
;
}
if
(
currentKey
===
'
ArrowDown
'
)
{
if
(
currentKey
===
'
ArrowDown
'
)
{
isDownArrow
=
true
;
}
}
if
(
isUpArrow
){
currentIndex
--
;
}
if
(
isDownArrow
){
currentIndex
++
;
}
if
(
currentIndex
<
0
){
currentIndex
=
0
;
}
if
(
isUpArrow
)
{
currentIndex
--
;
}
if
(
isDownArrow
)
{
currentIndex
++
;
}
if
(
currentIndex
<
0
)
{
currentIndex
=
0
;
}
list
.
currentIndex
=
currentIndex
;
setMenuForArrows
(
e
.
detail
.
hook
.
list
);
};
...
...
app/assets/javascripts/droplab/plugins/ajax.js
View file @
4d0db16f
...
...
@@ -43,12 +43,12 @@ const Ajax = {
return
AjaxCache
.
retrieve
(
config
.
endpoint
)
.
then
(
self
.
preprocessing
.
bind
(
null
,
config
))
.
then
(
(
data
)
=>
self
.
_loadData
(
data
,
config
,
self
))
.
then
(
data
=>
self
.
_loadData
(
data
,
config
,
self
))
.
catch
(
config
.
onError
);
},
destroy
:
function
()
{
this
.
destroyed
=
true
;
}
}
,
};
export
default
Ajax
;
app/assets/javascripts/droplab/plugins/ajax_filter.js
View file @
4d0db16f
...
...
@@ -41,8 +41,10 @@ const AjaxFilter = {
if
(
config
.
searchValueFunction
)
{
searchValue
=
config
.
searchValueFunction
();
}
if
(
config
.
loadingTemplate
&&
this
.
hook
.
list
.
data
===
undefined
||
this
.
hook
.
list
.
data
.
length
===
0
)
{
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
;
...
...
@@ -61,7 +63,7 @@ const AjaxFilter = {
params
[
config
.
searchKey
]
=
searchValue
;
var
url
=
config
.
endpoint
+
this
.
buildParams
(
params
);
return
AjaxCache
.
retrieve
(
url
)
.
then
(
(
data
)
=>
{
.
then
(
data
=>
{
this
.
_loadData
(
data
,
config
);
if
(
config
.
onLoadingFinished
)
{
config
.
onLoadingFinished
(
data
);
...
...
@@ -72,8 +74,7 @@ const AjaxFilter = {
_loadData
(
data
,
config
)
{
const
list
=
this
.
hook
.
list
;
if
(
config
.
loadingTemplate
&&
list
.
data
===
undefined
||
list
.
data
.
length
===
0
)
{
if
((
config
.
loadingTemplate
&&
list
.
data
===
undefined
)
||
list
.
data
.
length
===
0
)
{
const
dataLoadingTemplate
=
list
.
list
.
querySelector
(
'
[data-loading-template]
'
);
if
(
dataLoadingTemplate
)
{
dataLoadingTemplate
.
outerHTML
=
this
.
listTemplate
;
...
...
@@ -81,7 +82,8 @@ const AjaxFilter = {
}
if
(
!
this
.
destroyed
)
{
var
hookListChildren
=
list
.
list
.
children
;
var
onlyDynamicList
=
hookListChildren
.
length
===
1
&&
hookListChildren
[
0
].
hasAttribute
(
'
data-dynamic
'
);
var
onlyDynamicList
=
hookListChildren
.
length
===
1
&&
hookListChildren
[
0
].
hasAttribute
(
'
data-dynamic
'
);
if
(
onlyDynamicList
&&
data
.
length
===
0
)
{
list
.
hide
();
}
...
...
@@ -100,12 +102,12 @@ const AjaxFilter = {
},
destroy
:
function
destroy
()
{
if
(
this
.
timeout
)
clearTimeout
(
this
.
timeout
);
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
View file @
4d0db16f
/* eslint-disable */
const
Filter
=
{
keydown
:
function
(
e
){
keydown
:
function
(
e
)
{
if
(
this
.
destroyed
)
return
;
var
hiddenCount
=
0
;
...
...
@@ -14,14 +14,14 @@ const Filter = {
var
matches
=
[];
var
filterFunction
;
// will only work on dynamically set data
if
(
!
data
)
{
if
(
!
data
)
{
return
;
}
if
(
config
&&
config
.
filterFunction
&&
typeof
config
.
filterFunction
===
'
function
'
)
{
filterFunction
=
config
.
filterFunction
;
}
else
{
filterFunction
=
function
(
o
){
filterFunction
=
function
(
o
)
{
// cheap string search
o
.
droplab_hidden
=
o
[
config
.
template
].
toLowerCase
().
indexOf
(
value
)
===
-
1
;
return
o
;
...
...
@@ -47,7 +47,8 @@ const Filter = {
},
debounceKeydown
:
function
debounceKeydown
(
e
)
{
if
([
if
(
[
13
,
// enter
16
,
// shift
17
,
// ctrl
...
...
@@ -60,7 +61,9 @@ const Filter = {
91
,
// left window
92
,
// right window
93
,
// select
].
indexOf
(
e
.
detail
.
which
||
e
.
detail
.
keyCode
)
>
-
1
)
return
;
].
indexOf
(
e
.
detail
.
which
||
e
.
detail
.
keyCode
)
>
-
1
)
return
;
if
(
this
.
timeout
)
clearTimeout
(
this
.
timeout
);
this
.
timeout
=
setTimeout
(
this
.
keydown
.
bind
(
this
,
e
),
200
);
...
...
@@ -87,7 +90,7 @@ const Filter = {
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
View file @
4d0db16f
...
...
@@ -36,8 +36,8 @@ const InputSetter = {
const
inputAttribute
=
config
.
inputAttribute
;
if
(
input
.
hasAttribute
(
inputAttribute
))
return
input
.
setAttribute
(
inputAttribute
,
newValue
);
if
(
input
.
tagName
===
'
INPUT
'
)
return
input
.
value
=
newValue
;
return
input
.
textContent
=
newValue
;
if
(
input
.
tagName
===
'
INPUT
'
)
return
(
input
.
value
=
newValue
)
;
return
(
input
.
textContent
=
newValue
)
;
},
destroy
()
{
...
...
app/assets/javascripts/droplab/utils.js
View file @
4d0db16f
...
...
@@ -5,7 +5,12 @@ import { DATA_TRIGGER, DATA_DROPDOWN, TEMPLATE_REGEX } from './constants';
const
utils
=
{
toCamelCase
(
attr
)
{
return
this
.
camelize
(
attr
.
split
(
'
-
'
).
slice
(
1
).
join
(
'
'
));
return
this
.
camelize
(
attr
.
split
(
'
-
'
)
.
slice
(
1
)
.
join
(
'
'
),
);
},
template
(
templateString
,
data
)
{
...
...
@@ -17,9 +22,11 @@ const utils = {
},
camelize
(
str
)
{
return
str
.
replace
(
/
(?:
^
\w
|
[
A-Z
]
|
\b\w)
/g
,
(
letter
,
index
)
=>
{
return
str
.
replace
(
/
(?:
^
\w
|
[
A-Z
]
|
\b\w)
/g
,
(
letter
,
index
)
=>
{
return
index
===
0
?
letter
.
toLowerCase
()
:
letter
.
toUpperCase
();
}).
replace
(
/
\s
+/g
,
''
);
})
.
replace
(
/
\s
+/g
,
''
);
},
closest
(
thisTag
,
stopTag
)
{
...
...
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