You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
devdocs/assets/javascripts/views/search/search.js

279 lines
6.5 KiB

// TODO: This file was created by bulk-decaffeinate.
// Sanity-check the conversion and remove this comment.
/*
* decaffeinate suggestions:
* DS002: Fix invalid constructor
* 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
*/
1 year ago
(function () {
let SEARCH_PARAM = undefined;
let HASH_RGX = undefined;
app.views.Search = class Search extends app.View {
constructor(...args) {
this.focus = this.focus.bind(this);
this.autoFocus = this.autoFocus.bind(this);
this.onWindowFocus = this.onWindowFocus.bind(this);
this.onReady = this.onReady.bind(this);
this.onInput = this.onInput.bind(this);
this.searchUrl = this.searchUrl.bind(this);
this.google = this.google.bind(this);
this.stackoverflow = this.stackoverflow.bind(this);
this.duckduckgo = this.duckduckgo.bind(this);
this.onResults = this.onResults.bind(this);
this.onEnd = this.onEnd.bind(this);
this.onClick = this.onClick.bind(this);
this.onScopeChange = this.onScopeChange.bind(this);
this.afterRoute = this.afterRoute.bind(this);
super(...args);
}
static initClass() {
SEARCH_PARAM = app.config.search_param;
1 year ago
this.el = "._search";
this.activeClass = "_search-active";
this.elements = {
1 year ago
input: "._search-input",
resetLink: "._search-clear",
};
1 year ago
this.events = {
1 year ago
input: "onInput",
click: "onClick",
submit: "onSubmit",
};
1 year ago
this.shortcuts = {
1 year ago
typing: "focus",
altG: "google",
altS: "stackoverflow",
altD: "duckduckgo",
};
1 year ago
this.routes = { after: "afterRoute" };
HASH_RGX = new RegExp(`^#${SEARCH_PARAM}=(.*)`);
}
init() {
1 year ago
this.addSubview((this.scope = new app.views.SearchScope(this.el)));
1 year ago
this.searcher = new app.Searcher();
this.searcher.on("results", this.onResults).on("end", this.onEnd);
1 year ago
this.scope.on("change", this.onScopeChange);
1 year ago
app.on("ready", this.onReady);
$.on(window, "hashchange", this.searchUrl);
$.on(window, "focus", this.onWindowFocus);
}
focus() {
1 year ago
if (document.activeElement === this.input) {
return;
}
if (app.settings.get("noAutofocus")) {
return;
}
this.input.focus();
}
autoFocus() {
1 year ago
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();
}
onWindowFocus(event) {
1 year ago
if (event.target === window) {
return this.autoFocus();
}
}
getScopeDoc() {
1 year ago
if (this.scope.isActive()) {
return this.scope.getScope();
}
}
reset(force) {
1 year ago
if (force || !this.input.value) {
this.scope.reset();
}
this.el.reset();
this.onInput();
this.autoFocus();
}
onReady() {
1 year ago
this.value = "";
this.delay(this.onInput);
}
onInput() {
1 year ago
if (
this.value == null || // ignore events pre-"ready"
this.value === this.input.value
) {
return;
}
this.value = this.input.value;
if (this.value.length) {
this.search();
} else {
this.clear();
}
}
search(url) {
1 year ago
if (url == null) {
url = false;
}
this.addClass(this.constructor.activeClass);
1 year ago
this.trigger("searching");
this.hasResults = null;
1 year ago
this.flags = { urlSearch: url, initialResults: true };
this.searcher.find(
this.scope.getScope().entries.all(),
"text",
this.value,
);
}
searchUrl() {
let value;
1 year ago
if (location.pathname === "/") {
this.scope.searchUrl();
} else if (!app.router.isIndex()) {
return;
}
1 year ago
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);
1 year ago
this.trigger("clear");
}
externalSearch(url) {
let value;
1 year ago
if ((value = this.value)) {
if (this.scope.name()) {
value = `${this.scope.name()} ${value}`;
}
$.popup(`${url}${encodeURIComponent(value)}`);
this.reset();
}
}
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) {
1 year ago
if (results.length) {
this.hasResults = true;
}
this.trigger("results", results, this.flags);
this.flags.initialResults = false;
}
onEnd() {
1 year ago
if (!this.hasResults) {
this.trigger("noresults");
}
}
onClick(event) {
if (event.target === this.resetLink) {
$.stopEvent(event);
this.reset();
}
}
onSubmit(event) {
$.stopEvent(event);
}
onScopeChange() {
1 year ago
this.value = "";
this.onInput();
}
afterRoute(name, context) {
1 year ago
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);
}
extractHashValue() {
let value;
if ((value = this.getHashValue()) != null) {
app.router.replaceHash();
return value;
}
}
getHashValue() {
1 year ago
try {
return __guard__(
HASH_RGX.exec($.urlDecode(location.hash)),
(x) => x[1],
);
} catch (error) {}
}
};
app.views.Search.initClass();
return app.views.Search;
})();
function __guard__(value, transform) {
1 year ago
return typeof value !== "undefined" && value !== null
? transform(value)
: undefined;
}