search: Remove support for experimental search pills.

This in-progress feature was started in 2018 and hasn't
been worked on much since. It's already in a broken state,
which makes it hard to iterate on the existing search bar
since it's hard to know how those changes will affect search
pills.

We do still want to add search pills eventually, and when
we work on that, we can refer to this diff to readd the
changes back.
This commit is contained in:
evykassirer
2023-05-18 15:55:49 -07:00
committed by Tim Abbott
parent e20e7482ca
commit aa270bcef0
22 changed files with 14 additions and 1863 deletions

View File

@@ -5,9 +5,6 @@ const {strict: assert} = require("assert");
const {mock_esm, set_global, zrequire} = require("./lib/namespace");
const {run_test} = require("./lib/test");
const $ = require("./lib/zjquery");
const {page_params} = require("./lib/zpage_params");
page_params.search_pills_enabled = false;
const narrow = mock_esm("../src/narrow");
const narrow_state = mock_esm("../src/narrow_state");
@@ -386,21 +383,11 @@ run_test("initiate_search", () => {
is_searchbox_text_selected = true;
});
let searchbox_css_args;
$("#searchbox").css = (args) => {
searchbox_css_args = args;
};
search.initiate_search();
assert.ok(typeahead_forced_open);
assert.ok(is_searchbox_text_selected);
assert.equal($("#search_query").val(), "ver");
assert.deepEqual(searchbox_css_args, {
"box-shadow": "inset 0px 0px 0px 2px hsl(204, 20%, 74%)",
});
// test that we append space for user convenience
narrow_state.filter = () => ({is_search: () => false});
search.initiate_search();

View File

