search.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. summaryInclude = 200;
  2. var fuseOptions = {
  3. shouldSort: true,
  4. includeMatches: true,
  5. threshold: 0.0,
  6. tokenize: true,
  7. location: 0,
  8. distance: 100,
  9. maxPatternLength: 32,
  10. minMatchCharLength: 3,
  11. includeScore: true,
  12. isCaseSensitive: false,
  13. keys: [{
  14. name: "title",
  15. weight: 0.6
  16. },
  17. {
  18. name: "contents",
  19. weight: 0.3
  20. },
  21. {
  22. name: "tags",
  23. weight: 0.05
  24. },
  25. {
  26. name: "categories",
  27. weight: 0.05
  28. }
  29. ]
  30. };
  31. var searchQuery = param("s");
  32. if (searchQuery) {
  33. $("#search-form-wrapper").removeClass("add-margin-top-search-form");
  34. $("#search-query").val(searchQuery);
  35. executeSearch(searchQuery);
  36. } else {
  37. $("#search-form-wrapper").addClass("add-margin-top-search-form");
  38. }
  39. function executeSearch(searchQuery) {
  40. $("#loading-icon").fadeIn();
  41. $.getJSON("/index.json?t=" + $("#search-db-version").text(), function (data) {
  42. var pages = data;
  43. var fuse = new Fuse(pages, fuseOptions);
  44. var result = fuse.search(searchQuery);
  45. $("#loading-icon").hide();
  46. if (result.length > 0) {
  47. populateResults(result);
  48. } else {
  49. $('#search-results').append("<p>No matches found</p>");
  50. }
  51. });
  52. }
  53. function populateResults(result) {
  54. $.each(result, function (key, value) {
  55. var contents = value.item.contents;
  56. var snippet = "";
  57. var snippetHighlights = [];
  58. var tags = [];
  59. if (fuseOptions.tokenize) {
  60. snippetHighlights.push(searchQuery);
  61. } else {
  62. $.each(value.matches, function (matchKey, mvalue) {
  63. if (mvalue.key == "tags" || mvalue.key == "categories") {
  64. snippetHighlights.push(mvalue.value);
  65. } else if (mvalue.key == "contents") {
  66. start = mvalue.indices[0][0] - summaryInclude > 0 ? mvalue.indices[0][0] - summaryInclude : 0;
  67. end = mvalue.indices[0][1] + summaryInclude < contents.length ? mvalue.indices[0][1] + summaryInclude : contents.length;
  68. snippet += contents.substring(start, end);
  69. snippetHighlights.push(mvalue.value.substring(mvalue.indices[0][0], mvalue.indices[0][1] - mvalue.indices[0][0] + 1));
  70. }
  71. });
  72. }
  73. if (snippet.length < 1) {
  74. snippet += contents.substring(0, summaryInclude * 2);
  75. }
  76. //pull template from hugo templarte definition
  77. var templateDefinition = $('#search-result-template').html();
  78. //replace values
  79. var output = render(templateDefinition, {
  80. key: key,
  81. title: value.item.title,
  82. link: value.item.permalink,
  83. tags: value.item.tags,
  84. categories: value.item.categories,
  85. snippet: snippet,
  86. score: value.score
  87. });
  88. $('#search-results').append(output);
  89. $.each(snippetHighlights, function (snipkey, snipvalue) {
  90. $("#summary-" + key).mark(snipvalue);
  91. });
  92. });
  93. }
  94. function param(name) {
  95. return decodeURIComponent((location.search.split(name + '=')[1] || '').split('&')[0]).replace(/\+/g, ' ');
  96. }
  97. function render(templateString, data) {
  98. var conditionalMatches, conditionalPattern, copy;
  99. conditionalPattern = /\$\{\s*isset ([a-zA-Z]*) \s*\}(.*)\$\{\s*end\s*}/g;
  100. //since loop below depends on re.lastInxdex, we use a copy to capture any manipulations whilst inside the loop
  101. copy = templateString;
  102. while ((conditionalMatches = conditionalPattern.exec(templateString)) !== null) {
  103. if (data[conditionalMatches[1]]) {
  104. //valid key, remove conditionals, leave contents.
  105. copy = copy.replace(conditionalMatches[0], conditionalMatches[2]);
  106. } else {
  107. //not valid, remove entire section
  108. copy = copy.replace(conditionalMatches[0], '');
  109. }
  110. }
  111. templateString = copy;
  112. //now any conditionals removed we can do simple substitution
  113. var key, find, re;
  114. for (key in data) {
  115. find = '\\$\\{\\s*' + key + '\\s*\\}';
  116. re = new RegExp(find, 'g');
  117. templateString = templateString.replace(re, data[key]);
  118. }
  119. return templateString;
  120. }