DEV: Remove widget search menu (#25545)
This commit is contained in:
parent
2caaadea4a
commit
5c43fd5054
|
@ -17,7 +17,7 @@ import {
|
|||
registerReviewableActionModal,
|
||||
} from "discourse/components/reviewable-item";
|
||||
import { addAdvancedSearchOptions } from "discourse/components/search-advanced-options";
|
||||
import { addSearchSuggestion as addGlimmerSearchSuggestion } from "discourse/components/search-menu/results/assistant";
|
||||
import { addSearchSuggestion } from "discourse/components/search-menu/results/assistant";
|
||||
import { addItemSelectCallback as addSearchMenuAssistantSelectCallback } from "discourse/components/search-menu/results/assistant-item";
|
||||
import {
|
||||
addQuickSearchRandomTip,
|
||||
|
@ -117,12 +117,6 @@ import {
|
|||
preventCloak,
|
||||
} from "discourse/widgets/post-stream";
|
||||
import { disableNameSuppression } from "discourse/widgets/poster-name";
|
||||
import { addOnKeyDownCallback } from "discourse/widgets/search-menu";
|
||||
import {
|
||||
addQuickSearchRandomTip as addWidgetQuickSearchRandomTip,
|
||||
addSearchSuggestion,
|
||||
removeDefaultQuickSearchRandomTips as removeWidgetDefaultQuickSearchRandomTips,
|
||||
} from "discourse/widgets/search-menu-results";
|
||||
import {
|
||||
changeSetting,
|
||||
createWidget,
|
||||
|
@ -1867,7 +1861,6 @@ class PluginApi {
|
|||
*/
|
||||
addSearchSuggestion(value) {
|
||||
addSearchSuggestion(value);
|
||||
addGlimmerSearchSuggestion(value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1941,7 +1934,6 @@ class PluginApi {
|
|||
*
|
||||
*/
|
||||
addSearchMenuOnKeyDownCallback(fn) {
|
||||
addOnKeyDownCallback(fn);
|
||||
addOnKeyUpCallback(fn);
|
||||
}
|
||||
|
||||
|
@ -1962,7 +1954,6 @@ class PluginApi {
|
|||
*/
|
||||
addQuickSearchRandomTip(tip) {
|
||||
addQuickSearchRandomTip(tip);
|
||||
addWidgetQuickSearchRandomTip(tip);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1976,7 +1967,6 @@ class PluginApi {
|
|||
*/
|
||||
removeDefaultQuickSearchRandomTips() {
|
||||
removeDefaultQuickSearchRandomTips();
|
||||
removeWidgetDefaultQuickSearchRandomTips();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -249,7 +249,7 @@ createWidget("header-icons", {
|
|||
icon: "search",
|
||||
iconId: SEARCH_BUTTON_ID,
|
||||
action: "toggleSearchMenu",
|
||||
active: attrs.searchVisible || this.search.visible,
|
||||
active: this.search.visible,
|
||||
href: getURL("/search"),
|
||||
classNames: ["search-dropdown"],
|
||||
});
|
||||
|
@ -447,14 +447,14 @@ createWidget("revamped-user-menu-wrapper", {
|
|||
},
|
||||
});
|
||||
|
||||
createWidget("glimmer-search-menu-wrapper", {
|
||||
createWidget("search-menu-wrapper", {
|
||||
services: ["search"],
|
||||
buildAttributes() {
|
||||
return { "data-click-outside": true, "aria-live": "polite" };
|
||||
return { "aria-live": "polite" };
|
||||
},
|
||||
|
||||
buildClasses() {
|
||||
return ["search-menu glimmer-search-menu"];
|
||||
return ["search-menu"];
|
||||
},
|
||||
|
||||
html() {
|
||||
|
@ -502,7 +502,7 @@ export default createWidget("header", {
|
|||
|
||||
html(attrs, state) {
|
||||
let inTopicRoute = false;
|
||||
if (this.state.inTopicContext || this.search.inTopicContext) {
|
||||
if (this.search.inTopicContext) {
|
||||
inTopicRoute = this.router.currentRouteName.startsWith("topic.");
|
||||
}
|
||||
|
||||
|
@ -510,7 +510,7 @@ export default createWidget("header", {
|
|||
const headerIcons = this.attach("header-icons", {
|
||||
hamburgerVisible: state.hamburgerVisible,
|
||||
userVisible: state.userVisible,
|
||||
searchVisible: state.searchVisible || this.search.visible,
|
||||
searchVisible: this.search.visible,
|
||||
flagCount: attrs.flagCount,
|
||||
user: this.currentUser,
|
||||
sidebarEnabled: attrs.sidebarEnabled,
|
||||
|
@ -522,18 +522,9 @@ export default createWidget("header", {
|
|||
|
||||
const panels = [this.attach("header-buttons", attrs), headerIcons];
|
||||
|
||||
if (state.searchVisible || this.search.visible) {
|
||||
if (this.siteSettings.experimental_search_menu) {
|
||||
this.search.inTopicContext =
|
||||
this.search.inTopicContext && inTopicRoute;
|
||||
panels.push(this.attach("glimmer-search-menu-wrapper"));
|
||||
} else {
|
||||
panels.push(
|
||||
this.attach("search-menu", {
|
||||
inTopicContext: state.inTopicContext && inTopicRoute,
|
||||
})
|
||||
);
|
||||
}
|
||||
if (this.search.visible) {
|
||||
this.search.inTopicContext = this.search.inTopicContext && inTopicRoute;
|
||||
panels.push(this.attach("search-menu-wrapper"));
|
||||
} else if (state.hamburgerVisible) {
|
||||
panels.push(this.attach("hamburger-dropdown-wrapper", {}));
|
||||
} else if (state.userVisible) {
|
||||
|
@ -570,7 +561,7 @@ export default createWidget("header", {
|
|||
},
|
||||
|
||||
updateHighlight() {
|
||||
if (!this.state.searchVisible || !this.search.visible) {
|
||||
if (!this.search.visible) {
|
||||
this.search.highlightTerm = "";
|
||||
}
|
||||
},
|
||||
|
@ -578,7 +569,6 @@ export default createWidget("header", {
|
|||
closeAll() {
|
||||
this.state.userVisible = false;
|
||||
this.state.hamburgerVisible = false;
|
||||
this.state.searchVisible = false;
|
||||
this.search.visible = false;
|
||||
this.toggleBodyScrolling(false);
|
||||
},
|
||||
|
@ -619,15 +609,10 @@ export default createWidget("header", {
|
|||
}
|
||||
}
|
||||
|
||||
this.state.searchVisible = !this.state.searchVisible;
|
||||
this.search.visible = !this.search.visible;
|
||||
this.updateHighlight();
|
||||
|
||||
if (this.state.searchVisible) {
|
||||
// only used by the widget search-menu
|
||||
this.focusSearchInput();
|
||||
} else {
|
||||
this.state.inTopicContext = false;
|
||||
if (!this.search.searchVisible) {
|
||||
this.search.inTopicContext = false;
|
||||
}
|
||||
},
|
||||
|
@ -664,10 +649,7 @@ export default createWidget("header", {
|
|||
},
|
||||
|
||||
togglePageSearch() {
|
||||
const { state } = this;
|
||||
this.search.inTopicContext = false;
|
||||
state.inTopicContext = false;
|
||||
|
||||
let showSearch = this.router.currentRouteName.startsWith("topic.");
|
||||
|
||||
// If we're viewing a topic, only intercept search if there are cloaked posts
|
||||
|
@ -681,13 +663,12 @@ export default createWidget("header", {
|
|||
$(".topic-post .cooked, .small-action:not(.time-gap)").length < total;
|
||||
}
|
||||
|
||||
if (state.searchVisible || this.search.visible) {
|
||||
if (this.search.visible) {
|
||||
this.toggleSearchMenu();
|
||||
return showSearch;
|
||||
}
|
||||
|
||||
if (showSearch) {
|
||||
state.inTopicContext = true;
|
||||
this.search.inTopicContext = true;
|
||||
this.toggleSearchMenu();
|
||||
return false;
|
||||
|
@ -699,12 +680,7 @@ export default createWidget("header", {
|
|||
domClean() {
|
||||
const { state } = this;
|
||||
|
||||
if (
|
||||
state.searchVisible ||
|
||||
this.search.visible ||
|
||||
state.hamburgerVisible ||
|
||||
state.userVisible
|
||||
) {
|
||||
if (this.search.visible || state.hamburgerVisible || state.userVisible) {
|
||||
this.closeAll();
|
||||
}
|
||||
},
|
||||
|
@ -728,30 +704,4 @@ export default createWidget("header", {
|
|||
break;
|
||||
}
|
||||
},
|
||||
|
||||
// only used by the widget search-menu
|
||||
focusSearchInput() {
|
||||
if (
|
||||
this.state.searchVisible &&
|
||||
!this.siteSettings.experimental_search_menu
|
||||
) {
|
||||
schedule("afterRender", () => {
|
||||
const searchInput = document.querySelector("#search-term");
|
||||
searchInput.focus();
|
||||
searchInput.select();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// only used by the widget search-menu
|
||||
setTopicContext() {
|
||||
this.state.inTopicContext = true;
|
||||
this.focusSearchInput();
|
||||
},
|
||||
|
||||
// only used by the widget search-menu
|
||||
clearContext() {
|
||||
this.state.inTopicContext = false;
|
||||
this.focusSearchInput();
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
import { createWidget } from "discourse/widgets/widget";
|
||||
import I18n from "discourse-i18n";
|
||||
|
||||
createWidget("search-term", {
|
||||
tagName: "input",
|
||||
buildId: () => "search-term",
|
||||
buildKey: () => "search-term",
|
||||
|
||||
buildAttributes(attrs) {
|
||||
return {
|
||||
type: "text",
|
||||
value: attrs.value || "",
|
||||
autocomplete: "off",
|
||||
placeholder: I18n.t("search.title"),
|
||||
"aria-label": I18n.t("search.title"),
|
||||
};
|
||||
},
|
||||
|
||||
input(e) {
|
||||
const val = this.attrs.value;
|
||||
|
||||
// remove zero-width chars
|
||||
const newVal = e.target.value.replace(/[\u200B-\u200D\uFEFF]/, "");
|
||||
|
||||
if (newVal !== val) {
|
||||
this.sendWidgetAction("searchTermChanged", newVal);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// TODO: No longer used, remove in December 2021
|
||||
createWidget("search-context", {
|
||||
html() {
|
||||
return false;
|
||||
},
|
||||
});
|
|
@ -1,901 +0,0 @@
|
|||
import { hbs } from "ember-cli-htmlbars";
|
||||
import { h } from "virtual-dom";
|
||||
import { dateNode } from "discourse/helpers/node";
|
||||
import highlightSearch from "discourse/lib/highlight-search";
|
||||
import renderTag from "discourse/lib/render-tag";
|
||||
import { emojiUnescape } from "discourse/lib/text";
|
||||
import { escapeExpression, formatUsername } from "discourse/lib/utilities";
|
||||
import User from "discourse/models/user";
|
||||
import widgetHbs from "discourse/widgets/hbs-compiler";
|
||||
import { avatarImg } from "discourse/widgets/post";
|
||||
import RawHtml from "discourse/widgets/raw-html";
|
||||
import RenderGlimmer from "discourse/widgets/render-glimmer";
|
||||
import { MODIFIER_REGEXP } from "discourse/widgets/search-menu";
|
||||
import { createWidget } from "discourse/widgets/widget";
|
||||
import getURL from "discourse-common/lib/get-url";
|
||||
import { iconNode } from "discourse-common/lib/icon-library";
|
||||
import { deepMerge } from "discourse-common/lib/object";
|
||||
import I18n from "discourse-i18n";
|
||||
|
||||
const suggestionShortcuts = [
|
||||
"in:title",
|
||||
"in:pinned",
|
||||
"status:open",
|
||||
"status:closed",
|
||||
"status:public",
|
||||
"status:noreplies",
|
||||
"order:latest",
|
||||
"order:views",
|
||||
"order:likes",
|
||||
"order:latest_topic",
|
||||
];
|
||||
|
||||
const DEFAULT_QUICK_TIPS = [
|
||||
{
|
||||
label: "#",
|
||||
description: I18n.t("search.tips.category_tag"),
|
||||
clickable: true,
|
||||
},
|
||||
{
|
||||
label: "@",
|
||||
description: I18n.t("search.tips.author"),
|
||||
clickable: true,
|
||||
},
|
||||
{
|
||||
label: "in:",
|
||||
description: I18n.t("search.tips.in"),
|
||||
clickable: true,
|
||||
},
|
||||
{
|
||||
label: "status:",
|
||||
description: I18n.t("search.tips.status"),
|
||||
clickable: true,
|
||||
},
|
||||
{
|
||||
label: I18n.t("search.tips.full_search_key", { modifier: "Ctrl" }),
|
||||
description: I18n.t("search.tips.full_search"),
|
||||
},
|
||||
{
|
||||
label: "@me",
|
||||
description: I18n.t("search.tips.me"),
|
||||
},
|
||||
];
|
||||
|
||||
let QUICK_TIPS = [];
|
||||
|
||||
export function addSearchSuggestion(value) {
|
||||
if (!suggestionShortcuts.includes(value)) {
|
||||
suggestionShortcuts.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
export function addQuickSearchRandomTip(tip) {
|
||||
if (!QUICK_TIPS.includes(tip)) {
|
||||
QUICK_TIPS.push(tip);
|
||||
}
|
||||
}
|
||||
|
||||
export function removeDefaultQuickSearchRandomTips() {
|
||||
QUICK_TIPS = QUICK_TIPS.filter((tip) => !DEFAULT_QUICK_TIPS.includes(tip));
|
||||
}
|
||||
|
||||
export function resetQuickSearchRandomTips() {
|
||||
QUICK_TIPS = [].concat(DEFAULT_QUICK_TIPS);
|
||||
}
|
||||
|
||||
resetQuickSearchRandomTips();
|
||||
|
||||
class Highlighted extends RawHtml {
|
||||
constructor(html, term) {
|
||||
super({ html: `<span>${html}</span>` });
|
||||
this.term = term;
|
||||
}
|
||||
|
||||
decorate($html) {
|
||||
highlightSearch($html[0], this.term);
|
||||
}
|
||||
}
|
||||
|
||||
function createSearchResult({ type, linkField, builder }) {
|
||||
return createWidget(`search-result-${type}`, {
|
||||
tagName: "ul.list",
|
||||
|
||||
buildAttributes() {
|
||||
return {
|
||||
"aria-label": `${type} ${I18n.t("search.results")}`,
|
||||
};
|
||||
},
|
||||
|
||||
html(attrs) {
|
||||
return attrs.results.map((r) => {
|
||||
let searchResultId;
|
||||
|
||||
if (type === "topic") {
|
||||
searchResultId = r.topic_id;
|
||||
} else {
|
||||
searchResultId = r.id;
|
||||
}
|
||||
|
||||
return h(
|
||||
"li.item",
|
||||
this.attach("link", {
|
||||
href: r[linkField],
|
||||
contents: () => builder.call(this, r, attrs.term),
|
||||
className: "search-link",
|
||||
searchResultId,
|
||||
searchResultType: type,
|
||||
searchLogId: attrs.searchLogId,
|
||||
})
|
||||
);
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function postResult(result, link, term) {
|
||||
const html = [link];
|
||||
|
||||
if (!this.site.mobileView) {
|
||||
html.push(
|
||||
h("span.blurb", [
|
||||
dateNode(result.created_at),
|
||||
h("span", " - "),
|
||||
this.siteSettings.use_pg_headlines_for_excerpt
|
||||
? new RawHtml({ html: `<span>${result.blurb}</span>` })
|
||||
: new Highlighted(result.blurb, term),
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
createSearchResult({
|
||||
type: "tag",
|
||||
linkField: "url",
|
||||
builder(t) {
|
||||
const tag = escapeExpression(t.id);
|
||||
return [
|
||||
iconNode("tag"),
|
||||
new RawHtml({ html: renderTag(tag, { tagName: "span" }) }),
|
||||
];
|
||||
},
|
||||
});
|
||||
|
||||
createSearchResult({
|
||||
type: "category",
|
||||
linkField: "url",
|
||||
builder(c) {
|
||||
return this.attach("category-link", { category: c, link: false });
|
||||
},
|
||||
});
|
||||
|
||||
createSearchResult({
|
||||
type: "group",
|
||||
linkField: "url",
|
||||
builder(group) {
|
||||
const fullName = escapeExpression(group.fullName);
|
||||
const name = escapeExpression(group.name);
|
||||
const groupNames = [h("span.name", fullName || name)];
|
||||
|
||||
if (fullName) {
|
||||
groupNames.push(h("span.slug", name));
|
||||
}
|
||||
|
||||
let avatarFlair;
|
||||
if (group.flairUrl) {
|
||||
avatarFlair = this.attach("avatar-flair", {
|
||||
flair_name: name,
|
||||
flair_url: group.flairUrl,
|
||||
flair_bg_color: group.flairBgColor,
|
||||
flair_color: group.flairColor,
|
||||
});
|
||||
} else {
|
||||
avatarFlair = iconNode("users");
|
||||
}
|
||||
|
||||
const groupResultContents = [avatarFlair, h("div.group-names", groupNames)];
|
||||
|
||||
return h("div.group-result", groupResultContents);
|
||||
},
|
||||
});
|
||||
|
||||
createSearchResult({
|
||||
type: "user",
|
||||
linkField: "path",
|
||||
builder(u) {
|
||||
const userTitles = [];
|
||||
|
||||
if (u.name) {
|
||||
userTitles.push(h("span.name", u.name));
|
||||
}
|
||||
|
||||
userTitles.push(h("span.username", formatUsername(u.username)));
|
||||
|
||||
if (u.custom_data) {
|
||||
u.custom_data.forEach((row) =>
|
||||
userTitles.push(h("span.custom-field", `${row.name}: ${row.value}`))
|
||||
);
|
||||
}
|
||||
|
||||
const userResultContents = [
|
||||
avatarImg("small", {
|
||||
template: u.avatar_template,
|
||||
username: u.username,
|
||||
}),
|
||||
h("div.user-titles", userTitles),
|
||||
];
|
||||
|
||||
return h("div.user-result", userResultContents);
|
||||
},
|
||||
});
|
||||
|
||||
createSearchResult({
|
||||
type: "topic",
|
||||
linkField: "url",
|
||||
builder(result, term) {
|
||||
const topic = result.topic;
|
||||
|
||||
const firstLine = [
|
||||
this.attach("topic-status", { topic, disableActions: true }),
|
||||
h(
|
||||
"span.topic-title",
|
||||
{ attributes: { "data-topic-id": topic.id } },
|
||||
this.siteSettings.use_pg_headlines_for_excerpt &&
|
||||
result.topic_title_headline
|
||||
? new RawHtml({
|
||||
html: `<span>${emojiUnescape(
|
||||
result.topic_title_headline
|
||||
)}</span>`,
|
||||
})
|
||||
: new Highlighted(topic.fancyTitle, term)
|
||||
),
|
||||
];
|
||||
|
||||
const secondLine = [
|
||||
this.attach("category-link", {
|
||||
category: topic.category,
|
||||
link: false,
|
||||
}),
|
||||
];
|
||||
if (this.siteSettings.tagging_enabled) {
|
||||
secondLine.push(
|
||||
this.attach("discourse-tags", { topic, tagName: "span" })
|
||||
);
|
||||
}
|
||||
|
||||
const link = h("span.topic", [
|
||||
h("span.first-line", firstLine),
|
||||
h("span.second-line", secondLine),
|
||||
]);
|
||||
|
||||
return postResult.call(this, result, link, term);
|
||||
},
|
||||
});
|
||||
|
||||
createSearchResult({
|
||||
type: "post",
|
||||
linkField: "url",
|
||||
builder(result, term) {
|
||||
return postResult.call(
|
||||
this,
|
||||
result,
|
||||
I18n.t("search.post_format", result),
|
||||
term
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
createWidget("search-menu-results", {
|
||||
tagName: "div.results",
|
||||
|
||||
html(attrs) {
|
||||
const {
|
||||
term,
|
||||
suggestionKeyword,
|
||||
inTopicContext,
|
||||
results,
|
||||
searchTopics,
|
||||
onLinkClicked,
|
||||
} = attrs;
|
||||
|
||||
if (suggestionKeyword) {
|
||||
return this.attach("search-menu-assistant", {
|
||||
term,
|
||||
suggestionKeyword,
|
||||
results: attrs.suggestionResults || [],
|
||||
});
|
||||
}
|
||||
|
||||
if (searchTopics && attrs.invalidTerm) {
|
||||
return h("div.no-results", I18n.t("search.too_short"));
|
||||
}
|
||||
|
||||
if (searchTopics && attrs.noResults) {
|
||||
return h("div.no-results", I18n.t("search.no_results"));
|
||||
}
|
||||
|
||||
if (!term && !attrs.inPMInboxContext) {
|
||||
return this.attach("search-menu-initial-options", { term });
|
||||
}
|
||||
|
||||
const resultTypes = results.resultTypes || [];
|
||||
|
||||
const mainResultsContent = [];
|
||||
const usersAndGroups = [];
|
||||
const categoriesAndTags = [];
|
||||
|
||||
const buildMoreNode = (result) => {
|
||||
const moreArgs = {
|
||||
className: "filter search-link",
|
||||
contents: () => [I18n.t("more"), "..."],
|
||||
};
|
||||
|
||||
if (result.moreUrl) {
|
||||
return this.attach(
|
||||
"link",
|
||||
deepMerge(moreArgs, {
|
||||
href: result.moreUrl,
|
||||
})
|
||||
);
|
||||
} else if (result.more) {
|
||||
return this.attach(
|
||||
"link",
|
||||
deepMerge(moreArgs, {
|
||||
action: "moreOfType",
|
||||
actionParam: result.type,
|
||||
})
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const assignContainer = (result, node) => {
|
||||
if (searchTopics) {
|
||||
if (["topic"].includes(result.type)) {
|
||||
mainResultsContent.push(node);
|
||||
}
|
||||
} else {
|
||||
if (["user", "group"].includes(result.type)) {
|
||||
usersAndGroups.push(node);
|
||||
}
|
||||
|
||||
if (["category", "tag"].includes(result.type)) {
|
||||
categoriesAndTags.push(node);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
resultTypes.forEach((rt) => {
|
||||
const resultNodeContents = [
|
||||
this.attach(rt.componentName, {
|
||||
searchLogId: attrs.results.grouped_search_result.search_log_id,
|
||||
results: rt.results,
|
||||
term,
|
||||
}),
|
||||
];
|
||||
|
||||
if (["topic"].includes(rt.type)) {
|
||||
const more = buildMoreNode(rt);
|
||||
if (more) {
|
||||
resultNodeContents.push(h("div.search-menu__show-more", more));
|
||||
}
|
||||
}
|
||||
|
||||
assignContainer(rt, h(`div.${rt.componentName}`, resultNodeContents));
|
||||
});
|
||||
|
||||
const content = [];
|
||||
|
||||
if (!searchTopics) {
|
||||
if (!attrs.inPMInboxContext) {
|
||||
content.push(this.attach("search-menu-initial-options", { term }));
|
||||
}
|
||||
} else {
|
||||
if (mainResultsContent.length) {
|
||||
content.push(mainResultsContent);
|
||||
} else {
|
||||
return h("div.no-results", I18n.t("search.no_results"));
|
||||
}
|
||||
}
|
||||
|
||||
content.push(
|
||||
new RenderGlimmer(
|
||||
this,
|
||||
"div",
|
||||
hbs`<PluginOutlet @name="search-menu-results-top" @outletArgs={{@data.outletArgs}}/>`,
|
||||
{
|
||||
outletArgs: {
|
||||
searchTerm: term,
|
||||
inTopicContext,
|
||||
onLinkClicked,
|
||||
searchTopics,
|
||||
},
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
content.push(categoriesAndTags);
|
||||
content.push(usersAndGroups);
|
||||
|
||||
content.push(
|
||||
new RenderGlimmer(
|
||||
this,
|
||||
"div",
|
||||
hbs`<PluginOutlet @name="search-menu-results-bottom" @outletArgs={{@data.outletArgs}}/>`,
|
||||
{
|
||||
outletArgs: {
|
||||
searchTerm: term,
|
||||
inTopicContext,
|
||||
onLinkClicked,
|
||||
searchTopics,
|
||||
},
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
return content;
|
||||
},
|
||||
});
|
||||
|
||||
createWidget("search-menu-assistant", {
|
||||
tagName: "ul.search-menu-assistant",
|
||||
buildKey: () => `search-menu-assistant`,
|
||||
services: ["router"],
|
||||
|
||||
html(attrs) {
|
||||
if (this.currentUser) {
|
||||
addSearchSuggestion("in:likes");
|
||||
addSearchSuggestion("in:bookmarks");
|
||||
addSearchSuggestion("in:mine");
|
||||
addSearchSuggestion("in:messages");
|
||||
addSearchSuggestion("in:seen");
|
||||
addSearchSuggestion("in:tracking");
|
||||
addSearchSuggestion("in:unseen");
|
||||
addSearchSuggestion("in:watching");
|
||||
}
|
||||
if (this.siteSettings.tagging_enabled) {
|
||||
addSearchSuggestion("in:tagged");
|
||||
addSearchSuggestion("in:untagged");
|
||||
}
|
||||
|
||||
const content = [];
|
||||
const { suggestionKeyword, term } = attrs;
|
||||
|
||||
let prefix;
|
||||
if (suggestionKeyword !== "+") {
|
||||
prefix = term?.split(suggestionKeyword)[0].trim() || "";
|
||||
|
||||
if (prefix.length) {
|
||||
prefix = `${prefix} `;
|
||||
}
|
||||
}
|
||||
|
||||
switch (suggestionKeyword) {
|
||||
case "+":
|
||||
attrs.results.forEach((item) => {
|
||||
if (item.additionalTags) {
|
||||
prefix = term?.split(" ").slice(0, -1).join(" ").trim() || "";
|
||||
} else {
|
||||
prefix = term?.split("#")[0].trim() || "";
|
||||
}
|
||||
|
||||
if (prefix.length) {
|
||||
prefix = `${prefix} `;
|
||||
}
|
||||
|
||||
content.push(
|
||||
this.attach("search-menu-assistant-item", {
|
||||
prefix,
|
||||
tag: item.tagName,
|
||||
additionalTags: item.additionalTags,
|
||||
category: item.category,
|
||||
slug: term,
|
||||
withInLabel: attrs.withInLabel,
|
||||
isIntersection: true,
|
||||
})
|
||||
);
|
||||
});
|
||||
break;
|
||||
case "#":
|
||||
attrs.results.forEach((item) => {
|
||||
if (item.model) {
|
||||
const fullSlug = item.model.parentCategory
|
||||
? `#${item.model.parentCategory.slug}:${item.model.slug}`
|
||||
: `#${item.model.slug}`;
|
||||
|
||||
content.push(
|
||||
this.attach("search-menu-assistant-item", {
|
||||
prefix,
|
||||
category: item.model,
|
||||
slug: `${prefix}${fullSlug}`,
|
||||
withInLabel: attrs.withInLabel,
|
||||
})
|
||||
);
|
||||
} else {
|
||||
content.push(
|
||||
this.attach("search-menu-assistant-item", {
|
||||
prefix,
|
||||
tag: item.name,
|
||||
slug: `${prefix}#${item.name}`,
|
||||
withInLabel: attrs.withInLabel,
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case "@":
|
||||
// when only one user matches while in topic
|
||||
// quick suggest user search in the topic or globally
|
||||
if (
|
||||
attrs.results.length === 1 &&
|
||||
this.router.currentRouteName.startsWith("topic.")
|
||||
) {
|
||||
const user = attrs.results[0];
|
||||
content.push(
|
||||
this.attach("search-menu-assistant-item", {
|
||||
extraHint: I18n.t("search.enter_hint"),
|
||||
prefix,
|
||||
user,
|
||||
slug: `${prefix}@${user.username}`,
|
||||
suffix: h(
|
||||
"span.label-suffix",
|
||||
` ${I18n.t("search.in_topics_posts")}`
|
||||
),
|
||||
})
|
||||
);
|
||||
content.push(
|
||||
this.attach("search-menu-assistant-item", {
|
||||
prefix,
|
||||
user,
|
||||
setTopicContext: true,
|
||||
slug: `${prefix}@${user.username}`,
|
||||
suffix: h(
|
||||
"span.label-suffix",
|
||||
` ${I18n.t("search.in_this_topic")}`
|
||||
),
|
||||
})
|
||||
);
|
||||
} else {
|
||||
attrs.results.forEach((user) => {
|
||||
content.push(
|
||||
this.attach("search-menu-assistant-item", {
|
||||
prefix,
|
||||
user,
|
||||
slug: `${prefix}@${user.username}`,
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
suggestionShortcuts.forEach((item) => {
|
||||
if (item.includes(suggestionKeyword) || !suggestionKeyword) {
|
||||
content.push(
|
||||
this.attach("search-menu-assistant-item", {
|
||||
slug: `${prefix}${item}`,
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
return content.filter((c, i) => i <= 8);
|
||||
},
|
||||
});
|
||||
|
||||
createWidget("search-menu-initial-options", {
|
||||
tagName: "ul.search-menu-initial-options",
|
||||
services: ["search"],
|
||||
|
||||
html(attrs) {
|
||||
if (attrs.term?.match(MODIFIER_REGEXP)) {
|
||||
return this.defaultRow(attrs.term);
|
||||
}
|
||||
|
||||
const ctx = this.search.searchContext;
|
||||
const content = [];
|
||||
|
||||
if (attrs.term || ctx) {
|
||||
if (attrs.term) {
|
||||
content.push(this.defaultRow(attrs.term, { withLabel: true }));
|
||||
}
|
||||
|
||||
if (ctx) {
|
||||
const term = attrs.term || "";
|
||||
switch (ctx.type) {
|
||||
case "topic":
|
||||
content.push(
|
||||
this.attach("search-menu-assistant-item", {
|
||||
slug: term,
|
||||
setTopicContext: true,
|
||||
label: [
|
||||
h("span", `${term} `),
|
||||
h("span.label-suffix", I18n.t("search.in_this_topic")),
|
||||
],
|
||||
})
|
||||
);
|
||||
break;
|
||||
|
||||
case "private_messages":
|
||||
content.push(
|
||||
this.attach("search-menu-assistant-item", {
|
||||
slug: `${term} in:messages`,
|
||||
})
|
||||
);
|
||||
break;
|
||||
|
||||
case "category":
|
||||
const fullSlug = ctx.category.parentCategory
|
||||
? `#${ctx.category.parentCategory.slug}:${ctx.category.slug}`
|
||||
: `#${ctx.category.slug}`;
|
||||
|
||||
content.push(
|
||||
this.attach("search-menu-assistant", {
|
||||
term: `${term} ${fullSlug}`,
|
||||
suggestionKeyword: "#",
|
||||
results: [{ model: ctx.category }],
|
||||
withInLabel: true,
|
||||
})
|
||||
);
|
||||
|
||||
break;
|
||||
case "tag":
|
||||
content.push(
|
||||
this.attach("search-menu-assistant", {
|
||||
term: `${term} #${ctx.name}`,
|
||||
suggestionKeyword: "#",
|
||||
results: [{ name: ctx.name }],
|
||||
withInLabel: true,
|
||||
})
|
||||
);
|
||||
break;
|
||||
case "tagIntersection":
|
||||
let tagTerm;
|
||||
if (ctx.additionalTags) {
|
||||
const tags = [ctx.tagId, ...ctx.additionalTags];
|
||||
tagTerm = `${term} tags:${tags.join("+")}`;
|
||||
} else {
|
||||
tagTerm = `${term} #${ctx.tagId}`;
|
||||
}
|
||||
let suggestionOptions = {
|
||||
tagName: ctx.tagId,
|
||||
additionalTags: ctx.additionalTags,
|
||||
};
|
||||
if (ctx.category) {
|
||||
const categorySlug = ctx.category.parentCategory
|
||||
? `#${ctx.category.parentCategory.slug}:${ctx.category.slug}`
|
||||
: `#${ctx.category.slug}`;
|
||||
suggestionOptions.categoryName = categorySlug;
|
||||
suggestionOptions.category = ctx.category;
|
||||
tagTerm = tagTerm + ` ${categorySlug}`;
|
||||
}
|
||||
|
||||
content.push(
|
||||
this.attach("search-menu-assistant", {
|
||||
term: tagTerm,
|
||||
suggestionKeyword: "+",
|
||||
results: [suggestionOptions],
|
||||
withInLabel: true,
|
||||
})
|
||||
);
|
||||
break;
|
||||
case "user":
|
||||
content.push(
|
||||
this.attach("search-menu-assistant-item", {
|
||||
slug: `${term} @${ctx.user.username}`,
|
||||
label: [
|
||||
h("span", `${term} `),
|
||||
h(
|
||||
"span.label-suffix",
|
||||
I18n.t("search.in_posts_by", {
|
||||
username: ctx.user.username,
|
||||
})
|
||||
),
|
||||
],
|
||||
})
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
if (content.length === 0) {
|
||||
content.push(this.attach("random-quick-tip"));
|
||||
|
||||
if (this.currentUser && this.siteSettings.log_search_queries) {
|
||||
if (this.currentUser.recent_searches?.length) {
|
||||
content.push(this.attach("search-menu-recent-searches"));
|
||||
} else {
|
||||
this.loadRecentSearches();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return content;
|
||||
},
|
||||
|
||||
defaultRow(term, opts = { withLabel: false }) {
|
||||
return this.attach("search-menu-assistant-item", {
|
||||
slug: term,
|
||||
extraHint: I18n.t("search.enter_hint"),
|
||||
label: [
|
||||
h("span.keyword", `${term}`),
|
||||
opts.withLabel
|
||||
? h("span.label-suffix", I18n.t("search.in_topics_posts"))
|
||||
: null,
|
||||
],
|
||||
});
|
||||
},
|
||||
|
||||
refreshSearchMenuResults() {
|
||||
this.scheduleRerender();
|
||||
},
|
||||
|
||||
loadRecentSearches() {
|
||||
User.loadRecentSearches().then((result) => {
|
||||
if (result.success && result.recent_searches?.length) {
|
||||
this.currentUser.set(
|
||||
"recent_searches",
|
||||
Object.assign(result.recent_searches)
|
||||
);
|
||||
this.scheduleRerender();
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
createWidget("search-menu-assistant-item", {
|
||||
tagName: "li.search-menu-assistant-item",
|
||||
|
||||
html(attrs) {
|
||||
const prefix = attrs.prefix?.trim();
|
||||
const attributes = {};
|
||||
attributes.href = "#";
|
||||
|
||||
let content = [
|
||||
h(
|
||||
"span",
|
||||
{ attributes: { "aria-label": I18n.t("search.title") } },
|
||||
iconNode(attrs.icon || "search")
|
||||
),
|
||||
];
|
||||
|
||||
if (prefix) {
|
||||
content.push(h("span.search-item-prefix", `${prefix} `));
|
||||
}
|
||||
|
||||
if (attrs.withInLabel) {
|
||||
content.push(h("span.label-suffix", `${I18n.t("search.in")} `));
|
||||
}
|
||||
|
||||
if (attrs.category) {
|
||||
attributes.href = attrs.category.url;
|
||||
|
||||
content.push(
|
||||
this.attach("category-link", {
|
||||
category: attrs.category,
|
||||
allowUncategorized: true,
|
||||
recursive: true,
|
||||
link: false,
|
||||
})
|
||||
);
|
||||
|
||||
// category and tag combination
|
||||
if (attrs.tag && attrs.isIntersection) {
|
||||
attributes.href = getURL(`/tag/${attrs.tag}`);
|
||||
content.push(h("span.search-item-tag", [iconNode("tag"), attrs.tag]));
|
||||
}
|
||||
} else if (attrs.tag) {
|
||||
if (attrs.isIntersection && attrs.additionalTags?.length) {
|
||||
const tags = [attrs.tag, ...attrs.additionalTags];
|
||||
content.push(h("span.search-item-tag", `tags:${tags.join("+")}`));
|
||||
} else {
|
||||
attributes.href = getURL(`/tag/${attrs.tag}`);
|
||||
content.push(h("span.search-item-tag", [iconNode("tag"), attrs.tag]));
|
||||
}
|
||||
} else if (attrs.user) {
|
||||
const userResult = [
|
||||
avatarImg("small", {
|
||||
template: attrs.user.avatar_template,
|
||||
username: attrs.user.username,
|
||||
}),
|
||||
h("span.username", formatUsername(attrs.user.username)),
|
||||
attrs.suffix,
|
||||
];
|
||||
content.push(h("span.search-item-user", userResult));
|
||||
} else {
|
||||
content.push(h("span.search-item-slug", attrs.label || attrs.slug));
|
||||
}
|
||||
if (attrs.extraHint) {
|
||||
content.push(h("span.extra-hint", attrs.extraHint));
|
||||
}
|
||||
return h("a.widget-link.search-link", { attributes }, content);
|
||||
},
|
||||
|
||||
click(e) {
|
||||
const searchInput = document.querySelector("#search-term");
|
||||
searchInput.value = this.attrs.slug;
|
||||
searchInput.focus();
|
||||
this.sendWidgetAction("triggerAutocomplete", {
|
||||
value: this.attrs.slug,
|
||||
searchTopics: true,
|
||||
setTopicContext: this.attrs.setTopicContext,
|
||||
origin: this.attrs.origin,
|
||||
});
|
||||
e.preventDefault();
|
||||
return false;
|
||||
},
|
||||
});
|
||||
|
||||
createWidget("random-quick-tip", {
|
||||
tagName: "li.search-random-quick-tip",
|
||||
|
||||
buildKey: () => "random-quick-tip",
|
||||
|
||||
defaultState() {
|
||||
return QUICK_TIPS.length
|
||||
? QUICK_TIPS[Math.floor(Math.random() * QUICK_TIPS.length)]
|
||||
: {};
|
||||
},
|
||||
|
||||
html(attrs, state) {
|
||||
if (!Object.keys(state).length) {
|
||||
return;
|
||||
}
|
||||
|
||||
return [
|
||||
h(
|
||||
`span.tip-label${state.clickable ? ".tip-clickable" : ""}`,
|
||||
state.label
|
||||
),
|
||||
h("span.tip-description", state.description),
|
||||
];
|
||||
},
|
||||
|
||||
click(e) {
|
||||
if (e.target.classList.contains("tip-clickable")) {
|
||||
const searchInput = document.querySelector("#search-term");
|
||||
searchInput.value = this.state.label;
|
||||
searchInput.focus();
|
||||
this.sendWidgetAction("triggerAutocomplete", {
|
||||
value: this.state.label,
|
||||
searchTopics: this.state.searchTopics,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
createWidget("search-menu-recent-searches", {
|
||||
tagName: "div.search-menu-recent",
|
||||
|
||||
template: widgetHbs`
|
||||
<div class="heading">
|
||||
<h4>{{i18n "search.recent"}}</h4>
|
||||
{{flat-button
|
||||
className="clear-recent-searches"
|
||||
title="search.clear_recent"
|
||||
icon="times"
|
||||
action="clearRecent"
|
||||
}}
|
||||
</div>
|
||||
|
||||
{{#each this.currentUser.recent_searches as |slug|}}
|
||||
{{attach
|
||||
widget="search-menu-assistant-item"
|
||||
attrs=(hash slug=slug icon="history" origin="recent-search")
|
||||
}}
|
||||
{{/each}}
|
||||
`,
|
||||
|
||||
clearRecent() {
|
||||
return User.resetRecentSearches().then((result) => {
|
||||
if (result.success) {
|
||||
this.currentUser.recent_searches.clear();
|
||||
this.sendWidgetAction("refreshSearchMenuResults");
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
|
@ -1,595 +0,0 @@
|
|||
import { cancel } from "@ember/runloop";
|
||||
import { Promise } from "rsvp";
|
||||
import { h } from "virtual-dom";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import { CANCELLED_STATUS } from "discourse/lib/autocomplete";
|
||||
import { search as searchCategoryTag } from "discourse/lib/category-tag-search";
|
||||
import {
|
||||
isValidSearchTerm,
|
||||
searchForTerm,
|
||||
updateRecentSearches,
|
||||
} from "discourse/lib/search";
|
||||
import DiscourseURL from "discourse/lib/url";
|
||||
import userSearch from "discourse/lib/user-search";
|
||||
import { isiPad, translateModKey } from "discourse/lib/utilities";
|
||||
import { createWidget } from "discourse/widgets/widget";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import getURL from "discourse-common/lib/get-url";
|
||||
import { iconNode } from "discourse-common/lib/icon-library";
|
||||
import I18n from "discourse-i18n";
|
||||
|
||||
const CATEGORY_SLUG_REGEXP = /(\#[a-zA-Z0-9\-:]*)$/gi;
|
||||
const USERNAME_REGEXP = /(\@[a-zA-Z0-9\-\_]*)$/gi;
|
||||
const SUGGESTIONS_REGEXP = /(in:|status:|order:|:)([a-zA-Z]*)$/gi;
|
||||
const SECOND_ENTER_MAX_DELAY = 15000;
|
||||
export const MODIFIER_REGEXP = /.*(\#|\@|:).*$/gi;
|
||||
export const DEFAULT_TYPE_FILTER = "exclude_topics";
|
||||
|
||||
const searchData = {};
|
||||
|
||||
const onKeyDownCallbacks = [];
|
||||
|
||||
export function addOnKeyDownCallback(fn) {
|
||||
onKeyDownCallbacks.push(fn);
|
||||
}
|
||||
export function resetOnKeyDownCallbacks() {
|
||||
onKeyDownCallbacks.clear();
|
||||
}
|
||||
|
||||
export function initSearchData() {
|
||||
searchData.loading = false;
|
||||
searchData.results = {};
|
||||
searchData.noResults = false;
|
||||
searchData.term = undefined;
|
||||
searchData.typeFilter = DEFAULT_TYPE_FILTER;
|
||||
searchData.invalidTerm = false;
|
||||
searchData.suggestionResults = [];
|
||||
searchData.suggestionKeyword = false;
|
||||
}
|
||||
|
||||
initSearchData();
|
||||
|
||||
// Helps with debouncing and cancelling promises
|
||||
const SearchHelper = {
|
||||
_activeSearch: null,
|
||||
|
||||
// for cancelling debounced search
|
||||
cancel() {
|
||||
if (this._activeSearch) {
|
||||
this._activeSearch.abort();
|
||||
this._activeSearch = null;
|
||||
}
|
||||
},
|
||||
|
||||
perform(widget) {
|
||||
this.cancel();
|
||||
|
||||
const { term, typeFilter } = searchData;
|
||||
const searchContext = widget.searchContext();
|
||||
|
||||
const fullSearchUrl = widget.fullSearchUrl();
|
||||
const matchSuggestions = this.matchesSuggestions();
|
||||
|
||||
if (matchSuggestions) {
|
||||
searchData.noResults = true;
|
||||
searchData.results = {};
|
||||
searchData.loading = false;
|
||||
searchData.suggestionResults = [];
|
||||
|
||||
if (matchSuggestions.type === "category") {
|
||||
const categorySearchTerm = matchSuggestions.categoriesMatch[0].replace(
|
||||
"#",
|
||||
""
|
||||
);
|
||||
|
||||
const categoryTagSearch = searchCategoryTag(
|
||||
categorySearchTerm,
|
||||
widget.siteSettings
|
||||
);
|
||||
Promise.resolve(categoryTagSearch).then((results) => {
|
||||
if (results !== CANCELLED_STATUS) {
|
||||
searchData.suggestionResults = results;
|
||||
searchData.suggestionKeyword = "#";
|
||||
}
|
||||
widget.scheduleRerender();
|
||||
});
|
||||
} else if (matchSuggestions.type === "username") {
|
||||
const userSearchTerm = matchSuggestions.usernamesMatch[0].replace(
|
||||
"@",
|
||||
""
|
||||
);
|
||||
const opts = { includeGroups: true, limit: 6 };
|
||||
if (userSearchTerm.length > 0) {
|
||||
opts.term = userSearchTerm;
|
||||
} else {
|
||||
opts.lastSeenUsers = true;
|
||||
}
|
||||
|
||||
userSearch(opts).then((result) => {
|
||||
if (result?.users?.length > 0) {
|
||||
searchData.suggestionResults = result.users;
|
||||
searchData.suggestionKeyword = "@";
|
||||
} else {
|
||||
searchData.noResults = true;
|
||||
searchData.suggestionKeyword = false;
|
||||
}
|
||||
widget.scheduleRerender();
|
||||
});
|
||||
} else {
|
||||
searchData.suggestionKeyword = matchSuggestions[0];
|
||||
widget.scheduleRerender();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
searchData.suggestionKeyword = false;
|
||||
|
||||
if (!term) {
|
||||
searchData.noResults = false;
|
||||
searchData.results = {};
|
||||
searchData.loading = false;
|
||||
searchData.invalidTerm = false;
|
||||
|
||||
widget.scheduleRerender();
|
||||
} else if (!isValidSearchTerm(term, widget.siteSettings)) {
|
||||
searchData.noResults = true;
|
||||
searchData.results = {};
|
||||
searchData.loading = false;
|
||||
searchData.invalidTerm = true;
|
||||
|
||||
widget.scheduleRerender();
|
||||
} else {
|
||||
searchData.invalidTerm = false;
|
||||
|
||||
this._activeSearch = searchForTerm(term, {
|
||||
typeFilter,
|
||||
fullSearchUrl,
|
||||
searchContext,
|
||||
});
|
||||
this._activeSearch
|
||||
.then((results) => {
|
||||
// we ensure the current search term is the one used
|
||||
// when starting the query
|
||||
if (results && term === searchData.term) {
|
||||
if (searchContext) {
|
||||
widget.appEvents.trigger("post-stream:refresh", { force: true });
|
||||
}
|
||||
|
||||
searchData.noResults = results.resultTypes.length === 0;
|
||||
searchData.results = results;
|
||||
}
|
||||
})
|
||||
.catch(popupAjaxError)
|
||||
.finally(() => {
|
||||
searchData.loading = false;
|
||||
widget.scheduleRerender();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
matchesSuggestions() {
|
||||
if (searchData.term === undefined || this.includesTopics()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const term = searchData.term.trim();
|
||||
const categoriesMatch = term.match(CATEGORY_SLUG_REGEXP);
|
||||
|
||||
if (categoriesMatch) {
|
||||
return { type: "category", categoriesMatch };
|
||||
}
|
||||
|
||||
const usernamesMatch = term.match(USERNAME_REGEXP);
|
||||
if (usernamesMatch) {
|
||||
return { type: "username", usernamesMatch };
|
||||
}
|
||||
|
||||
const suggestionsMatch = term.match(SUGGESTIONS_REGEXP);
|
||||
if (suggestionsMatch) {
|
||||
return suggestionsMatch;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
includesTopics() {
|
||||
return searchData.typeFilter !== DEFAULT_TYPE_FILTER;
|
||||
},
|
||||
};
|
||||
|
||||
export default createWidget("search-menu", {
|
||||
tagName: "div.search-menu",
|
||||
services: ["search"],
|
||||
searchData,
|
||||
|
||||
buildAttributes() {
|
||||
return {
|
||||
"aria-live": "polite",
|
||||
};
|
||||
},
|
||||
|
||||
buildKey: () => "search-menu",
|
||||
|
||||
defaultState(attrs) {
|
||||
return {
|
||||
inTopicContext: attrs.inTopicContext,
|
||||
inPMInboxContext: this.search?.searchContext?.type === "private_messages",
|
||||
_lastEnterTimestamp: null,
|
||||
_debouncer: null,
|
||||
};
|
||||
},
|
||||
|
||||
fullSearchUrl(opts) {
|
||||
let url = "/search";
|
||||
const params = [];
|
||||
|
||||
if (searchData.term) {
|
||||
let query = "";
|
||||
|
||||
query += `q=${encodeURIComponent(searchData.term)}`;
|
||||
|
||||
const searchContext = this.searchContext();
|
||||
|
||||
if (searchContext?.type === "topic") {
|
||||
query += encodeURIComponent(` topic:${searchContext.id}`);
|
||||
} else if (searchContext?.type === "private_messages") {
|
||||
query += encodeURIComponent(` in:messages`);
|
||||
}
|
||||
|
||||
if (query) {
|
||||
params.push(query);
|
||||
}
|
||||
}
|
||||
|
||||
if (opts && opts.expanded) {
|
||||
params.push("expanded=true");
|
||||
}
|
||||
|
||||
if (params.length > 0) {
|
||||
url = `${url}?${params.join("&")}`;
|
||||
}
|
||||
|
||||
return getURL(url);
|
||||
},
|
||||
|
||||
panelContents() {
|
||||
let searchInput = [];
|
||||
if (this.state.inTopicContext) {
|
||||
searchInput.push(
|
||||
this.attach("button", {
|
||||
icon: "times",
|
||||
label: "search.in_this_topic",
|
||||
title: "search.in_this_topic_tooltip",
|
||||
className: "btn btn-small search-context",
|
||||
action: "clearTopicContext",
|
||||
iconRight: true,
|
||||
})
|
||||
);
|
||||
} else if (this.state.inPMInboxContext) {
|
||||
searchInput.push(
|
||||
this.attach("button", {
|
||||
icon: "times",
|
||||
label: "search.in_messages",
|
||||
title: "search.in_messages_tooltip",
|
||||
className: "btn btn-small search-context",
|
||||
action: "clearPMInboxContext",
|
||||
iconRight: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
searchInput.push(this.attach("search-term", { value: searchData.term }));
|
||||
|
||||
if (searchData.loading) {
|
||||
searchInput.push(h("div.searching", h("div.spinner")));
|
||||
} else {
|
||||
const clearButton = this.attach("link", {
|
||||
title: "search.clear_search",
|
||||
action: "clearSearch",
|
||||
className: "clear-search",
|
||||
contents: () => iconNode("times"),
|
||||
});
|
||||
|
||||
const advancedSearchButton = this.attach("link", {
|
||||
href: this.fullSearchUrl({ expanded: true }),
|
||||
contents: () => iconNode("sliders-h"),
|
||||
className: "show-advanced-search",
|
||||
title: "search.open_advanced",
|
||||
});
|
||||
|
||||
if (searchData.term) {
|
||||
searchInput.push(
|
||||
h("div.searching", [clearButton, advancedSearchButton])
|
||||
);
|
||||
} else {
|
||||
searchInput.push(h("div.searching", advancedSearchButton));
|
||||
}
|
||||
}
|
||||
|
||||
const results = [h("div.search-input", searchInput)];
|
||||
|
||||
if (
|
||||
this.state.inTopicContext &&
|
||||
(!SearchHelper.includesTopics() || !searchData.term)
|
||||
) {
|
||||
const isMobileDevice = this.site.isMobileDevice;
|
||||
|
||||
if (!isMobileDevice) {
|
||||
results.push(this.attach("browser-search-tip"));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
if (!searchData.loading) {
|
||||
results.push(
|
||||
this.attach("search-menu-results", {
|
||||
term: searchData.term,
|
||||
noResults: searchData.noResults,
|
||||
results: searchData.results,
|
||||
invalidTerm: searchData.invalidTerm,
|
||||
suggestionKeyword: searchData.suggestionKeyword,
|
||||
suggestionResults: searchData.suggestionResults,
|
||||
searchTopics: SearchHelper.includesTopics(),
|
||||
inPMInboxContext: this.state.inPMInboxContext,
|
||||
inTopicContext: this.state.inTopicContext,
|
||||
onLinkClicked: this.onLinkClicked.bind(this),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
return results;
|
||||
},
|
||||
|
||||
clearSearch() {
|
||||
searchData.term = "";
|
||||
const searchInput = document.getElementById("search-term");
|
||||
searchInput.value = "";
|
||||
searchInput.focus();
|
||||
this.triggerSearch();
|
||||
},
|
||||
|
||||
html(attrs, state) {
|
||||
if (attrs.inTopicContext === false) {
|
||||
state.inTopicContext = false;
|
||||
}
|
||||
|
||||
return this.attach("menu-panel", {
|
||||
maxWidth: 500,
|
||||
contents: () => this.panelContents(),
|
||||
});
|
||||
},
|
||||
|
||||
onLinkClicked() {
|
||||
return this.sendWidgetAction("linkClickedEvent");
|
||||
},
|
||||
|
||||
mouseDown(e) {
|
||||
if (e.target === document.querySelector("input#search-term")) {
|
||||
this.state.inputSelectionEvent = true;
|
||||
}
|
||||
},
|
||||
|
||||
clickOutside() {
|
||||
if (this.key === "search-menu" && !this.state.inputSelectionEvent) {
|
||||
this.sendWidgetAction("toggleSearchMenu");
|
||||
}
|
||||
this.state.inputSelectionEvent = false;
|
||||
},
|
||||
|
||||
clearTopicContext() {
|
||||
this.sendWidgetAction("clearContext");
|
||||
},
|
||||
|
||||
clearPMInboxContext() {
|
||||
this.state.inPMInboxContext = false;
|
||||
this.sendWidgetAction("focusSearchInput");
|
||||
},
|
||||
|
||||
keyDown(e) {
|
||||
if (
|
||||
onKeyDownCallbacks.length &&
|
||||
!onKeyDownCallbacks.some((fn) => fn(this, e))
|
||||
) {
|
||||
// Return early if any callbacks return false
|
||||
return;
|
||||
}
|
||||
|
||||
this.handleKeyDown(e);
|
||||
},
|
||||
|
||||
handleKeyDown(e) {
|
||||
if (e.key === "Escape") {
|
||||
this.sendWidgetAction("toggleSearchMenu");
|
||||
document.querySelector("#search-button").focus();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (searchData.loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.which === 65 /* a */) {
|
||||
if (document.activeElement?.classList.contains("search-link")) {
|
||||
if (document.querySelector("#reply-control.open")) {
|
||||
// add a link and focus composer
|
||||
|
||||
this.appEvents.trigger(
|
||||
"composer:insert-text",
|
||||
document.activeElement.href,
|
||||
{
|
||||
ensureSpace: true,
|
||||
}
|
||||
);
|
||||
this.appEvents.trigger("header:keyboard-trigger", { type: "search" });
|
||||
|
||||
e.preventDefault();
|
||||
document.querySelector("#reply-control.open textarea").focus();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const up = e.key === "ArrowUp";
|
||||
const down = e.key === "ArrowDown";
|
||||
if (up || down) {
|
||||
let focused = document.activeElement.closest(".search-menu")
|
||||
? document.activeElement
|
||||
: null;
|
||||
|
||||
if (!focused) {
|
||||
return;
|
||||
}
|
||||
|
||||
let links = document.querySelectorAll(".search-menu .results a");
|
||||
let results = document.querySelectorAll(
|
||||
".search-menu .results .search-link"
|
||||
);
|
||||
|
||||
if (!results.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
let prevResult;
|
||||
let result;
|
||||
|
||||
links.forEach((item) => {
|
||||
if (item.classList.contains("search-link")) {
|
||||
prevResult = item;
|
||||
}
|
||||
|
||||
if (item === focused) {
|
||||
result = prevResult;
|
||||
}
|
||||
});
|
||||
|
||||
let index = -1;
|
||||
|
||||
if (result) {
|
||||
index = Array.prototype.indexOf.call(results, result);
|
||||
}
|
||||
|
||||
if (index === -1 && down) {
|
||||
document.querySelector(".search-menu .results .search-link").focus();
|
||||
} else if (index === 0 && up) {
|
||||
document.querySelector(".search-menu input#search-term").focus();
|
||||
} else if (index > -1) {
|
||||
index += down ? 1 : -1;
|
||||
if (index >= 0 && index < results.length) {
|
||||
results[index].focus();
|
||||
}
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
const searchInput = document.querySelector("#search-term");
|
||||
if (e.key === "Enter" && e.target === searchInput) {
|
||||
const recentEnterHit =
|
||||
this.state._lastEnterTimestamp &&
|
||||
Date.now() - this.state._lastEnterTimestamp < SECOND_ENTER_MAX_DELAY;
|
||||
|
||||
// same combination as key-enter-escape mixin
|
||||
if (
|
||||
e.ctrlKey ||
|
||||
e.metaKey ||
|
||||
(isiPad() && e.altKey) ||
|
||||
(searchData.typeFilter !== DEFAULT_TYPE_FILTER && recentEnterHit)
|
||||
) {
|
||||
this.fullSearch();
|
||||
} else {
|
||||
searchData.typeFilter = null;
|
||||
this.triggerSearch();
|
||||
}
|
||||
this.state._lastEnterTimestamp = Date.now();
|
||||
}
|
||||
|
||||
if (e.target === searchInput && e.key === "Backspace") {
|
||||
if (!searchInput.value) {
|
||||
this.clearTopicContext();
|
||||
this.clearPMInboxContext();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
triggerSearch() {
|
||||
searchData.noResults = false;
|
||||
if (SearchHelper.includesTopics()) {
|
||||
if (this.state.inTopicContext) {
|
||||
this.search.set("highlightTerm", searchData.term);
|
||||
}
|
||||
|
||||
searchData.loading = true;
|
||||
cancel(this.state._debouncer);
|
||||
SearchHelper.perform(this);
|
||||
if (this.currentUser) {
|
||||
updateRecentSearches(this.currentUser, searchData.term);
|
||||
}
|
||||
} else {
|
||||
searchData.loading = false;
|
||||
if (!this.state.inTopicContext) {
|
||||
this.state._debouncer = discourseDebounce(
|
||||
SearchHelper,
|
||||
SearchHelper.perform,
|
||||
this,
|
||||
400
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
moreOfType(type) {
|
||||
searchData.typeFilter = type;
|
||||
this.triggerSearch();
|
||||
},
|
||||
|
||||
searchTermChanged(term, opts = {}) {
|
||||
searchData.typeFilter = opts.searchTopics ? null : DEFAULT_TYPE_FILTER;
|
||||
searchData.term = term;
|
||||
this.triggerSearch();
|
||||
},
|
||||
|
||||
triggerAutocomplete(opts = {}) {
|
||||
if (opts.setTopicContext) {
|
||||
this.sendWidgetAction("setTopicContext");
|
||||
this.state.inTopicContext = true;
|
||||
}
|
||||
this.searchTermChanged(opts.value, { searchTopics: opts.searchTopics });
|
||||
},
|
||||
|
||||
fullSearch() {
|
||||
searchData.loading = false;
|
||||
SearchHelper.cancel();
|
||||
const url = this.fullSearchUrl();
|
||||
if (url) {
|
||||
this.sendWidgetEvent("linkClicked");
|
||||
DiscourseURL.routeTo(url);
|
||||
}
|
||||
},
|
||||
|
||||
searchContext() {
|
||||
if (this.state.inTopicContext || this.state.inPMInboxContext) {
|
||||
return this.search.searchContext;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
});
|
||||
|
||||
createWidget("browser-search-tip", {
|
||||
buildKey: () => "browser-search-tip",
|
||||
tagName: "div.browser-search-tip",
|
||||
|
||||
html() {
|
||||
return [
|
||||
h(
|
||||
"span.tip-label",
|
||||
I18n.t("search.browser_tip", {
|
||||
modifier: translateModKey("Meta"),
|
||||
})
|
||||
),
|
||||
h("span.tip-description", I18n.t("search.browser_tip_description")),
|
||||
];
|
||||
},
|
||||
});
|
|
@ -1,50 +0,0 @@
|
|||
import { click, fillIn, visit } from "@ember/test-helpers";
|
||||
import { test } from "qunit";
|
||||
import {
|
||||
acceptance,
|
||||
count,
|
||||
exists,
|
||||
query,
|
||||
} from "discourse/tests/helpers/qunit-helpers";
|
||||
|
||||
acceptance("Search - Glimmer - Mobile", function (needs) {
|
||||
needs.mobileView();
|
||||
|
||||
test("search", async function (assert) {
|
||||
await visit("/");
|
||||
|
||||
await click("#search-button");
|
||||
|
||||
assert.ok(
|
||||
exists("input.full-page-search"),
|
||||
"it shows the full page search form"
|
||||
);
|
||||
|
||||
assert.ok(!exists(".search-results .fps-topic"), "no results by default");
|
||||
|
||||
await click(".advanced-filters summary");
|
||||
|
||||
assert.ok(
|
||||
exists(".advanced-filters[open]"),
|
||||
"it should expand advanced search filters"
|
||||
);
|
||||
|
||||
await fillIn(".search-query", "discourse");
|
||||
await click(".search-cta");
|
||||
|
||||
assert.strictEqual(count(".fps-topic"), 1, "has one post");
|
||||
|
||||
assert.notOk(
|
||||
exists(".advanced-filters[open]"),
|
||||
"it should collapse advanced search filters"
|
||||
);
|
||||
|
||||
await click("#search-button");
|
||||
|
||||
assert.strictEqual(
|
||||
query("input.full-page-search").value,
|
||||
"discourse",
|
||||
"it does not reset input when hitting search icon again"
|
||||
);
|
||||
});
|
||||
});
|
|
@ -47,24 +47,4 @@ acceptance("Search - Mobile", function (needs) {
|
|||
"it does not reset input when hitting search icon again"
|
||||
);
|
||||
});
|
||||
|
||||
test("Search context in full page search", async function (assert) {
|
||||
await visit("/search?context=tag&context_id=dev&skip_context=true");
|
||||
|
||||
assert.ok(exists(".search-header .search-context"));
|
||||
|
||||
assert.strictEqual(
|
||||
query(".search-header .search-context input[type='checkbox']").checked,
|
||||
false,
|
||||
"checkbox matches query parameter"
|
||||
);
|
||||
|
||||
await click(".search-header .search-context label");
|
||||
|
||||
assert.strictEqual(
|
||||
query(".search-header .search-context input[type='checkbox']").checked,
|
||||
true,
|
||||
"checkbox toggling works"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -19,7 +19,7 @@ import {
|
|||
import selectKit from "discourse/tests/helpers/select-kit-helper";
|
||||
import I18n from "discourse-i18n";
|
||||
|
||||
acceptance("Search - Glimmer - Anonymous", function (needs) {
|
||||
acceptance("Search - Anonymous", function (needs) {
|
||||
needs.pretender((server, helper) => {
|
||||
server.get("/search/query", (request) => {
|
||||
if (request.queryParams.type_filter === DEFAULT_TYPE_FILTER) {
|
||||
|
@ -431,7 +431,7 @@ acceptance("Search - Glimmer - Anonymous", function (needs) {
|
|||
});
|
||||
});
|
||||
|
||||
acceptance("Search - Glimmer - Authenticated", function (needs) {
|
||||
acceptance("Search - Authenticated", function (needs) {
|
||||
needs.user();
|
||||
needs.settings({
|
||||
log_search_queries: true,
|
||||
|
@ -741,7 +741,7 @@ acceptance("Search - Glimmer - Authenticated", function (needs) {
|
|||
});
|
||||
});
|
||||
|
||||
acceptance("Search - Glimmer - with tagging enabled", function (needs) {
|
||||
acceptance("Search - with tagging enabled", function (needs) {
|
||||
needs.user();
|
||||
needs.settings({ tagging_enabled: true });
|
||||
needs.pretender((server, helper) => {
|
||||
|
@ -923,7 +923,7 @@ acceptance("Search - Glimmer - with tagging enabled", function (needs) {
|
|||
});
|
||||
});
|
||||
|
||||
acceptance("Search - Glimmer - assistant", function (needs) {
|
||||
acceptance("Search - assistant", function (needs) {
|
||||
needs.user();
|
||||
needs.pretender((server, helper) => {
|
||||
server.get("/t/2179.json", () => {
|
|
@ -22,6 +22,7 @@ import { clearBulkButtons } from "discourse/components/modal/topic-bulk-actions"
|
|||
import { resetWidgetCleanCallbacks } from "discourse/components/mount-widget";
|
||||
import { resetDecorators as resetPluginOutletDecorators } from "discourse/components/plugin-connector";
|
||||
import { resetItemSelectCallbacks } from "discourse/components/search-menu/results/assistant-item";
|
||||
import { resetQuickSearchRandomTips } from "discourse/components/search-menu/results/random-quick-tip";
|
||||
import { resetOnKeyUpCallbacks } from "discourse/components/search-menu/search-term";
|
||||
import { resetTopicTitleDecorators } from "discourse/components/topic-title";
|
||||
import { resetUserMenuProfileTabItems } from "discourse/components/user-menu/profile-tab-content";
|
||||
|
@ -84,11 +85,6 @@ import {
|
|||
import { clearExtraHeaderIcons } from "discourse/widgets/header";
|
||||
import { resetDecorators as resetPostCookedDecorators } from "discourse/widgets/post-cooked";
|
||||
import { resetPostMenuExtraButtons } from "discourse/widgets/post-menu";
|
||||
import {
|
||||
initSearchData,
|
||||
resetOnKeyDownCallbacks,
|
||||
} from "discourse/widgets/search-menu";
|
||||
import { resetQuickSearchRandomTips } from "discourse/widgets/search-menu-results";
|
||||
import { resetDecorators } from "discourse/widgets/widget";
|
||||
import deprecated from "discourse-common/lib/deprecated";
|
||||
import { getOwnerWithFallback } from "discourse-common/lib/get-owner";
|
||||
|
@ -188,7 +184,6 @@ export function testCleanup(container, app) {
|
|||
clearOutletCache();
|
||||
clearHTMLCache();
|
||||
clearRewrites();
|
||||
initSearchData();
|
||||
resetDecorators();
|
||||
resetPostCookedDecorators();
|
||||
resetPluginOutletDecorators();
|
||||
|
@ -229,7 +224,6 @@ export function testCleanup(container, app) {
|
|||
resetNotificationTypeRenderers();
|
||||
resetSidebarPanels();
|
||||
clearExtraHeaderIcons();
|
||||
resetOnKeyDownCallbacks();
|
||||
resetOnKeyUpCallbacks();
|
||||
resetItemSelectCallbacks();
|
||||
resetUserMenuTabs();
|
||||
|
|
|
@ -10,7 +10,7 @@ import { exists, query } from "discourse/tests/helpers/qunit-helpers";
|
|||
import I18n from "discourse-i18n";
|
||||
|
||||
// Note this isn't a full-fledge test of the search menu. Those tests are in
|
||||
// acceptance/glimmer-search-test.js. This is simply about the rendering of the
|
||||
// acceptance/search-test.js. This is simply about the rendering of the
|
||||
// menu panel separate from the search input.
|
||||
module("Integration | Component | search-menu", function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
|
|
@ -130,11 +130,40 @@ $search-pad-horizontal: 0.5em;
|
|||
}
|
||||
|
||||
.search-result-group .group-result,
|
||||
.search-result-user .user-result {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: var(--font-down-1);
|
||||
.search-result-user {
|
||||
.search-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
img.avatar {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.user-titles {
|
||||
@include user-item-flex;
|
||||
|
||||
.name {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.username,
|
||||
.name,
|
||||
.custom-field {
|
||||
color: var(--primary-high-or-secondary-low);
|
||||
}
|
||||
|
||||
.custom-field {
|
||||
font-size: var(--font-down-2);
|
||||
}
|
||||
}
|
||||
.user-result {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: var(--font-down-1);
|
||||
}
|
||||
}
|
||||
|
||||
.search-result-group .group-result {
|
||||
.d-icon,
|
||||
.avatar-flair {
|
||||
|
@ -171,31 +200,6 @@ $search-pad-horizontal: 0.5em;
|
|||
}
|
||||
}
|
||||
|
||||
.search-result-user .user-result {
|
||||
.user-titles {
|
||||
@include user-item-flex;
|
||||
|
||||
.username,
|
||||
.name {
|
||||
@include ellipsis;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.username,
|
||||
.name,
|
||||
.custom-field {
|
||||
color: var(--primary-high-or-secondary-low);
|
||||
}
|
||||
|
||||
.custom-field {
|
||||
font-size: var(--font-down-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search-result-category,
|
||||
.search-result-tag {
|
||||
+ .search-result-user,
|
||||
|
@ -205,10 +209,18 @@ $search-pad-horizontal: 0.5em;
|
|||
}
|
||||
|
||||
.search-result-user .user-result img.avatar,
|
||||
.search-item-user img.avatar {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 0.5em;
|
||||
.search-item-user {
|
||||
display: flex;
|
||||
align-self: center;
|
||||
|
||||
img.avatar {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
.username {
|
||||
margin-right: 0.33em;
|
||||
}
|
||||
}
|
||||
|
||||
.label-suffix {
|
||||
|
@ -218,6 +230,10 @@ $search-pad-horizontal: 0.5em;
|
|||
|
||||
.search-item-tag {
|
||||
color: var(--primary-high);
|
||||
|
||||
.d-icon {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.extra-hint {
|
||||
|
@ -377,55 +393,3 @@ $search-pad-horizontal: 0.5em;
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// these styles will become the default once the glimmer search menu
|
||||
// is enabled for all users, and the old search menu is removed
|
||||
// we can then drop any '!important' rules
|
||||
.search-menu.glimmer-search-menu {
|
||||
.search-item-tag .d-icon {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
|
||||
.search-item-user {
|
||||
display: flex;
|
||||
align-self: center;
|
||||
|
||||
.username {
|
||||
margin-right: 0.33em;
|
||||
}
|
||||
}
|
||||
|
||||
.search-result-user {
|
||||
.search-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
img.avatar {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.user-titles {
|
||||
@include user-item-flex;
|
||||
|
||||
.username,
|
||||
.name {
|
||||
@include ellipsis;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.username,
|
||||
.name,
|
||||
.custom-field {
|
||||
color: var(--primary-high-or-secondary-low);
|
||||
}
|
||||
|
||||
.custom-field {
|
||||
font-size: var(--font-down-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2323,10 +2323,6 @@ developer:
|
|||
experimental_topics_filter:
|
||||
client: true
|
||||
default: false
|
||||
experimental_search_menu:
|
||||
client: true
|
||||
hidden: true
|
||||
default: true
|
||||
max_sidebar_section_links:
|
||||
default: 50
|
||||
hidden: true
|
||||
|
|
Loading…
Reference in New Issue