@@ -1,457 +0,0 @@
"use strict";
const {strict: assert} = require("assert");
const {mock_esm, zrequire} = require("./lib/namespace");
const {run_test} = require("./lib/test");
const $ = require("./lib/zjquery");
const {page_params} = require("./lib/zpage_params");
const noop = () => {};
const narrow = mock_esm("../src/narrow");
const narrow_state = mock_esm("../src/narrow_state", {
filter: () => false,
});
const search_suggestion = mock_esm("../src/search_suggestion");
mock_esm("../src/search_pill_widget", {
widget: {
getByElement: () => true,
},
});
mock_esm("../src/ui_util", {
place_caret_at_end: noop,
});
const search = zrequire("search");
const search_pill = zrequire("search_pill");
const {Filter} = zrequire("../src/filter");
function test(label, f) {
run_test(label, ({override, mock_template}) => {
page_params.search_pills_enabled = true;
f({override, mock_template});
});
}
test("clear_search_form", () => {
$("#search_query").val("noise");
$("#search_query").trigger("focus");
$(".search_close_button").prop("disabled", false);
search.clear_search_form();
assert.equal($("#search_query").is_focused(), false);
assert.equal($("#search_query").val(), "");
assert.equal($(".search_close_button").prop("disabled"), true);
});
test("update_button_visibility", () => {
const $search_query = $("#search_query");
const $close_button = $(".search_close_button");
$search_query.is = () => false;
$search_query.val("");
narrow_state.active = () => false;
$close_button.prop("disabled", true);
search.update_button_visibility();
assert.ok($close_button.prop("disabled"));
$search_query.is = () => true;
$search_query.val("");
delete narrow_state.active;
$close_button.prop("disabled", true);
search.update_button_visibility();
assert.ok(!$close_button.prop("disabled"));
$search_query.is = () => false;
$search_query.val("Test search term");
delete narrow_state.active;
$close_button.prop("disabled", true);
search.update_button_visibility();
assert.ok(!$close_button.prop("disabled"));
$search_query.is = () => false;
$search_query.val("");
narrow_state.active = () => true;
$close_button.prop("disabled", true);
search.update_button_visibility();
assert.ok(!$close_button.prop("disabled"));
});
test("initialize", ({mock_template}) => {
const $search_query_box = $("#search_query");
const $searchbox_form = $("#searchbox_form");
const $close_button = $(".search_close_button");
const $searchbox = $("#searchbox");
mock_template("search_list_item.hbs", true, (data, html) => {
assert.equal(typeof data.description_html, "string");
if (data.is_person) {
assert.equal(typeof data.user_pill_context.id, "number");
assert.equal(typeof data.user_pill_context.display_value, "string");
assert.equal(typeof data.user_pill_context.has_image, "boolean");
assert.equal(typeof data.user_pill_context.img_src, "string");
}
return html;
});
$search_query_box[0] = "stub";
search_pill.get_search_string_for_current_filter = () => "is:starred";
search_suggestion.max_num_of_search_results = 99;
$search_query_box.typeahead = (opts) => {
assert.equal(opts.items, 99);
assert.equal(opts.naturalSearch, true);
assert.equal(opts.helpOnEmptyStrings, true);
assert.equal(opts.matcher(), true);
opts.on_move();
{
const search_suggestions = {
lookup_table: new Map([
[
"stream:Verona",
{
description_html: "Stream <strong>Ver</strong>ona",
search_string: "stream:Verona",
},
],
[
"ver",
{
description_html: "Search for ver",
search_string: "ver",
},
],
]),
strings: ["ver", "stream:Verona"],
};
/* Test source */
search_suggestion.get_suggestions = () => search_suggestions;
const expected_source_value = search_suggestions.strings;
const source = opts.source("ver");
assert.equal(source, expected_source_value);
/* Test highlighter */
let expected_value = `<div class="search_list_item">\n <span>Search for ver</span>\n</div>\n`;
assert.equal(opts.highlighter(source[0]), expected_value);
expected_value = `<div class="search_list_item">\n <span>Stream <strong>Ver</strong>ona</span>\n</div>\n`;
assert.equal(opts.highlighter(source[1]), expected_value);
/* Test sorter */
assert.equal(opts.sorter(search_suggestions.strings), search_suggestions.strings);
}
{
const search_suggestions = {
lookup_table: new Map([
[
"dm-including:zo",
{
description_html: "group direct messages including",
is_person: true,
search_string: "dm-including:user7@zulipdev.com",
user_pill_context: {
display_value: "<strong>Zo</strong>e",
has_image: true,
id: 7,
img_src:
"https://secure.gravatar.com/avatar/0f030c97ab51312c7bbffd3966198ced?d=identicon&version=1&s=50",
},
},
],
[
"dm:zo",
{
description_html: "direct messages with",
is_person: true,
search_string: "dm:user7@zulipdev.com",
user_pill_context: {
display_value: "<strong>Zo</strong>e",
has_image: true,
id: 7,
img_src:
"https://secure.gravatar.com/avatar/0f030c97ab51312c7bbffd3966198ced?d=identicon&version=1&s=50",
},
},
],
[
"sender:zo",
{
description_html: "sent by",
is_person: true,
search_string: "sender:user7@zulipdev.com",
user_pill_context: {
display_value: "<strong>Zo</strong>e",
has_image: true,
id: 7,
img_src:
"https://secure.gravatar.com/avatar/0f030c97ab51312c7bbffd3966198ced?d=identicon&version=1&s=50",
},
},
],
[
"zo",
{
description_html: "Search for zo",
search_string: "zo",
},
],
]),
strings: ["zo", "sender:zo", "dm:zo", "dm-including:zo"],
};
/* Test source */
search_suggestion.get_suggestions = () => search_suggestions;
const expected_source_value = search_suggestions.strings;
const source = opts.source("zo");
assert.equal(source, expected_source_value);
/* Test highlighter */
let expected_value = `<div class="search_list_item">\n <span>Search for zo</span>\n</div>\n`;
assert.equal(opts.highlighter(source[0]), expected_value);
expected_value = `<div class="search_list_item">\n <span>sent by</span>\n <span class="pill-container pill-container-btn">\n <div class='pill ' tabindex=0>\n <img class="pill-image" src="https://secure.gravatar.com/avatar/0f030c97ab51312c7bbffd3966198ced?d&#x3D;identicon&amp;version&#x3D;1&amp;s&#x3D;50" />\n <span class="pill-value">&lt;strong&gt;Zo&lt;/strong&gt;e</span>\n <div class="exit">\n <span aria-hidden="true">&times;</span>\n </div>\n</div>\n </span>\n</div>\n`;
assert.equal(opts.highlighter(source[1]), expected_value);
expected_value = `<div class="search_list_item">\n <span>direct messages with</span>\n <span class="pill-container pill-container-btn">\n <div class='pill ' tabindex=0>\n <img class="pill-image" src="https://secure.gravatar.com/avatar/0f030c97ab51312c7bbffd3966198ced?d&#x3D;identicon&amp;version&#x3D;1&amp;s&#x3D;50" />\n <span class="pill-value">&lt;strong&gt;Zo&lt;/strong&gt;e</span>\n <div class="exit">\n <span aria-hidden="true">&times;</span>\n </div>\n</div>\n </span>\n</div>\n`;
assert.equal(opts.highlighter(source[2]), expected_value);
expected_value = `<div class="search_list_item">\n <span>group direct messages including</span>\n <span class="pill-container pill-container-btn">\n <div class='pill ' tabindex=0>\n <img class="pill-image" src="https://secure.gravatar.com/avatar/0f030c97ab51312c7bbffd3966198ced?d&#x3D;identicon&amp;version&#x3D;1&amp;s&#x3D;50" />\n <span class="pill-value">&lt;strong&gt;Zo&lt;/strong&gt;e</span>\n <div class="exit">\n <span aria-hidden="true">&times;</span>\n </div>\n</div>\n </span>\n</div>\n`;
assert.equal(opts.highlighter(source[3]), expected_value);
/* Test sorter */
assert.equal(opts.sorter(search_suggestions.strings), search_suggestions.strings);
}
{
let operators;
let is_blurred;
let is_append_search_string_called;
$search_query_box.on(
"blur",
/* istanbul ignore next */
() => {
is_blurred = true;
},
);
search_pill.append_search_string = () => {
is_append_search_string_called = true;
};
/* Test updater */
const _setup = (search_box_val) => {
is_blurred = false;
is_append_search_string_called = false;
$search_query_box.val(search_box_val);
/* istanbul ignore next */
Filter.parse = (search_string) => {
assert.equal(search_string, search_box_val);
return operators;
};
/* istanbul ignore next */
narrow.activate = (raw_operators, options) => {
assert.deepEqual(raw_operators, operators);
assert.deepEqual(options, {trigger: "search"});
};
/* istanbul ignore next */
search_pill.get_search_string_for_current_filter = () => search_box_val;
};
operators = [
{
negated: false,
operator: "search",
operand: "ver",
},
];
_setup("ver");
assert.equal(opts.updater("ver"), "ver");
assert.ok(!is_blurred);
assert.ok(is_append_search_string_called);
operators = [
{
negated: false,
operator: "stream",
operand: "Verona",
},
];
_setup("stream:Verona");
assert.equal(opts.updater("stream:Verona"), "stream:Verona");
assert.ok(!is_blurred);
assert.ok(is_append_search_string_called);
search.__Rewire__("is_using_input_method", true);
_setup("stream:Verona");
assert.equal(opts.updater("stream:Verona"), "stream:Verona");
assert.ok(!is_blurred);
assert.ok(is_append_search_string_called);
$search_query_box.off("blur");
}
};
search.initialize();
const $search_pill_stub = $.create(".pill");
$search_pill_stub.closest = () => ({data: noop});
const stub_event = {
// FIXME: event.relatedTarget should not be a jQuery object
relatedTarget: $search_pill_stub,
};
$search_query_box.val("test string");
narrow_state.search_string = () => "ver";
$search_query_box.trigger(new $.Event("blur", stub_event));
assert.equal($search_query_box.val(), "test string");
let css_args;
$searchbox.css = (args) => {
css_args = args;
};
$searchbox.trigger("focusout");
assert.deepEqual(css_args, {"box-shadow": "unset"});
search.__Rewire__("is_using_input_method", false);
$searchbox_form.trigger("compositionend");
assert.ok(search.is_using_input_method);
const keydown = $searchbox_form.get_on_handler("keydown");
let default_prevented = false;
let ev = {
type: "keydown",
key: "a",
preventDefault() {
default_prevented = true;
},
};
$search_query_box.is = () => false;
assert.equal(keydown(ev), undefined);
assert.ok(!default_prevented);
ev.key = "Enter";
assert.equal(keydown(ev), undefined);
assert.ok(!default_prevented);
ev.key = "Enter";
$search_query_box.is = () => true;
assert.equal(keydown(ev), undefined);
assert.ok(default_prevented);
let operators;
let is_blurred;
narrow_state.active = () => false;
$search_query_box.off("blur");
$search_query_box.on("blur", () => {
is_blurred = true;
});
const _setup = (search_box_val) => {
is_blurred = false;
$close_button.prop("disabled", false);
$search_query_box.val(search_box_val);
Filter.parse = (search_string) => {
assert.equal(search_string, search_box_val);
return operators;
};
narrow.activate = (raw_operators, options) => {
assert.deepEqual(raw_operators, operators);
assert.deepEqual(options, {trigger: "search"});
};
search_pill.get_search_string_for_current_filter = () => search_box_val;
};
operators = [
{
negated: false,
operator: "search",
operand: "",
},
];
_setup("");
ev = {
type: "keyup",
which: 15,
};
/* istanbul ignore next */
$search_query_box.is = () => false;
$searchbox_form.trigger(ev);
assert.ok(!is_blurred);
assert.ok(!$close_button.prop("disabled"));
ev.key = "Enter";
$search_query_box.is = () => false;
$searchbox_form.trigger(ev);
assert.ok(!is_blurred);
assert.ok(!$close_button.prop("disabled"));
ev.key = "Enter";
$search_query_box.is = () => true;
$searchbox_form.trigger(ev);
assert.ok(is_blurred);
_setup("ver");
search.__Rewire__("is_using_input_method", true);
$searchbox_form.trigger(ev);
// No change on Enter keyup event when using input tool
assert.ok(!is_blurred);
assert.ok(!$close_button.prop("disabled"));
_setup("ver");
ev.key = "Enter";
$search_query_box.is = () => true;
$searchbox_form.trigger(ev);
assert.ok(is_blurred);
assert.ok(!$close_button.prop("disabled"));
$close_button.prop("disabled", true);
$search_query_box.trigger("focus");
assert.ok(!$close_button.prop("disabled"));
});
test("initiate_search", () => {
// open typeahead and select text when navbar is open
// this implicitly expects the code to used the chained
// function calls, which is something to keep in mind if
// this test ever fails unexpectedly.
let typeahead_forced_open = false;
let is_searchbox_text_selected = false;
let is_searchbox_focused = false;
$("#search_query").off("focus");
$("#search_query").on("focus", () => {
is_searchbox_focused = true;
});
$("#search_query").typeahead = (lookup) => {
if (lookup === "lookup") {
typeahead_forced_open = true;
}
return $("#search_query");
};
$("#search_query").on("select", () => {
is_searchbox_text_selected = true;
});
$("#search_query")[0] = "stub";
const $searchbox = $("#searchbox");
let css_args;
$searchbox.css = (args) => {
css_args = args;
};
search.initiate_search();
assert.ok(typeahead_forced_open);
assert.ok(is_searchbox_text_selected);
assert.ok(is_searchbox_focused);
assert.deepEqual(css_args, {"box-shadow": "inset 0px 0px 0px 2px hsl(204, 20%, 74%)"});
});

