Commit Graph

65 Commits

Author SHA1 Message Date
Ryan Rehman 70b92c7eb3 search: Clicking on a search pill should not lose searchbox focus.
Whenever a search pill is selected or deleted by a click the navbar
gets rendered as the searchbox loses focus. This allows the user to
be able to continue editing the search query without having to refocus
the searchbox.
2020-06-19 16:18:52 -07:00
Ryan Rehman 63643c9d9d search: Fix blur event handler for `search_query_box`.
A main change is that we now display the navbar if the search box
is not focused. This was already present in the search pills version
but adding it to the legacy version is an improvement.

We sufficiently increase the timeout so that the pills are actually
deleted. This was required when `filter.is_common_narrow()` is true,
as then only we render the narrow description and close the search bar.

This commit also matches another behaviour of the legacy search.
i.e. We narrow every time a search suggestion is clicked.

The now redundant "focusin" and "focusout" event handler tests are
also removed.
2020-06-19 16:18:52 -07:00
Ryan Rehman 69f9c72edc search suggestions: De-duplicate legacy search codepath.
This merges the `exports.get_search_result_legacy` and
`exports.get_search_result` function.

The key differences between the two code paths are as follows:

* We only want to generate suggestions for the queries which
  the user is typing or can edit.
  For the legacy version, suggestions are displayed for the
  entire search string in the searchbox. (`all_operators`)
  For the pills enabled version, suggestions are displayed
  only for the input which hasn't been converted to pills.
  (`query_operators`)
  `all_operators` = `base_query_operators` + " " +  `query_operators`.
  trim is added at the end just to handle the legacy case
  where we pass the `base_query` as ''.

* It is not possible to detect whether the user wants to
  continue typing in the legacy version. However if the
  the searchbox is still focused even after pill creation
  we can assume the user still wants to continue typing.
  To handle this we push an empty term as the `last` operator.
  This is possible since the previous queries have been
  completely entered as evident from it's generated pill.

* When using the legacy version, `search_operators` are
  the same as `all_operators`, as mentioned in point 1.
  In the pills enabled version we perform most of the
  computations from the `query_operators`, but we do
  require all `all_operators`, only for filtering the last
  query's suggestion.

* And there is just one block unique to the legacy search
  system. More details are mentioned in the comments of that
  block.

We also refactor both the search suggestions node tests,
mainly to make them similar and easier to detect differences
when we switch over to the new version.
2020-06-18 01:44:15 -07:00
Ryan Rehman 531a803bfc typeahead: Allow automated selection for `contenteditable` elements.
This adds the support of our auto completion behaviour of the legacy
search code into the search pills version.
2020-06-18 01:35:19 -07:00
Ryan Rehman 4ed4aa7b6f search: Do not narrow on updation of search pills.
Previously we narrowed every time a search pill was created or deleted.
This commit allows the user to be able to continue typing without the
lag of narrowing.
This behaviour matches with the legacy version, whose code path remains
unchanged.
2020-06-18 01:33:56 -07:00
Ryan Rehman dd4460009b search: Remove redundant actions on `focus` events.
The 2 function calls of `open_search_bar_and_close_narrow_description`
was removed from the 2 event handlers since it was called again, from
the `search.initiate_search`.

