mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 14:03:30 +00:00 
			
		
		
		
	typeahead: Ignore mouse position for selection until it's moved.
Added a property `mouse_moved_since_typeahead` to the typeahead class which tracks whether the mouse has been moved since the typeahead menu appeared. The hovered over menu item is highlighted on `mouseenter` only if `mouseMoved` is true. Otherwise, the cursor is hidden temporarily. Code substantially reorganized by tabbott. Fixes: #21018.
This commit is contained in:
		@@ -491,6 +491,11 @@ class CommonUtils {
 | 
			
		||||
            `//*[@class="typeahead dropdown-menu" and contains(@style, "display: block")]//li[contains(normalize-space(), "${item}")]//a`,
 | 
			
		||||
            {visible: true},
 | 
			
		||||
        );
 | 
			
		||||
        const entry_x = (await entry?.boundingBox())?.x;
 | 
			
		||||
        const entry_y = (await entry?.boundingBox())?.y;
 | 
			
		||||
        if (entry_x && entry_y) {
 | 
			
		||||
            await page.mouse.move(entry_x, entry_y);
 | 
			
		||||
        }
 | 
			
		||||
        await page.evaluate((entry) => {
 | 
			
		||||
            entry.click();
 | 
			
		||||
        }, entry);
 | 
			
		||||
 
 | 
			
		||||
@@ -229,6 +229,9 @@ async function get_suggestions(page: Page, str: string): Promise<void> {
 | 
			
		||||
async function select_from_suggestions(page: Page, item: string): Promise<void> {
 | 
			
		||||
    await page.evaluate((item: string) => {
 | 
			
		||||
        const tah = $(".create_default_stream").data().typeahead;
 | 
			
		||||
        tah.mousemove({
 | 
			
		||||
            currentTarget: $(`.typeahead:visible li:contains("${CSS.escape(item)}")`)[0],
 | 
			
		||||
        });
 | 
			
		||||
        tah.mouseenter({
 | 
			
		||||
            currentTarget: $(`.typeahead:visible li:contains("${CSS.escape(item)}")`)[0],
 | 
			
		||||
        });
 | 
			
		||||
 
 | 
			
		||||
@@ -96,6 +96,7 @@
 | 
			
		||||
    this.$header = $(this.options.header_html).appendTo(this.$container)
 | 
			
		||||
    this.source = this.options.source
 | 
			
		||||
    this.shown = false
 | 
			
		||||
    this.mouse_moved_since_typeahead = false
 | 
			
		||||
    this.dropup = this.options.dropup
 | 
			
		||||
    this.fixed = this.options.fixed || false;
 | 
			
		||||
    this.automated = this.options.automated || this.automated;
 | 
			
		||||
@@ -199,6 +200,7 @@
 | 
			
		||||
 | 
			
		||||
      this.$container.show()
 | 
			
		||||
      this.shown = true
 | 
			
		||||
      this.mouse_moved_since_typeahead = false
 | 
			
		||||
      return this
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -328,11 +330,12 @@
 | 
			
		||||
      this.$menu
 | 
			
		||||
        .on('click', 'li', this.click.bind(this))
 | 
			
		||||
        .on('mouseenter', 'li', this.mouseenter.bind(this))
 | 
			
		||||
        .on('mousemove', 'li', this.mousemove.bind(this))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  , unlisten: function () {
 | 
			
		||||
      this.$container.remove();
 | 
			
		||||
      var events = ["blur", "keydown", "keyup", "keypress"];
 | 
			
		||||
      var events = ["blur", "keydown", "keyup", "keypress", "mousemove"];
 | 
			
		||||
      for (var i=0; i<events.length; i++) {
 | 
			
		||||
        this.$element.off(events[i]);
 | 
			
		||||
      }
 | 
			
		||||
@@ -375,6 +378,15 @@
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  , mousemove: function(e) {
 | 
			
		||||
      if (!this.mouse_moved_since_typeahead) {
 | 
			
		||||
        /* Undo cursor disabling in mouseenter handler. */
 | 
			
		||||
        $(e.currentTarget).find('a').css('cursor', '');
 | 
			
		||||
        this.mouse_moved_since_typeahead = true;
 | 
			
		||||
        this.mouseenter(e)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  , keydown: function (e) {
 | 
			
		||||
    if (this.trigger_selection(e)) {
 | 
			
		||||
      if (!this.shown) return;
 | 
			
		||||
@@ -450,6 +462,18 @@
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  , mouseenter: function (e) {
 | 
			
		||||
      if (!this.mouse_moved_since_typeahead) {
 | 
			
		||||
        // Prevent the annoying interaction where your mouse happens
 | 
			
		||||
        // to be in the space where typeahead will open.  (This would
 | 
			
		||||
        // result in the mouse taking priority over the keyboard for
 | 
			
		||||
        // what you selected). If the mouse has not been moved since
 | 
			
		||||
        // the appearance of the typeahead menu, we disable the
 | 
			
		||||
        // cursor, which in turn prevents the currently hovered
 | 
			
		||||
        // element from being selected.  The mousemove handler
 | 
			
		||||
        // overrides this logic.
 | 
			
		||||
        $(e.currentTarget).find('a').css('cursor', 'none')
 | 
			
		||||
        return
 | 
			
		||||
      }
 | 
			
		||||
      this.$menu.find('.active').removeClass('active')
 | 
			
		||||
      $(e.currentTarget).addClass('active')
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user