Unified · Split
| @@ -1,261 +1,222 @@ | ||
| 1 | −// TODO: This file was created by bulk-decaffeinate. | |
| 2 | −// Sanity-check the conversion and remove this comment. | |
| 3 | −/* | |
| 4 | − * decaffeinate suggestions: | |
| 5 | − * DS102: Remove unnecessary code created because of implicit returns | |
| 6 | − * DS103: Rewrite code to no longer use __guard__, or convert again using --optional-chaining | |
| 7 | − * DS206: Consider reworking classes to avoid initClass | |
| 8 | − * DS207: Consider shorter variations of null checks | |
| 9 | − * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md | |
| 10 | − */ | |
| 11 | −(function () { | |
| 12 | − let SEARCH_PARAM = undefined; | |
| 13 | − let HASH_RGX = undefined; | |
| 14 | − app.views.Search = class Search extends app.View { | |
| 15 | − static initClass() { | |
| 16 | − SEARCH_PARAM = app.config.search_param; | |
| 17 | − | |
| 18 | − this.el = "._search"; | |
| 19 | − this.activeClass = "_search-active"; | |
| 20 | − | |
| 21 | − this.elements = { | |
| 22 | − input: "._search-input", | |
| 23 | − resetLink: "._search-clear", | |
| 24 | − }; | |
| 25 | − | |
| 26 | − this.events = { | |
| 27 | − input: "onInput", | |
| 28 | − click: "onClick", | |
| 29 | − submit: "onSubmit", | |
| 30 | − }; | |
| 31 | − | |
| 32 | − this.shortcuts = { | |
| 33 | − typing: "focus", | |
| 34 | − altG: "google", | |
| 35 | − altS: "stackoverflow", | |
| 36 | − altD: "duckduckgo", | |
| 37 | − }; | |
| 38 | − | |
| 39 | − this.routes = { after: "afterRoute" }; | |
| 40 | − | |
| 41 | − HASH_RGX = new RegExp(`^#${SEARCH_PARAM}=(.*)`); | |
| 42 | − } | |
| 1 | +app.views.Search = class Search extends app.View { | |
| 2 | + static SEARCH_PARAM = app.config.search_param; | |
| 43 | 3 | |
| 44 | − init() { | |
| 45 | − this.addSubview((this.scope = new app.views.SearchScope(this.el))); | |
| 4 | + static el = "._search"; | |
| 5 | + static activeClass = "_search-active"; | |
| 46 | 6 | |
| 47 | − this.searcher = new app.Searcher(); | |
| 48 | − this.searcher | |
| 49 | − .on("results", (results) => this.onResults(results)) | |
| 50 | − .on("end", () => this.onEnd()); | |
| 7 | + static elements = { | |
| 8 | + input: "._search-input", | |
| 9 | + resetLink: "._search-clear", | |
| 10 | + }; | |
| 51 | 11 | |
| 52 | − this.scope.on("change", () => this.onScopeChange()); | |
| 12 | + static events = { | |
| 13 | + input: "onInput", | |
| 14 | + click: "onClick", | |
| 15 | + submit: "onSubmit", | |
| 16 | + }; | |
| 53 | 17 | |
| 54 | − app.on("ready", () => this.onReady()); | |
| 55 | − $.on(window, "hashchange", () => this.searchUrl()); | |
| 56 | − $.on(window, "focus", (event) => this.onWindowFocus(event)); | |
| 57 | − } | |
| 18 | + static shortcuts = { | |
| 19 | + typing: "focus", | |
| 20 | + altG: "google", | |
| 21 | + altS: "stackoverflow", | |
| 22 | + altD: "duckduckgo", | |
| 23 | + }; | |
| 58 | 24 | |
| 59 | − focus() { | |
| 60 | − if (document.activeElement === this.input) { | |
| 61 | − return; | |
| 62 | − } | |
| 63 | − if (app.settings.get("noAutofocus")) { | |
| 64 | − return; | |
| 65 | − } | |
| 66 | − this.input.focus(); | |
| 67 | − } | |
| 25 | + static routes = { after: "afterRoute" }; | |
| 68 | 26 | |
| 69 | − autoFocus() { | |
| 70 | − if (app.isMobile() || $.isAndroid() || $.isIOS()) { | |
| 71 | − return; | |
| 72 | − } | |
| 73 | − if ( | |
| 74 | − (document.activeElement != null | |
| 75 | − ? document.activeElement.tagName | |
| 76 | − : undefined) === "INPUT" | |
| 77 | − ) { | |
| 78 | − return; | |
| 79 | − } | |
| 80 | − if (app.settings.get("noAutofocus")) { | |
| 81 | − return; | |
| 82 | − } | |
| 83 | − this.input.focus(); | |
| 84 | − } | |
| 27 | + static HASH_RGX = new RegExp(`^#${Search.SEARCH_PARAM}=(.*)`); | |
| 85 | 28 | |
| 86 | − onWindowFocus(event) { | |
| 87 | − if (event.target === window) { | |
| 88 | − return this.autoFocus(); | |
| 89 | − } | |
| 90 | − } | |
| 29 | + init() { | |
| 30 | + this.addSubview((this.scope = new app.views.SearchScope(this.el))); | |
| 91 | 31 | |
| 92 | − getScopeDoc() { | |
| 93 | − if (this.scope.isActive()) { | |
| 94 | − return this.scope.getScope(); | |
| 95 | − } | |
| 96 | − } | |
| 32 | + this.searcher = new app.Searcher(); | |
| 33 | + this.searcher | |
| 34 | + .on("results", (results) => this.onResults(results)) | |
| 35 | + .on("end", () => this.onEnd()); | |
| 97 | 36 | |
| 98 | − reset(force) { | |
| 99 | − if (force || !this.input.value) { | |
| 100 | − this.scope.reset(); | |
| 101 | − } | |
| 102 | − this.el.reset(); | |
| 103 | − this.onInput(); | |
| 104 | − this.autoFocus(); | |
| 37 | + this.scope.on("change", () => this.onScopeChange()); | |
| 38 | + | |
| 39 | + app.on("ready", () => this.onReady()); | |
| 40 | + $.on(window, "hashchange", () => this.searchUrl()); | |
| 41 | + $.on(window, "focus", (event) => this.onWindowFocus(event)); | |
| 42 | + } | |
| 43 | + | |
| 44 | + focus() { | |
| 45 | + if (document.activeElement === this.input) { | |
| 46 | + return; | |
| 47 | + } | |
| 48 | + if (app.settings.get("noAutofocus")) { | |
| 49 | + return; | |
| 105 | 50 | } |
| 51 | + this.input.focus(); | |
| 52 | + } | |
| 106 | 53 | |
| 107 | − onReady() { | |
| 108 | − this.value = ""; | |
| 109 | − this.delay(this.onInput); | |
| 54 | + autoFocus() { | |
| 55 | + if (app.isMobile() || $.isAndroid() || $.isIOS()) { | |
| 56 | + return; | |
| 57 | + } | |
| 58 | + if (document.activeElement?.tagName === "INPUT") { | |
| 59 | + return; | |
| 110 | 60 | } |
| 61 | + if (app.settings.get("noAutofocus")) { | |
| 62 | + return; | |
| 63 | + } | |
| 64 | + this.input.focus(); | |
| 65 | + } | |
| 111 | 66 | |
| 112 | − onInput() { | |
| 113 | − if ( | |
| 114 | − this.value == null || // ignore events pre-"ready" | |
| 115 | − this.value === this.input.value | |
| 116 | − ) { | |
| 117 | − return; | |
| 118 | − } | |
| 119 | − this.value = this.input.value; | |
| 67 | + onWindowFocus(event) { | |
| 68 | + if (event.target === window) { | |
| 69 | + return this.autoFocus(); | |
| 70 | + } | |
| 71 | + } | |
| 120 | 72 | |
| 121 | − if (this.value.length) { | |
| 122 | − this.search(); | |
| 123 | − } else { | |
| 124 | − this.clear(); | |
| 125 | − } | |
| 73 | + getScopeDoc() { | |
| 74 | + if (this.scope.isActive()) { | |
| 75 | + return this.scope.getScope(); | |
| 126 | 76 | } |
| 77 | + } | |
| 127 | 78 | |
| 128 | − search(url) { | |
| 129 | − if (url == null) { | |
| 130 | − url = false; | |
| 131 | − } | |
| 132 | − this.addClass(this.constructor.activeClass); | |
| 133 | − this.trigger("searching"); | |
| 134 | − | |
| 135 | − this.hasResults = null; | |
| 136 | − this.flags = { urlSearch: url, initialResults: true }; | |
| 137 | − this.searcher.find( | |
| 138 | − this.scope.getScope().entries.all(), | |
| 139 | − "text", | |
| 140 | − this.value, | |
| 141 | − ); | |
| 79 | + reset(force) { | |
| 80 | + if (force || !this.input.value) { | |
| 81 | + this.scope.reset(); | |
| 142 | 82 | } |
| 83 | + this.el.reset(); | |
| 84 | + this.onInput(); | |
| 85 | + this.autoFocus(); | |
| 86 | + } | |
| 143 | 87 | |
| 144 | − searchUrl() { | |
| 145 | − let value; | |
| 146 | − if (location.pathname === "/") { | |
| 147 | − this.scope.searchUrl(); | |
| 148 | − } else if (!app.router.isIndex()) { | |
| 149 | − return; | |
| 150 | − } | |
| 88 | + onReady() { | |
| 89 | + this.value = ""; | |
| 90 | + this.delay(this.onInput); | |
| 91 | + } | |
| 151 | 92 | |
| 152 | − if (!(value = this.extractHashValue())) { | |
| 153 | − return; | |
| 154 | − } | |
| 155 | − this.input.value = this.value = value; | |
| 156 | − this.input.setSelectionRange(value.length, value.length); | |
| 157 | − this.search(true); | |
| 158 | − return true; | |
| 93 | + onInput() { | |
| 94 | + if ( | |
| 95 | + this.value == null || // ignore events pre-"ready" | |
| 96 | + this.value === this.input.value | |
| 97 | + ) { | |
| 98 | + return; | |
| 159 | 99 | } |
| 100 | + this.value = this.input.value; | |
| 160 | 101 | |
| 161 | − clear() { | |
| 162 | − this.removeClass(this.constructor.activeClass); | |
| 163 | − this.trigger("clear"); | |
| 102 | + if (this.value.length) { | |
| 103 | + this.search(); | |
| 104 | + } else { | |
| 105 | + this.clear(); | |
| 164 | 106 | } |
| 107 | + } | |
| 165 | 108 | |
| 166 | − externalSearch(url) { | |
| 167 | − let value; | |
| 168 | − if ((value = this.value)) { | |
| 169 | − if (this.scope.name()) { | |
| 170 | − value = `${this.scope.name()} ${value}`; | |
| 171 | − } | |
| 172 | − $.popup(`${url}${encodeURIComponent(value)}`); | |
| 173 | − this.reset(); | |
| 174 | − } | |
| 109 | + search(url) { | |
| 110 | + if (url == null) { | |
| 111 | + url = false; | |
| 175 | 112 | } |
| 113 | + this.addClass(this.constructor.activeClass); | |
| 114 | + this.trigger("searching"); | |
| 176 | 115 | |
| 177 | − google() { | |
| 178 | − this.externalSearch("https://www.google.com/search?q="); | |
| 179 | − } | |
| 116 | + this.hasResults = null; | |
| 117 | + this.flags = { urlSearch: url, initialResults: true }; | |
| 118 | + this.searcher.find(this.scope.getScope().entries.all(), "text", this.value); | |
| 119 | + } | |
| 180 | 120 | |
| 181 | − stackoverflow() { | |
| 182 | − this.externalSearch("https://stackoverflow.com/search?q="); | |
| 121 | + searchUrl() { | |
| 122 | + let value; | |
| 123 | + if (location.pathname === "/") { | |
| 124 | + this.scope.searchUrl(); | |
| 125 | + } else if (!app.router.isIndex()) { | |
| 126 | + return; | |
| 183 | 127 | } |
| 184 | 128 | |
| 185 | − duckduckgo() { | |
| 186 | − this.externalSearch("https://duckduckgo.com/?t=devdocs&q="); | |
| 129 | + if (!(value = this.extractHashValue())) { | |
| 130 | + return; | |
| 187 | 131 | } |
| 132 | + this.input.value = this.value = value; | |
| 133 | + this.input.setSelectionRange(value.length, value.length); | |
| 134 | + this.search(true); | |
| 135 | + return true; | |
| 136 | + } | |
| 137 | + | |
| 138 | + clear() { | |
| 139 | + this.removeClass(this.constructor.activeClass); | |
| 140 | + this.trigger("clear"); | |
| 141 | + } | |
| 188 | 142 | |
| 189 | − onResults(results) { | |
| 190 | − if (results.length) { | |
| 191 | − this.hasResults = true; | |
| 143 | + externalSearch(url) { | |
| 144 | + let value; | |
| 145 | + if ((value = this.value)) { | |
| 146 | + if (this.scope.name()) { | |
| 147 | + value = `${this.scope.name()} ${value}`; | |
| 192 | 148 | } |
| 193 | − this.trigger("results", results, this.flags); | |
| 194 | − this.flags.initialResults = false; | |
| 149 | + $.popup(`${url}${encodeURIComponent(value)}`); | |
| 150 | + this.reset(); | |
| 195 | 151 | } |
| 152 | + } | |
| 196 | 153 | |
| 197 | − onEnd() { | |
| 198 | − if (!this.hasResults) { | |
| 199 | − this.trigger("noresults"); | |
| 200 | − } | |
| 154 | + google() { | |
| 155 | + this.externalSearch("https://www.google.com/search?q="); | |
| 156 | + } | |
| 157 | + | |
| 158 | + stackoverflow() { | |
| 159 | + this.externalSearch("https://stackoverflow.com/search?q="); | |
| 160 | + } | |
| 161 | + | |
| 162 | + duckduckgo() { | |
| 163 | + this.externalSearch("https://duckduckgo.com/?t=devdocs&q="); | |
| 164 | + } | |
| 165 | + | |
| 166 | + onResults(results) { | |
| 167 | + if (results.length) { | |
| 168 | + this.hasResults = true; | |
| 201 | 169 | } |
| 170 | + this.trigger("results", results, this.flags); | |
| 171 | + this.flags.initialResults = false; | |
| 172 | + } | |
| 202 | 173 | |
| 203 | − onClick(event) { | |
| 204 | − if (event.target === this.resetLink) { | |
| 205 | − $.stopEvent(event); | |
| 206 | − this.reset(); | |
| 207 | − } | |
| 174 | + onEnd() { | |
| 175 | + if (!this.hasResults) { | |
| 176 | + this.trigger("noresults"); | |
| 208 | 177 | } |
| 178 | + } | |
| 209 | 179 | |
| 210 | − onSubmit(event) { | |
| 180 | + onClick(event) { | |
| 181 | + if (event.target === this.resetLink) { | |
| 211 | 182 | $.stopEvent(event); |
| 183 | + this.reset(); | |
| 212 | 184 | } |
| 185 | + } | |
| 213 | 186 | |
| 214 | − onScopeChange() { | |
| 215 | − this.value = ""; | |
| 216 | − this.onInput(); | |
| 217 | − } | |
| 187 | + onSubmit(event) { | |
| 188 | + $.stopEvent(event); | |
| 189 | + } | |
| 218 | 190 | |
| 219 | − afterRoute(name, context) { | |
| 220 | − if ( | |
| 221 | − (app.shortcuts.eventInProgress != null | |
| 222 | − ? app.shortcuts.eventInProgress.name | |
| 223 | − : undefined) === "escape" | |
| 224 | − ) { | |
| 225 | − return; | |
| 226 | − } | |
| 227 | − if (!context.init && app.router.isIndex()) { | |
| 228 | − this.reset(true); | |
| 229 | − } | |
| 230 | − if (context.hash) { | |
| 231 | − this.delay(this.searchUrl); | |
| 232 | − } | |
| 233 | − $.requestAnimationFrame(() => this.autoFocus()); | |
| 234 | − } | |
| 191 | + onScopeChange() { | |
| 192 | + this.value = ""; | |
| 193 | + this.onInput(); | |
| 194 | + } | |
| 235 | 195 | |
| 236 | − extractHashValue() { | |
| 237 | − let value; | |
| 238 | − if ((value = this.getHashValue()) != null) { | |
| 239 | − app.router.replaceHash(); | |
| 240 | − return value; | |
| 241 | − } | |
| 196 | + afterRoute(name, context) { | |
| 197 | + if (app.shortcuts.eventInProgress?.name === "escape") { | |
| 198 | + return; | |
| 199 | + } | |
| 200 | + if (!context.init && app.router.isIndex()) { | |
| 201 | + this.reset(true); | |
| 202 | + } | |
| 203 | + if (context.hash) { | |
| 204 | + this.delay(this.searchUrl); | |
| 242 | 205 | } |
| 206 | + $.requestAnimationFrame(() => this.autoFocus()); | |
| 207 | + } | |
| 243 | 208 | |
| 244 | − getHashValue() { | |
| 245 | − try { | |
| 246 | − return __guard__( | |
| 247 | − HASH_RGX.exec($.urlDecode(location.hash)), | |
| 248 | − (x) => x[1], | |
| 249 | − ); | |
| 250 | − } catch (error) {} | |
| 209 | + extractHashValue() { | |
| 210 | + let value = this.getHashValue(); | |
| 211 | + if (value != null) { | |
| 212 | + app.router.replaceHash(); | |
| 213 | + return value; | |
| 251 | 214 | } |
| 252 | − }; | |
| 253 | − app.views.Search.initClass(); | |
| 254 | − return app.views.Search; | |
| 255 | −})(); | |
| 256 | − | |
| 257 | −function __guard__(value, transform) { | |
| 258 | − return typeof value !== "undefined" && value !== null | |
| 259 | − ? transform(value) | |
| 260 | − : undefined; | |
| 261 | −} | |
| 215 | + } | |
| 216 | + | |
| 217 | + getHashValue() { | |
| 218 | + try { | |
| 219 | + return Search.HASH_RGX.exec($.urlDecode(location.hash))?.[1]; | |
| 220 | + } catch (error) {} | |
| 221 | + } | |
| 222 | +}; | |