mirror of https://github.com/zulip/zulip.git
parent
ea619ff75f
commit
cb04ae1f95
|
@ -158,6 +158,7 @@ EXEMPT_FILES = make_set(
|
|||
"web/src/scheduled_messages_overlay_ui.js",
|
||||
"web/src/scroll_bar.ts",
|
||||
"web/src/scroll_util.ts",
|
||||
"web/src/search.js",
|
||||
"web/src/sent_messages.js",
|
||||
"web/src/sentry.ts",
|
||||
"web/src/server_events.js",
|
||||
|
|
|
@ -143,7 +143,7 @@ async function search_and_check(
|
|||
expected_narrow_title: string,
|
||||
): Promise<void> {
|
||||
await page.click(".search_icon");
|
||||
await page.waitForSelector("#search_query", {visible: true});
|
||||
await page.waitForSelector(".navbar-search.expanded", {visible: true});
|
||||
await common.select_item_via_typeahead(page, "#search_query", search_str, item_to_select);
|
||||
await check(page);
|
||||
assert.strictEqual(await page.title(), expected_narrow_title);
|
||||
|
@ -153,7 +153,7 @@ async function search_and_check(
|
|||
|
||||
async function search_silent_user(page: Page, str: string, item: string): Promise<void> {
|
||||
await page.click(".search_icon");
|
||||
await page.waitForSelector("#search_query", {visible: true});
|
||||
await page.waitForSelector(".navbar-search.expanded", {visible: true});
|
||||
await common.select_item_via_typeahead(page, "#search_query", str, item);
|
||||
await page.waitForSelector(".empty_feed_notice", {visible: true});
|
||||
const expect_message = "You haven't received any messages sent by Email Gateway yet.";
|
||||
|
@ -185,7 +185,7 @@ async function expect_non_existing_users(page: Page): Promise<void> {
|
|||
|
||||
async function search_non_existing_user(page: Page, str: string, item: string): Promise<void> {
|
||||
await page.click(".search_icon");
|
||||
await page.waitForSelector("#search_query", {visible: true});
|
||||
await page.waitForSelector(".navbar-search.expanded", {visible: true});
|
||||
await common.select_item_via_typeahead(page, "#search_query", str, item);
|
||||
await expect_non_existing_user(page);
|
||||
await un_narrow(page);
|
||||
|
|
|
@ -9,7 +9,6 @@ import * as peer_data from "./peer_data";
|
|||
import * as popovers from "./popovers";
|
||||
import * as recent_view_util from "./recent_view_util";
|
||||
import * as rendered_markdown from "./rendered_markdown";
|
||||
import * as search from "./search";
|
||||
|
||||
function get_formatted_sub_count(sub_count) {
|
||||
if (sub_count >= 1000) {
|
||||
|
@ -94,65 +93,35 @@ function append_and_display_title_area(message_view_header_data) {
|
|||
}
|
||||
}
|
||||
|
||||
function bind_title_area_handlers() {
|
||||
$(".search_closed").on("click", (e) => {
|
||||
popovers.hide_all();
|
||||
search.initiate_search();
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
$("#message_view_header .navbar-click-opens-search").on("click", (e) => {
|
||||
popovers.hide_all();
|
||||
|
||||
if (document.getSelection().type === "Range") {
|
||||
// Allow copy/paste to work normally without interference.
|
||||
return;
|
||||
}
|
||||
|
||||
// Let links behave normally, ie, do nothing if <a>
|
||||
if ($(e.target).closest("a").length === 0) {
|
||||
search.initiate_search();
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
});
|
||||
|
||||
// handler that makes sure that hover plays nicely
|
||||
// with whether search is being opened or not.
|
||||
$("#message_view_header .narrow_description > a")
|
||||
.on("mouseenter", () => {
|
||||
$("#message_view_header .search_closed").css("opacity", 0.5);
|
||||
})
|
||||
.on("mouseleave", () => {
|
||||
$("#message_view_header .search_closed").css("opacity", "");
|
||||
});
|
||||
}
|
||||
|
||||
function build_message_view_header(filter) {
|
||||
// This makes sure we don't waste time appending
|
||||
// message_view_header on a template where it's never used
|
||||
if (filter && !filter.is_common_narrow()) {
|
||||
open_search_bar_and_close_narrow_description();
|
||||
$("#search_query").val(narrow_state.search_string());
|
||||
} else {
|
||||
const message_view_header_data = make_message_view_header(filter);
|
||||
append_and_display_title_area(message_view_header_data);
|
||||
bind_title_area_handlers();
|
||||
close_search_bar_and_open_narrow_description();
|
||||
}
|
||||
}
|
||||
|
||||
// This is what the default searchbox text would be for this narrow,
|
||||
// NOT what might be currently displayed there. We can use this both
|
||||
// to set the initial text and to see if the user has changed it.
|
||||
export function get_initial_search_string() {
|
||||
let search_string = narrow_state.search_string();
|
||||
if (search_string !== "" && !narrow_state.filter().is_search()) {
|
||||
// saves the user a keystroke for quick searches
|
||||
search_string = search_string + " ";
|
||||
}
|
||||
return search_string;
|
||||
}
|
||||
|
||||
// we rely entirely on this function to ensure
|
||||
// the searchbar has the right text.
|
||||
export function reset_searchbox_text() {
|
||||
let search_string = narrow_state.search_string();
|
||||
if (search_string !== "") {
|
||||
if (!narrow_state.filter().is_search()) {
|
||||
// saves the user a keystroke for quick searches
|
||||
search_string = search_string + " ";
|
||||
}
|
||||
$("#search_query").val(search_string);
|
||||
}
|
||||
$("#search_query").val(get_initial_search_string());
|
||||
}
|
||||
|
||||
export function exit_search() {
|
||||
|
@ -164,6 +133,7 @@ export function exit_search() {
|
|||
// for "searching narrows", we redirect
|
||||
window.location.href = filter.generate_redirect_url();
|
||||
}
|
||||
$("#search_query").trigger("blur");
|
||||
$(".app").trigger("focus");
|
||||
}
|
||||
|
||||
|
@ -177,6 +147,24 @@ export function initialize() {
|
|||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
});
|
||||
$("#search_exit").on("blur", (e) => {
|
||||
// Blurs that move focus to elsewhere within the search input shouldn't
|
||||
// close search.
|
||||
if ($(e.relatedTarget).parents("#searchbox-input-container").length > 0) {
|
||||
return;
|
||||
}
|
||||
// But otherwise, it should behave like the input blurring.
|
||||
$("#search_query").trigger("blur");
|
||||
});
|
||||
// This prevents a bug where tab shows a visual change before the blur handler kicks in
|
||||
$("#search_exit").on("keydown", (e) => {
|
||||
if (e.key === "tab") {
|
||||
popovers.hide_all();
|
||||
exit_search();
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function render_title_area() {
|
||||
|
@ -195,12 +183,23 @@ export function maybe_rerender_title_area_for_stream(modified_sub) {
|
|||
}
|
||||
|
||||
export function open_search_bar_and_close_narrow_description() {
|
||||
reset_searchbox_text();
|
||||
// Preserve user input if they've already started typing, but
|
||||
// otherwise fill the input field with the text operators for
|
||||
// the current narrow.
|
||||
if ($("#search_query").val() === "") {
|
||||
reset_searchbox_text();
|
||||
}
|
||||
$(".navbar-search").addClass("expanded");
|
||||
$("#message_view_header").addClass("hidden");
|
||||
}
|
||||
|
||||
export function close_search_bar_and_open_narrow_description() {
|
||||
// Hide the dropdown before closing the search bar. We do this
|
||||
// to avoid being in a situation where the typeahead gets narrow
|
||||
// in width as the search bar closes, which doesn't look great.
|
||||
$("#searchbox_form .dropdown-menu").hide();
|
||||
|
||||
$("#search_query").val("");
|
||||
const filter = narrow_state.filter();
|
||||
if (!filter || filter.is_common_narrow()) {
|
||||
$(".navbar-search").removeClass("expanded");
|
||||
|
|
|
@ -51,7 +51,7 @@ export function initialize({on_narrow_search}) {
|
|||
search_map = suggestions.lookup_table;
|
||||
return suggestions.strings;
|
||||
},
|
||||
parentElement: "#searchbox",
|
||||
parentElement: "#searchbox_form",
|
||||
items: search_suggestion.max_num_of_search_results,
|
||||
helpOnEmptyStrings: true,
|
||||
naturalSearch: true,
|
||||
|
@ -73,7 +73,19 @@ export function initialize({on_narrow_search}) {
|
|||
// Use our custom typeahead `on_escape` hook to exit
|
||||
// the search bar as soon as the user hits Esc.
|
||||
on_escape: message_view_header.exit_search,
|
||||
tabIsEnter: false,
|
||||
openInputFieldOnKeyUp() {
|
||||
if ($(".navbar-search.expanded").length === 0) {
|
||||
message_view_header.open_search_bar_and_close_narrow_description();
|
||||
}
|
||||
},
|
||||
closeInputFieldOnHide() {
|
||||
// Don't close the search bar if the user has changed
|
||||
// the text from the default, they might accidentally
|
||||
// click away and not want to lose it.
|
||||
if (message_view_header.get_initial_search_string() !== $("#search_query").val()) {
|
||||
return;
|
||||
}
|
||||
const filter = narrow_state.filter();
|
||||
if (!filter || filter.is_common_narrow()) {
|
||||
message_view_header.close_search_bar_and_open_narrow_description();
|
||||
|
@ -118,11 +130,40 @@ export function initialize({on_narrow_search}) {
|
|||
$search_query_box.trigger("blur");
|
||||
}
|
||||
});
|
||||
|
||||
// We don't want to make this a focus handler because selecting the
|
||||
// typehead seems to trigger this (and we don't want to open search
|
||||
// when an option is selected and we're closing search).
|
||||
// Instead we explicitly initiate search on click and on specific keyboard
|
||||
// shortcuts.
|
||||
$search_query_box.on("click", initiate_search);
|
||||
|
||||
$(".search_icon").on("mousedown", (e) => {
|
||||
e.preventDefault();
|
||||
// Clicking on the collapsed search box's icon opens search, but
|
||||
// clicking on the expanded search box's search icon does nothing.
|
||||
if ($(e.target).parents(".navbar-search.expanded").length === 0) {
|
||||
initiate_search();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function initiate_search() {
|
||||
message_view_header.open_search_bar_and_close_narrow_description();
|
||||
$("#search_query").typeahead("lookup").trigger("select");
|
||||
const search_bar_already_open = $(".navbar-search.expanded").length > 0;
|
||||
if (!search_bar_already_open) {
|
||||
message_view_header.open_search_bar_and_close_narrow_description();
|
||||
}
|
||||
|
||||
// Open the typeahead after opening the search bar, so that we don't
|
||||
// get a weird visual jump where the typeahead results are narrow
|
||||
// before the search bar expands and then wider it expands.
|
||||
if (!$("#searchbox .dropdown-menu").is(":visible")) {
|
||||
$("#search_query").typeahead("lookup");
|
||||
}
|
||||
|
||||
if (!search_bar_already_open) {
|
||||
$("#search_query").typeahead("lookup").trigger("select");
|
||||
}
|
||||
}
|
||||
|
||||
export function clear_search_form() {
|
||||
|
|
|
@ -476,7 +476,6 @@
|
|||
.pill-container,
|
||||
.user-status-content-wrapper,
|
||||
#custom-expiration-time-input,
|
||||
#searchbox #search_query,
|
||||
#org-join-settings .dropdown-widget-button {
|
||||
background-color: hsl(0deg 0% 0% / 20%);
|
||||
border-color: hsl(0deg 0% 0% / 60%);
|
||||
|
@ -519,19 +518,21 @@
|
|||
background-color: hsl(0deg 0% 0% / 20%);
|
||||
}
|
||||
|
||||
#searchbox-input-container .pill,
|
||||
#compose-direct-recipient.pill-container .pill {
|
||||
color: inherit;
|
||||
border: 1px solid hsl(0deg 0% 0% / 50%);
|
||||
background-color: hsl(0deg 0% 0% / 25%);
|
||||
font-weight: 600;
|
||||
}
|
||||
#searchbox {
|
||||
/* Light theme shows hover mostly through box-shadow,
|
||||
and dark theme shows it mostly through changing color
|
||||
of the search button. */
|
||||
.navbar-search:not(.expanded)
|
||||
#searchbox-input-container:hover
|
||||
.search_icon {
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
#searchbox-input-container .pill:focus,
|
||||
#compose-direct-recipient.pill-container .pill:focus {
|
||||
color: hsl(0deg 0% 100%);
|
||||
border: 1px solid hsl(176deg 78% 28% / 60%);
|
||||
background-color: hsl(176deg 49% 42% / 40%);
|
||||
/* Colors are inherited in light theme */
|
||||
.navbar-search .search_icon,
|
||||
.navbar-search .search_close_button {
|
||||
color: hsl(0deg 0% 78%);
|
||||
}
|
||||
}
|
||||
|
||||
.new-style .button.no-style {
|
||||
|
@ -670,6 +671,11 @@
|
|||
background-color: hsl(212deg 32% 14%);
|
||||
}
|
||||
|
||||
/* Undo default dropdown background color for dark mode. */
|
||||
#searchbox_form .dropdown-menu ul {
|
||||
background-color: unset;
|
||||
}
|
||||
|
||||
.dropdown-menu a {
|
||||
color: inherit;
|
||||
}
|
||||
|
|
|
@ -2,112 +2,51 @@
|
|||
width: 100%;
|
||||
height: var(--header-height);
|
||||
|
||||
.navbar-search:not(.expanded) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.navbar-search.expanded {
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
width: calc(100% - 2px);
|
||||
.navbar-search {
|
||||
margin: 5.5px 0;
|
||||
border-radius: 5px;
|
||||
position: absolute;
|
||||
|
||||
@media (width < $md_min) {
|
||||
width: calc(100% - 42px);
|
||||
}
|
||||
|
||||
.search_close_button {
|
||||
display: inline;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.zulip-icon-close {
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.typeahead.dropdown-menu {
|
||||
/* Match the typeahead's width to its parent container. */
|
||||
right: 0;
|
||||
|
||||
@media (width < $md_min) {
|
||||
margin-left: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.input-append {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
width: max-content;
|
||||
min-width: 100%;
|
||||
|
||||
.zulip-icon-search {
|
||||
padding: 0;
|
||||
font-size: 20px;
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 10px;
|
||||
z-index: 5;
|
||||
|
||||
@media (width < $sm_min) {
|
||||
top: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.zulip-icon-search:not(.deactivated) {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
#search_query {
|
||||
width: 100%;
|
||||
font-size: 16px;
|
||||
height: calc(var(--header-height) - 1px);
|
||||
min-height: 30px;
|
||||
padding: 0;
|
||||
padding-right: 40px;
|
||||
.search_icon {
|
||||
text-decoration: none;
|
||||
padding: 0 7px;
|
||||
font-size: 17px;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
font-family: "Source Sans 3 VF", sans-serif;
|
||||
font-weight: 300;
|
||||
line-height: var(--header-height);
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
padding-left: 35px;
|
||||
color: hsl(0deg 0% 33%);
|
||||
background-color: transparent;
|
||||
color: hsl(0deg 0% 0%);
|
||||
opacity: 0.5;
|
||||
cursor: default;
|
||||
|
||||
&:active,
|
||||
&:focus {
|
||||
outline: 0;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
@media (width < $sm_min) {
|
||||
vertical-align: text-bottom;
|
||||
&:disabled {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
#searchbox-input-container:focus {
|
||||
box-shadow: inset 0 0 0 2px hsl(204deg 20% 74%);
|
||||
}
|
||||
|
||||
.search_close_button {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 6px;
|
||||
width: 28px;
|
||||
height: 100%;
|
||||
background: none;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
height: 30px;
|
||||
text-align: center;
|
||||
padding: 4px;
|
||||
color: inherit;
|
||||
opacity: 0.5;
|
||||
font-size: 18px;
|
||||
box-shadow: none;
|
||||
text-shadow: none;
|
||||
z-index: 5;
|
||||
line-height: 0;
|
||||
border-radius: 4px;
|
||||
/* Leave room for the focus outline. */
|
||||
margin-right: 1px;
|
||||
|
||||
&:focus {
|
||||
/* Reduce height to leave 1px on top and bottom for the outline. */
|
||||
height: calc(100% - 2px);
|
||||
}
|
||||
|
||||
&:not(:focus-visible) {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
|
@ -116,36 +55,194 @@
|
|||
&:disabled {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.zulip-icon-close {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.navbar-search:not(.expanded) {
|
||||
right: 0;
|
||||
|
||||
.search_close_button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#searchbox-input-container {
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
border-radius: 5px;
|
||||
color: var(--color-text-search);
|
||||
|
||||
box-shadow: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
|
||||
@media (width >= $md_min) {
|
||||
box-shadow:
|
||||
0 4px 20px var(--color-search-box-hover-shadow),
|
||||
0 1px 5px var(--color-search-box-hover-shadow);
|
||||
}
|
||||
|
||||
.search_icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < $md_min) {
|
||||
#searchbox-input-container {
|
||||
/* On small screens, the input container/button becomes just
|
||||
an icon. Width is to match the width of nearby buttons. */
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.search-query {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < $sm_min) {
|
||||
top: 0;
|
||||
#searchbox-input-container .search_icon {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search_icon {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
text-decoration: none;
|
||||
padding: 0 10px;
|
||||
font-size: 20px;
|
||||
z-index: 5;
|
||||
left: 0;
|
||||
.navbar-search.expanded {
|
||||
width: 100%;
|
||||
box-shadow:
|
||||
0 4px 20px var(--color-search-shadow-wide),
|
||||
0 1px 5px var(--color-search-shadow-tight);
|
||||
|
||||
@media (width < $md_min) {
|
||||
/* 3px chosen so that the cursor clicks the search button
|
||||
and close button from the same position. */
|
||||
width: calc(100% - 3px);
|
||||
/* z-index to not see the gear icon underneath */
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.typeahead.dropdown-menu {
|
||||
/* Match the typeahead's width to its parent container. */
|
||||
right: 0;
|
||||
top: 0;
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
box-shadow: none;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
background: var(--color-background-search);
|
||||
color: var(--color-text-search);
|
||||
|
||||
border-width: 0;
|
||||
border-top-width: 1px;
|
||||
border-top-color: var(--color-search-dropdown-top-border);
|
||||
border-radius: 0 0 4px 4px;
|
||||
|
||||
.active > a {
|
||||
background-color: var(--color-background-search-option-hover);
|
||||
background-image: none;
|
||||
color: var(--color-text-search-hover);
|
||||
}
|
||||
}
|
||||
|
||||
.input-append {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.search-query {
|
||||
font-size: 14px;
|
||||
/* override bootstrap padding for input[type="text"] */
|
||||
padding: 0;
|
||||
border: none;
|
||||
outline: none;
|
||||
border-radius: 0;
|
||||
font-family: "Source Sans 3 VF", sans-serif;
|
||||
font-weight: 400;
|
||||
height: var(--search-box-height);
|
||||
/* override bootstrap min-height for input[type="text"] */
|
||||
min-height: var(--search-box-height);
|
||||
background: transparent;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
flex-grow: 1;
|
||||
|
||||
color: var(--color-text-search);
|
||||
|
||||
&::placeholder {
|
||||
color: var(--color-text-search-placeholder);
|
||||
}
|
||||
}
|
||||
|
||||
#searchbox-input-container {
|
||||
font-size: 90%;
|
||||
letter-spacing: normal;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.typeahead-menu li a {
|
||||
.search_list_item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
/* override .input-append style from app_components.js */
|
||||
letter-spacing: normal;
|
||||
height: var(--search-box-height);
|
||||
}
|
||||
|
||||
.search_list_item .pill-container {
|
||||
margin-left: 5px;
|
||||
@media (width >= $md_min) {
|
||||
.navbar-search {
|
||||
background: var(--color-background-search);
|
||||
}
|
||||
|
||||
.navbar-search:not(.expanded) {
|
||||
box-shadow: 0 0 2px var(--color-search-box-hover-shadow);
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < $md_min) {
|
||||
.navbar-search:not(.expanded) .search_icon:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.navbar-search.expanded {
|
||||
background: var(--color-background-search);
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < $sm_min) {
|
||||
#searchbox_form {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#searchbox_form.expanded {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 9px;
|
||||
width: 100%;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
/* To be visible over `#streamlist-toggle-unreadcount`
|
||||
and `#userlist-toggle-unreadcount`. */
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.typeahead.dropdown-menu {
|
||||
box-shadow: 0 1px 5px var(--color-search-shadow-wide);
|
||||
}
|
||||
}
|
||||
|
||||
.typeahead-menu li a {
|
||||
padding: 3px 30px;
|
||||
|
||||
.search_list_item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.search_list_item .pill-container {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,6 +57,17 @@ body {
|
|||
--header-height: 30px;
|
||||
}
|
||||
|
||||
/*
|
||||
Height of the search box, which appears in the header.
|
||||
On very small screens, the search box's height becomes
|
||||
the height of its parent (i.e. the header height).
|
||||
*/
|
||||
--search-box-height: 28px;
|
||||
|
||||
@media (width < $sm_min) {
|
||||
--search-box-height: var(--header-height);
|
||||
}
|
||||
|
||||
/*
|
||||
Since #navbar_alerts_wrapper can take variable height depending upon
|
||||
window width / language, we sync its height in navbar_alerts.js
|
||||
|
@ -156,7 +167,7 @@ body {
|
|||
--color-message-header-icon-interactive: hsl(0deg 0% 0%);
|
||||
--color-background: hsl(0deg 0% 94%);
|
||||
--color-background-widget-input: hsl(0deg 0% 100%);
|
||||
--color-background-navbar: hsl(0deg 0% 96%);
|
||||
--color-background-navbar: hsl(0deg 0% 97%);
|
||||
--color-background-active-narrow-filter: hsl(202deg 56% 91%);
|
||||
--color-background-hover-narrow-filter: hsl(120deg 12.3% 71.4% / 38%);
|
||||
--color-navbar-bottom-border: hsl(0deg 0% 80%);
|
||||
|
@ -165,6 +176,12 @@ body {
|
|||
--color-background-modal: hsl(0deg 0% 98%);
|
||||
--color-unmuted-or-followed-topic-list-item: hsl(0deg 0% 20%);
|
||||
--color-outline-focus: hsl(215deg 47% 50%);
|
||||
--color-background-search: hsl(0deg 0% 100%);
|
||||
--color-background-search-option-hover: hsl(0deg 0% 94%);
|
||||
--color-search-box-hover-shadow: hsl(0deg 0% 0% / 10%);
|
||||
--color-search-shadow-wide: hsl(0deg 0% 0% / 25%);
|
||||
--color-search-shadow-tight: hsl(0deg 0% 0% / 10%);
|
||||
--color-search-dropdown-top-border: hsla(0deg 0% 0% / 10%);
|
||||
|
||||
/* Text colors */
|
||||
--color-text-default: hsl(0deg 0% 20%);
|
||||
|
@ -175,6 +192,9 @@ body {
|
|||
--color-text-self-direct-mention: hsl(240deg 52% 45% / 100%);
|
||||
--color-text-self-group-mention: hsl(183deg 52% 26% / 100%);
|
||||
--color-text-show-more-less-button: hsl(240deg 52% 53%);
|
||||
--color-text-search: hsl(0deg 0% 35%);
|
||||
--color-text-search-hover: hsl(0deg 0% 0%);
|
||||
--color-text-search-placeholder: hsl(0deg 0% 50%);
|
||||
|
||||
/* Icon colors */
|
||||
--color-icon-bot: hsl(180deg 8% 65% / 100%);
|
||||
|
@ -248,6 +268,10 @@ body {
|
|||
--color-background-modal: hsl(212deg 28% 18%);
|
||||
--color-unmuted-or-followed-topic-list-item: hsl(236deg 33% 90%);
|
||||
--color-recipient-bar-controls-spinner: hsl(0deg 0% 100%);
|
||||
--color-background-search: hsl(0deg 0% 20%);
|
||||
--color-background-search-option-hover: hsl(0deg 0% 30%);
|
||||
--color-search-box-hover-shadow: hsl(0deg 0% 0% / 30%);
|
||||
--color-search-dropdown-top-border: hsla(0deg 0% 0% / 35%);
|
||||
|
||||
/* Text colors */
|
||||
--color-text-default: hsl(0deg 0% 100% / 75%);
|
||||
|
@ -262,6 +286,9 @@ body {
|
|||
--color-text-self-direct-mention: hsl(240deg 100% 88% / 100%);
|
||||
--color-text-self-group-mention: hsl(184deg 52% 63% / 100%);
|
||||
--color-text-show-more-less-button: hsl(240deg 30% 65%);
|
||||
--color-text-search: hsl(0deg 0% 100% / 75%);
|
||||
--color-text-search-hover: hsl(0deg 0% 100%);
|
||||
--color-text-search-placeholder: hsl(0deg 0% 100% / 50%);
|
||||
|
||||
/* Icon colors */
|
||||
--color-icon-bot: hsl(180deg 5% 50% / 100%);
|
||||
|
@ -2003,7 +2030,6 @@ div.focused-message-list {
|
|||
align-content: flex-start;
|
||||
flex-wrap: nowrap;
|
||||
margin: 0;
|
||||
border: none;
|
||||
white-space: nowrap;
|
||||
cursor: default;
|
||||
|
||||
|
@ -2131,9 +2157,12 @@ div.focused-message-list {
|
|||
before the stream name must begin to shrink */
|
||||
flex-shrink: 100;
|
||||
white-space: nowrap;
|
||||
margin: 0;
|
||||
padding: 12px 0;
|
||||
padding-left: 10px;
|
||||
/* We are adding right margin so the text can truncate
|
||||
and it doesn't overflow through search section. We make it
|
||||
5px more than the size of the search box. */
|
||||
margin: 0 155px 0 0;
|
||||
|
||||
@media (width < $sm_min) {
|
||||
padding: 7px 0;
|
||||
|
@ -2143,19 +2172,9 @@ div.focused-message-list {
|
|||
& > a {
|
||||
padding: 12px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.search_closed {
|
||||
overflow: visible;
|
||||
flex: 0; /* makes sure search icon is always visible */
|
||||
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
|
||||
padding: 10px 15px 0 0;
|
||||
|
||||
@media (width < $sm_min) {
|
||||
padding: 0 15px 0 0;
|
||||
@media (width < $md_min) {
|
||||
margin-right: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2163,15 +2182,9 @@ div.focused-message-list {
|
|||
last element is either the narrow description (for stream narrows) or
|
||||
the "title" (for other narrows). The flex-grow property ensures these
|
||||
elements take up the entirety of the white space. */
|
||||
.navbar-click-opens-search {
|
||||
.navbar_title,
|
||||
.narrow_description {
|
||||
flex-grow: 1;
|
||||
|
||||
/* Provide the visual cue that clicking this will work as expected. */
|
||||
cursor: pointer;
|
||||
|
||||
&:hover ~ .search_closed {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2341,6 +2354,7 @@ div.focused-message-list {
|
|||
|
||||
nav {
|
||||
.column-left {
|
||||
text-align: left;
|
||||
margin-left: 15px;
|
||||
|
||||
.nav-logo {
|
||||
|
@ -2975,10 +2989,6 @@ select.invite-as {
|
|||
#navbar-middle {
|
||||
margin-right: 87px;
|
||||
}
|
||||
|
||||
.search_closed .zulip-icon-search {
|
||||
right: 115px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < $md_min) {
|
||||
|
@ -3036,13 +3046,26 @@ select.invite-as {
|
|||
display: block;
|
||||
}
|
||||
|
||||
.top-navbar-border {
|
||||
.top-navbar-container {
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
.search_closed .zulip-icon-search {
|
||||
.zulip-icon-search {
|
||||
right: 115px;
|
||||
}
|
||||
|
||||
.dropdown-menu ul {
|
||||
margin: 0 -25px 0 0;
|
||||
background: transparent;
|
||||
|
||||
& li {
|
||||
width: 100%;
|
||||
|
||||
& a {
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < $sm_min) {
|
||||
|
@ -3066,15 +3089,8 @@ select.invite-as {
|
|||
}
|
||||
}
|
||||
|
||||
/* Usually the styling is applied directly to the icon, but here
|
||||
the icon is `position: static`, so we can't. */
|
||||
.search_closed {
|
||||
top: 5px;
|
||||
}
|
||||
|
||||
#streamlist-toggle,
|
||||
#navbar-buttons,
|
||||
.navbar-search,
|
||||
#message_view_header,
|
||||
#searchbox,
|
||||
.header {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<a class="sub_count no-style tippy-zulip-tooltip hidden-for-spectators" data-tippy-content="{{sub_count_tooltip_text}}" data-tippy-placement="bottom" href="{{stream_settings_link}}">
|
||||
<i class="fa fa-user-o"></i>{{formatted_sub_count}}
|
||||
</a>
|
||||
<span class="narrow_description navbar-click-opens-search rendered_markdown">
|
||||
<span class="narrow_description rendered_markdown">
|
||||
{{#if rendered_narrow_description}}
|
||||
{{rendered_markdown rendered_narrow_description}}
|
||||
{{else}}
|
||||
|
@ -14,8 +14,7 @@
|
|||
{{/if}}
|
||||
</span>
|
||||
{{else}}
|
||||
<span class="navbar-click-opens-search">
|
||||
<span class="navbar_title">
|
||||
{{> navbar_icon_and_title }}
|
||||
</span>
|
||||
{{/if}}
|
||||
<span class="search_icon search_closed" role="button"><i class="zulip-icon zulip-icon-search tippy-zulip-delayed-tooltip" data-tooltip-template-id="search-query-tooltip-template" aria-hidden="true"></i></span>
|
||||
|
|
|
@ -12,16 +12,16 @@
|
|||
<span id="streamlist-toggle-unreadcount">0</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="top-navbar-border top-header-container">
|
||||
<div class="top-navbar-container">
|
||||
<div id="message_view_header" class="notdisplayed">
|
||||
</div>
|
||||
<div id="searchbox">
|
||||
<form id="searchbox_form" class="navbar-search">
|
||||
<div id="searchbox-input-container" class="input-append">
|
||||
<span class="search_icon"><i class="zulip-icon zulip-icon-search tippy-zulip-delayed-tooltip" data-tooltip-template-id="search-query-tooltip-template"></i></span>
|
||||
<i class="search_icon zulip-icon zulip-icon-search"></i>
|
||||
<input class="search-query input-block-level home-page-input" id="search_query" type="text" placeholder="{{t 'Search' }}"
|
||||
autocomplete="off"/>
|
||||
<button class="btn search_close_button tippy-zulip-delayed-tooltip" type="button" id="search_exit" aria-label="{{t 'Exit search' }}" data-tippy-content="Close"><i class="zulip-icon zulip-icon-close" aria-hidden="true"></i></button>
|
||||
<button class="search_close_button tippy-zulip-delayed-tooltip" type="button" id="search_exit" aria-label="{{t 'Exit search' }}" data-tippy-content="Close"><i class="zulip-icon zulip-icon-close" aria-hidden="true"></i></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -19,7 +19,7 @@ const search = zrequire("search");
|
|||
|
||||
run_test("clear_search_form", () => {
|
||||
$("#search_query").val("noise");
|
||||
$("#search_query").trigger("focus");
|
||||
$("#search_query").trigger("click");
|
||||
|
||||
search.clear_search_form();
|
||||
|
||||
|
@ -215,6 +215,7 @@ run_test("initialize", ({mock_template}) => {
|
|||
|
||||
$search_query_box.off("blur");
|
||||
}
|
||||
return {};
|
||||
};
|
||||
|
||||
search.initialize({
|
||||
|
@ -226,8 +227,6 @@ run_test("initialize", ({mock_template}) => {
|
|||
|
||||
$search_query_box.val("test string");
|
||||
narrow_state.search_string = () => "ver";
|
||||
$search_query_box.trigger("blur");
|
||||
assert.equal($search_query_box.val(), "test string");
|
||||
|
||||
search.__Rewire__("is_using_input_method", false);
|
||||
$searchbox_form.trigger("compositionend");
|
||||
|
@ -301,6 +300,7 @@ run_test("initialize", ({mock_template}) => {
|
|||
assert.ok(is_blurred);
|
||||
|
||||
_setup("ver");
|
||||
ev.key = "Enter";
|
||||
search.__Rewire__("is_using_input_method", true);
|
||||
$searchbox_form.trigger(ev);
|
||||
// No change on Enter keyup event when using input tool
|
||||
|
@ -318,7 +318,7 @@ run_test("initiate_search", () => {
|
|||
// this implicitly expects the code to used the chained
|
||||
// function calls, which is something to keep in mind if
|
||||
// this test ever fails unexpectedly.
|
||||
narrow_state.filter = () => ({is_search: () => true});
|
||||
narrow_state.filter = () => ({is_search: () => false});
|
||||
let typeahead_forced_open = false;
|
||||
let is_searchbox_text_selected = false;
|
||||
$("#search_query").typeahead = (lookup) => {
|
||||
|
@ -331,13 +331,10 @@ run_test("initiate_search", () => {
|
|||
is_searchbox_text_selected = true;
|
||||
});
|
||||
|
||||
$(".navbar-search.expanded").length = 0;
|
||||
search.initiate_search();
|
||||
assert.ok(typeahead_forced_open);
|
||||
assert.ok(is_searchbox_text_selected);
|
||||
assert.equal($("#search_query").val(), "ver");
|
||||
|
||||
// test that we append space for user convenience
|
||||
narrow_state.filter = () => ({is_search: () => false});
|
||||
search.initiate_search();
|
||||
assert.equal($("#search_query").val(), "ver ");
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue