RFC6901 JSON Pointer implementation in OCaml using jsont
1/* The browsers interpretation of the CORS origin policy prevents to run
2 webworkers from javascript files fetched from the file:// protocol. This hack
3 is to workaround this restriction. */
4function createWebWorker() {
5 var searchs = search_urls.map((search_url) => {
6 let parts = document.location.href.split("/");
7 parts[parts.length - 1] = search_url;
8 return '"' + parts.join("/") + '"';
9 });
10 blobContents = ["importScripts(" + searchs.join(",") + ");"];
11 var blob = new Blob(blobContents, { type: "application/javascript" });
12 var blobUrl = URL.createObjectURL(blob);
13
14 var worker = new Worker(blobUrl);
15 URL.revokeObjectURL(blobUrl);
16
17 return worker;
18}
19
20var worker;
21var waiting = 0;
22
23function wait() {
24 waiting = waiting + 1;
25 document.querySelector(".search-snake").classList.add("search-busy");
26}
27
28function stop_waiting() {
29 if (waiting > 0) waiting = waiting - 1;
30 else waiting = 0;
31 if (waiting == 0) {
32 document.querySelector(".search-snake").classList.remove("search-busy");
33 }
34}
35
36document.querySelector(".search-bar").addEventListener("focus", (ev) => {
37 if (typeof worker == "undefined") {
38 worker = createWebWorker();
39 worker.onmessage = (e) => {
40 stop_waiting();
41 let results = e.data;
42 let search_results = document.querySelector(".search-result");
43 search_results.innerHTML = "";
44 let f = (entry) => {
45 let search_result = document.createElement("a");
46 search_result.classList.add("search-entry");
47 search_result.href = base_url + entry.url;
48 search_result.innerHTML = entry.html;
49 search_results.appendChild(search_result);
50 };
51 results.forEach(f);
52 let search_request = document.querySelector(".search-bar").value;
53 if (results.length == 0 && search_request != "") {
54 let no_result = document.createElement("div");
55 no_result.classList.add("search-no-result");
56 no_result.innerText = "No result...";
57 search_results.appendChild(no_result);
58 }
59 };
60 }
61});
62
63document.querySelector(".search-bar").addEventListener("input", (ev) => {
64 wait();
65 worker.postMessage(ev.target.value);
66});
67
68
69/** Navigation */
70
71let search_result_elt = document.querySelector(".search-result")
72
73function search_results() {
74 return search_result_elt.children;
75}
76
77function enter_search() {
78 document.querySelector(".search-bar").focus();
79}
80
81function escape_search() {
82 document.activeElement.blur()
83}
84
85function focus_previous_result() {
86 let results = Array.from(search_results());
87 let current_focus = results.findIndex((elt) => (document.activeElement === elt));
88 if (current_focus === -1)
89 return;
90 else if (current_focus === 0)
91 enter_search();
92 else
93 results[current_focus - 1].focus();
94}
95
96function focus_next_result() {
97 let results = Array.from(search_results());
98 if (results.length === 0) return;
99 let current_focus = results.findIndex((elt) => (document.activeElement === elt));
100 if (current_focus === -1)
101 results[0].focus();
102 else if (current_focus + 1 === results.length)
103 return;
104 else
105 results[current_focus + 1].focus();
106}
107
108
109function is_searching() {
110 return (document.querySelectorAll(".odoc-search:focus-within").length > 0);
111}
112
113function is_typing() {
114 return (document.activeElement === document.querySelector(".search-bar"));
115}
116
117function handle_key_down(event) {
118 if (is_searching()) {
119 if (event.key === "ArrowUp") {
120 event.preventDefault();
121 focus_previous_result();
122 }
123 if (event.key === "ArrowDown") {
124 event.preventDefault();
125 focus_next_result();
126 }
127 if (event.key === "Escape") {
128 event.preventDefault();
129 escape_search();
130 }
131 }
132 if (!(is_typing())) {
133 let ascii = event.key.charCodeAt(0);
134 if (event.key === "/") {
135 event.preventDefault();
136 enter_search();
137 }
138 else if ( is_searching()
139 && event.key.length === 1
140 && ( (ascii >= 65 && ascii <= 90) // lowercase letter
141 || (ascii >= 97 && ascii <= 122) // uppercase letter
142 || (ascii >= 48 && ascii <= 57) // numbers
143 || (ascii >= 32 && ascii <= 46) // ` ` to `.`
144 || (ascii >= 58 && ascii <= 64)) // `:` to `@`
145 )
146 // We do not prevent default because we want the char to be added to the input
147 enter_search ();
148 }
149}
150document.addEventListener("keydown", handle_key_down);