A semantic search engine for source code https://bitshift.benkurtovic.com/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

176 lines
5.9 KiB

  1. /*
  2. * @file Manages all advanced search form logic.
  3. */
  4. var searchGroups = $("div#search-groups");
  5. /*
  6. * Load all advanced search form libraries.
  7. */
  8. function loadInputFieldWidgets(){
  9. $(".search-group input#date-last-modified").datepicker();
  10. $(".search-group input#date-created").datepicker();
  11. $(".search-group input#autocomplete").autocomplete({
  12. source: function(request, response){
  13. var matcher = new RegExp(
  14. $.ui.autocomplete.escapeRegex(request.term), "i");
  15. response($.grep(AUTOCOMPLETE_LANGUAGES, function(item){
  16. return matcher.test(item);
  17. }));
  18. }
  19. });
  20. };
  21. loadInputFieldWidgets();
  22. /*
  23. * Set all advanced search form button callbacks.
  24. */
  25. (function setSearchFormCallbacks(){
  26. // Create a new search group, and update the `#sidebar` checklist.
  27. $("button#add-group").click(function(){
  28. $("div#sidebar input[type=checkbox]").prop("checked", false);
  29. searchGroups.children("#selected").removeAttr("id");
  30. var searchGroup = $("<div/>", {
  31. class : "search-group",
  32. id : "selected"
  33. });
  34. searchGroups.append(
  35. searchGroup.append(createSearchGroupInput("language", "languages")));
  36. loadInputFieldWidgets();
  37. $("div#sidebar input[type=checkbox]#language").prop("checked", true);
  38. searchGroups[0].scrollTop = searchGroups[0].scrollHeight;
  39. });
  40. // Remove the currently selected group if it's not the only one, and mark
  41. // one of its siblings as selected.
  42. $("button#remove-group").click(function(){
  43. var currentGroup = $("div.search-group#selected");
  44. if($("div.search-group").length == 1)
  45. return;
  46. else {
  47. var nextGroup = currentGroup.prev();
  48. if(nextGroup.size() == 0)
  49. nextGroup = currentGroup.next();
  50. }
  51. currentGroup.remove();
  52. nextGroup.click();
  53. });
  54. // Select a search group, and update the `#sidebar` checklist accordingly.
  55. $(document).on("click", "div.search-group", function(){
  56. searchGroups.children("#selected").removeAttr("id");
  57. $(this).attr("id", "selected");
  58. $("div#sidebar input[type=checkbox]").prop("checked", false);
  59. $(this).find("input[type=text]").each(function(){
  60. var checkBoxSelector = "div#sidebar input[type=checkbox]";
  61. $(checkBoxSelector + "#" + $(this).attr("class").split(" ")[0]).
  62. prop("checked", true);
  63. })
  64. });
  65. // Toggle the presence of an input field.
  66. $("div#sidebar input[type=checkbox]").click(function(){
  67. var fieldId = $(this).prop("id");
  68. if($(this).is(":checked")){
  69. $("div.search-group#selected").append(
  70. $.parseHTML(createSearchGroupInput(
  71. fieldId, $(this).next("label").children("div").
  72. text())));
  73. loadInputFieldWidgets();
  74. if(fieldId.slice(0, 4) == "date")
  75. $(".search-group#selected ." + fieldId).datepicker();
  76. }
  77. else {
  78. if($(".search-group#selected").children("div").length > 1)
  79. $(".search-group#selected #" + fieldId).remove()
  80. else
  81. $(this).prop("checked", true);
  82. }
  83. searchGroups[0].scrollTop = searchGroups[0].scrollHeight;
  84. });
  85. $("div#advanced-search button#submit").click(function(){
  86. $("div#advanced-search").hide();
  87. advancedSearchButton.removeClass("clicked");
  88. assembleQuery();
  89. populateResults();
  90. })
  91. var previousAdvancedQuery = "";
  92. var searchBar = $("form#search-bar input[name=query]");
  93. window.setInterval(function(){
  94. var currentQuery = assembleQuery();
  95. if(currentQuery != previousAdvancedQuery){
  96. previousAdvancedQuery = currentQuery;
  97. searchBar.val(assembleQuery());
  98. }
  99. }, 1e3 / 15);
  100. }());
  101. /*
  102. * Return an HTML string representing a new input field div in a search group.
  103. *
  104. * @param fieldId The id of the input field div, and its child elements.
  105. * @param name The name to display next to the input field.
  106. */
  107. function createSearchGroupInput(fieldId, name){
  108. var fieldHTML = [
  109. "<div id='" + fieldId + "'>",
  110. "<div class='name'>" + name + "</div>",
  111. "<input class='" + fieldId + "' name='" + fieldId + "'type='text'>",
  112. "<input type='checkbox' name='regex'>",
  113. "<span class='regex'>Regex</span>",
  114. "</div>"
  115. ]
  116. if(fieldId == "language")
  117. fieldHTML[2] = [
  118. "<input id='autocomplete' class='language'",
  119. "name='language' type='text'>"
  120. ].join(" ");
  121. return fieldHTML.join("");
  122. }
  123. /*
  124. * Create a query from advanced-search groups.
  125. */
  126. function assembleQuery(){
  127. var groups = searchGroups.children(".search-group");
  128. var groupQueries = [];
  129. for(var group = 0; group < groups.length; group++){
  130. var inputFields = groups[group].querySelectorAll("input[type=text]");
  131. var regexCheckbox = groups[group].querySelectorAll("input[name=regex]");
  132. var groupQuery = [];
  133. for(var field = 0; field < inputFields.length; field++)
  134. if(inputFields[field].value.length > 0)
  135. groupQuery.push(genFieldQueryString(
  136. inputFields[field], regexCheckbox[field].checked));
  137. if(groupQuery.length > 0)
  138. groupQueries.push(groupQuery.join(" AND "));
  139. }
  140. return groupQueries.join(" OR ");
  141. }
  142. /*
  143. * Generate a processed query string for an input field's value.
  144. *
  145. * @param field (DOM element) An `input[type=text]` element.
  146. * @param hasRegex (boolean) Whether or not the field's value has regex.
  147. *
  148. * @return The processed query.
  149. */
  150. function genFieldQueryString(field, hasRegex){
  151. var terms = field.value.replace(/\\/g, "\\\\").replace(/\"/g, "\\\"");
  152. var query = field.getAttribute("name") + ":" + (hasRegex?"re:":"") + terms;
  153. return '"' + query + '"';
  154. }