A semantic search engine for source code https://bitshift.benkurtovic.com/
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

index.js 7.9 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * @file Manages all query entry, `index.html` server querying, and results
  3. * diplay.
  4. */
  5. FINISH_TYPING_INTERVAL = 650;
  6. searchBar = $("form#search-bar input[type='text']")[0];
  7. resultsDiv = $("div#results")[0];
  8. var typingTimer, lastValue;
  9. //Obtained by parsing python file with pygments
  10. var codeExample = '<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n 9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n33\n34\n35\n36\n37\n38\n39\n40</pre></div></td><td class="code"><div class="hll"><pre><span class="sd">&quot;&quot;&quot;</span>\n<span class="sd">Module to contain all the project&#39;s Flask server plumbing.</span>\n<span class="sd">&quot;&quot;&quot;</span>\n\n<span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">Flask</span>\n<span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">render_template</span><span class="p">,</span> <span class="n">session</span>\n\n<span class="kn">from</span> <span class="nn">bitshift</span> <span class="kn">import</span> <span class="n">assets</span>\n<span class="c"># from bitshift.database import Database</span>\n<span class="c"># from bitshift.query import parse_query</span>\n\n<span class="n">app</span> <span class="o">=</span> <span class="n">Flask</span><span class="p">(</span><span class="n">__name__</span><span class="p">)</span>\n<span class="n">app</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">from_object</span><span class="p">(</span><span class="s">&quot;bitshift.config&quot;</span><span class="p">)</span>\n\n<span class="n">app_env</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="n">jinja_env</span>\n<span class="n">app_env</span><span class="o">.</span><span class="n">line_statement_prefix</span> <span class="o">=</span> <span class="s">&quot;=&quot;</span>\n<span class="n">app_env</span><span class="o">.</span><span class="n">globals</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">assets</span><span class="o">=</span><span class="n">assets</span><span class="p">)</span>\n\n<span class="c"># database = Database()</span>\n\n<span class="nd">@app.route</span><span class="p">(</span><span class="s">&quot;/&quot;</span><span class="p">)</span>\n<span class="k">def</span> <span class="nf">index</span><span class="p">():</span>\n <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">&quot;index.html&quot;</span><span class="p">)</span>\n\n<span class="nd">@app.route</span><span class="p">(</span><span class="s">&quot;/search/&lt;query&gt;&quot;</span><span class="p">)</span>\n<span class="k">def</span> <span class="nf">search</span><span class="p">(</span><span class="n">query</span><span class="p">):</span>\n <span class="c"># tree = parse_query(query)</span>\n <span class="c"># database.search(tree)</span>\n <span class="k">pass</span>\n\n<span class="nd">@app.route</span><span class="p">(</span><span class="s">&quot;/about&quot;</span><span class="p">)</span>\n<span class="k">def</span> <span class="nf">about</span><span class="p">():</span>\n <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">&quot;about.html&quot;</span><span class="p">)</span>\n\n<span class="nd">@app.route</span><span class="p">(</span><span class="s">&quot;/developers&quot;</span><span class="p">)</span>\n<span class="k">def</span> <span class="nf">developers</span><span class="p">():</span>\n <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">&quot;developers.html&quot;</span><span class="p">)</span>\n\n<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&quot;__main__&quot;</span><span class="p">:</span>\n <span class="n">app</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">debug</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>\n</pre></div>\n</td></tr></table>'
  11. searchBar.onkeyup = typingTimer;
  12. // Enable infinite scrolling down the results page.
  13. $(window).scroll(function() {
  14. var searchField = $("div#search-field");
  15. if($(window).scrollTop() + $(window).height() == $(document).height() && searchField.hasClass('partly-visible')){
  16. loadMoreResults();
  17. }
  18. });
  19. // Enable capturing the `enter` key.
  20. $("form#search-bar").submit(function(event){
  21. event.preventDefault();
  22. return false;
  23. });
  24. /*
  25. * Clear the existing timer and set a new one the the user types text into the
  26. * search bar.
  27. */
  28. function typingTimer(event){
  29. clearTimeout(typingTimer);
  30. var enterKeyCode = 13;
  31. if(event.keyCode != enterKeyCode){
  32. if(lastValue != searchBar.value)
  33. typingTimer = setTimeout(finishedTyping, FINISH_TYPING_INTERVAL);
  34. }
  35. else {
  36. event.preventDefault();
  37. finishedTyping();
  38. return false;
  39. }
  40. };
  41. /*
  42. * Callback which queries the server whenver the user stops typing.
  43. *
  44. * Whenever the user doesn't type for a `FINISH_TYPING_INTERVAL` after having
  45. * entered new text in the search bar, send the current query request to the
  46. * server.
  47. */
  48. function finishedTyping(){
  49. lastValue = searchBar.value;
  50. var searchField = $("div#search-field");
  51. clearResults();
  52. if(searchBar.value){
  53. if(!searchField.hasClass("partly-visible"))
  54. searchField.addClass("partly-visible");
  55. populateResults();
  56. }
  57. else
  58. searchField.removeClass("partly-visible");
  59. }
  60. /*
  61. * Removes any child elements of `div#results`.
  62. */
  63. function clearResults(){
  64. while(resultsDiv.firstChild)
  65. resultsDiv.removeChild(resultsDiv.firstChild);
  66. }
  67. /*
  68. * Query the server with the current search string, and populate `div#results`
  69. * with its response.
  70. */
  71. function populateResults(){
  72. var results = queryServer();
  73. for(var result = 0; result < results.length; result++){
  74. var newDiv = results[result];
  75. resultsDiv.appendChild(newDiv);
  76. setTimeout(
  77. (function(divReference){
  78. return function(){
  79. divReference.classList.add("cascade");
  80. };
  81. }(newDiv)), result * 20);
  82. }
  83. }
  84. /*
  85. * AJAX the current query string to the server, and return its response.
  86. *
  87. * @return {Array} The server's response in the form of `div.result` DOM
  88. * elements, to fill `div#results`.
  89. */
  90. function queryServer(){
  91. var resultDivs = []
  92. for(var result = 0; result < 20; result++){
  93. var newDiv = document.createElement("div"),
  94. table = document.createElement("table"),
  95. row = document.createElement("tr"),
  96. sidebar = document.createElement("td"),
  97. codeElt = document.createElement("td"),
  98. meta = document.createElement("td");
  99. newDiv.classList.add("result");
  100. sidebar.id = 'sidebar';
  101. codeElt.id = 'code';
  102. meta.id = 'meta';
  103. sidebar.innerHTML = '';
  104. codeElt.innerHTML = '<div id=tablecontainer>' + codeExample + '</div>';
  105. row.appendChild(sidebar);
  106. row.appendChild(codeElt);
  107. row.appendChild(meta);
  108. table.appendChild(row);
  109. newDiv.appendChild(table);
  110. resultDivs.push(newDiv);
  111. }
  112. return resultDivs;
  113. }
  114. /*
  115. * Adds more results to `div#results`.
  116. */
  117. function loadMoreResults(){
  118. results = queryServer();
  119. for(var result = 0; result < results.length; result++){
  120. var newDiv = results[result];
  121. resultsDiv.appendChild(newDiv);
  122. setTimeout(
  123. (function(divReference){
  124. return function(){
  125. divReference.classList.add("cascade");
  126. };
  127. }(newDiv)), result * 20);
  128. }
  129. }