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.
 
 
 
 
 
 

152 lines
4.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. var languages = new Bloodhound({
  12. datumTokenizer: Bloodhound.tokenizers.obj.whitespace("value"),
  13. queryTokenizer: Bloodhound.tokenizers.whitespace,
  14. local: $.map(TYPEAHEAD_LANGUAGES, function(state){
  15. return {value : state};
  16. })
  17. });
  18. languages.initialize();
  19. $("#language.typeahead").typeahead({
  20. hint: true,
  21. highlight: true,
  22. minLength: 1
  23. },
  24. {
  25. name: "languages",
  26. displayKey: "value",
  27. source: languages.ttAdapter()
  28. });
  29. }());
  30. /*
  31. * Set all advanced search form button callbacks.
  32. */
  33. (function setSearchFormCallbacks(){
  34. // Create a new search group, and update the `#sidebar` checklist accordingly.
  35. $("button#add-group").click(function(){
  36. $("div#sidebar input[type=checkbox]").prop("checked", false);
  37. searchGroups.children("#selected").removeAttr("id");
  38. var searchGroup = $("<div/>", {class : "search-group", id : "selected"});
  39. searchGroups.append(searchGroup.append(createSearchGroupInput("language")));
  40. $("div#sidebar input[type=checkbox]#language").prop("checked", true);
  41. });
  42. // Remove the currently selected group if it's not the only one, and mark one
  43. // of its siblings as selected.
  44. $("button#remove-group").click(function(){
  45. var currentGroup = $("div.search-group#selected");
  46. if($("div.search-group").length == 1)
  47. return;
  48. else {
  49. var nextGroup = currentGroup.prev();
  50. if(nextGroup.size() == 0)
  51. nextGroup = currentGroup.next();
  52. }
  53. currentGroup.remove();
  54. nextGroup.click();
  55. });
  56. // Select a search group, and update the `#sidebar` checklist accordingly.
  57. $(document).on("click", "div.search-group", function(){
  58. searchGroups.children("#selected").removeAttr("id");
  59. $(this).attr("id", "selected");
  60. $("div#sidebar input[type=checkbox]").prop("checked", false);
  61. $(this).find("input[type=text]").each(function(){
  62. var checkBoxSelector = "div#sidebar input[type=checkbox]";
  63. $(checkBoxSelector + "#" + $(this).attr("class").split(" ")[0]).
  64. prop("checked", true);
  65. })
  66. });
  67. // Add an input field to the currently selected search group.
  68. $("div#sidebar input[type=checkbox]").click(function(){
  69. var fieldId = $(this).prop("id");
  70. if($(this).is(":checked")){
  71. $("div.search-group#selected").append(
  72. $.parseHTML(createSearchGroupInput(fieldId)));
  73. if(fieldId.slice(0, 4) == "date")
  74. $(".search-group#selected ." + fieldId).datepicker();
  75. }
  76. else
  77. $("div.search-group#selected #" + fieldId).remove()
  78. });
  79. }());
  80. /*
  81. * Return an HTML string representing a new input field div in a search group.
  82. *
  83. * @param fieldId The id of the input field div, and its child elements.
  84. */
  85. function createSearchGroupInput(fieldId){
  86. return [
  87. "<div id='" + fieldId + "'>",
  88. "<div>" + fieldId.replace(/-/g, " ") + "</div>",
  89. "<input class='" + fieldId + "' name='" + fieldId + "'type='text'>",
  90. "<input type='checkbox' name='regex'><span>Regex</span>",
  91. "</div>"
  92. ].join("");
  93. }
  94. /*
  95. * Create a query from advanced-search groups.
  96. */
  97. function assembleQuery(){
  98. var groups = searchGroups.children(".search-group");
  99. var groupQueries = [];
  100. for(var group = 0; group < groups.length; group++){
  101. var inputs = groups[group].querySelectorAll("input[type=text]");
  102. var groupQuery = []
  103. for(var field = 0; field < inputs.length; field++)
  104. if(inputs[field].value.length > 0)
  105. groupQuery.push(genFieldQueryString(inputs[field]));
  106. groupQueries.push(groupQuery.join(" AND "));
  107. }
  108. // console.log(groupQueries.join(" OR "));
  109. }
  110. /*
  111. * Generate a processed query string for an input field's value.
  112. *
  113. * @param field An `input[type=text]` DOM element.
  114. */
  115. function genFieldQueryString(field){
  116. var terms = field.value.replace(/\\/g, "\\\\").replace(/\"/g, "\\\"");
  117. if(field.value.indexOf('"') >= 0)
  118. return '"' + field.getAttribute("name") + ":" + terms + '"';
  119. return terms;
  120. }
  121. (function testQueryStringGeneration(){
  122. var sampleStrings = [
  123. "A B",
  124. "A \\ B",
  125. '"A \\" B"',
  126. '"A \\" B" C D "A B"',
  127. ];
  128. for(var string = 0; string < sampleStrings.length; string++)
  129. console.log([
  130. (sampleStrings[string] + " ").slice(0, 12),
  131. ":",
  132. " " + genFieldQueryString($("<input>").val(sampleStrings[string])[0])
  133. ].join(""));
  134. })();