View File

@@ -1,85 +0,0 @@
"use strict";
const {strict: assert} = require("assert");
const {mock_esm, zrequire} = require("./lib/namespace");
const {run_test} = require("./lib/test");
const input_pill = mock_esm("../src/input_pill");
const search_pill = zrequire("search_pill");
const is_starred_item = {
display_value: "is:starred",
description_html: "starred messages",
};
const is_private_item = {
display_value: "is:private",
description_html: "direct messages",
};
run_test("create_item", () => {
function test_create_item(search_string, current_items, expected_item) {
const item = search_pill.create_item_from_search_string(search_string, current_items);
assert.deepEqual(item, expected_item);
}
test_create_item("is:starred", [], is_starred_item);
});
run_test("get_search_string", () => {
assert.equal(search_pill.get_search_string_from_item(is_starred_item), "is:starred");
});
run_test("append", () => {
let appended;
let cleared;
function fake_append(search_string) {
appended = true;
assert.equal(search_string, is_starred_item.display_value);
}
function fake_clear() {
cleared = true;
}
const pill_widget = {
appendValue: fake_append,
clear_text: fake_clear,
};
search_pill.append_search_string(is_starred_item.display_value, pill_widget);
assert.ok(appended);
assert.ok(cleared);
});
run_test("get_items", () => {
const items = [is_starred_item, is_private_item];
const pill_widget = {
items() {
return items;
},
};
assert.deepEqual(
search_pill.get_search_string_for_current_filter(pill_widget),
is_starred_item.display_value + " " + is_private_item.display_value,
);
});
run_test("create_pills", ({override}) => {
let input_pill_create_called = false;
override(input_pill, "create", () => {
input_pill_create_called = true;
return {dummy: "dummy"};
});
const pills = search_pill.create_pills({});
assert.ok(input_pill_create_called);
assert.deepEqual(pills, {dummy: "dummy"});
});

View File

@@ -53,7 +53,6 @@ const example_avatar_url = "http://example.com/example.png";
function init() {
page_params.is_admin = true;
page_params.search_pills_enabled = false;
people.init();
people.add_active_user(bob);

File diff suppressed because it is too large Load Diff