Export old code into es6 modules
This commit is contained in:
parent
bcb14a0dbb
commit
aa90e8ea5b
13 changed files with 731 additions and 749 deletions
|
@ -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';
|
||||||
/* 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';
|
||||||
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';
|
||||||
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();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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';
|
||||||
|
|
|
@ -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 @@ $(() => {
|
||||||
mergeConflictsStore.setLoadingState(false);
|
mergeConflictsStore.setLoadingState(false);
|
||||||
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
$('.js-syntax-highlight').syntaxHighlight();
|
syntaxHighlight($('.js-syntax-highlight'));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -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';
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
||||||
|
|
|
@ -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);
|
|
||||||
this.filePaths = {};
|
|
||||||
this.inputElement = this.element.find(".file-finder-input");
|
|
||||||
// init event
|
|
||||||
this.initEvent();
|
|
||||||
// focus text input box
|
|
||||||
this.inputElement.focus();
|
|
||||||
// load file list
|
|
||||||
this.load(this.options.url);
|
|
||||||
}
|
|
||||||
|
|
||||||
ProjectFindFile.prototype.initEvent = function() {
|
|
||||||
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));
|
|
||||||
};
|
|
||||||
|
|
||||||
ProjectFindFile.prototype.findFile = function() {
|
|
||||||
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
|
|
||||||
ProjectFindFile.prototype.load = function(url) {
|
|
||||||
return $.ajax({
|
|
||||||
url: url,
|
|
||||||
method: "get",
|
|
||||||
dataType: "json",
|
|
||||||
success: (function(_this) {
|
|
||||||
return function(data) {
|
|
||||||
_this.element.find(".loading").hide();
|
|
||||||
_this.filePaths = data;
|
|
||||||
_this.findFile();
|
|
||||||
return _this.element.find(".files-slider tr.tree-item").eq(0).addClass("selected").focus();
|
|
||||||
};
|
|
||||||
})(this)
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// render result
|
|
||||||
ProjectFindFile.prototype.renderList = function(filePaths, searchText) {
|
|
||||||
var blobItemUrl, filePath, html, i, j, len, matches, results;
|
|
||||||
this.element.find(".tree-table > tbody").empty();
|
|
||||||
results = [];
|
|
||||||
for (i = j = 0, len = filePaths.length; j < len; i = (j += 1)) {
|
|
||||||
filePath = filePaths[i];
|
|
||||||
if (i === 20) {
|
|
||||||
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) {
|
if (matchedChars.length) {
|
||||||
element.append(matchedChars.join("").bold());
|
element.append(matchedChars.join("").bold());
|
||||||
}
|
}
|
||||||
return element.append(document.createTextNode(text.substring(lastIndex)));
|
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)));
|
||||||
|
};
|
||||||
|
|
||||||
// make tbody row html
|
export default class ProjectFindFile {
|
||||||
ProjectFindFile.prototype.makeHtml = function(filePath, matches, blobItemUrl) {
|
constructor(element1, options) {
|
||||||
var $tr;
|
this.element = element1;
|
||||||
$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>");
|
this.options = options;
|
||||||
if (matches) {
|
this.goToBlob = this.goToBlob.bind(this);
|
||||||
$tr.find("a").replaceWith(highlighter($tr.find("a"), filePath, matches).attr("href", blobItemUrl));
|
this.goToTree = this.goToTree.bind(this);
|
||||||
} else {
|
this.selectRowDown = this.selectRowDown.bind(this);
|
||||||
$tr.find("a").attr("href", blobItemUrl);
|
this.selectRowUp = this.selectRowUp.bind(this);
|
||||||
$tr.find(".str-truncated").text(filePath);
|
this.filePaths = {};
|
||||||
}
|
this.inputElement = this.element.find(".file-finder-input");
|
||||||
return $tr;
|
// init event
|
||||||
};
|
this.initEvent();
|
||||||
|
// focus text input box
|
||||||
|
this.inputElement.focus();
|
||||||
|
// load file list
|
||||||
|
this.load(this.options.url);
|
||||||
|
}
|
||||||
|
|
||||||
ProjectFindFile.prototype.selectRow = function(type) {
|
initEvent() {
|
||||||
var next, rows, selectedRow;
|
this.inputElement.off("keyup");
|
||||||
rows = this.element.find(".files-slider tr.tree-item");
|
this.inputElement.on("keyup", (function(_this) {
|
||||||
selectedRow = this.element.find(".files-slider tr.tree-item.selected");
|
return function(event) {
|
||||||
if (rows && rows.length > 0) {
|
var oldValue, ref, target, value;
|
||||||
if (selectedRow && selectedRow.length > 0) {
|
target = $(event.target);
|
||||||
if (type === "UP") {
|
value = target.val();
|
||||||
next = selectedRow.prev();
|
oldValue = (ref = target.data("oldValue")) != null ? ref : "";
|
||||||
} else if (type === "DOWN") {
|
if (value !== oldValue) {
|
||||||
next = selectedRow.next();
|
target.data("oldValue", value);
|
||||||
}
|
_this.findFile();
|
||||||
if (next.length > 0) {
|
return _this.element.find("tr.tree-item").eq(0).addClass("selected").focus();
|
||||||
selectedRow.removeClass("selected");
|
|
||||||
selectedRow = next;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
selectedRow = rows.eq(0);
|
|
||||||
}
|
}
|
||||||
return selectedRow.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
|
||||||
|
load(url) {
|
||||||
|
return $.ajax({
|
||||||
|
url: url,
|
||||||
|
method: "get",
|
||||||
|
dataType: "json",
|
||||||
|
success: (function(_this) {
|
||||||
|
return function(data) {
|
||||||
|
_this.element.find(".loading").hide();
|
||||||
|
_this.filePaths = data;
|
||||||
|
_this.findFile();
|
||||||
|
return _this.element.find(".files-slider tr.tree-item").eq(0).addClass("selected").focus();
|
||||||
|
};
|
||||||
|
})(this)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// render result
|
||||||
|
renderList(filePaths, searchText) {
|
||||||
|
var blobItemUrl, filePath, html, i, j, len, matches, results;
|
||||||
|
this.element.find(".tree-table > tbody").empty();
|
||||||
|
results = [];
|
||||||
|
for (i = j = 0, len = filePaths.length; j < len; i = (j += 1)) {
|
||||||
|
filePath = filePaths[i];
|
||||||
|
if (i === 20) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
if (searchText) {
|
||||||
|
matches = fuzzaldrinPlus.match(filePath, searchText);
|
||||||
ProjectFindFile.prototype.selectRowUp = function() {
|
|
||||||
return this.selectRow("UP");
|
|
||||||
};
|
|
||||||
|
|
||||||
ProjectFindFile.prototype.selectRowDown = function() {
|
|
||||||
return this.selectRow("DOWN");
|
|
||||||
};
|
|
||||||
|
|
||||||
ProjectFindFile.prototype.goToTree = function() {
|
|
||||||
return location.href = this.options.treeUrl;
|
|
||||||
};
|
|
||||||
|
|
||||||
ProjectFindFile.prototype.goToBlob = function() {
|
|
||||||
var $link = this.element.find(".tree-item.selected .tree-item-file-name a");
|
|
||||||
|
|
||||||
if ($link.length) {
|
|
||||||
$link.get(0).click();
|
|
||||||
}
|
}
|
||||||
};
|
blobItemUrl = this.options.blobUrlTemplate + "/" + filePath;
|
||||||
|
html = ProjectFindFile.makeHtml(filePath, matches, blobItemUrl);
|
||||||
|
results.push(this.element.find(".tree-table > tbody").append(html));
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
return ProjectFindFile;
|
// make tbody row html
|
||||||
})();
|
static makeHtml(filePath, matches, blobItemUrl) {
|
||||||
}).call(window);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
selectedRow = rows.eq(0);
|
||||||
|
}
|
||||||
|
return selectedRow.addClass("selected").focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selectRowUp() {
|
||||||
|
return this.selectRow("UP");
|
||||||
|
}
|
||||||
|
|
||||||
|
selectRowDown() {
|
||||||
|
return this.selectRow("DOWN");
|
||||||
|
}
|
||||||
|
|
||||||
|
goToTree() {
|
||||||
|
return location.href = this.options.treeUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
goToBlob() {
|
||||||
|
var $link = this.element.find(".tree-item.selected .tree-item-file-name a");
|
||||||
|
|
||||||
|
if ($link.length) {
|
||||||
|
$link.get(0).click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
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;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<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 {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
highlightFile() {
|
highlightFile() {
|
||||||
$(this.$el).find('.file-content').syntaxHighlight();
|
syntaxHighlight($(this.$el).find('.file-content'));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
|
@ -1,118 +1,113 @@
|
||||||
/* 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)
|
eventListeners() {
|
||||||
});
|
$(document)
|
||||||
|
.off('keyup', this.searchInput)
|
||||||
|
.on('keyup', this.searchInput, this.searchKeyUp);
|
||||||
|
$(document)
|
||||||
|
.off('click', this.searchClear)
|
||||||
|
.on('click', this.searchClear, this.clearSearchField.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
static submitSearch() {
|
||||||
|
return $('.js-search-form').submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
searchKeyUp() {
|
||||||
|
const $input = $(this);
|
||||||
|
if ($input.val() === '') {
|
||||||
|
$('.js-search-clear').addClass('hidden');
|
||||||
|
} else {
|
||||||
|
$('.js-search-clear').removeClass('hidden');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Search.prototype.eventListeners = function() {
|
clearSearchField() {
|
||||||
$(document).off('keyup', '.js-search-input').on('keyup', '.js-search-input', this.searchKeyUp);
|
return $(this.searchInput).val('').trigger('keyup').focus();
|
||||||
return $(document).off('click', '.js-search-clear').on('click', '.js-search-clear', this.clearSearchField);
|
}
|
||||||
};
|
|
||||||
|
|
||||||
Search.prototype.submitSearch = function() {
|
getProjectsData(term) {
|
||||||
return $('.js-search-form').submit();
|
return new Promise((resolve) => {
|
||||||
};
|
if (this.groupId) {
|
||||||
|
Api.groupProjects(this.groupId, term, resolve);
|
||||||
Search.prototype.searchKeyUp = function() {
|
|
||||||
var $input;
|
|
||||||
$input = $(this);
|
|
||||||
if ($input.val() === '') {
|
|
||||||
return $('.js-search-clear').addClass('hidden');
|
|
||||||
} else {
|
} else {
|
||||||
return $('.js-search-clear').removeClass('hidden');
|
Api.projects(term, {
|
||||||
|
order_by: 'id',
|
||||||
|
}, resolve);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
}
|
||||||
Search.prototype.clearSearchField = function() {
|
}
|
||||||
return $('.js-search-input').val('').trigger('keyup').focus();
|
|
||||||
};
|
|
||||||
|
|
||||||
Search.prototype.getProjectsData = function(term) {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
if (this.groupId) {
|
|
||||||
Api.groupProjects(this.groupId, term, resolve);
|
|
||||||
} else {
|
|
||||||
Api.projects(term, {
|
|
||||||
order_by: 'id',
|
|
||||||
}, resolve);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return Search;
|
|
||||||
})();
|
|
||||||
}).call(window);
|
|
||||||
|
|
|
@ -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,
|
};
|
||||||
};
|
|
||||||
|
|
||||||
class SearchAutocomplete {
|
function setSearchOptions() {
|
||||||
constructor({ wrap, optsEl, autocompletePath, projectId, projectRef } = {}) {
|
var $projectOptionsDataEl = $('.js-search-project-options');
|
||||||
this.bindEventContext();
|
var $groupOptionsDataEl = $('.js-search-group-options');
|
||||||
this.wrap = wrap || $('.search');
|
var $dashboardOptionsDataEl = $('.js-search-dashboard-options');
|
||||||
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 ($projectOptionsDataEl.length) {
|
||||||
if (gon.current_user_id) {
|
gl.projectOptions = gl.projectOptions || {};
|
||||||
this.createAutocomplete();
|
|
||||||
|
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'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.searchInput.addClass('disabled');
|
||||||
|
this.saveTextLength();
|
||||||
|
this.bindEvents();
|
||||||
|
this.dropdownToggle.dropdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finds an element inside wrapper element
|
||||||
|
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() {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent multiple ajax calls
|
||||||
|
if (this.loadingSuggestions) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loadingSuggestions = true;
|
||||||
|
|
||||||
|
return $.get(this.autocompletePath, {
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.searchInput.addClass('disabled');
|
const data = [];
|
||||||
this.saveTextLength();
|
// List results
|
||||||
this.bindEvents();
|
firstCategory = true;
|
||||||
this.dropdownToggle.dropdown();
|
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({
|
||||||
|
id: (suggestion.category.toLowerCase()) + "-" + suggestion.id,
|
||||||
|
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()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return callback(data);
|
||||||
|
})
|
||||||
|
.always(() => { this.loadingSuggestions = false; });
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finds an element inside wrapper element
|
const { issuesPath, mrPath, name, issuesDisabled } = options;
|
||||||
bindEventContext() {
|
const baseItems = [];
|
||||||
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() {
|
if (name) {
|
||||||
return this.originalState = this.serializeState();
|
baseItems.push({
|
||||||
}
|
header: `${name}`,
|
||||||
|
|
||||||
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) {
|
const issueItems = [
|
||||||
return selectedObject.id ? selectedObject.text : '';
|
{
|
||||||
|
text: 'Issues assigned to me',
|
||||||
|
url: `${issuesPath}/?assignee_username=${userName}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
serializeState() {
|
||||||
|
return {
|
||||||
|
// Search Criteria
|
||||||
|
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(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
bindEvents() {
|
||||||
|
this.searchInput.on('keydown', this.onSearchInputKeyDown);
|
||||||
|
this.searchInput.on('keyup', this.onSearchInputKeyUp);
|
||||||
|
this.searchInput.on('focus', this.onSearchInputFocus);
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
getData(term, callback) {
|
// If the dropdown is closed, we'll open it
|
||||||
if (!term) {
|
if (!this.dropdown.hasClass('open')) {
|
||||||
const contents = this.getCategoryContents();
|
this.loadingSuggestions = false;
|
||||||
if (contents) {
|
this.dropdownToggle.dropdown('toggle');
|
||||||
this.searchInput.data('glDropdown').filter.options.callback(contents);
|
return this.searchInput.removeClass('disabled');
|
||||||
this.enableAutocomplete();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prevent multiple ajax calls
|
|
||||||
if (this.loadingSuggestions) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.loadingSuggestions = true;
|
|
||||||
|
|
||||||
return $.get(this.autocompletePath, {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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({
|
|
||||||
id: (suggestion.category.toLowerCase()) + "-" + suggestion.id,
|
|
||||||
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()),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return callback(data);
|
|
||||||
})
|
|
||||||
.always(() => { this.loadingSuggestions = false; });
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { issuesPath, mrPath, name, issuesDisabled } = options;
|
|
||||||
const baseItems = [];
|
|
||||||
|
|
||||||
if (name) {
|
|
||||||
baseItems.push({
|
|
||||||
header: `${name}`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const issueItems = [
|
|
||||||
{
|
|
||||||
text: 'Issues assigned to me',
|
|
||||||
url: `${issuesPath}/?assignee_username=${userName}`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
serializeState() {
|
|
||||||
return {
|
|
||||||
// Search Criteria
|
|
||||||
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(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
bindEvents() {
|
|
||||||
this.searchInput.on('keydown', this.onSearchInputKeyDown);
|
|
||||||
this.searchInput.on('keyup', this.onSearchInputKeyUp);
|
|
||||||
this.searchInput.on('focus', this.onSearchInputFocus);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the dropdown is closed, we'll open it
|
|
||||||
if (!this.dropdown.hasClass('open')) {
|
|
||||||
this.loadingSuggestions = false;
|
|
||||||
this.dropdownToggle.dropdown('toggle');
|
|
||||||
return this.searchInput.removeClass('disabled');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Saves last length of the entered text
|
|
||||||
onSearchInputKeyDown() {
|
|
||||||
return this.saveTextLength();
|
|
||||||
}
|
|
||||||
|
|
||||||
onSearchInputKeyUp(e) {
|
|
||||||
switch (e.keyCode) {
|
|
||||||
case KEYCODE.BACKSPACE:
|
|
||||||
// when trying to remove the location badge
|
|
||||||
if (this.lastTextLength === 0 && this.badgePresent()) {
|
|
||||||
this.removeLocationBadge();
|
|
||||||
}
|
|
||||||
// When removing the last character and no badge is present
|
|
||||||
if (this.lastTextLength === 1) {
|
|
||||||
this.disableAutocomplete();
|
|
||||||
}
|
|
||||||
// When removing any character from existin value
|
|
||||||
if (this.lastTextLength > 1) {
|
|
||||||
this.enableAutocomplete();
|
|
||||||
}
|
|
||||||
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();
|
|
||||||
} 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
onSearchInputFocus() {
|
|
||||||
this.isFocused = true;
|
|
||||||
this.wrap.addClass('search-active');
|
|
||||||
if (this.getValue() === '') {
|
|
||||||
return this.getData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getValue() {
|
|
||||||
return this.searchInput.val();
|
|
||||||
}
|
|
||||||
|
|
||||||
onClearInputClick(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
this.wrap.toggleClass('has-value', !!e.target.value);
|
|
||||||
return this.searchInput.val('').focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
onSearchInputBlur(e) {
|
|
||||||
this.isFocused = false;
|
|
||||||
this.wrap.removeClass('search-active');
|
|
||||||
// If input is blank then restore state
|
|
||||||
if (this.searchInput.val() === '') {
|
|
||||||
return this.restoreOriginalState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addLocationBadge(item) {
|
|
||||||
var badgeText, category, value;
|
|
||||||
category = item.category != null ? item.category + ": " : '';
|
|
||||||
value = item.value != null ? item.value : '';
|
|
||||||
badgeText = "" + category + value;
|
|
||||||
this.locationBadgeEl.text(badgeText).show();
|
|
||||||
return this.wrap.addClass('has-location-badge');
|
|
||||||
}
|
|
||||||
|
|
||||||
hasLocationBadge() {
|
|
||||||
return this.wrap.is('.has-location-badge');
|
|
||||||
}
|
|
||||||
|
|
||||||
restoreOriginalState() {
|
|
||||||
var i, input, inputs, len;
|
|
||||||
inputs = Object.keys(this.originalState);
|
|
||||||
for (i = 0, len = inputs.length; i < len; i += 1) {
|
|
||||||
input = inputs[i];
|
|
||||||
this.getElement("#" + input).val(this.originalState[input]);
|
|
||||||
}
|
|
||||||
if (this.originalState._location === '') {
|
|
||||||
return this.locationBadgeEl.hide();
|
|
||||||
} else {
|
|
||||||
return this.addLocationBadge({
|
|
||||||
value: this.originalState._location,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
badgePresent() {
|
|
||||||
return this.locationBadgeEl.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
resetSearchState() {
|
|
||||||
var i, input, inputs, len, results;
|
|
||||||
inputs = Object.keys(this.originalState);
|
|
||||||
results = [];
|
|
||||||
for (i = 0, len = inputs.length; i < len; i += 1) {
|
|
||||||
input = inputs[i];
|
|
||||||
// _location isnt a input
|
|
||||||
if (input === '_location') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
results.push(this.getElement("#" + input).val(''));
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
removeLocationBadge() {
|
|
||||||
this.locationBadgeEl.hide();
|
|
||||||
this.resetSearchState();
|
|
||||||
this.wrap.removeClass('has-location-badge');
|
|
||||||
return this.disableAutocomplete();
|
|
||||||
}
|
|
||||||
|
|
||||||
disableAutocomplete() {
|
|
||||||
if (!this.searchInput.hasClass('disabled') && this.dropdown.hasClass('open')) {
|
|
||||||
this.searchInput.addClass('disabled');
|
|
||||||
this.dropdown.removeClass('open').trigger('hidden.bs.dropdown');
|
|
||||||
this.restoreMenu();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
restoreMenu() {
|
|
||||||
var html;
|
|
||||||
html = '<ul><li class="dropdown-menu-empty-item"><a>Loading...</a></li></ul>';
|
|
||||||
return this.dropdownContent.html(html);
|
|
||||||
}
|
|
||||||
|
|
||||||
onClick(item, $el, e) {
|
|
||||||
if (location.pathname.indexOf(item.url) !== -1) {
|
|
||||||
if (!e.metaKey) e.preventDefault();
|
|
||||||
if (!this.badgePresent) {
|
|
||||||
if (item.category === 'Projects') {
|
|
||||||
this.projectInputEl.val(item.id);
|
|
||||||
this.addLocationBadge({
|
|
||||||
value: 'This project',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (item.category === 'Groups') {
|
|
||||||
this.groupInputEl.val(item.id);
|
|
||||||
this.addLocationBadge({
|
|
||||||
value: 'This group',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$el.removeClass('is-active');
|
|
||||||
this.disableAutocomplete();
|
|
||||||
return this.searchInput.val('').focus();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
global.SearchAutocomplete = SearchAutocomplete;
|
// Saves last length of the entered text
|
||||||
|
onSearchInputKeyDown() {
|
||||||
|
return this.saveTextLength();
|
||||||
|
}
|
||||||
|
|
||||||
$(function() {
|
onSearchInputKeyUp(e) {
|
||||||
var $projectOptionsDataEl = $('.js-search-project-options');
|
switch (e.keyCode) {
|
||||||
var $groupOptionsDataEl = $('.js-search-group-options');
|
case KEYCODE.BACKSPACE:
|
||||||
var $dashboardOptionsDataEl = $('.js-search-dashboard-options');
|
// when trying to remove the location badge
|
||||||
|
if (this.lastTextLength === 0 && this.badgePresent()) {
|
||||||
if ($projectOptionsDataEl.length) {
|
this.removeLocationBadge();
|
||||||
gl.projectOptions = gl.projectOptions || {};
|
}
|
||||||
|
// When removing the last character and no badge is present
|
||||||
var projectPath = $projectOptionsDataEl.data('project-path');
|
if (this.lastTextLength === 1) {
|
||||||
|
this.disableAutocomplete();
|
||||||
gl.projectOptions[projectPath] = {
|
}
|
||||||
name: $projectOptionsDataEl.data('name'),
|
// When removing any character from existin value
|
||||||
issuesPath: $projectOptionsDataEl.data('issues-path'),
|
if (this.lastTextLength > 1) {
|
||||||
issuesDisabled: $projectOptionsDataEl.data('issues-disabled'),
|
this.enableAutocomplete();
|
||||||
mrPath: $projectOptionsDataEl.data('mr-path'),
|
}
|
||||||
};
|
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();
|
||||||
|
} 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);
|
||||||
|
}
|
||||||
|
|
||||||
if ($groupOptionsDataEl.length) {
|
onSearchInputFocus() {
|
||||||
gl.groupOptions = gl.groupOptions || {};
|
this.isFocused = true;
|
||||||
|
this.wrap.addClass('search-active');
|
||||||
var groupPath = $groupOptionsDataEl.data('group-path');
|
if (this.getValue() === '') {
|
||||||
|
return this.getData();
|
||||||
gl.groupOptions[groupPath] = {
|
|
||||||
name: $groupOptionsDataEl.data('name'),
|
|
||||||
issuesPath: $groupOptionsDataEl.data('issues-path'),
|
|
||||||
mrPath: $groupOptionsDataEl.data('mr-path'),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($dashboardOptionsDataEl.length) {
|
getValue() {
|
||||||
gl.dashboardOptions = {
|
return this.searchInput.val();
|
||||||
issuesPath: $dashboardOptionsDataEl.data('issues-path'),
|
}
|
||||||
mrPath: $dashboardOptionsDataEl.data('mr-path'),
|
|
||||||
};
|
onClearInputClick(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.wrap.toggleClass('has-value', !!e.target.value);
|
||||||
|
return this.searchInput.val('').focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
onSearchInputBlur(e) {
|
||||||
|
this.isFocused = false;
|
||||||
|
this.wrap.removeClass('search-active');
|
||||||
|
// If input is blank then restore state
|
||||||
|
if (this.searchInput.val() === '') {
|
||||||
|
return this.restoreOriginalState();
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
})(window.gl || (window.gl = {}));
|
|
||||||
|
addLocationBadge(item) {
|
||||||
|
var badgeText, category, value;
|
||||||
|
category = item.category != null ? item.category + ": " : '';
|
||||||
|
value = item.value != null ? item.value : '';
|
||||||
|
badgeText = "" + category + value;
|
||||||
|
this.locationBadgeEl.text(badgeText).show();
|
||||||
|
return this.wrap.addClass('has-location-badge');
|
||||||
|
}
|
||||||
|
|
||||||
|
hasLocationBadge() {
|
||||||
|
return this.wrap.is('.has-location-badge');
|
||||||
|
}
|
||||||
|
|
||||||
|
restoreOriginalState() {
|
||||||
|
var i, input, inputs, len;
|
||||||
|
inputs = Object.keys(this.originalState);
|
||||||
|
for (i = 0, len = inputs.length; i < len; i += 1) {
|
||||||
|
input = inputs[i];
|
||||||
|
this.getElement("#" + input).val(this.originalState[input]);
|
||||||
|
}
|
||||||
|
if (this.originalState._location === '') {
|
||||||
|
return this.locationBadgeEl.hide();
|
||||||
|
} else {
|
||||||
|
return this.addLocationBadge({
|
||||||
|
value: this.originalState._location,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
badgePresent() {
|
||||||
|
return this.locationBadgeEl.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
resetSearchState() {
|
||||||
|
var i, input, inputs, len, results;
|
||||||
|
inputs = Object.keys(this.originalState);
|
||||||
|
results = [];
|
||||||
|
for (i = 0, len = inputs.length; i < len; i += 1) {
|
||||||
|
input = inputs[i];
|
||||||
|
// _location isnt a input
|
||||||
|
if (input === '_location') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
results.push(this.getElement("#" + input).val(''));
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
removeLocationBadge() {
|
||||||
|
this.locationBadgeEl.hide();
|
||||||
|
this.resetSearchState();
|
||||||
|
this.wrap.removeClass('has-location-badge');
|
||||||
|
return this.disableAutocomplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
disableAutocomplete() {
|
||||||
|
if (!this.searchInput.hasClass('disabled') && this.dropdown.hasClass('open')) {
|
||||||
|
this.searchInput.addClass('disabled');
|
||||||
|
this.dropdown.removeClass('open').trigger('hidden.bs.dropdown');
|
||||||
|
this.restoreMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
restoreMenu() {
|
||||||
|
var html;
|
||||||
|
html = '<ul><li class="dropdown-menu-empty-item"><a>Loading...</a></li></ul>';
|
||||||
|
return this.dropdownContent.html(html);
|
||||||
|
}
|
||||||
|
|
||||||
|
onClick(item, $el, e) {
|
||||||
|
if (location.pathname.indexOf(item.url) !== -1) {
|
||||||
|
if (!e.metaKey) e.preventDefault();
|
||||||
|
if (!this.badgePresent) {
|
||||||
|
if (item.category === 'Projects') {
|
||||||
|
this.projectInputEl.val(item.id);
|
||||||
|
this.addLocationBadge({
|
||||||
|
value: 'This project',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (item.category === 'Groups') {
|
||||||
|
this.groupInputEl.val(item.id);
|
||||||
|
this.addLocationBadge({
|
||||||
|
value: 'This group',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$el.removeClass('is-active');
|
||||||
|
this.disableAutocomplete();
|
||||||
|
return this.searchInput.val('').focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
_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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* 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';
|
||||||
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() {
|
||||||
|
|
|
@ -1,44 +1,42 @@
|
||||||
/* 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();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in a new issue