Unified · Split
| @@ -1,207 +1,180 @@ | ||
| 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.SearchScope = class SearchScope extends app.View { | |
| 15 | − static initClass() { | |
| 16 | − SEARCH_PARAM = app.config.search_param; | |
| 17 | − | |
| 18 | − this.elements = { | |
| 19 | − input: "._search-input", | |
| 20 | − tag: "._search-tag", | |
| 21 | − }; | |
| 22 | − | |
| 23 | − this.events = { | |
| 24 | − click: "onClick", | |
| 25 | − keydown: "onKeydown", | |
| 26 | − textInput: "onTextInput", | |
| 27 | − }; | |
| 28 | − | |
| 29 | − this.routes = { after: "afterRoute" }; | |
| 30 | − | |
| 31 | − HASH_RGX = new RegExp(`^#${SEARCH_PARAM}=(.+?) .`); | |
| 32 | − } | |
| 1 | +app.views.SearchScope = class SearchScope extends app.View { | |
| 2 | + static SEARCH_PARAM = app.config.search_param; | |
| 33 | 3 | |
| 34 | − init() { | |
| 35 | − this.placeholder = this.input.getAttribute("placeholder"); | |
| 4 | + static elements = { | |
| 5 | + input: "._search-input", | |
| 6 | + tag: "._search-tag", | |
| 7 | + }; | |
| 36 | 8 | |
| 37 | − this.searcher = new app.SynchronousSearcher({ | |
| 38 | − fuzzy_min_length: 2, | |
| 39 | − max_results: 1, | |
| 40 | − }); | |
| 41 | − this.searcher.on("results", (results) => this.onResults(results)); | |
| 42 | − } | |
| 9 | + static events = { | |
| 10 | + click: "onClick", | |
| 11 | + keydown: "onKeydown", | |
| 12 | + textInput: "onTextInput", | |
| 13 | + }; | |
| 43 | 14 | |
| 44 | − getScope() { | |
| 45 | − return this.doc || app; | |
| 46 | − } | |
| 15 | + static routes = { after: "afterRoute" }; | |
| 47 | 16 | |
| 48 | − isActive() { | |
| 49 | − return !!this.doc; | |
| 50 | − } | |
| 17 | + static HASH_RGX = new RegExp(`^#${SearchScope.SEARCH_PARAM}=(.+?) .`); | |
| 18 | + | |
| 19 | + init() { | |
| 20 | + this.placeholder = this.input.getAttribute("placeholder"); | |
| 21 | + | |
| 22 | + this.searcher = new app.SynchronousSearcher({ | |
| 23 | + fuzzy_min_length: 2, | |
| 24 | + max_results: 1, | |
| 25 | + }); | |
| 26 | + this.searcher.on("results", (results) => this.onResults(results)); | |
| 27 | + } | |
| 28 | + | |
| 29 | + getScope() { | |
| 30 | + return this.doc || app; | |
| 31 | + } | |
| 32 | + | |
| 33 | + isActive() { | |
| 34 | + return !!this.doc; | |
| 35 | + } | |
| 51 | 36 | |
| 52 | − name() { | |
| 53 | − return this.doc != null ? this.doc.name : undefined; | |
| 37 | + name() { | |
| 38 | + return this.doc != null ? this.doc.name : undefined; | |
| 39 | + } | |
| 40 | + | |
| 41 | + search(value, searchDisabled) { | |
| 42 | + if (searchDisabled == null) { | |
| 43 | + searchDisabled = false; | |
| 44 | + } | |
| 45 | + if (this.doc) { | |
| 46 | + return; | |
| 47 | + } | |
| 48 | + this.searcher.find(app.docs.all(), "text", value); | |
| 49 | + if (!this.doc && searchDisabled) { | |
| 50 | + this.searcher.find(app.disabledDocs.all(), "text", value); | |
| 54 | 51 | } |
| 52 | + } | |
| 55 | 53 | |
| 56 | − search(value, searchDisabled) { | |
| 57 | − if (searchDisabled == null) { | |
| 58 | − searchDisabled = false; | |
| 59 | − } | |
| 60 | − if (this.doc) { | |
| 61 | − return; | |
| 62 | − } | |
| 63 | − this.searcher.find(app.docs.all(), "text", value); | |
| 64 | − if (!this.doc && searchDisabled) { | |
| 65 | − this.searcher.find(app.disabledDocs.all(), "text", value); | |
| 66 | − } | |
| 54 | + searchUrl() { | |
| 55 | + let value; | |
| 56 | + if ((value = this.extractHashValue())) { | |
| 57 | + this.search(value, true); | |
| 67 | 58 | } |
| 59 | + } | |
| 68 | 60 | |
| 69 | − searchUrl() { | |
| 70 | − let value; | |
| 71 | − if ((value = this.extractHashValue())) { | |
| 72 | − this.search(value, true); | |
| 73 | − } | |
| 61 | + onResults(results) { | |
| 62 | + let doc; | |
| 63 | + if (!(doc = results[0])) { | |
| 64 | + return; | |
| 74 | 65 | } |
| 66 | + if (app.docs.contains(doc)) { | |
| 67 | + this.selectDoc(doc); | |
| 68 | + } else { | |
| 69 | + this.redirectToDoc(doc); | |
| 70 | + } | |
| 71 | + } | |
| 75 | 72 | |
| 76 | − onResults(results) { | |
| 77 | − let doc; | |
| 78 | − if (!(doc = results[0])) { | |
| 79 | − return; | |
| 80 | − } | |
| 81 | − if (app.docs.contains(doc)) { | |
| 82 | − this.selectDoc(doc); | |
| 83 | − } else { | |
| 84 | − this.redirectToDoc(doc); | |
| 85 | − } | |
| 73 | + selectDoc(doc) { | |
| 74 | + const previousDoc = this.doc; | |
| 75 | + if (doc === previousDoc) { | |
| 76 | + return; | |
| 86 | 77 | } |
| 78 | + this.doc = doc; | |
| 87 | 79 | |
| 88 | − selectDoc(doc) { | |
| 89 | − const previousDoc = this.doc; | |
| 90 | − if (doc === previousDoc) { | |
| 91 | − return; | |
| 92 | − } | |
| 93 | − this.doc = doc; | |
| 80 | + this.tag.textContent = doc.fullName; | |
| 81 | + this.tag.style.display = "block"; | |
| 94 | 82 | |
| 95 | − this.tag.textContent = doc.fullName; | |
| 96 | − this.tag.style.display = "block"; | |
| 83 | + this.input.removeAttribute("placeholder"); | |
| 84 | + this.input.value = this.input.value.slice(this.input.selectionStart); | |
| 85 | + this.input.style.paddingLeft = this.tag.offsetWidth + 10 + "px"; | |
| 97 | 86 | |
| 98 | − this.input.removeAttribute("placeholder"); | |
| 99 | − this.input.value = this.input.value.slice(this.input.selectionStart); | |
| 100 | − this.input.style.paddingLeft = this.tag.offsetWidth + 10 + "px"; | |
| 87 | + $.trigger(this.input, "input"); | |
| 88 | + this.trigger("change", this.doc, previousDoc); | |
| 89 | + } | |
| 101 | 90 | |
| 102 | − $.trigger(this.input, "input"); | |
| 103 | − this.trigger("change", this.doc, previousDoc); | |
| 104 | − } | |
| 91 | + redirectToDoc(doc) { | |
| 92 | + const { hash } = location; | |
| 93 | + app.router.replaceHash(""); | |
| 94 | + location.assign(doc.fullPath() + hash); | |
| 95 | + } | |
| 105 | 96 | |
| 106 | − redirectToDoc(doc) { | |
| 107 | − const { hash } = location; | |
| 108 | − app.router.replaceHash(""); | |
| 109 | − location.assign(doc.fullPath() + hash); | |
| 97 | + reset() { | |
| 98 | + if (!this.doc) { | |
| 99 | + return; | |
| 110 | 100 | } |
| 101 | + const previousDoc = this.doc; | |
| 102 | + this.doc = null; | |
| 111 | 103 | |
| 112 | − reset() { | |
| 113 | − if (!this.doc) { | |
| 114 | − return; | |
| 115 | − } | |
| 116 | − const previousDoc = this.doc; | |
| 117 | − this.doc = null; | |
| 104 | + this.tag.textContent = ""; | |
| 105 | + this.tag.style.display = "none"; | |
| 118 | 106 | |
| 119 | − this.tag.textContent = ""; | |
| 120 | − this.tag.style.display = "none"; | |
| 107 | + this.input.setAttribute("placeholder", this.placeholder); | |
| 108 | + this.input.style.paddingLeft = ""; | |
| 121 | 109 | |
| 122 | − this.input.setAttribute("placeholder", this.placeholder); | |
| 123 | − this.input.style.paddingLeft = ""; | |
| 110 | + this.trigger("change", null, previousDoc); | |
| 111 | + } | |
| 124 | 112 | |
| 125 | − this.trigger("change", null, previousDoc); | |
| 113 | + doScopeSearch(event) { | |
| 114 | + this.search(this.input.value.slice(0, this.input.selectionStart)); | |
| 115 | + if (this.doc) { | |
| 116 | + $.stopEvent(event); | |
| 126 | 117 | } |
| 118 | + } | |
| 127 | 119 | |
| 128 | − doScopeSearch(event) { | |
| 129 | − this.search(this.input.value.slice(0, this.input.selectionStart)); | |
| 130 | − if (this.doc) { | |
| 131 | − $.stopEvent(event); | |
| 132 | − } | |
| 120 | + onClick(event) { | |
| 121 | + if (event.target === this.tag) { | |
| 122 | + this.reset(); | |
| 123 | + $.stopEvent(event); | |
| 133 | 124 | } |
| 125 | + } | |
| 134 | 126 | |
| 135 | − onClick(event) { | |
| 136 | − if (event.target === this.tag) { | |
| 127 | + onKeydown(event) { | |
| 128 | + if (event.which === 8) { | |
| 129 | + // backspace | |
| 130 | + if (this.doc && this.input.selectionEnd === 0) { | |
| 137 | 131 | this.reset(); |
| 138 | 132 | $.stopEvent(event); |
| 139 | 133 | } |
| 140 | − } | |
| 141 | − | |
| 142 | − onKeydown(event) { | |
| 143 | − if (event.which === 8) { | |
| 144 | − // backspace | |
| 145 | − if (this.doc && this.input.selectionEnd === 0) { | |
| 146 | − this.reset(); | |
| 147 | − $.stopEvent(event); | |
| 148 | − } | |
| 149 | − } else if (!this.doc && this.input.value && !$.isChromeForAndroid()) { | |
| 150 | − if (event.ctrlKey || event.metaKey || event.altKey || event.shiftKey) { | |
| 151 | − return; | |
| 152 | − } | |
| 153 | − if ( | |
| 154 | − event.which === 9 || // tab | |
| 155 | − (event.which === 32 && app.isMobile()) | |
| 156 | − ) { | |
| 157 | − // space | |
| 158 | − this.doScopeSearch(event); | |
| 159 | − } | |
| 160 | − } | |
| 161 | − } | |
| 162 | − | |
| 163 | − onTextInput(event) { | |
| 164 | − if (!$.isChromeForAndroid()) { | |
| 134 | + } else if (!this.doc && this.input.value && !$.isChromeForAndroid()) { | |
| 135 | + if (event.ctrlKey || event.metaKey || event.altKey || event.shiftKey) { | |
| 165 | 136 | return; |
| 166 | 137 | } |
| 167 | − if (!this.doc && this.input.value && event.data === " ") { | |
| 138 | + if ( | |
| 139 | + event.which === 9 || // tab | |
| 140 | + (event.which === 32 && app.isMobile()) | |
| 141 | + ) { | |
| 142 | + // space | |
| 168 | 143 | this.doScopeSearch(event); |
| 169 | 144 | } |
| 170 | 145 | } |
| 146 | + } | |
| 171 | 147 | |
| 172 | − extractHashValue() { | |
| 173 | − let value; | |
| 174 | − if ((value = this.getHashValue())) { | |
| 175 | − const newHash = $.urlDecode(location.hash).replace( | |
| 176 | − `#${SEARCH_PARAM}=${value} `, | |
| 177 | − `#${SEARCH_PARAM}=`, | |
| 178 | − ); | |
| 179 | − app.router.replaceHash(newHash); | |
| 180 | − return value; | |
| 181 | − } | |
| 148 | + onTextInput(event) { | |
| 149 | + if (!$.isChromeForAndroid()) { | |
| 150 | + return; | |
| 182 | 151 | } |
| 152 | + if (!this.doc && this.input.value && event.data === " ") { | |
| 153 | + this.doScopeSearch(event); | |
| 154 | + } | |
| 155 | + } | |
| 183 | 156 | |
| 184 | − getHashValue() { | |
| 185 | − try { | |
| 186 | − return __guard__( | |
| 187 | − HASH_RGX.exec($.urlDecode(location.hash)), | |
| 188 | − (x) => x[1], | |
| 189 | − ); | |
| 190 | − } catch (error) {} | |
| 157 | + extractHashValue() { | |
| 158 | + let value; | |
| 159 | + if ((value = this.getHashValue())) { | |
| 160 | + const newHash = $.urlDecode(location.hash).replace( | |
| 161 | + `#${SearchScope.SEARCH_PARAM}=${value} `, | |
| 162 | + `#${SearchScope.SEARCH_PARAM}=`, | |
| 163 | + ); | |
| 164 | + app.router.replaceHash(newHash); | |
| 165 | + return value; | |
| 191 | 166 | } |
| 167 | + } | |
| 192 | 168 | |
| 193 | − afterRoute(name, context) { | |
| 194 | − if (!app.isSingleDoc() && context.init && context.doc) { | |
| 195 | − this.selectDoc(context.doc); | |
| 196 | − } | |
| 169 | + getHashValue() { | |
| 170 | + try { | |
| 171 | + return SearchScope.HASH_RGX.exec($.urlDecode(location.hash))?.[1]; | |
| 172 | + } catch (error) {} | |
| 173 | + } | |
| 174 | + | |
| 175 | + afterRoute(name, context) { | |
| 176 | + if (!app.isSingleDoc() && context.init && context.doc) { | |
| 177 | + this.selectDoc(context.doc); | |
| 197 | 178 | } |
| 198 | − }; | |
| 199 | − app.views.SearchScope.initClass(); | |
| 200 | − return app.views.SearchScope; | |
| 201 | −})(); | |
| 202 | − | |
| 203 | −function __guard__(value, transform) { | |
| 204 | − return typeof value !== "undefined" && value !== null | |
| 205 | − ? transform(value) | |
| 206 | − : undefined; | |
| 207 | −} | |
| 179 | + } | |
| 180 | +}; | |