webcompat / web-bugs

A place to report bugs on websites.
https://webcompat.com
Mozilla Public License 2.0
742 stars 65 forks source link

web.whatsapp.com - layout is messed up #8070

Closed ioana-chiorean closed 5 years ago

ioana-chiorean commented 7 years ago

URL: https://web.whatsapp.com/ Browser / Version: Firefox Mobile 56.0 Operating System: Android 7.1.2 Problem type: Layout is messed up

Steps to Reproduce

  1. Navigate to: https://web.whatsapp.com/
  2. Tap the menu button - top right corner

Expected Behavior:

Actual Behavior:

Screenshot Description

From webcompat.com with ❤️

adamopenweb commented 7 years ago

Thanks @ioana-chiorean. I can reproduce this as well in Firefox 56 for Android.

<a>
  <div class="page-header__menu" onclick="toggle_menu()">

    <svg version="1.1" id="icon-menu" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="37px" height="37px" viewBox="0 0 37 37" style="enable-background:new 0 0 37 37;" xml:space="preserve">
    <path class="icon_white" d="M8,26h21v-1.8H8V26z M8,11v1.8h21V11H8z M8,19.2h21v-1.8H8V19.2z"></path>
    </svg>

  </div>
</a>

Fennec seems to be a little touchy when it comes to selecting. Not sure what here is making it highlight the button.

karlcow commented 6 years ago

They have a function which redefines touch

(function (f, r, u) {
  document.createEvent && (f.addTouchSupport = function () {
    var e = f.$,
    p = f.An$;
    e.fn = e.fn || {
    };
    e.each('touchstart touchmove touchend swipe swipeleft swiperight '.split(' '), function (b, d) {
      p.prototype[d] = e.fn[d] = function (b) {
        return b ? this.bind(d, b)  : this.trigger(d)
      };
      e.attrFn && (e.attrFn[d] = !0)
    });
    var h = 'ontouchend' in document,
    l = !h && r.navigator.msPointerEnabled,
    q = h ? 'touchstart' : 'mousedown',
    x = h ? 'touchend' : 'mouseup',
    s = h ? 'touchmove' : 'mousemove';
    e.event.special.swipe = {
      scrollSupressionThreshold: 30,
      durationThreshold: 1000,
      horizontalDistanceThreshold: 30,
      verticalDistanceThreshold: 75,
      swipeEvent: e.Event('swipe'),
      swipeLeftEvent: e.Event('swipeleft'),
      swipeRightEvent: e.Event('swiperight'),
      setup: function () {
        if (!this.setupDone) {
          var b = e(this);
          l && b.css('-ms-touch-action', 'pan-y pinch-zoom double-tap-zoom');
          b.bind(q, function (d) {
            function c(d) {
              b.unbind(x, c);
              b.unbind(s, f);
              t && a && a.time - t.time < e.event.special.swipe.durationThreshold && Math.abs(t.coords[0] - a.coords[0]) > e.event.special.swipe.horizontalDistanceThreshold && Math.abs(t.coords[1] -
              a.coords[1]) < e.event.special.swipe.verticalDistanceThreshold && b.trigger(e.event.special.swipe.swipeEvent).trigger(t.coords[0] > a.coords[0] ? e.event.special.swipe.swipeLeftEvent : e.event.special.swipe.swipeRightEvent);
              t = a = u
            }
            function f(b) {
              if (t) {
                var c = b.touches ? b.touches[0] : b.originalEvent.touches ? b.originalEvent.touches[0] : b;
                a = {
                  time: (new Date).getTime(),
                  coords: [
                    c.pageX,
                    c.pageY
                  ]
                };
                Math.abs(t.coords[0] - a.coords[0]) > e.event.special.swipe.scrollSupressionThreshold && b.preventDefault()
              }
            }
            var h = d.touches ? d.touches[0] :
            d.originalEvent.touches ? d.originalEvent.touches[0] : d,
            t = {
              time: (new Date).getTime(),
              coords: [
                h.pageX,
                h.pageY
              ],
              origin: e(d.target)
            },
            a;
            b.bind(s, f).bind(x, c)
          });
          this.setupDone = !0
        }
      }
    };
    e.each({
      swipeleft: 'swipe',
      swiperight: 'swipe'
    }, function (b, d) {
      e.event.special[b] = {
        setup: function () {
          e(this).bind(d, e.noop)
        },
        teardown: function (b, f, h) {
          e(b).unbind(d)
        }
      }
    })
  })
}) (AdobeEdge, window);

The issue can still be reproduced.


    var open = false;
    var speed = 200;
    function toggle_lng_menu() {
        if(open) {
            $('#lng_open').slideUp(speed);
            $('.header').removeClass('is-expanded');
        } else {
            $('#lng_open').slideDown(speed);
            $('.header').addClass('is-expanded');
        }
        open = !open;
    }

    function toggle_menu() {
        $('.page-header__drawer').toggleClass('is-visible');
    }

    function toggle_search() {
        $('.page-subheader--search').slideToggle();
    }

    $(function() {
                    $(window).scroll(function(e) {
                  if ($('body').scrollTop() > 0) {
                $('.header').addClass("fixed");
              } else {
                $('.header').removeClass("fixed");
              }
            });
            })

THis part

    function toggle_menu() {
        $('.page-header__drawer').toggleClass('is-visible');
    }

works perfectly on the console. So it is definitely something outside of this function.

karlcow commented 6 years ago

@wisniewskit This is working without issue on RDM but indeed it keeps the selection on Firefox Android.

wisniewskit commented 6 years ago

@karlcow, this is almost certainly because they're using an SVG for the icon, and Firefox presently brings up the text-selection interface when SVGs are tapped (see bz1286882):

<div class="page-header__menu" onclick="toggle_menu()">
  <svg version="1.1" id="icon-menu" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="37px" height="37px" viewBox="0 0 37 37" style="enable-background:new 0 0 37 37;" xml:space="preserve">
    <path class="icon_white" d="M8,26h21v-1.8H8V26z M8,11v1.8h21V11H8z M8,19.2h21v-1.8H8V19.2z"></path>
  </svg>
</div>

Mobile browsers have had issues like this for a long time, so a common trick sites use is to explicitly disable text-selection on elements that should never have them with the CSS user-select property. For instance, they can work around this by adding this chunk of CSS:

.page-header__menu, .drawer__close {
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

That's working for me in local testing, and I would encourage them to do this regardless of whether Firefox fixes this specific issue (though they may want to be more liberal about which elements get this treatment, for instance they can change the rule to apply to all svg elements if they don't ever have SVGs with text the user should be able to select).

karlcow commented 5 years ago

This has been fixed on Firefox side.