History

Sanity-check decaffeinate app.views.SearchScope

Simon Legner committed 2 years ago

Commit 0c3f1811 parent bdfea4b1 file · +140 −167Browse files

Unified · Split

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