The "focusin" event was redundant since there are multiple other event
handlers (like the `tab_bar` or `hotkeys`) for this purpose, and all
of them call the `search.initiate_search` function.
2020-06-18 01:32:11 -07:00
Ryan Rehman aeb4419d52 search: Open typeahead on initiating search.
This fixes a bug where the hotkeys used to search messages
doesn't work for pills enabled case.
2020-06-05 17:16:20 -07:00
Ryan Rehman a7aae94e64 navbar: Update searchbox event listeners behaviour.
These are some UI and UX changes mainly related for when to
display the search pills and when to dispay the narrow description
in the search bar.
2020-05-26 22:04:36 -07:00
Ryan Rehman c4e59309e4 navbar: Refactor `#searchbox`.
Along with various style fixes for the search pills
enabled case, this de-duplicates the css.
2020-05-26 22:04:36 -07:00
Ryan Rehman 02ab48a61e search: Simplify `narrow_or_search_for_term` code path.
The main reasoning for this change is as follows:

    * When the search bar contains multiple search queries
        but no search results, the last search operand does
        not get displayed.

        This happens due to the fact that filter object
        contained 2 terms having the operator key value as
        "search" instead of a single term where operator is
        "search" and operand is a single string containing
        the space seperated search queries. This condition
        occurs for search_pills_enabled case only because
        we used to Filter.parse the query twice
        (once for the `base_operators` and once for the
        `suggestion_operator instead of doing both at once).

        Thus the `search_query` value inside the
        `narrow.show_search_query` function which only
        selected the operands of the first term displayed
        an incomplete result.

    * Another benefit of this commit is to display the narrow
        operators in the URL fragment the same way as when
        search_pills_enabled = False.

        For example, On entering the queries in the mentioned
        order -> 'is: starred', 'abc', 'def', 'is: private',
        'ghi'. This is the URL:

        Previously:
        /#narrow/is/starred/is/private/search/abc.20def/search/ghi

        Now (same as pills disabled case):
        /#narrow/is/starred/is/private/search/abc.20def.20ghi

    * We are also able to de-duplicate the non-typeahead search
        query code path.
2020-05-26 22:04:36 -07:00
Ryan Rehman 9e221977c4 search pills: Narrow when typeahead is not used.
We can remove the typeahead by clicking outside the search box
after we have entered the search string to be filtered and then
focus on the searchbox  and press enter or just by pressing enter
on an empty string.

Previously, the narrow would just deactivate for the above condition
as the searchbox value which was passed as the raw_operators parameter
to the narrow.activate function was empty.
This happened because we called the activate function on pressing
enter for the keyup event, while the keydown event in the parent
container made a pill from the text and cleared the input. (as
mentioned in the comment for `KEY.ENTER` case in `input_pill.js`)
2020-05-26 22:04:36 -07:00
Steve Howell b46c8d1dc3 typeahead: Avoid tracebacks due to navbar changes.
In our recent navbar changes, we made it so that the
Esc key auto-closed the navbar. Unfortunately,
that code would break other typeaheads with a traceback.

One user-facing symptom was that if you drafted a PM
and started a typeahead on a recipient, then hitting
the Esc key wouldn't close the typeahead.

Now we use an `on_escape` mechanism that is specific
to the navbar typeahead, so that it's both generic and
harder to break for widgets that don't opt in to it.

See bbdc66a214 for
more details on the commit that introduced this
regression.

Note that I only call `tab_bar.exit_search` now.
I don't check the class name of the input element,
since I know that the Esc key is happening in the
context of search.  And I don't blur the input,
since it's going to be hidden.
2020-05-06 13:25:49 -07:00
YashRE42 bbdc66a214 typeahead: Close/open typeahead with searchbox.
The todo here is to ensure that we open and close the typeahead as
soon as the navbar search is opened/closed.
2020-04-17 13:37:04 -07:00
YashRE42 eb4a2b9d4e navbar: Improve structure & styling for top navbar.
This updates the logged-in top navbar to display the stream/message
name, number of users, and description. It also replaces the search
bar with a search icon that expands into a full-width search bar.

Co-authored-by: Max Nussenbaum <max@maxnuss.com>

Fixes: #164.
Fixes: #5198.
2020-04-17 13:35:44 -07:00
Anders Kaseorg 7c6ec51e5d search_suggestions: Convert lookup_table from object to Map.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-12 10:39:01 -08:00
Steve Howell ab34ee0800 search performance: Stop at max_items.
Once we have max_items results, stop trying
to get more items.

This should really help large realms when
you do a search on streams that turns up
more than N streams (where N is about 12).
We won't even bother to find people.
2019-12-28 11:09:28 -08:00
Anders Kaseorg 28f3dfa284 js: Automatically convert var to let and const in most files.
This commit was originally automatically generated using `tools/lint
--only=eslint --fix`.  It was then modified by tabbott to contain only
changes to a set of files that are unlikely to result in significant
merge conflicts with any open pull request, excluding about 20 files.
His plan is to merge the remaining changes with more precise care,
potentially involving merging parts of conflicting pull requests
before running the `eslint --fix` operation.

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-11-03 12:42:39 -08:00
Anders Kaseorg d17b577d0c js: Purge useless IIFEs.
With webpack, variables declared in each file are already file-local
(Global variables need to be explicitly exported), so these IIFEs are
no longer needed.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-10-25 13:51:21 -07:00
Tim Abbott 838dd6d273 lint: Add eslint enforcement for comma-spacing.
We've been enforcing this manually for a long time, and hadn't
realized it was missing from our eslint configuration.
2018-12-07 12:22:24 -08:00
Tim Abbott 9ea4f50c1b Revert "search: Open typeahead on empty string only if lookup triggered by Tab."
This reverts commit b961093c14.
2018-12-04 13:58:00 -08:00
Shubham Padia b961093c14 search: Open typeahead on empty string only if lookup triggered by Tab.
Fixes part of #10026.
Adds additional option to typeahead:
`tabOpensEmptyTypeahead`(default: false):
tabOpensEmptyTypeahead overrides helpOnEmptyStrings.
This commit sets helpOnEmptyStrings to false and
tabOpensEmptyTypeahead to true. Now typeahead will
open on an empty string only if Tab has been pressed.
2018-12-03 16:54:38 -08:00
Steve Howell 06b1aece31 Simplify narrow/search interactions.
Before this change, if you hit ESC, then hotkey
code would call search.clear_search, which would
call narrow.deactivate(), which would then use
`$('#search_query')` to clear a value, but then
let search.clear_search blur the input and
disable the exit button.  It was all confusing.

Things are a bit more organized now.

Now the code works like this:

    hotkey.process_escape_key
        Just call narrow.deactivate.

    $('#search_exit').on('click', ...):
        Just call narrow.deactivate.

    narrow.deactivate:
        Just call search.clear_search_form

    search.clear_search_form:
        Just do simple jquery stuff.  Don't
        change the entire user's narrow, not
        even indirectly!

There's still a two-way interaction between
the narrow.js module and the search.js module,
but in each direction it's a one-liner.

The guiding principle here is that we only
want one top-level API, which is narrow.deactivate,
and that does the whole "kitchen sink" of
clearing searches, closing popovers, switching
in views, etc.  And then all the functions it
calls out to tend to have much smaller jobs to
do.

This commit can mostly be considered a refactoring, but the
order of operations changes slightly.  Basically, as
soon as you hit ESC or click on the search "X", we
clear the search widget.  Most users won't notice
any difference, because we don't have to hit the
server to populate the home view.  And it's arguably
an improvement to give more immediate feedback.
2018-10-24 16:54:35 -07:00
Shubham Padia 28589c5563 search pills: Backspace should remove a search pill with typeahead open.
Fixes part of #10026.

Typeaheads stopped propogation of keydown and keyup events for any
key except tab and enter. If stopAdvance was true even tab and enter
were not allowed.

advanceKeyCodes option was added to typeahead which allowed to specify
key codes for which propogation of keydown and keyup events should not
stop. advanceKeyCodes does not respect the stopAdvance option.
As the backspace key code is added to advanceKeyCodes in search.js,
the backspace key deletes pill on pressing backspace if input is empty
or only consists of spaces.
2018-07-30 14:33:06 -07:00
Shubham Padia 9b1dc48ebd keyboard-shortcuts: Focus instead of select on `/` if search pills enabled.
If search pills are not enabled, the text present in the search bar
will be selected on pressing '/' and writing someting without deselecting
the text will clear the search text. Since selecting the pills would
not make sense in this context, the search box is focused instead.
2018-07-23 11:29:10 -07:00
Shubham Padia 22b2393cae pills: Use `widget` instead of `my_pill` throughout the app.
`compose_pm_pill.my_pill`, `search_pill_widget.my_pill` and any of
its occurrences throughout the app have been replaced to use `widget`
instead.
2018-07-23 11:29:10 -07:00
Shubham Padia 1f553a41d0 search: Higlight `#searchbox` on focus.
Adds box-shadow to `#searchbox` when either `#search_query` or any
of the pills have focus. Uses jquery instead of pure css as the
`:focus` event occurs on `#search_query`, while we want to add
box-shadow to `#searchbox`. This could have been done with
`:focus-within` CSS selector, but it is not supported in IE or Opera.

`#search_query` already had an onfocus/focusout listener, adding
listeners to `#searchbox.pills` for those events wouldn't have worked
as you don't want the focusout event to fire when the focus shifts
from input to pill.

Also adds `focusin`, `focusout` and `css()` to zjquery. `css` is
same as `val`, except it returns an empty object in case of no value
instead of an empty string. I don't think `css()` is valid syntax
in actual jquery.
2018-07-23 11:29:10 -07:00
Shubham Padia 8b153f6452 search: Validate suggestion against existing operators.
After adding search pills, suggestions were based only on the
current input and no validation against the existing pills was done.
operator_subset_suggestions have been removed. Default suggestions
for base_operators have also been removed.
Handle multiple operators:
if `is:starred stream:Ver` was typed without selecting the typeahead
or pressing enter in between i.e search pill for is:starred has not yet
been added, then the description of `is:starred` will act as a prefix
in every suggestion.
Also makes changes re-enabling person suggestions for names with spaces.
2018-07-23 11:29:10 -07:00
Tim Abbott 5b0e9b7fe6 search: Duplicate search_suggestions.get_suggestions.
This large function will need to be modified significantly as part of
the pills effort, and copying it lets us preserve behavior in
production until we're ready to cut things over.
2018-07-23 11:29:10 -07:00
Shubham Padia 36707a33ca search: Add a basic implementation of search pills.
Following points have been implemented in this commit:
1.) Add search pill on selecting typeahead.
2.) Re-narrow after removing a search pill.
3.) Add quiet optional parameter to removeLastPill.
4.) Pre populate search pills in narrow.activate.
5.) Clear existing search pills on narrow.deactivate.

