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
1
Merge Requests
1
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
nexedi
gitlab-ce
Commits
aa90e8ea
Commit
aa90e8ea
authored
Dec 13, 2017
by
Filipa Lacerda
Committed by
Phil Hughes
Dec 13, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Export old code into es6 modules
parent
bcb14a0d
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
688 additions
and
706 deletions
+688
-706
app/assets/javascripts/dispatcher.js
app/assets/javascripts/dispatcher.js
+4
-3
app/assets/javascripts/main.js
app/assets/javascripts/main.js
+0
-5
app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js
...ets/javascripts/merge_conflicts/merge_conflicts_bundle.js
+2
-1
app/assets/javascripts/merge_request_tabs.js
app/assets/javascripts/merge_request_tabs.js
+2
-1
app/assets/javascripts/project_find_file.js
app/assets/javascripts/project_find_file.js
+146
-152
app/assets/javascripts/render_gfm.js
app/assets/javascripts/render_gfm.js
+2
-2
app/assets/javascripts/repo/components/repo_preview.vue
app/assets/javascripts/repo/components/repo_preview.vue
+2
-1
app/assets/javascripts/search.js
app/assets/javascripts/search.js
+101
-106
app/assets/javascripts/search_autocomplete.js
app/assets/javascripts/search_autocomplete.js
+383
-386
app/assets/javascripts/single_file_diff.js
app/assets/javascripts/single_file_diff.js
+2
-1
app/assets/javascripts/syntax_highlight.js
app/assets/javascripts/syntax_highlight.js
+6
-8
spec/javascripts/search_autocomplete_spec.js
spec/javascripts/search_autocomplete_spec.js
+2
-2
spec/javascripts/syntax_highlight_spec.js
spec/javascripts/syntax_highlight_spec.js
+36
-38
No files found.
app/assets/javascripts/dispatcher.js
View file @
aa90e8ea
...
@@ -15,7 +15,7 @@ import GroupLabelSubscription from './group_label_subscription';
...
@@ -15,7 +15,7 @@ import GroupLabelSubscription from './group_label_subscription';
import
BuildArtifacts
from
'
./build_artifacts
'
;
import
BuildArtifacts
from
'
./build_artifacts
'
;
import
CILintEditor
from
'
./ci_lint_editor
'
;
import
CILintEditor
from
'
./ci_lint_editor
'
;
import
groupsSelect
from
'
./groups_select
'
;
import
groupsSelect
from
'
./groups_select
'
;
/* global Search */
import
Search
from
'
./search
'
;
/* global Admin */
/* global Admin */
import
NamespaceSelect
from
'
./namespace_select
'
;
import
NamespaceSelect
from
'
./namespace_select
'
;
import
NewCommitForm
from
'
./new_commit_form
'
;
import
NewCommitForm
from
'
./new_commit_form
'
;
...
@@ -24,7 +24,7 @@ import projectAvatar from './project_avatar';
...
@@ -24,7 +24,7 @@ import projectAvatar from './project_avatar';
/* global MergeRequest */
/* global MergeRequest */
import
Compare
from
'
./compare
'
;
import
Compare
from
'
./compare
'
;
import
initCompareAutocomplete
from
'
./compare_autocomplete
'
;
import
initCompareAutocomplete
from
'
./compare_autocomplete
'
;
/* global ProjectFindFile */
import
ProjectFindFile
from
'
./project_find_file
'
;
import
ProjectNew
from
'
./project_new
'
;
import
ProjectNew
from
'
./project_new
'
;
import
projectImport
from
'
./project_import
'
;
import
projectImport
from
'
./project_import
'
;
import
Labels
from
'
./labels
'
;
import
Labels
from
'
./labels
'
;
...
@@ -91,6 +91,7 @@ import DueDateSelectors from './due_date_select';
...
@@ -91,6 +91,7 @@ import DueDateSelectors from './due_date_select';
import
Diff
from
'
./diff
'
;
import
Diff
from
'
./diff
'
;
import
ProjectLabelSubscription
from
'
./project_label_subscription
'
;
import
ProjectLabelSubscription
from
'
./project_label_subscription
'
;
import
ProjectVariables
from
'
./project_variables
'
;
import
ProjectVariables
from
'
./project_variables
'
;
import
SearchAutocomplete
from
'
./search_autocomplete
'
;
(
function
()
{
(
function
()
{
var
Dispatcher
;
var
Dispatcher
;
...
@@ -683,7 +684,7 @@ import ProjectVariables from './project_variables';
...
@@ -683,7 +684,7 @@ import ProjectVariables from './project_variables';
Dispatcher
.
prototype
.
initSearch
=
function
()
{
Dispatcher
.
prototype
.
initSearch
=
function
()
{
// Only when search form is present
// Only when search form is present
if
(
$
(
'
.search
'
).
length
)
{
if
(
$
(
'
.search
'
).
length
)
{
return
new
gl
.
SearchAutocomplete
();
return
new
SearchAutocomplete
();
}
}
};
};
...
...
app/assets/javascripts/main.js
View file @
aa90e8ea
...
@@ -60,15 +60,10 @@ import './notifications_dropdown';
...
@@ -60,15 +60,10 @@ import './notifications_dropdown';
import
'
./notifications_form
'
;
import
'
./notifications_form
'
;
import
'
./pager
'
;
import
'
./pager
'
;
import
'
./preview_markdown
'
;
import
'
./preview_markdown
'
;
import
'
./project_find_file
'
;
import
'
./project_import
'
;
import
'
./project_import
'
;
import
'
./projects_dropdown
'
;
import
'
./projects_dropdown
'
;
import
'
./projects_list
'
;
import
'
./syntax_highlight
'
;
import
'
./render_gfm
'
;
import
'
./render_gfm
'
;
import
'
./right_sidebar
'
;
import
'
./right_sidebar
'
;
import
'
./search
'
;
import
'
./search_autocomplete
'
;
import
initBreadcrumbs
from
'
./breadcrumb
'
;
import
initBreadcrumbs
from
'
./breadcrumb
'
;
import
'
./dispatcher
'
;
import
'
./dispatcher
'
;
...
...
app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js
View file @
aa90e8ea
...
@@ -10,6 +10,7 @@ import './mixins/line_conflict_actions';
...
@@ -10,6 +10,7 @@ import './mixins/line_conflict_actions';
import
'
./components/diff_file_editor
'
;
import
'
./components/diff_file_editor
'
;
import
'
./components/inline_conflict_lines
'
;
import
'
./components/inline_conflict_lines
'
;
import
'
./components/parallel_conflict_lines
'
;
import
'
./components/parallel_conflict_lines
'
;
import
syntaxHighlight
from
'
../syntax_highlight
'
;
$
(()
=>
{
$
(()
=>
{
const
INTERACTIVE_RESOLVE_MODE
=
'
interactive
'
;
const
INTERACTIVE_RESOLVE_MODE
=
'
interactive
'
;
...
@@ -53,7 +54,7 @@ $(() => {
...
@@ -53,7 +54,7 @@ $(() => {
mergeConflictsStore
.
setLoadingState
(
false
);
mergeConflictsStore
.
setLoadingState
(
false
);
this
.
$nextTick
(()
=>
{
this
.
$nextTick
(()
=>
{
$
(
'
.js-syntax-highlight
'
).
syntaxHighlight
(
);
syntaxHighlight
(
$
(
'
.js-syntax-highlight
'
)
);
});
});
});
});
},
},
...
...
app/assets/javascripts/merge_request_tabs.js
View file @
aa90e8ea
...
@@ -14,6 +14,7 @@ import {
...
@@ -14,6 +14,7 @@ import {
import
{
getLocationHash
}
from
'
./lib/utils/url_utility
'
;
import
{
getLocationHash
}
from
'
./lib/utils/url_utility
'
;
import
initDiscussionTab
from
'
./image_diff/init_discussion_tab
'
;
import
initDiscussionTab
from
'
./image_diff/init_discussion_tab
'
;
import
Diff
from
'
./diff
'
;
import
Diff
from
'
./diff
'
;
import
syntaxHighlight
from
'
./syntax_highlight
'
;
/* eslint-disable max-len */
/* eslint-disable max-len */
// MergeRequestTabs
// MergeRequestTabs
...
@@ -295,7 +296,7 @@ import Diff from './diff';
...
@@ -295,7 +296,7 @@ import Diff from './diff';
}
}
gl
.
utils
.
localTimeAgo
(
$
(
'
.js-timeago
'
,
'
div#diffs
'
));
gl
.
utils
.
localTimeAgo
(
$
(
'
.js-timeago
'
,
'
div#diffs
'
));
$
(
'
#diffs .js-syntax-highlight
'
).
syntaxHighlight
(
);
syntaxHighlight
(
$
(
'
#diffs .js-syntax-highlight
'
)
);
if
(
this
.
diffViewType
()
===
'
parallel
'
&&
this
.
isDiffAction
(
this
.
currentAction
))
{
if
(
this
.
diffViewType
()
===
'
parallel
'
&&
this
.
isDiffAction
(
this
.
currentAction
))
{
this
.
expandViewContainer
();
this
.
expandViewContainer
();
...
...
app/assets/javascripts/project_find_file.js
View file @
aa90e8ea
...
@@ -2,169 +2,163 @@
...
@@ -2,169 +2,163 @@
import
fuzzaldrinPlus
from
'
fuzzaldrin-plus
'
;
import
fuzzaldrinPlus
from
'
fuzzaldrin-plus
'
;
(
function
()
{
// highlight text(awefwbwgtc -> <b>a</b>wefw<b>b</b>wgt<b>c</b> )
this
.
ProjectFindFile
=
(
function
()
{
const
highlighter
=
function
(
element
,
text
,
matches
)
{
var
highlighter
;
var
highlightText
,
j
,
lastIndex
,
len
,
matchIndex
,
matchedChars
,
unmatched
;
lastIndex
=
0
;
function
ProjectFindFile
(
element1
,
options
)
{
highlightText
=
""
;
this
.
element
=
element1
;
matchedChars
=
[];
this
.
options
=
options
;
for
(
j
=
0
,
len
=
matches
.
length
;
j
<
len
;
j
+=
1
)
{
this
.
goToBlob
=
this
.
goToBlob
.
bind
(
this
);
matchIndex
=
matches
[
j
];
this
.
goToTree
=
this
.
goToTree
.
bind
(
this
);
unmatched
=
text
.
substring
(
lastIndex
,
matchIndex
);
this
.
selectRowDown
=
this
.
selectRowDown
.
bind
(
this
);
if
(
unmatched
)
{
this
.
selectRowUp
=
this
.
selectRowUp
.
bind
(
this
);
if
(
matchedChars
.
length
)
{
this
.
filePaths
=
{};
element
.
append
(
matchedChars
.
join
(
""
).
bold
());
this
.
inputElement
=
this
.
element
.
find
(
"
.file-finder-input
"
);
}
// init event
matchedChars
=
[];
this
.
initEvent
();
element
.
append
(
document
.
createTextNode
(
unmatched
));
// focus text input box
this
.
inputElement
.
focus
();
// load file list
this
.
load
(
this
.
options
.
url
);
}
}
matchedChars
.
push
(
text
[
matchIndex
]);
ProjectFindFile
.
prototype
.
initEvent
=
function
()
{
lastIndex
=
matchIndex
+
1
;
this
.
inputElement
.
off
(
"
keyup
"
);
}
this
.
inputElement
.
on
(
"
keyup
"
,
(
function
(
_this
)
{
if
(
matchedChars
.
length
)
{
return
function
(
event
)
{
element
.
append
(
matchedChars
.
join
(
""
).
bold
());
var
oldValue
,
ref
,
target
,
value
;
}
target
=
$
(
event
.
target
);
return
element
.
append
(
document
.
createTextNode
(
text
.
substring
(
lastIndex
)));
value
=
target
.
val
();
};
oldValue
=
(
ref
=
target
.
data
(
"
oldValue
"
))
!=
null
?
ref
:
""
;
if
(
value
!==
oldValue
)
{
export
default
class
ProjectFindFile
{
target
.
data
(
"
oldValue
"
,
value
);
constructor
(
element1
,
options
)
{
_this
.
findFile
();
this
.
element
=
element1
;
return
_this
.
element
.
find
(
"
tr.tree-item
"
).
eq
(
0
).
addClass
(
"
selected
"
).
focus
();
this
.
options
=
options
;
}
this
.
goToBlob
=
this
.
goToBlob
.
bind
(
this
);
};
this
.
goToTree
=
this
.
goToTree
.
bind
(
this
);
})(
this
));
this
.
selectRowDown
=
this
.
selectRowDown
.
bind
(
this
);
};
this
.
selectRowUp
=
this
.
selectRowUp
.
bind
(
this
);
this
.
filePaths
=
{};
ProjectFindFile
.
prototype
.
findFile
=
function
()
{
this
.
inputElement
=
this
.
element
.
find
(
"
.file-finder-input
"
);
var
result
,
searchText
;
// init event
searchText
=
this
.
inputElement
.
val
();
this
.
initEvent
();
result
=
searchText
.
length
>
0
?
fuzzaldrinPlus
.
filter
(
this
.
filePaths
,
searchText
)
:
this
.
filePaths
;
// focus text input box
return
this
.
renderList
(
result
,
searchText
);
this
.
inputElement
.
focus
();
// find file
// load file list
};
this
.
load
(
this
.
options
.
url
);
}
initEvent
()
{
this
.
inputElement
.
off
(
"
keyup
"
);
this
.
inputElement
.
on
(
"
keyup
"
,
(
function
(
_this
)
{
return
function
(
event
)
{
var
oldValue
,
ref
,
target
,
value
;
target
=
$
(
event
.
target
);
value
=
target
.
val
();
oldValue
=
(
ref
=
target
.
data
(
"
oldValue
"
))
!=
null
?
ref
:
""
;
if
(
value
!==
oldValue
)
{
target
.
data
(
"
oldValue
"
,
value
);
_this
.
findFile
();
return
_this
.
element
.
find
(
"
tr.tree-item
"
).
eq
(
0
).
addClass
(
"
selected
"
).
focus
();
}
};
})(
this
));
}
findFile
()
{
var
result
,
searchText
;
searchText
=
this
.
inputElement
.
val
();
result
=
searchText
.
length
>
0
?
fuzzaldrinPlus
.
filter
(
this
.
filePaths
,
searchText
)
:
this
.
filePaths
;
return
this
.
renderList
(
result
,
searchText
);
// find file
}
// files pathes load
// files pathes load
ProjectFindFile
.
prototype
.
load
=
function
(
url
)
{
load
(
url
)
{
return
$
.
ajax
({
return
$
.
ajax
({
url
:
url
,
url
:
url
,
method
:
"
get
"
,
method
:
"
get
"
,
dataType
:
"
json
"
,
dataType
:
"
json
"
,
success
:
(
function
(
_this
)
{
success
:
(
function
(
_this
)
{
return
function
(
data
)
{
return
function
(
data
)
{
_this
.
element
.
find
(
"
.loading
"
).
hide
();
_this
.
element
.
find
(
"
.loading
"
).
hide
();
_this
.
filePaths
=
data
;
_this
.
filePaths
=
data
;
_this
.
findFile
();
_this
.
findFile
();
return
_this
.
element
.
find
(
"
.files-slider tr.tree-item
"
).
eq
(
0
).
addClass
(
"
selected
"
).
focus
();
return
_this
.
element
.
find
(
"
.files-slider tr.tree-item
"
).
eq
(
0
).
addClass
(
"
selected
"
).
focus
();
};
};
})(
this
)
})(
this
)
});
});
};
}
// render result
// render result
ProjectFindFile
.
prototype
.
renderList
=
function
(
filePaths
,
searchText
)
{
renderList
(
filePaths
,
searchText
)
{
var
blobItemUrl
,
filePath
,
html
,
i
,
j
,
len
,
matches
,
results
;
var
blobItemUrl
,
filePath
,
html
,
i
,
j
,
len
,
matches
,
results
;
this
.
element
.
find
(
"
.tree-table > tbody
"
).
empty
();
this
.
element
.
find
(
"
.tree-table > tbody
"
).
empty
();
results
=
[];
results
=
[];
for
(
i
=
j
=
0
,
len
=
filePaths
.
length
;
j
<
len
;
i
=
(
j
+=
1
))
{
for
(
i
=
j
=
0
,
len
=
filePaths
.
length
;
j
<
len
;
i
=
(
j
+=
1
))
{
filePath
=
filePaths
[
i
];
filePath
=
filePaths
[
i
];
if
(
i
===
20
)
{
if
(
i
===
20
)
{
break
;
break
;
}
if
(
searchText
)
{
matches
=
fuzzaldrinPlus
.
match
(
filePath
,
searchText
);
}
blobItemUrl
=
this
.
options
.
blobUrlTemplate
+
"
/
"
+
filePath
;
html
=
this
.
makeHtml
(
filePath
,
matches
,
blobItemUrl
);
results
.
push
(
this
.
element
.
find
(
"
.tree-table > tbody
"
).
append
(
html
));
}
return
results
;
};
// highlight text(awefwbwgtc -> <b>a</b>wefw<b>b</b>wgt<b>c</b> )
highlighter
=
function
(
element
,
text
,
matches
)
{
var
highlightText
,
j
,
lastIndex
,
len
,
matchIndex
,
matchedChars
,
unmatched
;
lastIndex
=
0
;
highlightText
=
""
;
matchedChars
=
[];
for
(
j
=
0
,
len
=
matches
.
length
;
j
<
len
;
j
+=
1
)
{
matchIndex
=
matches
[
j
];
unmatched
=
text
.
substring
(
lastIndex
,
matchIndex
);
if
(
unmatched
)
{
if
(
matchedChars
.
length
)
{
element
.
append
(
matchedChars
.
join
(
""
).
bold
());
}
matchedChars
=
[];
element
.
append
(
document
.
createTextNode
(
unmatched
));
}
matchedChars
.
push
(
text
[
matchIndex
]);
lastIndex
=
matchIndex
+
1
;
}
if
(
matchedChars
.
length
)
{
element
.
append
(
matchedChars
.
join
(
""
).
bold
());
}
}
return
element
.
append
(
document
.
createTextNode
(
text
.
substring
(
lastIndex
)));
if
(
searchText
)
{
};
matches
=
fuzzaldrinPlus
.
match
(
filePath
,
searchText
);
// make tbody row html
ProjectFindFile
.
prototype
.
makeHtml
=
function
(
filePath
,
matches
,
blobItemUrl
)
{
var
$tr
;
$tr
=
$
(
"
<tr class='tree-item'><td class='tree-item-file-name link-container'><a><i class='fa fa-file-text-o fa-fw'></i><span class='str-truncated'></span></a></td></tr>
"
);
if
(
matches
)
{
$tr
.
find
(
"
a
"
).
replaceWith
(
highlighter
(
$tr
.
find
(
"
a
"
),
filePath
,
matches
).
attr
(
"
href
"
,
blobItemUrl
));
}
else
{
$tr
.
find
(
"
a
"
).
attr
(
"
href
"
,
blobItemUrl
);
$tr
.
find
(
"
.str-truncated
"
).
text
(
filePath
);
}
}
return
$tr
;
blobItemUrl
=
this
.
options
.
blobUrlTemplate
+
"
/
"
+
filePath
;
};
html
=
ProjectFindFile
.
makeHtml
(
filePath
,
matches
,
blobItemUrl
);
results
.
push
(
this
.
element
.
find
(
"
.tree-table > tbody
"
).
append
(
html
));
ProjectFindFile
.
prototype
.
selectRow
=
function
(
type
)
{
}
var
next
,
rows
,
selectedRow
;
return
results
;
rows
=
this
.
element
.
find
(
"
.files-slider tr.tree-item
"
);
}
selectedRow
=
this
.
element
.
find
(
"
.files-slider tr.tree-item.selected
"
);
if
(
rows
&&
rows
.
length
>
0
)
{
// make tbody row html
if
(
selectedRow
&&
selectedRow
.
length
>
0
)
{
static
makeHtml
(
filePath
,
matches
,
blobItemUrl
)
{
if
(
type
===
"
UP
"
)
{
var
$tr
;
next
=
selectedRow
.
prev
();
$tr
=
$
(
"
<tr class='tree-item'><td class='tree-item-file-name link-container'><a><i class='fa fa-file-text-o fa-fw'></i><span class='str-truncated'></span></a></td></tr>
"
);
}
else
if
(
type
===
"
DOWN
"
)
{
if
(
matches
)
{
next
=
selectedRow
.
next
();
$tr
.
find
(
"
a
"
).
replaceWith
(
highlighter
(
$tr
.
find
(
"
a
"
),
filePath
,
matches
).
attr
(
"
href
"
,
blobItemUrl
));
}
}
else
{
if
(
next
.
length
>
0
)
{
$tr
.
find
(
"
a
"
).
attr
(
"
href
"
,
blobItemUrl
);
selectedRow
.
removeClass
(
"
selected
"
);
$tr
.
find
(
"
.str-truncated
"
).
text
(
filePath
);
selectedRow
=
next
;
}
}
return
$tr
;
}
else
{
}
selectedRow
=
rows
.
eq
(
0
);
selectRow
(
type
)
{
var
next
,
rows
,
selectedRow
;
rows
=
this
.
element
.
find
(
"
.files-slider tr.tree-item
"
);
selectedRow
=
this
.
element
.
find
(
"
.files-slider tr.tree-item.selected
"
);
if
(
rows
&&
rows
.
length
>
0
)
{
if
(
selectedRow
&&
selectedRow
.
length
>
0
)
{
if
(
type
===
"
UP
"
)
{
next
=
selectedRow
.
prev
();
}
else
if
(
type
===
"
DOWN
"
)
{
next
=
selectedRow
.
next
();
}
if
(
next
.
length
>
0
)
{
selectedRow
.
removeClass
(
"
selected
"
);
selectedRow
=
next
;
}
}
return
selectedRow
.
addClass
(
"
selected
"
).
focus
();
}
else
{
selectedRow
=
rows
.
eq
(
0
);
}
}
};
return
selectedRow
.
addClass
(
"
selected
"
).
focus
();
}
ProjectFindFile
.
prototype
.
selectRowUp
=
function
()
{
}
return
this
.
selectRow
(
"
UP
"
);
};
ProjectFindFile
.
prototype
.
selectRowDown
=
function
()
{
selectRowUp
()
{
return
this
.
selectRow
(
"
DOWN
"
);
return
this
.
selectRow
(
"
UP
"
);
};
}
ProjectFindFile
.
prototype
.
goToTree
=
functio
n
()
{
selectRowDow
n
()
{
return
location
.
href
=
this
.
options
.
treeUrl
;
return
this
.
selectRow
(
"
DOWN
"
)
;
};
}
ProjectFindFile
.
prototype
.
goToBlob
=
function
()
{
goToTree
()
{
var
$link
=
this
.
element
.
find
(
"
.tree-item.selected .tree-item-file-name a
"
);
return
location
.
href
=
this
.
options
.
treeUrl
;
}
if
(
$link
.
length
)
{
goToBlob
()
{
$link
.
get
(
0
).
click
();
var
$link
=
this
.
element
.
find
(
"
.tree-item.selected .tree-item-file-name a
"
);
}
};
return
ProjectFindFile
;
if
(
$link
.
length
)
{
})();
$link
.
get
(
0
).
click
();
}).
call
(
window
);
}
}
}
app/assets/javascripts/render_gfm.js
View file @
aa90e8ea
import
renderMath
from
'
./render_math
'
;
import
renderMath
from
'
./render_math
'
;
import
renderMermaid
from
'
./render_mermaid
'
;
import
renderMermaid
from
'
./render_mermaid
'
;
import
syntaxHighlight
from
'
./syntax_highlight
'
;
// Render Gitlab flavoured Markdown
// Render Gitlab flavoured Markdown
//
//
// Delegates to syntax highlight and render math & mermaid diagrams.
// Delegates to syntax highlight and render math & mermaid diagrams.
//
//
$
.
fn
.
renderGFM
=
function
renderGFM
()
{
$
.
fn
.
renderGFM
=
function
renderGFM
()
{
this
.
find
(
'
.js-syntax-highlight
'
).
syntaxHighlight
(
);
syntaxHighlight
(
this
.
find
(
'
.js-syntax-highlight
'
)
);
renderMath
(
this
.
find
(
'
.js-render-math
'
));
renderMath
(
this
.
find
(
'
.js-render-math
'
));
renderMermaid
(
this
.
find
(
'
.js-render-mermaid
'
));
renderMermaid
(
this
.
find
(
'
.js-render-mermaid
'
));
return
this
;
return
this
;
...
...
app/assets/javascripts/repo/components/repo_preview.vue
View file @
aa90e8ea
<
script
>
<
script
>
/* global LineHighlighter */
/* global LineHighlighter */
import
{
mapGetters
}
from
'
vuex
'
;
import
{
mapGetters
}
from
'
vuex
'
;
import
syntaxHighlight
from
'
../../syntax_highlight
'
;
export
default
{
export
default
{
computed
:
{
computed
:
{
...
@@ -13,7 +14,7 @@ export default {
...
@@ -13,7 +14,7 @@ export default {
},
},
methods
:
{
methods
:
{
highlightFile
()
{
highlightFile
()
{
$
(
this
.
$el
).
find
(
'
.file-content
'
).
syntaxHighlight
(
);
syntaxHighlight
(
$
(
this
.
$el
).
find
(
'
.file-content
'
)
);
},
},
},
},
mounted
()
{
mounted
()
{
...
...
app/assets/javascripts/search.js
View file @
aa90e8ea
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, one-var, one-var-declaration-per-line, object-shorthand, prefer-arrow-callback, comma-dangle, prefer-template, quotes, no-else-return, max-len */
import
Flash
from
'
./flash
'
;
import
Flash
from
'
./flash
'
;
import
Api
from
'
./api
'
;
import
Api
from
'
./api
'
;
(
function
()
{
export
default
class
Search
{
this
.
Search
=
(
function
()
{
constructor
()
{
function
Search
()
{
const
$groupDropdown
=
$
(
'
.js-search-group-dropdown
'
);
var
$groupDropdown
,
$projectDropdown
;
const
$projectDropdown
=
$
(
'
.js-search-project-dropdown
'
);
$groupDropdown
=
$
(
'
.js-search-group-dropdown
'
);
$projectDropdown
=
$
(
'
.js-search-project-dropdown
'
);
this
.
searchInput
=
'
.js-search-input
'
;
this
.
groupId
=
$groupDropdown
.
data
(
'
group-id
'
);
this
.
searchClear
=
'
.js-search-clear
'
;
this
.
eventListeners
();
$groupDropdown
.
glDropdown
({
this
.
groupId
=
$groupDropdown
.
data
(
'
group-id
'
);
selectable
:
true
,
this
.
eventListeners
();
filterable
:
true
,
fieldName
:
'
group_id
'
,
$groupDropdown
.
glDropdown
({
search
:
{
selectable
:
true
,
fields
:
[
'
full_name
'
]
filterable
:
true
,
},
fieldName
:
'
group_id
'
,
data
:
function
(
term
,
callback
)
{
search
:
{
return
Api
.
groups
(
term
,
{},
function
(
data
)
{
fields
:
[
'
full_name
'
],
},
data
(
term
,
callback
)
{
return
Api
.
groups
(
term
,
{},
(
data
)
=>
{
data
.
unshift
({
full_name
:
'
Any
'
,
});
data
.
splice
(
1
,
0
,
'
divider
'
);
return
callback
(
data
);
});
},
id
(
obj
)
{
return
obj
.
id
;
},
text
(
obj
)
{
return
obj
.
full_name
;
},
toggleLabel
(
obj
)
{
return
`
${(
$groupDropdown
.
data
(
'
default-label
'
))}
${
obj
.
full_name
}
`
;
},
clicked
:
()
=>
Search
.
submitSearch
(),
});
$projectDropdown
.
glDropdown
({
selectable
:
true
,
filterable
:
true
,
fieldName
:
'
project_id
'
,
search
:
{
fields
:
[
'
name
'
],
},
data
:
(
term
,
callback
)
=>
{
this
.
getProjectsData
(
term
)
.
then
((
data
)
=>
{
data
.
unshift
({
data
.
unshift
({
full_name
:
'
Any
'
name_with_namespace
:
'
Any
'
,
});
});
data
.
splice
(
1
,
0
,
'
divider
'
);
data
.
splice
(
1
,
0
,
'
divider
'
);
return
callback
(
data
);
});
},
id
:
function
(
obj
)
{
return
obj
.
id
;
},
text
:
function
(
obj
)
{
return
obj
.
full_name
;
},
toggleLabel
:
function
(
obj
)
{
return
(
$groupDropdown
.
data
(
'
default-label
'
))
+
"
"
+
obj
.
full_name
;
},
clicked
:
(
function
(
_this
)
{
return
function
()
{
return
_this
.
submitSearch
();
};
})(
this
)
});
$projectDropdown
.
glDropdown
({
selectable
:
true
,
filterable
:
true
,
fieldName
:
'
project_id
'
,
search
:
{
fields
:
[
'
name
'
]
},
data
:
(
term
,
callback
)
=>
{
this
.
getProjectsData
(
term
)
.
then
((
data
)
=>
{
data
.
unshift
({
name_with_namespace
:
'
Any
'
});
data
.
splice
(
1
,
0
,
'
divider
'
);
return
data
;
return
data
;
})
})
.
then
(
data
=>
callback
(
data
))
.
then
(
data
=>
callback
(
data
))
.
catch
(()
=>
new
Flash
(
'
Error fetching projects
'
));
.
catch
(()
=>
new
Flash
(
'
Error fetching projects
'
));
},
},
id
:
function
(
obj
)
{
id
(
obj
)
{
return
obj
.
id
;
return
obj
.
id
;
},
},
text
:
function
(
obj
)
{
text
(
obj
)
{
return
obj
.
name_with_namespace
;
return
obj
.
name_with_namespace
;
},
},
toggleLabel
:
function
(
obj
)
{
toggleLabel
(
obj
)
{
return
(
$projectDropdown
.
data
(
'
default-label
'
))
+
"
"
+
obj
.
name_with_namespace
;
return
`
${(
$projectDropdown
.
data
(
'
default-label
'
))}
${
obj
.
name_with_namespace
}
`
;
},
},
clicked
:
(
function
(
_this
)
{
clicked
:
()
=>
Search
.
submitSearch
(),
return
function
()
{
});
return
_this
.
submitSearch
();
}
};
})(
this
)
});
}
Search
.
prototype
.
eventListeners
=
function
()
{
eventListeners
()
{
$
(
document
).
off
(
'
keyup
'
,
'
.js-search-input
'
).
on
(
'
keyup
'
,
'
.js-search-input
'
,
this
.
searchKeyUp
);
$
(
document
)
return
$
(
document
).
off
(
'
click
'
,
'
.js-search-clear
'
).
on
(
'
click
'
,
'
.js-search-clear
'
,
this
.
clearSearchField
);
.
off
(
'
keyup
'
,
this
.
searchInput
)
};
.
on
(
'
keyup
'
,
this
.
searchInput
,
this
.
searchKeyUp
);
$
(
document
)
.
off
(
'
click
'
,
this
.
searchClear
)
.
on
(
'
click
'
,
this
.
searchClear
,
this
.
clearSearchField
.
bind
(
this
));
}
Search
.
prototype
.
submitSearch
=
function
()
{
static
submitSearch
()
{
return
$
(
'
.js-search-form
'
).
submit
();
return
$
(
'
.js-search-form
'
).
submit
();
};
}
Search
.
prototype
.
searchKeyUp
=
function
()
{
searchKeyUp
()
{
var
$input
;
const
$input
=
$
(
this
);
$input
=
$
(
this
);
if
(
$input
.
val
()
===
''
)
{
if
(
$input
.
val
()
===
''
)
{
$
(
'
.js-search-clear
'
).
addClass
(
'
hidden
'
);
return
$
(
'
.js-search-clear
'
).
addClass
(
'
hidden
'
);
}
else
{
}
else
{
$
(
'
.js-search-clear
'
).
removeClass
(
'
hidden
'
);
return
$
(
'
.js-search-clear
'
).
removeClass
(
'
hidden
'
);
}
}
}
};
Search
.
prototype
.
clearSearchField
=
function
()
{
return
$
(
'
.js-search-input
'
).
val
(
''
).
trigger
(
'
keyup
'
).
focus
();
};
Search
.
prototype
.
getProjectsData
=
function
(
term
)
{
clearSearchField
()
{
return
new
Promise
((
resolve
)
=>
{
return
$
(
this
.
searchInput
).
val
(
''
).
trigger
(
'
keyup
'
).
focus
();
if
(
this
.
groupId
)
{
}
Api
.
groupProjects
(
this
.
groupId
,
term
,
resolve
);
}
else
{
Api
.
projects
(
term
,
{
order_by
:
'
id
'
,
},
resolve
);
}
});
};
return
Search
;
getProjectsData
(
term
)
{
})();
return
new
Promise
((
resolve
)
=>
{
}).
call
(
window
);
if
(
this
.
groupId
)
{
Api
.
groupProjects
(
this
.
groupId
,
term
,
resolve
);
}
else
{
Api
.
projects
(
term
,
{
order_by
:
'
id
'
,
},
resolve
);
}
});
}
}
app/assets/javascripts/search_autocomplete.js
View file @
aa90e8ea
...
@@ -8,448 +8,445 @@ import { isInGroupsPage, isInProjectPage, getGroupSlug, getProjectSlug } from '.
...
@@ -8,448 +8,445 @@ import { isInGroupsPage, isInProjectPage, getGroupSlug, getProjectSlug } from '.
* When the user clicks `x` button it cleans the input and closes the dropdown.
* When the user clicks `x` button it cleans the input and closes the dropdown.
*/
*/
((
global
)
=>
{
const
KEYCODE
=
{
const
KEYCODE
=
{
ESCAPE
:
27
,
ESCAPE
:
27
,
BACKSPACE
:
8
,
BACKSPACE
:
8
,
ENTER
:
13
,
ENTER
:
13
,
UP
:
38
,
UP
:
38
,
DOWN
:
40
,
DOWN
:
40
,
};
};
function
setSearchOptions
()
{
class
SearchAutocomplete
{
var
$projectOptionsDataEl
=
$
(
'
.js-search-project-options
'
);
constructor
({
wrap
,
optsEl
,
autocompletePath
,
projectId
,
projectRef
}
=
{})
{
var
$groupOptionsDataEl
=
$
(
'
.js-search-group-options
'
);
this
.
bindEventContext
();
var
$dashboardOptionsDataEl
=
$
(
'
.js-search-dashboard-options
'
);
this
.
wrap
=
wrap
||
$
(
'
.search
'
);
this
.
optsEl
=
optsEl
||
this
.
wrap
.
find
(
'
.search-autocomplete-opts
'
);
if
(
$projectOptionsDataEl
.
length
)
{
this
.
autocompletePath
=
autocompletePath
||
this
.
optsEl
.
data
(
'
autocomplete-path
'
);
gl
.
projectOptions
=
gl
.
projectOptions
||
{};
this
.
projectId
=
projectId
||
(
this
.
optsEl
.
data
(
'
autocomplete-project-id
'
)
||
''
);
this
.
projectRef
=
projectRef
||
(
this
.
optsEl
.
data
(
'
autocomplete-project-ref
'
)
||
''
);
var
projectPath
=
$projectOptionsDataEl
.
data
(
'
project-path
'
);
this
.
dropdown
=
this
.
wrap
.
find
(
'
.dropdown
'
);
this
.
dropdownToggle
=
this
.
wrap
.
find
(
'
.js-dropdown-search-toggle
'
);
gl
.
projectOptions
[
projectPath
]
=
{
this
.
dropdownContent
=
this
.
dropdown
.
find
(
'
.dropdown-content
'
);
name
:
$projectOptionsDataEl
.
data
(
'
name
'
),
this
.
locationBadgeEl
=
this
.
getElement
(
'
.location-badge
'
);
issuesPath
:
$projectOptionsDataEl
.
data
(
'
issues-path
'
),
this
.
scopeInputEl
=
this
.
getElement
(
'
#scope
'
);
issuesDisabled
:
$projectOptionsDataEl
.
data
(
'
issues-disabled
'
),
this
.
searchInput
=
this
.
getElement
(
'
.search-input
'
);
mrPath
:
$projectOptionsDataEl
.
data
(
'
mr-path
'
),
this
.
projectInputEl
=
this
.
getElement
(
'
#search_project_id
'
);
};
this
.
groupInputEl
=
this
.
getElement
(
'
#group_id
'
);
}
this
.
searchCodeInputEl
=
this
.
getElement
(
'
#search_code
'
);
this
.
repositoryInputEl
=
this
.
getElement
(
'
#repository_ref
'
);
this
.
clearInput
=
this
.
getElement
(
'
.js-clear-input
'
);
this
.
saveOriginalState
();
// Only when user is logged in
if
(
gon
.
current_user_id
)
{
this
.
createAutocomplete
();
}
this
.
searchInput
.
addClass
(
'
disabled
'
);
if
(
$groupOptionsDataEl
.
length
)
{
this
.
saveTextLength
();
gl
.
groupOptions
=
gl
.
groupOptions
||
{};
this
.
bindEvents
();
this
.
dropdownToggle
.
dropdown
();
}
// Finds an element inside wrapper element
var
groupPath
=
$groupOptionsDataEl
.
data
(
'
group-path
'
);
bindEventContext
()
{
this
.
onSearchInputBlur
=
this
.
onSearchInputBlur
.
bind
(
this
);
this
.
onClearInputClick
=
this
.
onClearInputClick
.
bind
(
this
);
this
.
onSearchInputFocus
=
this
.
onSearchInputFocus
.
bind
(
this
);
this
.
onSearchInputKeyUp
=
this
.
onSearchInputKeyUp
.
bind
(
this
);
this
.
onSearchInputKeyDown
=
this
.
onSearchInputKeyDown
.
bind
(
this
);
}
getElement
(
selector
)
{
return
this
.
wrap
.
find
(
selector
);
}
saveOriginalState
()
{
gl
.
groupOptions
[
groupPath
]
=
{
return
this
.
originalState
=
this
.
serializeState
();
name
:
$groupOptionsDataEl
.
data
(
'
name
'
),
}
issuesPath
:
$groupOptionsDataEl
.
data
(
'
issues-path
'
),
mrPath
:
$groupOptionsDataEl
.
data
(
'
mr-path
'
),
};
}
saveTextLength
()
{
if
(
$dashboardOptionsDataEl
.
length
)
{
return
this
.
lastTextLength
=
this
.
searchInput
.
val
().
length
;
gl
.
dashboardOptions
=
{
issuesPath
:
$dashboardOptionsDataEl
.
data
(
'
issues-path
'
),
mrPath
:
$dashboardOptionsDataEl
.
data
(
'
mr-path
'
),
};
}
}
export
default
class
SearchAutocomplete
{
constructor
({
wrap
,
optsEl
,
autocompletePath
,
projectId
,
projectRef
}
=
{})
{
setSearchOptions
();
this
.
bindEventContext
();
this
.
wrap
=
wrap
||
$
(
'
.search
'
);
this
.
optsEl
=
optsEl
||
this
.
wrap
.
find
(
'
.search-autocomplete-opts
'
);
this
.
autocompletePath
=
autocompletePath
||
this
.
optsEl
.
data
(
'
autocomplete-path
'
);
this
.
projectId
=
projectId
||
(
this
.
optsEl
.
data
(
'
autocomplete-project-id
'
)
||
''
);
this
.
projectRef
=
projectRef
||
(
this
.
optsEl
.
data
(
'
autocomplete-project-ref
'
)
||
''
);
this
.
dropdown
=
this
.
wrap
.
find
(
'
.dropdown
'
);
this
.
dropdownToggle
=
this
.
wrap
.
find
(
'
.js-dropdown-search-toggle
'
);
this
.
dropdownContent
=
this
.
dropdown
.
find
(
'
.dropdown-content
'
);
this
.
locationBadgeEl
=
this
.
getElement
(
'
.location-badge
'
);
this
.
scopeInputEl
=
this
.
getElement
(
'
#scope
'
);
this
.
searchInput
=
this
.
getElement
(
'
.search-input
'
);
this
.
projectInputEl
=
this
.
getElement
(
'
#search_project_id
'
);
this
.
groupInputEl
=
this
.
getElement
(
'
#group_id
'
);
this
.
searchCodeInputEl
=
this
.
getElement
(
'
#search_code
'
);
this
.
repositoryInputEl
=
this
.
getElement
(
'
#repository_ref
'
);
this
.
clearInput
=
this
.
getElement
(
'
.js-clear-input
'
);
this
.
saveOriginalState
();
// Only when user is logged in
if
(
gon
.
current_user_id
)
{
this
.
createAutocomplete
();
}
}
createAutocomplete
()
{
this
.
searchInput
.
addClass
(
'
disabled
'
);
return
this
.
searchInput
.
glDropdown
({
this
.
saveTextLength
();
filterInputBlur
:
false
,
this
.
bindEvents
();
filterable
:
true
,
this
.
dropdownToggle
.
dropdown
();
filterRemote
:
true
,
}
highlight
:
true
,
enterCallback
:
false
,
// Finds an element inside wrapper element
filterInput
:
'
input#search
'
,
bindEventContext
()
{
search
:
{
this
.
onSearchInputBlur
=
this
.
onSearchInputBlur
.
bind
(
this
);
fields
:
[
'
text
'
],
this
.
onClearInputClick
=
this
.
onClearInputClick
.
bind
(
this
);
},
this
.
onSearchInputFocus
=
this
.
onSearchInputFocus
.
bind
(
this
);
id
:
this
.
getSearchText
,
this
.
onSearchInputKeyUp
=
this
.
onSearchInputKeyUp
.
bind
(
this
);
data
:
this
.
getData
.
bind
(
this
),
this
.
onSearchInputKeyDown
=
this
.
onSearchInputKeyDown
.
bind
(
this
);
selectable
:
true
,
}
clicked
:
this
.
onClick
.
bind
(
this
),
getElement
(
selector
)
{
});
return
this
.
wrap
.
find
(
selector
);
}
saveOriginalState
()
{
return
this
.
originalState
=
this
.
serializeState
();
}
saveTextLength
()
{
return
this
.
lastTextLength
=
this
.
searchInput
.
val
().
length
;
}
createAutocomplete
()
{
return
this
.
searchInput
.
glDropdown
({
filterInputBlur
:
false
,
filterable
:
true
,
filterRemote
:
true
,
highlight
:
true
,
enterCallback
:
false
,
filterInput
:
'
input#search
'
,
search
:
{
fields
:
[
'
text
'
],
},
id
:
this
.
getSearchText
,
data
:
this
.
getData
.
bind
(
this
),
selectable
:
true
,
clicked
:
this
.
onClick
.
bind
(
this
),
});
}
getSearchText
(
selectedObject
,
el
)
{
return
selectedObject
.
id
?
selectedObject
.
text
:
''
;
}
getData
(
term
,
callback
)
{
if
(
!
term
)
{
const
contents
=
this
.
getCategoryContents
();
if
(
contents
)
{
this
.
searchInput
.
data
(
'
glDropdown
'
).
filter
.
options
.
callback
(
contents
);
this
.
enableAutocomplete
();
}
return
;
}
}
getSearchText
(
selectedObject
,
el
)
{
// Prevent multiple ajax calls
return
selectedObject
.
id
?
selectedObject
.
text
:
''
;
if
(
this
.
loadingSuggestions
)
{
return
;
}
}
getData
(
term
,
callback
)
{
this
.
loadingSuggestions
=
true
;
if
(
!
term
)
{
const
contents
=
this
.
getCategoryContents
();
if
(
contents
)
{
this
.
searchInput
.
data
(
'
glDropdown
'
).
filter
.
options
.
callback
(
contents
);
this
.
enableAutocomplete
();
}
return
;
}
// Prevent multiple ajax calls
return
$
.
get
(
this
.
autocompletePath
,
{
if
(
this
.
loadingSuggestions
)
{
project_id
:
this
.
projectId
,
project_ref
:
this
.
projectRef
,
term
:
term
,
},
(
response
)
=>
{
var
firstCategory
,
i
,
lastCategory
,
len
,
suggestion
;
// Hide dropdown menu if no suggestions returns
if
(
!
response
.
length
)
{
this
.
disableAutocomplete
();
return
;
return
;
}
}
this
.
loadingSuggestions
=
true
;
const
data
=
[];
// List results
return
$
.
get
(
this
.
autocompletePath
,
{
firstCategory
=
true
;
project_id
:
this
.
projectId
,
for
(
i
=
0
,
len
=
response
.
length
;
i
<
len
;
i
+=
1
)
{
project_ref
:
this
.
projectRef
,
suggestion
=
response
[
i
];
term
:
term
,
// Add group header before list each group
},
(
response
)
=>
{
if
(
lastCategory
!==
suggestion
.
category
)
{
var
firstCategory
,
i
,
lastCategory
,
len
,
suggestion
;
if
(
!
firstCategory
)
{
// Hide dropdown menu if no suggestions returns
data
.
push
(
'
separator
'
);
if
(
!
response
.
length
)
{
}
this
.
disableAutocomplete
();
if
(
firstCategory
)
{
return
;
firstCategory
=
false
;
}
const
data
=
[];
// List results
firstCategory
=
true
;
for
(
i
=
0
,
len
=
response
.
length
;
i
<
len
;
i
+=
1
)
{
suggestion
=
response
[
i
];
// Add group header before list each group
if
(
lastCategory
!==
suggestion
.
category
)
{
if
(
!
firstCategory
)
{
data
.
push
(
'
separator
'
);
}
if
(
firstCategory
)
{
firstCategory
=
false
;
}
data
.
push
({
header
:
suggestion
.
category
,
});
lastCategory
=
suggestion
.
category
;
}
}
data
.
push
({
data
.
push
({
id
:
(
suggestion
.
category
.
toLowerCase
())
+
"
-
"
+
suggestion
.
id
,
header
:
suggestion
.
category
,
category
:
suggestion
.
category
,
text
:
suggestion
.
label
,
url
:
suggestion
.
url
,
});
}
// Add option to proceed with the search
if
(
data
.
length
)
{
data
.
push
(
'
separator
'
);
data
.
push
({
text
:
"
Result name contains
\"
"
+
term
+
"
\"
"
,
url
:
"
/search?search=
"
+
term
+
"
&project_id=
"
+
(
this
.
projectInputEl
.
val
())
+
"
&group_id=
"
+
(
this
.
groupInputEl
.
val
()),
});
});
lastCategory
=
suggestion
.
category
;
}
}
return
callback
(
data
);
data
.
push
({
})
id
:
(
suggestion
.
category
.
toLowerCase
())
+
"
-
"
+
suggestion
.
id
,
.
always
(()
=>
{
this
.
loadingSuggestions
=
false
;
});
category
:
suggestion
.
category
,
}
text
:
suggestion
.
label
,
url
:
suggestion
.
url
,
getCategoryContents
()
{
});
const
userId
=
gon
.
current_user_id
;
const
userName
=
gon
.
current_username
;
const
{
projectOptions
,
groupOptions
,
dashboardOptions
}
=
gl
;
// Get options
let
options
;
if
(
isInGroupsPage
()
&&
groupOptions
)
{
options
=
groupOptions
[
getGroupSlug
()];
}
else
if
(
isInProjectPage
()
&&
projectOptions
)
{
options
=
projectOptions
[
getProjectSlug
()];
}
else
if
(
dashboardOptions
)
{
options
=
dashboardOptions
;
}
}
// Add option to proceed with the search
const
{
issuesPath
,
mrPath
,
name
,
issuesDisabled
}
=
options
;
if
(
data
.
length
)
{
const
baseItems
=
[];
data
.
push
(
'
separator
'
);
data
.
push
({
if
(
name
)
{
text
:
"
Result name contains
\"
"
+
term
+
"
\"
"
,
baseItems
.
push
({
url
:
"
/search?search=
"
+
term
+
"
&project_id=
"
+
(
this
.
projectInputEl
.
val
())
+
"
&group_id=
"
+
(
this
.
groupInputEl
.
val
()),
header
:
`
${
name
}
`
,
});
});
}
}
return
callback
(
data
);
})
.
always
(()
=>
{
this
.
loadingSuggestions
=
false
;
});
}
const
issueItems
=
[
getCategoryContents
()
{
{
const
userId
=
gon
.
current_user_id
;
text
:
'
Issues assigned to me
'
,
const
userName
=
gon
.
current_username
;
url
:
`
${
issuesPath
}
/?assignee_username=
${
userName
}
`
,
const
{
projectOptions
,
groupOptions
,
dashboardOptions
}
=
gl
;
},
{
// Get options
text
:
"
Issues I've created
"
,
let
options
;
url
:
`
${
issuesPath
}
/?author_username=
${
userName
}
`
,
if
(
isInGroupsPage
()
&&
groupOptions
)
{
},
options
=
groupOptions
[
getGroupSlug
()];
];
}
else
if
(
isInProjectPage
()
&&
projectOptions
)
{
const
mergeRequestItems
=
[
options
=
projectOptions
[
getProjectSlug
()];
{
}
else
if
(
dashboardOptions
)
{
text
:
'
Merge requests assigned to me
'
,
options
=
dashboardOptions
;
url
:
`
${
mrPath
}
/?assignee_username=
${
userName
}
`
,
},
{
text
:
"
Merge requests I've created
"
,
url
:
`
${
mrPath
}
/?author_username=
${
userName
}
`
,
},
];
let
items
;
if
(
issuesDisabled
)
{
items
=
baseItems
.
concat
(
mergeRequestItems
);
}
else
{
items
=
baseItems
.
concat
(...
issueItems
,
'
separator
'
,
...
mergeRequestItems
);
}
return
items
;
}
}
serializeState
()
{
const
{
issuesPath
,
mrPath
,
name
,
issuesDisabled
}
=
options
;
return
{
const
baseItems
=
[];
// Search Criteria
search_project_id
:
this
.
projectInputEl
.
val
(),
if
(
name
)
{
group_id
:
this
.
groupInputEl
.
val
(),
baseItems
.
push
({
search_code
:
this
.
searchCodeInputEl
.
val
(),
header
:
`
${
name
}
`
,
repository_ref
:
this
.
repositoryInputEl
.
val
(),
});
scope
:
this
.
scopeInputEl
.
val
(),
// Location badge
_location
:
this
.
locationBadgeEl
.
text
(),
};
}
}
bindEvents
()
{
const
issueItems
=
[
this
.
searchInput
.
on
(
'
keydown
'
,
this
.
onSearchInputKeyDown
);
{
this
.
searchInput
.
on
(
'
keyup
'
,
this
.
onSearchInputKeyUp
);
text
:
'
Issues assigned to me
'
,
this
.
searchInput
.
on
(
'
focus
'
,
this
.
onSearchInputFocus
);
url
:
`
${
issuesPath
}
/?assignee_username=
${
userName
}
`
,
this
.
searchInput
.
on
(
'
blur
'
,
this
.
onSearchInputBlur
);
},
this
.
clearInput
.
on
(
'
click
'
,
this
.
onClearInputClick
);
{
this
.
locationBadgeEl
.
on
(
'
click
'
,
()
=>
this
.
searchInput
.
focus
());
text
:
"
Issues I've created
"
,
url
:
`
${
issuesPath
}
/?author_username=
${
userName
}
`
,
},
];
const
mergeRequestItems
=
[
{
text
:
'
Merge requests assigned to me
'
,
url
:
`
${
mrPath
}
/?assignee_username=
${
userName
}
`
,
},
{
text
:
"
Merge requests I've created
"
,
url
:
`
${
mrPath
}
/?author_username=
${
userName
}
`
,
},
];
let
items
;
if
(
issuesDisabled
)
{
items
=
baseItems
.
concat
(
mergeRequestItems
);
}
else
{
items
=
baseItems
.
concat
(...
issueItems
,
'
separator
'
,
...
mergeRequestItems
);
}
}
return
items
;
}
enableAutocomplete
()
{
serializeState
()
{
// No need to enable anything if user is not logged in
return
{
if
(
!
gon
.
current_user_id
)
{
// Search Criteria
return
;
search_project_id
:
this
.
projectInputEl
.
val
(),
}
group_id
:
this
.
groupInputEl
.
val
(),
search_code
:
this
.
searchCodeInputEl
.
val
(),
repository_ref
:
this
.
repositoryInputEl
.
val
(),
scope
:
this
.
scopeInputEl
.
val
(),
// Location badge
_location
:
this
.
locationBadgeEl
.
text
(),
};
}
// If the dropdown is closed, we'll open it
bindEvents
()
{
if
(
!
this
.
dropdown
.
hasClass
(
'
open
'
))
{
this
.
searchInput
.
on
(
'
keydown
'
,
this
.
onSearchInputKeyDown
);
this
.
loadingSuggestions
=
false
;
this
.
searchInput
.
on
(
'
keyup
'
,
this
.
onSearchInputKeyUp
);
this
.
dropdownToggle
.
dropdown
(
'
toggle
'
);
this
.
searchInput
.
on
(
'
focus
'
,
this
.
onSearchInputFocus
);
return
this
.
searchInput
.
removeClass
(
'
disabled
'
);
this
.
searchInput
.
on
(
'
blur
'
,
this
.
onSearchInputBlur
);
}
this
.
clearInput
.
on
(
'
click
'
,
this
.
onClearInputClick
);
this
.
locationBadgeEl
.
on
(
'
click
'
,
()
=>
this
.
searchInput
.
focus
());
}
enableAutocomplete
()
{
// No need to enable anything if user is not logged in
if
(
!
gon
.
current_user_id
)
{
return
;
}
}
// Saves last length of the entered text
// If the dropdown is closed, we'll open it
onSearchInputKeyDown
()
{
if
(
!
this
.
dropdown
.
hasClass
(
'
open
'
))
{
return
this
.
saveTextLength
();
this
.
loadingSuggestions
=
false
;
this
.
dropdownToggle
.
dropdown
(
'
toggle
'
);
return
this
.
searchInput
.
removeClass
(
'
disabled
'
);
}
}
}
onSearchInputKeyUp
(
e
)
{
// Saves last length of the entered text
switch
(
e
.
keyCode
)
{
onSearchInputKeyDown
()
{
case
KEYCODE
.
BACKSPACE
:
return
this
.
saveTextLength
();
// when trying to remove the location badge
}
if
(
this
.
lastTextLength
===
0
&&
this
.
badgePresent
())
{
this
.
removeLocationBadge
();
onSearchInputKeyUp
(
e
)
{
}
switch
(
e
.
keyCode
)
{
// When removing the last character and no badge is present
case
KEYCODE
.
BACKSPACE
:
if
(
this
.
lastTextLength
===
1
)
{
// when trying to remove the location badge
this
.
disableAutocomplete
();
if
(
this
.
lastTextLength
===
0
&&
this
.
badgePresent
())
{
}
this
.
removeLocationBadge
();
// When removing any character from existin value
}
if
(
this
.
lastTextLength
>
1
)
{
// When removing the last character and no badge is present
this
.
enableAutocomplete
();
if
(
this
.
lastTextLength
===
1
)
{
}
this
.
disableAutocomplete
();
break
;
}
case
KEYCODE
.
ESCAPE
:
// When removing any character from existin value
this
.
restoreOriginalState
();
if
(
this
.
lastTextLength
>
1
)
{
break
;
this
.
enableAutocomplete
();
case
KEYCODE
.
ENTER
:
}
break
;
case
KEYCODE
.
ESCAPE
:
this
.
restoreOriginalState
();
break
;
case
KEYCODE
.
ENTER
:
this
.
disableAutocomplete
();
break
;
case
KEYCODE
.
UP
:
case
KEYCODE
.
DOWN
:
return
;
default
:
// Handle the case when deleting the input value other than backspace
// e.g. Pressing ctrl + backspace or ctrl + x
if
(
this
.
searchInput
.
val
()
===
''
)
{
this
.
disableAutocomplete
();
this
.
disableAutocomplete
();
break
;
}
else
{
case
KEYCODE
.
UP
:
// We should display the menu only when input is not empty
case
KEYCODE
.
DOWN
:
if
(
e
.
keyCode
!==
KEYCODE
.
ENTER
)
{
return
;
this
.
enableAutocomplete
();
default
:
// Handle the case when deleting the input value other than backspace
// e.g. Pressing ctrl + backspace or ctrl + x
if
(
this
.
searchInput
.
val
()
===
''
)
{
this
.
disableAutocomplete
();
}
else
{
// We should display the menu only when input is not empty
if
(
e
.
keyCode
!==
KEYCODE
.
ENTER
)
{
this
.
enableAutocomplete
();
}
}
}
}
}
this
.
wrap
.
toggleClass
(
'
has-value
'
,
!!
e
.
target
.
value
);
}
}
this
.
wrap
.
toggleClass
(
'
has-value
'
,
!!
e
.
target
.
value
);
}
onSearchInputFocus
()
{
onSearchInputFocus
()
{
this
.
isFocused
=
true
;
this
.
isFocused
=
true
;
this
.
wrap
.
addClass
(
'
search-active
'
);
this
.
wrap
.
addClass
(
'
search-active
'
);
if
(
this
.
getValue
()
===
''
)
{
if
(
this
.
getValue
()
===
''
)
{
return
this
.
getData
();
return
this
.
getData
();
}
}
}
}
getValue
()
{
getValue
()
{
return
this
.
searchInput
.
val
();
return
this
.
searchInput
.
val
();
}
}
onClearInputClick
(
e
)
{
onClearInputClick
(
e
)
{
e
.
preventDefault
();
e
.
preventDefault
();
this
.
wrap
.
toggleClass
(
'
has-value
'
,
!!
e
.
target
.
value
);
this
.
wrap
.
toggleClass
(
'
has-value
'
,
!!
e
.
target
.
value
);
return
this
.
searchInput
.
val
(
''
).
focus
();
return
this
.
searchInput
.
val
(
''
).
focus
();
}
}
onSearchInputBlur
(
e
)
{
onSearchInputBlur
(
e
)
{
this
.
isFocused
=
false
;
this
.
isFocused
=
false
;
this
.
wrap
.
removeClass
(
'
search-active
'
);
this
.
wrap
.
removeClass
(
'
search-active
'
);
// If input is blank then restore state
// If input is blank then restore state
if
(
this
.
searchInput
.
val
()
===
''
)
{
if
(
this
.
searchInput
.
val
()
===
''
)
{
return
this
.
restoreOriginalState
();
return
this
.
restoreOriginalState
();
}
}
}
}
addLocationBadge
(
item
)
{
addLocationBadge
(
item
)
{
var
badgeText
,
category
,
value
;
var
badgeText
,
category
,
value
;
category
=
item
.
category
!=
null
?
item
.
category
+
"
:
"
:
''
;
category
=
item
.
category
!=
null
?
item
.
category
+
"
:
"
:
''
;
value
=
item
.
value
!=
null
?
item
.
value
:
''
;
value
=
item
.
value
!=
null
?
item
.
value
:
''
;
badgeText
=
""
+
category
+
value
;
badgeText
=
""
+
category
+
value
;
this
.
locationBadgeEl
.
text
(
badgeText
).
show
();
this
.
locationBadgeEl
.
text
(
badgeText
).
show
();
return
this
.
wrap
.
addClass
(
'
has-location-badge
'
);
return
this
.
wrap
.
addClass
(
'
has-location-badge
'
);
}
}
hasLocationBadge
()
{
hasLocationBadge
()
{
return
this
.
wrap
.
is
(
'
.has-location-badge
'
);
return
this
.
wrap
.
is
(
'
.has-location-badge
'
);
}
}
restoreOriginalState
()
{
restoreOriginalState
()
{
var
i
,
input
,
inputs
,
len
;
var
i
,
input
,
inputs
,
len
;
inputs
=
Object
.
keys
(
this
.
originalState
);
inputs
=
Object
.
keys
(
this
.
originalState
);
for
(
i
=
0
,
len
=
inputs
.
length
;
i
<
len
;
i
+=
1
)
{
for
(
i
=
0
,
len
=
inputs
.
length
;
i
<
len
;
i
+=
1
)
{
input
=
inputs
[
i
];
input
=
inputs
[
i
];
this
.
getElement
(
"
#
"
+
input
).
val
(
this
.
originalState
[
input
]);
this
.
getElement
(
"
#
"
+
input
).
val
(
this
.
originalState
[
input
]);
}
if
(
this
.
originalState
.
_location
===
''
)
{
return
this
.
locationBadgeEl
.
hide
();
}
else
{
return
this
.
addLocationBadge
({
value
:
this
.
originalState
.
_location
,
});
}
}
}
if
(
this
.
originalState
.
_location
===
''
)
{
badgePresent
()
{
return
this
.
locationBadgeEl
.
hide
();
return
this
.
locationBadgeEl
.
length
;
}
else
{
return
this
.
addLocationBadge
({
value
:
this
.
originalState
.
_location
,
});
}
}
}
resetSearchState
()
{
badgePresent
()
{
var
i
,
input
,
inputs
,
len
,
results
;
return
this
.
locationBadgeEl
.
length
;
inputs
=
Object
.
keys
(
this
.
originalState
);
}
results
=
[];
for
(
i
=
0
,
len
=
inputs
.
length
;
i
<
len
;
i
+=
1
)
{
resetSearchState
()
{
input
=
inputs
[
i
];
var
i
,
input
,
inputs
,
len
,
results
;
// _location isnt a input
inputs
=
Object
.
keys
(
this
.
originalState
);
if
(
input
===
'
_location
'
)
{
results
=
[];
break
;
for
(
i
=
0
,
len
=
inputs
.
length
;
i
<
len
;
i
+=
1
)
{
}
input
=
inputs
[
i
];
results
.
push
(
this
.
getElement
(
"
#
"
+
input
).
val
(
''
));
// _location isnt a input
if
(
input
===
'
_location
'
)
{
break
;
}
}
re
turn
results
;
re
sults
.
push
(
this
.
getElement
(
"
#
"
+
input
).
val
(
''
))
;
}
}
return
results
;
}
removeLocationBadge
()
{
removeLocationBadge
()
{
this
.
locationBadgeEl
.
hide
();
this
.
locationBadgeEl
.
hide
();
this
.
resetSearchState
();
this
.
resetSearchState
();
this
.
wrap
.
removeClass
(
'
has-location-badge
'
);
this
.
wrap
.
removeClass
(
'
has-location-badge
'
);
return
this
.
disableAutocomplete
();
return
this
.
disableAutocomplete
();
}
}
disableAutocomplete
()
{
disableAutocomplete
()
{
if
(
!
this
.
searchInput
.
hasClass
(
'
disabled
'
)
&&
this
.
dropdown
.
hasClass
(
'
open
'
))
{
if
(
!
this
.
searchInput
.
hasClass
(
'
disabled
'
)
&&
this
.
dropdown
.
hasClass
(
'
open
'
))
{
this
.
searchInput
.
addClass
(
'
disabled
'
);
this
.
searchInput
.
addClass
(
'
disabled
'
);
this
.
dropdown
.
removeClass
(
'
open
'
).
trigger
(
'
hidden.bs.dropdown
'
);
this
.
dropdown
.
removeClass
(
'
open
'
).
trigger
(
'
hidden.bs.dropdown
'
);
this
.
restoreMenu
();
this
.
restoreMenu
();
}
}
}
}
restoreMenu
()
{
restoreMenu
()
{
var
html
;
var
html
;
html
=
'
<ul><li class="dropdown-menu-empty-item"><a>Loading...</a></li></ul>
'
;
html
=
'
<ul><li class="dropdown-menu-empty-item"><a>Loading...</a></li></ul>
'
;
return
this
.
dropdownContent
.
html
(
html
);
return
this
.
dropdownContent
.
html
(
html
);
}
}
onClick
(
item
,
$el
,
e
)
{
onClick
(
item
,
$el
,
e
)
{
if
(
location
.
pathname
.
indexOf
(
item
.
url
)
!==
-
1
)
{
if
(
location
.
pathname
.
indexOf
(
item
.
url
)
!==
-
1
)
{
if
(
!
e
.
metaKey
)
e
.
preventDefault
();
if
(
!
e
.
metaKey
)
e
.
preventDefault
();
if
(
!
this
.
badgePresent
)
{
if
(
!
this
.
badgePresent
)
{
if
(
item
.
category
===
'
Projects
'
)
{
if
(
item
.
category
===
'
Projects
'
)
{
this
.
projectInputEl
.
val
(
item
.
id
);
this
.
projectInputEl
.
val
(
item
.
id
);
this
.
addLocationBadge
({
this
.
addLocationBadge
({
value
:
'
This project
'
,
value
:
'
This project
'
,
});
});
}
}
if
(
item
.
category
===
'
Groups
'
)
{
if
(
item
.
category
===
'
Groups
'
)
{
this
.
groupInputEl
.
val
(
item
.
id
);
this
.
groupInputEl
.
val
(
item
.
id
);
this
.
addLocationBadge
({
this
.
addLocationBadge
({
value
:
'
This group
'
,
value
:
'
This group
'
,
});
});
}
}
}
$el
.
removeClass
(
'
is-active
'
);
this
.
disableAutocomplete
();
return
this
.
searchInput
.
val
(
''
).
focus
();
}
}
$el
.
removeClass
(
'
is-active
'
);
this
.
disableAutocomplete
();
return
this
.
searchInput
.
val
(
''
).
focus
();
}
}
}
}
}
global
.
SearchAutocomplete
=
SearchAutocomplete
;
$
(
function
()
{
var
$projectOptionsDataEl
=
$
(
'
.js-search-project-options
'
);
var
$groupOptionsDataEl
=
$
(
'
.js-search-group-options
'
);
var
$dashboardOptionsDataEl
=
$
(
'
.js-search-dashboard-options
'
);
if
(
$projectOptionsDataEl
.
length
)
{
gl
.
projectOptions
=
gl
.
projectOptions
||
{};
var
projectPath
=
$projectOptionsDataEl
.
data
(
'
project-path
'
);
gl
.
projectOptions
[
projectPath
]
=
{
name
:
$projectOptionsDataEl
.
data
(
'
name
'
),
issuesPath
:
$projectOptionsDataEl
.
data
(
'
issues-path
'
),
issuesDisabled
:
$projectOptionsDataEl
.
data
(
'
issues-disabled
'
),
mrPath
:
$projectOptionsDataEl
.
data
(
'
mr-path
'
),
};
}
if
(
$groupOptionsDataEl
.
length
)
{
gl
.
groupOptions
=
gl
.
groupOptions
||
{};
var
groupPath
=
$groupOptionsDataEl
.
data
(
'
group-path
'
);
gl
.
groupOptions
[
groupPath
]
=
{
name
:
$groupOptionsDataEl
.
data
(
'
name
'
),
issuesPath
:
$groupOptionsDataEl
.
data
(
'
issues-path
'
),
mrPath
:
$groupOptionsDataEl
.
data
(
'
mr-path
'
),
};
}
if
(
$dashboardOptionsDataEl
.
length
)
{
gl
.
dashboardOptions
=
{
issuesPath
:
$dashboardOptionsDataEl
.
data
(
'
issues-path
'
),
mrPath
:
$dashboardOptionsDataEl
.
data
(
'
mr-path
'
),
};
}
});
})(
window
.
gl
||
(
window
.
gl
=
{}));
app/assets/javascripts/single_file_diff.js
View file @
aa90e8ea
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
import
FilesCommentButton
from
'
./files_comment_button
'
;
import
FilesCommentButton
from
'
./files_comment_button
'
;
import
imageDiffHelper
from
'
./image_diff/helpers/index
'
;
import
imageDiffHelper
from
'
./image_diff/helpers/index
'
;
import
syntaxHighlight
from
'
./syntax_highlight
'
;
const
WRAPPER
=
'
<div class="diff-content"></div>
'
;
const
WRAPPER
=
'
<div class="diff-content"></div>
'
;
const
LOADING_HTML
=
'
<i class="fa fa-spinner fa-spin"></i>
'
;
const
LOADING_HTML
=
'
<i class="fa fa-spinner fa-spin"></i>
'
;
...
@@ -64,7 +65,7 @@ export default class SingleFileDiff {
...
@@ -64,7 +65,7 @@ export default class SingleFileDiff {
_this
.
loadingContent
.
hide
();
_this
.
loadingContent
.
hide
();
if
(
data
.
html
)
{
if
(
data
.
html
)
{
_this
.
content
=
$
(
data
.
html
);
_this
.
content
=
$
(
data
.
html
);
_this
.
content
.
syntaxHighlight
(
);
syntaxHighlight
(
_this
.
content
);
}
else
{
}
else
{
_this
.
hasError
=
true
;
_this
.
hasError
=
true
;
_this
.
content
=
$
(
ERROR_HTML
);
_this
.
content
=
$
(
ERROR_HTML
);
...
...
app/assets/javascripts/syntax_highlight.js
View file @
aa90e8ea
...
@@ -10,17 +10,15 @@
...
@@ -10,17 +10,15 @@
// <div class="js-syntax-highlight"></div>
// <div class="js-syntax-highlight"></div>
//
//
$
.
fn
.
syntaxHighlight
=
function
()
{
export
default
function
syntaxHighlight
(
el
)
{
var
$children
;
if
(
$
(
el
).
hasClass
(
'
js-syntax-highlight
'
))
{
if
(
$
(
this
).
hasClass
(
'
js-syntax-highlight
'
))
{
// Given the element itself, apply highlighting
// Given the element itself, apply highlighting
return
$
(
this
).
addClass
(
gon
.
user_color_scheme
);
return
$
(
el
).
addClass
(
gon
.
user_color_scheme
);
}
else
{
}
else
{
// Given a parent element, recurse to any of its applicable children
// Given a parent element, recurse to any of its applicable children
$children
=
$
(
this
).
find
(
'
.js-syntax-highlight
'
);
const
$children
=
$
(
el
).
find
(
'
.js-syntax-highlight
'
);
if
(
$children
.
length
)
{
if
(
$children
.
length
)
{
return
$children
.
syntaxHighlight
(
);
return
syntaxHighlight
(
$children
);
}
}
}
}
}
;
}
spec/javascripts/search_autocomplete_spec.js
View file @
aa90e8ea
/* eslint-disable space-before-function-paren, max-len, no-var, one-var, one-var-declaration-per-line, no-unused-expressions, consistent-return, no-param-reassign, default-case, no-return-assign, comma-dangle, object-shorthand, prefer-template, quotes, new-parens, vars-on-top, new-cap, max-len */
/* eslint-disable space-before-function-paren, max-len, no-var, one-var, one-var-declaration-per-line, no-unused-expressions, consistent-return, no-param-reassign, default-case, no-return-assign, comma-dangle, object-shorthand, prefer-template, quotes, new-parens, vars-on-top, new-cap, max-len */
import
'
~/gl_dropdown
'
;
import
'
~/gl_dropdown
'
;
import
'
~/search_autocomplete
'
;
import
SearchAutocomplete
from
'
~/search_autocomplete
'
;
import
'
~/lib/utils/common_utils
'
;
import
'
~/lib/utils/common_utils
'
;
import
*
as
urlUtils
from
'
~/lib/utils/url_utility
'
;
import
*
as
urlUtils
from
'
~/lib/utils/url_utility
'
;
...
@@ -128,7 +128,7 @@ import * as urlUtils from '~/lib/utils/url_utility';
...
@@ -128,7 +128,7 @@ import * as urlUtils from '~/lib/utils/url_utility';
window
.
gon
.
current_user_id
=
userId
;
window
.
gon
.
current_user_id
=
userId
;
window
.
gon
.
current_username
=
userName
;
window
.
gon
.
current_username
=
userName
;
return
widget
=
new
gl
.
SearchAutocomplete
;
return
widget
=
new
SearchAutocomplete
()
;
});
});
afterEach
(
function
()
{
afterEach
(
function
()
{
...
...
spec/javascripts/syntax_highlight_spec.js
View file @
aa90e8ea
/* eslint-disable space-before-function-paren, no-var, no-return-assign, quotes */
/* eslint-disable space-before-function-paren, no-var, no-return-assign, quotes */
import
'
~/syntax_highlight
'
;
import
syntaxHighlight
from
'
~/syntax_highlight
'
;
(
function
()
{
describe
(
'
Syntax Highlighter
'
,
function
()
{
describe
(
'
Syntax Highlighter
'
,
function
()
{
var
stubUserColorScheme
;
var
stubUserColorScheme
;
stubUserColorScheme
=
function
(
value
)
{
stubUserColorScheme
=
function
(
value
)
{
if
(
window
.
gon
==
null
)
{
if
(
window
.
gon
==
null
)
{
window
.
gon
=
{};
window
.
gon
=
{};
}
}
return
window
.
gon
.
user_color_scheme
=
value
;
return
window
.
gon
.
user_color_scheme
=
value
;
};
};
describe
(
'
on a js-syntax-highlight element
'
,
function
()
{
describe
(
'
on a js-syntax-highlight element
'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
return
setFixtures
(
'
<div class="js-syntax-highlight"></div>
'
);
return
setFixtures
(
'
<div class="js-syntax-highlight"></div>
'
);
});
return
it
(
'
applies syntax highlighting
'
,
function
()
{
stubUserColorScheme
(
'
monokai
'
);
$
(
'
.js-syntax-highlight
'
).
syntaxHighlight
();
return
expect
(
$
(
'
.js-syntax-highlight
'
)).
toHaveClass
(
'
monokai
'
);
});
});
});
return
describe
(
'
on a parent element
'
,
function
()
{
return
it
(
'
applies syntax highlighting
'
,
function
()
{
beforeEach
(
function
()
{
stubUserColorScheme
(
'
monokai
'
);
return
setFixtures
(
"
<div class=
\"
parent
\"
>
\n
<div class=
\"
js-syntax-highlight
\"
></div>
\n
<div class=
\"
foo
\"
></div>
\n
<div class=
\"
js-syntax-highlight
\"
></div>
\n
</div>
"
);
syntaxHighlight
(
$
(
'
.js-syntax-highlight
'
));
});
return
expect
(
$
(
'
.js-syntax-highlight
'
)).
toHaveClass
(
'
monokai
'
);
it
(
'
applies highlighting to all applicable children
'
,
function
()
{
stubUserColorScheme
(
'
monokai
'
);
$
(
'
.parent
'
).
syntaxHighlight
();
expect
(
$
(
'
.parent, .foo
'
)).
not
.
toHaveClass
(
'
monokai
'
);
return
expect
(
$
(
'
.monokai
'
).
length
).
toBe
(
2
);
});
return
it
(
'
prevents an infinite loop when no matches exist
'
,
function
()
{
var
highlight
;
setFixtures
(
'
<div></div>
'
);
highlight
=
function
()
{
return
$
(
'
div
'
).
syntaxHighlight
();
};
return
expect
(
highlight
).
not
.
toThrow
();
});
});
});
});
});
}).
call
(
window
);
return
describe
(
'
on a parent element
'
,
function
()
{
beforeEach
(
function
()
{
return
setFixtures
(
"
<div class=
\"
parent
\"
>
\n
<div class=
\"
js-syntax-highlight
\"
></div>
\n
<div class=
\"
foo
\"
></div>
\n
<div class=
\"
js-syntax-highlight
\"
></div>
\n
</div>
"
);
});
it
(
'
applies highlighting to all applicable children
'
,
function
()
{
stubUserColorScheme
(
'
monokai
'
);
syntaxHighlight
(
$
(
'
.parent
'
));
expect
(
$
(
'
.parent, .foo
'
)).
not
.
toHaveClass
(
'
monokai
'
);
return
expect
(
$
(
'
.monokai
'
).
length
).
toBe
(
2
);
});
return
it
(
'
prevents an infinite loop when no matches exist
'
,
function
()
{
var
highlight
;
setFixtures
(
'
<div></div>
'
);
highlight
=
function
()
{
return
syntaxHighlight
(
$
(
'
div
'
));
};
return
expect
(
highlight
).
not
.
toThrow
();
});
});
});
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