|
|
@@ -1,261 +1,222 @@
|
|
|
-// TODO: This file was created by bulk-decaffeinate.
|
|
|
-// Sanity-check the conversion and remove this comment.
|
|
|
-/*
|
|
|
- * decaffeinate suggestions:
|
|
|
- * DS102: Remove unnecessary code created because of implicit returns
|
|
|
- * DS103: Rewrite code to no longer use __guard__, or convert again using --optional-chaining
|
|
|
- * DS206: Consider reworking classes to avoid initClass
|
|
|
- * DS207: Consider shorter variations of null checks
|
|
|
- * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
|
|
|
- */
|
|
|
-(function () {
|
|
|
- let SEARCH_PARAM = undefined;
|
|
|
- let HASH_RGX = undefined;
|
|
|
- app.views.Search = class Search extends app.View {
|
|
|
- static initClass() {
|
|
|
- SEARCH_PARAM = app.config.search_param;
|
|
|
-
|
|
|
- this.el = "._search";
|
|
|
- this.activeClass = "_search-active";
|
|
|
-
|
|
|
- this.elements = {
|
|
|
- input: "._search-input",
|
|
|
- resetLink: "._search-clear",
|
|
|
- };
|
|
|
-
|
|
|
- this.events = {
|
|
|
- input: "onInput",
|
|
|
- click: "onClick",
|
|
|
- submit: "onSubmit",
|
|
|
- };
|
|
|
-
|
|
|
- this.shortcuts = {
|
|
|
- typing: "focus",
|
|
|
- altG: "google",
|
|
|
- altS: "stackoverflow",
|
|
|
- altD: "duckduckgo",
|
|
|
- };
|
|
|
-
|
|
|
- this.routes = { after: "afterRoute" };
|
|
|
-
|
|
|
- HASH_RGX = new RegExp(`^#${SEARCH_PARAM}=(.*)`);
|
|
|
- }
|
|
|
+app.views.Search = class Search extends app.View {
|
|
|
+ static SEARCH_PARAM = app.config.search_param;
|
|
|
|
|
|
- init() {
|
|
|
- this.addSubview((this.scope = new app.views.SearchScope(this.el)));
|
|
|
+ static el = "._search";
|
|
|
+ static activeClass = "_search-active";
|
|
|
|
|
|
- this.searcher = new app.Searcher();
|
|
|
- this.searcher
|
|
|
- .on("results", (results) => this.onResults(results))
|
|
|
- .on("end", () => this.onEnd());
|
|
|
+ static elements = {
|
|
|
+ input: "._search-input",
|
|
|
+ resetLink: "._search-clear",
|
|
|
+ };
|
|
|
|
|
|
- this.scope.on("change", () => this.onScopeChange());
|
|
|
+ static events = {
|
|
|
+ input: "onInput",
|
|
|
+ click: "onClick",
|
|
|
+ submit: "onSubmit",
|
|
|
+ };
|
|
|
|
|
|
- app.on("ready", () => this.onReady());
|
|
|
- $.on(window, "hashchange", () => this.searchUrl());
|
|
|
- $.on(window, "focus", (event) => this.onWindowFocus(event));
|
|
|
- }
|
|
|
+ static shortcuts = {
|
|
|
+ typing: "focus",
|
|
|
+ altG: "google",
|
|
|
+ altS: "stackoverflow",
|
|
|
+ altD: "duckduckgo",
|
|
|
+ };
|
|
|
|
|
|
- focus() {
|
|
|
- if (document.activeElement === this.input) {
|
|
|
- return;
|
|
|
- }
|
|
|
- if (app.settings.get("noAutofocus")) {
|
|
|
- return;
|
|
|
- }
|
|
|
- this.input.focus();
|
|
|
- }
|
|
|
+ static routes = { after: "afterRoute" };
|
|
|
|
|
|
- autoFocus() {
|
|
|
- if (app.isMobile() || $.isAndroid() || $.isIOS()) {
|
|
|
- return;
|
|
|
- }
|
|
|
- if (
|
|
|
- (document.activeElement != null
|
|
|
- ? document.activeElement.tagName
|
|
|
- : undefined) === "INPUT"
|
|
|
- ) {
|
|
|
- return;
|
|
|
- }
|
|
|
- if (app.settings.get("noAutofocus")) {
|
|
|
- return;
|
|
|
- }
|
|
|
- this.input.focus();
|
|
|
- }
|
|
|
+ static HASH_RGX = new RegExp(`^#${Search.SEARCH_PARAM}=(.*)`);
|
|
|
|
|
|
- onWindowFocus(event) {
|
|
|
- if (event.target === window) {
|
|
|
- return this.autoFocus();
|
|
|
- }
|
|
|
- }
|
|
|
+ init() {
|
|
|
+ this.addSubview((this.scope = new app.views.SearchScope(this.el)));
|
|
|
|
|
|
- getScopeDoc() {
|
|
|
- if (this.scope.isActive()) {
|
|
|
- return this.scope.getScope();
|
|
|
- }
|
|
|
- }
|
|
|
+ this.searcher = new app.Searcher();
|
|
|
+ this.searcher
|
|
|
+ .on("results", (results) => this.onResults(results))
|
|
|
+ .on("end", () => this.onEnd());
|
|
|
|
|
|
- reset(force) {
|
|
|
- if (force || !this.input.value) {
|
|
|
- this.scope.reset();
|
|
|
- }
|
|
|
- this.el.reset();
|
|
|
- this.onInput();
|
|
|
- this.autoFocus();
|
|
|
+ this.scope.on("change", () => this.onScopeChange());
|
|
|
+
|
|
|
+ app.on("ready", () => this.onReady());
|
|
|
+ $.on(window, "hashchange", () => this.searchUrl());
|
|
|
+ $.on(window, "focus", (event) => this.onWindowFocus(event));
|
|
|
+ }
|
|
|
+
|
|
|
+ focus() {
|
|
|
+ if (document.activeElement === this.input) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (app.settings.get("noAutofocus")) {
|
|
|
+ return;
|
|
|
}
|
|
|
+ this.input.focus();
|
|
|
+ }
|
|
|
|
|
|
- onReady() {
|
|
|
- this.value = "";
|
|
|
- this.delay(this.onInput);
|
|
|
+ autoFocus() {
|
|
|
+ if (app.isMobile() || $.isAndroid() || $.isIOS()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (document.activeElement?.tagName === "INPUT") {
|
|
|
+ return;
|
|
|
}
|
|
|
+ if (app.settings.get("noAutofocus")) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.input.focus();
|
|
|
+ }
|
|
|
|
|
|
- onInput() {
|
|
|
- if (
|
|
|
- this.value == null || // ignore events pre-"ready"
|
|
|
- this.value === this.input.value
|
|
|
- ) {
|
|
|
- return;
|
|
|
- }
|
|
|
- this.value = this.input.value;
|
|
|
+ onWindowFocus(event) {
|
|
|
+ if (event.target === window) {
|
|
|
+ return this.autoFocus();
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- if (this.value.length) {
|
|
|
- this.search();
|
|
|
- } else {
|
|
|
- this.clear();
|
|
|
- }
|
|
|
+ getScopeDoc() {
|
|
|
+ if (this.scope.isActive()) {
|
|
|
+ return this.scope.getScope();
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- search(url) {
|
|
|
- if (url == null) {
|
|
|
- url = false;
|
|
|
- }
|
|
|
- this.addClass(this.constructor.activeClass);
|
|
|
- this.trigger("searching");
|
|
|
-
|
|
|
- this.hasResults = null;
|
|
|
- this.flags = { urlSearch: url, initialResults: true };
|
|
|
- this.searcher.find(
|
|
|
- this.scope.getScope().entries.all(),
|
|
|
- "text",
|
|
|
- this.value,
|
|
|
- );
|
|
|
+ reset(force) {
|
|
|
+ if (force || !this.input.value) {
|
|
|
+ this.scope.reset();
|
|
|
}
|
|
|
+ this.el.reset();
|
|
|
+ this.onInput();
|
|
|
+ this.autoFocus();
|
|
|
+ }
|
|
|
|
|
|
- searchUrl() {
|
|
|
- let value;
|
|
|
- if (location.pathname === "/") {
|
|
|
- this.scope.searchUrl();
|
|
|
- } else if (!app.router.isIndex()) {
|
|
|
- return;
|
|
|
- }
|
|
|
+ onReady() {
|
|
|
+ this.value = "";
|
|
|
+ this.delay(this.onInput);
|
|
|
+ }
|
|
|
|
|
|
- if (!(value = this.extractHashValue())) {
|
|
|
- return;
|
|
|
- }
|
|
|
- this.input.value = this.value = value;
|
|
|
- this.input.setSelectionRange(value.length, value.length);
|
|
|
- this.search(true);
|
|
|
- return true;
|
|
|
+ onInput() {
|
|
|
+ if (
|
|
|
+ this.value == null || // ignore events pre-"ready"
|
|
|
+ this.value === this.input.value
|
|
|
+ ) {
|
|
|
+ return;
|
|
|
}
|
|
|
+ this.value = this.input.value;
|
|
|
|
|
|
- clear() {
|
|
|
- this.removeClass(this.constructor.activeClass);
|
|
|
- this.trigger("clear");
|
|
|
+ if (this.value.length) {
|
|
|
+ this.search();
|
|
|
+ } else {
|
|
|
+ this.clear();
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- externalSearch(url) {
|
|
|
- let value;
|
|
|
- if ((value = this.value)) {
|
|
|
- if (this.scope.name()) {
|
|
|
- value = `${this.scope.name()} ${value}`;
|
|
|
- }
|
|
|
- $.popup(`${url}${encodeURIComponent(value)}`);
|
|
|
- this.reset();
|
|
|
- }
|
|
|
+ search(url) {
|
|
|
+ if (url == null) {
|
|
|
+ url = false;
|
|
|
}
|
|
|
+ this.addClass(this.constructor.activeClass);
|
|
|
+ this.trigger("searching");
|
|
|
|
|
|
- google() {
|
|
|
- this.externalSearch("https://www.google.com/search?q=");
|
|
|
- }
|
|
|
+ this.hasResults = null;
|
|
|
+ this.flags = { urlSearch: url, initialResults: true };
|
|
|
+ this.searcher.find(this.scope.getScope().entries.all(), "text", this.value);
|
|
|
+ }
|
|
|
|
|
|
- stackoverflow() {
|
|
|
- this.externalSearch("https://stackoverflow.com/search?q=");
|
|
|
+ searchUrl() {
|
|
|
+ let value;
|
|
|
+ if (location.pathname === "/") {
|
|
|
+ this.scope.searchUrl();
|
|
|
+ } else if (!app.router.isIndex()) {
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
- duckduckgo() {
|
|
|
- this.externalSearch("https://duckduckgo.com/?t=devdocs&q=");
|
|
|
+ if (!(value = this.extractHashValue())) {
|
|
|
+ return;
|
|
|
}
|
|
|
+ this.input.value = this.value = value;
|
|
|
+ this.input.setSelectionRange(value.length, value.length);
|
|
|
+ this.search(true);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ clear() {
|
|
|
+ this.removeClass(this.constructor.activeClass);
|
|
|
+ this.trigger("clear");
|
|
|
+ }
|
|
|
|
|
|
- onResults(results) {
|
|
|
- if (results.length) {
|
|
|
- this.hasResults = true;
|
|
|
+ externalSearch(url) {
|
|
|
+ let value;
|
|
|
+ if ((value = this.value)) {
|
|
|
+ if (this.scope.name()) {
|
|
|
+ value = `${this.scope.name()} ${value}`;
|
|
|
}
|
|
|
- this.trigger("results", results, this.flags);
|
|
|
- this.flags.initialResults = false;
|
|
|
+ $.popup(`${url}${encodeURIComponent(value)}`);
|
|
|
+ this.reset();
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- onEnd() {
|
|
|
- if (!this.hasResults) {
|
|
|
- this.trigger("noresults");
|
|
|
- }
|
|
|
+ google() {
|
|
|
+ this.externalSearch("https://www.google.com/search?q=");
|
|
|
+ }
|
|
|
+
|
|
|
+ stackoverflow() {
|
|
|
+ this.externalSearch("https://stackoverflow.com/search?q=");
|
|
|
+ }
|
|
|
+
|
|
|
+ duckduckgo() {
|
|
|
+ this.externalSearch("https://duckduckgo.com/?t=devdocs&q=");
|
|
|
+ }
|
|
|
+
|
|
|
+ onResults(results) {
|
|
|
+ if (results.length) {
|
|
|
+ this.hasResults = true;
|
|
|
}
|
|
|
+ this.trigger("results", results, this.flags);
|
|
|
+ this.flags.initialResults = false;
|
|
|
+ }
|
|
|
|
|
|
- onClick(event) {
|
|
|
- if (event.target === this.resetLink) {
|
|
|
- $.stopEvent(event);
|
|
|
- this.reset();
|
|
|
- }
|
|
|
+ onEnd() {
|
|
|
+ if (!this.hasResults) {
|
|
|
+ this.trigger("noresults");
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- onSubmit(event) {
|
|
|
+ onClick(event) {
|
|
|
+ if (event.target === this.resetLink) {
|
|
|
$.stopEvent(event);
|
|
|
+ this.reset();
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- onScopeChange() {
|
|
|
- this.value = "";
|
|
|
- this.onInput();
|
|
|
- }
|
|
|
+ onSubmit(event) {
|
|
|
+ $.stopEvent(event);
|
|
|
+ }
|
|
|
|
|
|
- afterRoute(name, context) {
|
|
|
- if (
|
|
|
- (app.shortcuts.eventInProgress != null
|
|
|
- ? app.shortcuts.eventInProgress.name
|
|
|
- : undefined) === "escape"
|
|
|
- ) {
|
|
|
- return;
|
|
|
- }
|
|
|
- if (!context.init && app.router.isIndex()) {
|
|
|
- this.reset(true);
|
|
|
- }
|
|
|
- if (context.hash) {
|
|
|
- this.delay(this.searchUrl);
|
|
|
- }
|
|
|
- $.requestAnimationFrame(() => this.autoFocus());
|
|
|
- }
|
|
|
+ onScopeChange() {
|
|
|
+ this.value = "";
|
|
|
+ this.onInput();
|
|
|
+ }
|
|
|
|
|
|
- extractHashValue() {
|
|
|
- let value;
|
|
|
- if ((value = this.getHashValue()) != null) {
|
|
|
- app.router.replaceHash();
|
|
|
- return value;
|
|
|
- }
|
|
|
+ afterRoute(name, context) {
|
|
|
+ if (app.shortcuts.eventInProgress?.name === "escape") {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!context.init && app.router.isIndex()) {
|
|
|
+ this.reset(true);
|
|
|
+ }
|
|
|
+ if (context.hash) {
|
|
|
+ this.delay(this.searchUrl);
|
|
|
}
|
|
|
+ $.requestAnimationFrame(() => this.autoFocus());
|
|
|
+ }
|
|
|
|
|
|
- getHashValue() {
|
|
|
- try {
|
|
|
- return __guard__(
|
|
|
- HASH_RGX.exec($.urlDecode(location.hash)),
|
|
|
- (x) => x[1],
|
|
|
- );
|
|
|
- } catch (error) {}
|
|
|
+ extractHashValue() {
|
|
|
+ let value = this.getHashValue();
|
|
|
+ if (value != null) {
|
|
|
+ app.router.replaceHash();
|
|
|
+ return value;
|
|
|
}
|
|
|
- };
|
|
|
- app.views.Search.initClass();
|
|
|
- return app.views.Search;
|
|
|
-})();
|
|
|
-
|
|
|
-function __guard__(value, transform) {
|
|
|
- return typeof value !== "undefined" && value !== null
|
|
|
- ? transform(value)
|
|
|
- : undefined;
|
|
|
-}
|
|
|
+ }
|
|
|
+
|
|
|
+ getHashValue() {
|
|
|
+ try {
|
|
|
+ return Search.HASH_RGX.exec($.urlDecode(location.hash))?.[1];
|
|
|
+ } catch (error) {}
|
|
|
+ }
|
|
|
+};
|