Description of above points:
1.) I tried out using the description from suggestions.lookup_table
to append a pill using appendValidatedData so that the description
had not to be calculated again. But the description in the suggestions
lookup contains html due to highlighting. This html is escaped when
inputed in a pill. An attempt was also made to remove the higlighting
by replacing the tags. But other espaced characters like &lt; also
popped up, so it was better to use append_search_string.
3.) If one wants to refresh the pill using pill.clear and wants to
repopulate them, evaluating the event_handler associated with the
action of removing the pill may not be desired.
4.) Pill population code is added to narrow.activate. Pills are not
populated if the narrow was triggered by search as search handles the
addition and removal of pill by itself. The reason for not handling
search too in narrow.activate is to avoid clearing the pills and
repopulating them. Example of some of the triggers for narrow.activate
include `restore draft`, `topic change`,`sidebar`.

Also modifies tests for search.js
2018-07-23 11:29:10 -07:00
Armaan Ahluwalia 6d255efe4c app: Prepare JS files for consumption by webpack.
This commit prepares the frontend code to be consumed by webpack.

It is a hack: In theory, modules should be declaring and importing the
modules they depend on and the globals they expose directly.

However, that requires significant per-module work, which we don't
really want to block moving our toolchain to webpack on.

So we expose the modules by setting window.varName = varName; as
needed in the js files.
2018-07-05 10:53:36 +02:00
Shubham Dhama 42f9ecb841 search: Remove a redundant preventDefault & export is_using_input_method.
Return false is equivalent to preventDefault and stopPropogation.
is_using_input_method is exported for node testing.
2018-06-22 07:58:06 -04:00
Shubham Dhama 35be5a88ac search: Remove redundant re-declaration of variables for search box.
This is just a minor refactor.
2018-06-22 07:58:06 -04:00
Shubham Dhama 053b5a0da6 search: Refactor update_buttons_with_focus.
This just change `attr` to `prop` as it is more preferred.
Also, a minor renaming of variable is done here.
2018-06-22 07:58:06 -04:00
Shubham Dhama 9b5986d320 search: Fix "Enter to search" while using an input method.
NOTE:   To test this locally I've used Google Chrome input tool.
        This change will not affect users who don't use input tools.

