Files
zulip/static/js/portico/header.js
Eeshan Garg 132498894f header: Stop trying to detect if touch is enabled for click events.
We found a bug in our top-level nav on certain Samsung phones where
tapping on the dropdowns didn't do anything. As it turns out, trying
to figure out whether touch is enabled on a device using CSS media
queries such as `(hover: none)` is very tricky business! While it
may work on some devices, it may break spectacularly on others.

This commit presents a potential solution to this. Media queries
about widths are a lot more device-independent than hover media
queries. So, this is what we do now:

- We fire click events regardless of whether the top-level nav is in
  the vertical sidebar orientation or the horizontal orientation.
  Since we are no longer dependent on hover media queries for click
  events, this fixes the mobile bug mentioned above because taps or
  clicks will always work regardless of device.
- The mouseover/mouseout events are only fired when the header is
  in the horizontal orientation and the primary input mechanism
  supports hovering over elements. This allows us to support hovering
  over menus on desktop. However, since mouseout/mouseover events are
  irrelevant for mobile, we are fine on that front since clicks/taps
  will still work.

NOTE that the above approach also takes care of weird edge cases where
you have a horizontal orientation on a device such as the iPad Pro that
is flipped in the horizontal position. Since clicks work anyway, these
edge cases are largely taken care of.
2021-08-07 06:22:29 -07:00

50 lines
2.0 KiB
JavaScript

import $ from "jquery";
$(() => {
$(".portico-header li.logout").on("click", () => {
$("#logout_form").trigger("submit");
return false;
});
$(".dropdown").on("click", (e) => {
const $this = $(e.target);
const dropdown_is_shown = $this.closest("ul .dropdown").hasClass("show");
if (!dropdown_is_shown) {
$this.closest("ul .dropdown").addClass("show");
} else if (dropdown_is_shown) {
$this.closest("ul .dropdown").removeClass("show");
}
});
$(".nav-dropdown").on("mouseover", (e) => {
const $this = $(e.target);
// We switch to a vertical sidebar menu at width <= 1024px
const in_vertical_orientation = window.matchMedia("(max-width: 1024px)").matches;
// We only support mouseover events if we are in a horizontal
// orientation (width > 1024px) and if the primary input mechanism
// can hover over elements.
const hover_supported = window.matchMedia("(hover: hover)").matches;
const dropdown_is_shown = $this.closest("ul .dropdown").hasClass("show");
if (!dropdown_is_shown && !in_vertical_orientation && hover_supported) {
$this.closest("ul .dropdown").addClass("show");
}
});
$(".nav-dropdown").on("mouseout", (e) => {
const $this = $(e.target);
// We switch to a vertical sidebar menu at width <= 1024px
const in_vertical_orientation = window.matchMedia("(max-width: 1024px)").matches;
// We only support mouseout events if we are in a horizontal
// orientation (width > 1024px) and if the primary input mechanism
// can hover over elements.
const hover_supported = window.matchMedia("(hover: hover)").matches;
const dropdown_is_shown = $this.closest("ul .dropdown").hasClass("show");
if (dropdown_is_shown && !in_vertical_orientation && hover_supported) {
$this.closest("ul .dropdown").removeClass("show");
}
});
});