Here is the algorithm used to deal with this case and other important
points:

* Here I've used `compositionend` event which is triggered
as soon as an input tool completes a word or user press "enter"
to get the suggested text. (There was a situation where it is
triggered even when input tool wasn't closed, that is when we
press space, but it also triggers another `compositionstart`
event simultaneously so our logic can't be affected by this.)

* We are using a variable `is_using_input_method` which sets to
`true` when `compositionend` event is triggered.

* Basically our searching is initiated by `keyup` event which
is triggered by the same keypress which triggers `compositionend`
event to get the text, so our main goal is to suppress the searching
triggered by this key pressing.

* Observation shows that `compositionend` is triggered before the
`keyup` and calling of callback `narrow_or_search_for_term`
used by typeahead.
    i.e. chronological order of triggering of this event is
`compositionend` > calling of `narrow_or_search_for_term` > `keyup`.

* So the main logic is to set `is_using_input_method` to `false`
by default and if used the input tool then when we press enter
to get the suggested text we set it to `true` which indicate
further events triggered after it to skip the searching and
finally in `keyup` we set it to default `false` so when pressed
enter again we have it set to false and we have a successful
search.

Fixes: #9396.
2018-06-20 16:32:51 -04:00
Felix Yan 974f015837 js: Fix a typo in search.js. 2018-06-08 12:14:55 -07:00
Tim Abbott 7ab8a8e820 js: Fix a bunch of indentation issues found by eslint.
This is preparation for enabling an eslint indentation configuration.
90% of these changes are just fixes for indentation errors that have
snuck into the codebase over the years; the others are more
significant reformatting to make eslint happy (that are not otherwise
actually improvements).

The one area that we do not attempt to work on here is the
"switch/case" indentation.
2018-05-06 16:25:02 -07:00
Tim Abbott e4c50ff4fd narrow: Remove unnecessary select_first_unread option.
We consistently either pass a `then_select_id` into narrow.activate,
or were using the select_first_unread option.  Now, we just compute
select_first_unread based on the value of then_select_id.
2018-04-22 21:33:33 -07:00
Tim Abbott 0c9b1dc9ff search: Use select_first_unread when narrowing.
Apparently, our search code was the last holdout that was still using
the pointer to determine where to place a narrow.
2018-04-22 21:33:33 -07:00
Tim Abbott 82b708b721 eslint: Add and enforce space-in-parens lint rule. 2017-10-06 12:36:59 -07:00
Cory Lynch d32e89aae4 jQuery: Remove broken use of "removeAttr".
This function no longer sets properties to false, so the supported
way of doing this is to instead use prop(foo, false). Some tests
had to be fixed to accommodate this.
2017-07-24 10:54:47 -07:00
Steve Howell 8eb86335b9 Extract narrow_state.js.
Despite the length of this commit, it is a very straightforward
moving of code from narrow.js -> narrow_state.js, and then
everything else is just s/narrow.foo()/narrow_state.foo()/
(with a few tiny cleanups to remove some code duplication
in certain callers).

The only new functions are simple setter/getters that
encapsulate the current_filter variable:

    narrow_state.reset_current_filter()
    narrow_state.set_current_filter()
    narrow_state.get_current_filter()

We removed narrow.predicate() as part of this, since it was dead
code.

Also, we removed the shim for narrow_state.set_compose_defaults(),
and since that was the last shim, we removed shim.js from the app.
2017-04-25 09:57:32 -07:00
Maxim Averin 08690132fe Decrease maximum number of search suggestions.
This fixes an issue with the menu going below the bottom of screen
with non-tiny windows, and it was rare that anyone benefitted from the
extra suggestions.

Fixes: #4133.
2017-04-04 13:02:10 -07:00
Steve Howell d026344b37 Extract js/ui_util.js. 2017-03-19 11:05:45 -07:00
Raghav Jajodia c3dbce810e right-sidebar: Added clear-search button on user-list searchbar.
A clear-search option to clear the user-list searchbox has been added.
This feature was present in the main searchbar but absent elsewhere.
Fix a part of #3716.
2017-03-04 20:30:58 -08:00
Tim Abbott 998dff9e50 lint: Add dangling commas in JavaScript objects. 2017-01-11 15:23:42 -08:00
Rafid Aslam 45f39be37f lint: Fix many no-unused-vars eslint rule violations.
These have been carefully audited by tabbott to ensure they are
unlikely to cause regressions.
2016-12-14 21:34:51 -08:00
Zev Benjamin fa097a1201 Remove jquery.highlight
The one call we were making to it was actually unnecessary since highlighting is
no longer done client-side.

(imported from commit 7644a5961ca48cd57f4b65c6f698083677e0a130)
2014-01-15 16:07:20 -05:00
acrefoot 0d08acaa1b Transition from tables to divs for the message list.
This breaks our casperjs tests.

(imported from commit c63181c73a24eed4a80bfa56966d1f0871c5edb2)
2013-12-19 18:28:11 -05:00
Kevin Mehall e82f11ed46 Fix a JS error introduced by the debug logging.
Narrow.activate was called without an options object in one
obscure location. I'm not sure how it's actually triggered,
since all searches seem to go through the typeahead path with
the "Search for x" option, but someone managed to do it.

(imported from commit 5e0e1bbe7570e5f6a654949547dc164e01125efa)
2013-11-05 15:07:24 -05:00
Steve Howell c4d598b36e Move parse/unparse from narrow to Filter.
I'm trying to move well-isolated methods out of narrow.js, so that
narrow.js is more strongly focused on UI/ajax interactions and
big, heavy lifting stuff.  The logical home for parse/unparse
seemed to be Filter, and they brought along two private methods
with them.  The big code moves involved trivial follow ups
like s/exports/Filter/.

(imported from commit ace0fe5aa1c7abce0334d079ba9eb8d9a57bd10f)
2013-08-22 14:53:00 -04:00