Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

www.casio.com - Desktop site instead of mobile site when accessing the page #42325

Closed
webcompat-bot opened this issue Oct 15, 2019 · 6 comments
Closed
Labels
browser-fenix engine-gecko The browser uses the Gecko rendering engine priority-normal severity-important A non-core broken piece of functionality, not behaving the way you would expect. type-viewport
Milestone

Comments

@webcompat-bot
Copy link

URL: https://www.casio.com/products/watches/dress

Browser / Version: Firefox Mobile 71.0
Operating System: Android
Tested Another Browser: No

Problem type: Desktop site instead of mobile site
Description: A pop up redirects user to the desktop site whenever they try to exit it.
Steps to Reproduce:
Opened website, scrolled down until a pop up appeared, tried to tap outside of the bounds to close it, then the desktop version opened.

Browser Configuration
  • None

Submitted in the name of @kolgza

From webcompat.com with ❤️

@webcompat-bot webcompat-bot added this to the needstriage milestone Oct 15, 2019
@webcompat-bot webcompat-bot added browser-fenix engine-gecko The browser uses the Gecko rendering engine labels Oct 15, 2019
@softvision-oana-arbuzov softvision-oana-arbuzov changed the title www.casio.com - desktop site instead of mobile site www.casio.com - Desktop site instead of mobile site when accessign the page Oct 16, 2019
@softvision-oana-arbuzov
Copy link
Member

Thanks for the report, I was able to reproduce the issue.
MobileRedirectToDesktop

Note:

  1. Workaround: Refreshing the page the mobile layout is displayed.
  2. The issue is not reproducible on Firefox and Chrome.

Tested with:
Browser / Version: Firefox Preview Nightly 191010(🦎: 71.0a1-20191004094656)
Operating System: Huawei P20 Lite (Android 8.0.0) - 1080 x 2280 pixels, 19:9 ratio (~432 ppi density), Samsung Galaxy S7 Edge (Android 8.0.0) - Resolution 1440 x 2560 pixels (~534 ppi pixel density)

Moving to Needsdiagnosis for further investigation.

@softvision-oana-arbuzov softvision-oana-arbuzov added severity-important A non-core broken piece of functionality, not behaving the way you would expect. priority-normal labels Oct 16, 2019
@wisniewskit wisniewskit self-assigned this Oct 16, 2019
@wisniewskit
Copy link
Member

wisniewskit commented Oct 16, 2019

Confirmed on Firefox Preview (which shows the desktop view crammed into the screen) and Firefox Preview nightly (which shows a zoomed-in desktop view instead).

Unfortuately, the remote debugger is pretty busted while testing with Firefox Preview (nightly or non-nightly), and I had to clear my caches between each attempt, so this one was a royal pain to deal with.

There is a click handler on the close button, but when I set the debugger to pause on click events, the page has already changed over to the desktop version before the click event actually fires.

When I set the debugger to pause instead on all mouse and touch events, that is early enough to catch the problem, but the remote debugger isn't able to actually do anything at that point and just sits there perma-paused like the tab has crashed.

I was able to have it log instead and persist logs and get this output:

13:30:36.149  touchend { target: button.ub-emb-close, isTrusted: true, touches: TouchList, targetTouches: TouchList, changedTouches: TouchList(1), altKey: false, metaKey: false, ctrlKey: false, shiftKey: false, view: Window, … }   jquery-1.11.2.min.js:3:5183
13:30:36.157  mousemove { target: button.ub-emb-close, buttons: 0, clientX: 317, clientY: 127, layerX: 7, layerY: 12 }   fromEvent.js:17
13:30:36.162  click { target: button.ub-emb-close, buttons: 0, clientX: 317, clientY: 127, layerX: 7, layerY: 12 }       preact.mjs:179
13:26:02.619    GET   https://casiocdn.com/casio-v2/resource/theme/images/social-icons.svg   [HTTP/2.0 200 OK 175ms]
13:30:36.420  click { target: button.ub-emb-close, buttons: 0, clientX: 317, clientY: 127, layerX: -251, layerY: -382 }  preact.mjs:179
13:30:36.423  click { target: button.ub-emb-close, buttons: 0, clientX: 317, clientY: 127, layerX: -251, layerY: -382 }  989b00e7def54bfb6f6f5591880b5528.js:70:22034
13:30:36.428  click { target: button.ub-emb-close, buttons: 0, clientX: 317, clientY: 127, layerX: -251, layerY: -382 }  gtm.js:752:79

From there I cleared my breakpoints and set new ones on each line above, in an attempt to figure out which one was the step where the desktop version of the page appears and work from there, but I can't actually click the "play" icon after the first breakpoint is triggered in the remote debugger; it just flashes a yellow box for a moment under the play button and nothing happens, and the tab is basically crashed at that point.

And so I cleared my breakpoints and tried again, this time comparing the HTML markup before and after the popup is dismissed (by using copy outer HTML on the html tag each time, then diffing the results). The most pertinent thing that changes is that this meta viewport tag vanishes from their markup:

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, shrink-to-fit=no">

And indeed, if I manually add back that meta tag, then the "desktop view" is gone, and we're back to the mobile one as though we have reloaded the page. So maybe that's the problem?

I tried setting a DOM mutation breakpoing on the removal of that node, but it didn't actually manage to break early enough for me to see the line causing the issue (plus the debugger was in a broken state again at that point).

In fact, the debugger just doesn't want to step through breakpoints today, making it impossible to confirm what might be causing the issue. But I did find a few spots where they seem to be removing meta tags, and this one is the one in the main.bundle.js seems to be the culprit (since the others seem to be hit too late, once the tag is already removed):

      function o() {
        var e = document.getElementById('lp-pom-root'),
        t = document.querySelector('meta[name="viewport"]');
        if (e && t && 600 < window.innerWidth && window.innerWidth < 1024) {
          var n = window.innerWidth,
          o = e.offsetWidth,
          r = n / o;
          t.content = o <= n ? 'initial-scale=1.0, width=device-width, user-scalable=yes' : 'initial-scale=' + r + ', user-scalable=yes'
        }
      }

Searching through their code, I found this spot where viewport tags seem to possibly be removed in viewportMeta.js:

function remove() {
  if (document.head && document.head.querySelectorAll('meta[name="viewport"]').length > 1) {
    // If a viewport meta tag already exists, we should revert this change so that the mobile
    // browser will fall back to the original meta tag.
    meta.removeAttribute('content');
  } else {
    // If this tag is the only viewport meta tag on the page then we should set the content to
    // an empty string so our viewport settings are removed.
    meta.setAttribute('content', '');
  }

  if (document.head) {
    document.head.removeChild(meta);
  }
}

But breakpoints are again not working, so I had to use logpoints to confirm that the remove is called from that spot (which it is). Unfortuantely that doesn't really help much, because I don't have a call stack to know where the call is being made from.

Still, in Chrome calls the same code, and the meta tag is removed as well, so I made a reduced test-case to see what's going on, and nope: simply removing the meta tag doesn't seem to be the culprit here. Of course, that is completely at-odds with the fact that re-adding the meta tag "fixes" the problem, so I'm at a loss here.

I fear I'm basically stuck here until the remote debugger starts cooperating with breakpoints.

@karlcow, do you have any ideas?

If you'd like to try re-adding the meta tag yourself, you can run this code remote console after dismissing the popup:

var meta = document.createElement("meta")
meta.setAttribute("name","viewport")
meta.setAttribute("content","width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, shrink-to-fit=no")
document.head.appendChild(meta)

PS: I should also mention that in Fennec, the meta viewport tag does not seem to get removed, though I have not investigated why.

@karlcow
Copy link
Member

karlcow commented Oct 17, 2019

The click is caught by:
https://connect.facebook.net/signals/config/286369075303246?v=2.9.6&r=stable

          var f = c.target instanceof HTMLElement ? c.target : null;

which is happening on

<div class="ub-emb-scroll-wrapper">
  <div class="ub-emb-iframe-wrapper ub-emb-mobile ub-emb-visible" style="height: 338px; width: 320px;">
    <button class="ub-emb-close" type="button">×</button>
    <iframe class="ub-emb-iframe" src="//1f8e679b9a124392b5b95c0bfea02da9.pages.ubembed.com/283948e4-5572-488c-b21e-60c1e49146ae/a.html?closedAt=0" style="width: 320px !important; height: 338px !important;"></iframe>
  </div>
  <div class="ub-emb-iframe-wrapper ub-emb-mobile" style="height: 0px; width: 0px;">
    <button class="ub-emb-close" type="button">×</button>
    <iframe class="ub-emb-iframe" src="" style="width: 0px !important; height: 0px !important;"></iframe>
  </div>
</div>

with an impressive z-index 😉

.ub-emb-overlay.ub-emb-visible .ub-emb-backdrop, .ub-emb-overlay.ub-emb-visible .ub-emb-scroll-wrapper {
	opacity: 1;
	transition: opacity .4s ease;
	z-index: 2147483647;
}

then it eventually reaches
in https://assets.ubembed.com/universalscript/releases/v0.177.0/bundle.js

  function p(e) {
    return this._listeners[e.type](O.event && O.event(e) || e)
  }

When exiting the p(e), it's when the view switches to desktop. This is reproducible on the RDM view and debugging. Note at this point the meta for the viewport is still in there.

<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, user-scalable=no">

So the viewport is not entirely related I guess.

Removing the cookies and restarting the step by step. This time it switched to desktop view when passing on webpack:///node_modules/preact/dist/preact.mjs

function eventProxy(e) {
	return this._listeners[e.type](options.event && options.event(e) || e);
}

which is probably the same thing, but the devtools understood the semantic of the scripts I guess this time. Setting a breakpoint on this return line instead of the click and stepping in.

we reach webpack:///src/components/App.jsx

            onClose={() => this.handleClose(emb)}

which is part of this chunk of code.

        return (
          <EmbeddableComponent
            // We incorporate the emb's URL into the key so that if changes, for some reason,
            // Preact will remove and re-add the Overlay component (including its iframes) to the
            // DOM. This would cause the new URL to be preloaded and the state of the Overlay
            // component to reset.
            key={`${id}-${pageSrc}`}

            device={state.device}
            emb={emb}
            isVisible={visibleEmbOfType === id}
            onClose={() => this.handleClose(emb)}
            scrollPosition={state.scrollPosition}
            size={embPageSize}
            viewport={state.viewport}
          >
            <IframeWrapper
              // Main emb content
              isMobile={isMobile}
              isVisible={!showConfirmation}
              size={embPageSizeCss}
              hostPageUrl={state.locationHref || global.location.href}
              // We append the closedAt time to the src URL so that when the emb is closed, the
              // iframe reloads. This prevents embedded videos from continuing to play, but leaves
              // the iframe in a loaded state, ready to be triggered again.
              src={`${pageSrc}${/\?/.test(pageSrc) ? '&' : '?'}closedAt=${closedAt}`}
              onClose={() => this.handleClose(emb)}
              onFormConfirmation={(confirmationSize, confirmationSrc) =>
                dispatch(actions.embFormConfirmation({id, confirmationSize, confirmationSrc}))}
              onFormSubmit={isConversion => dispatch(actions.formSubmitEvent({id, isConversion}))}
              onLinkClick={(isConversion, linkUrl = '', shouldRedirect = false) =>
                dispatch(actions.linkClickEvent({id, isConversion, linkUrl, shouldRedirect}))}
              onLoad={pageSize => dispatch(actions.embLoaded({id, pageSize}))}
            />

            <IframeWrapper
              // Form confirmation dialog
              isMobile={isMobile}
              isVisible={showConfirmation}
              size={embConfirmationSizeCss}
              hostPageUrl={state.locationHref || global.location.href}
              src={emb.confirmationSrc}
              onClose={() => this.handleClose(emb)}
              onFormConfirmation={noop}
              onFormSubmit={noop}
              onLinkClick={(isConversion, linkUrl = '', shouldRedirect = false) =>
                dispatch(actions.linkClickEvent({id, isConversion, linkUrl, shouldRedirect}))}
              onLoad={noop}
            />
          </EmbeddableComponent>
        );

Not there yet but getting close @wisniewskit

@karlcow
Copy link
Member

karlcow commented Oct 17, 2019

Now setting a breakpoint on onClose={() => this.handleClose(emb)} instead of the previous one.

state.device
Object { isIOS: false, isOldIOS: false, isMobile: true }

After more steps in… a lore more… we reach

webpack:///src/viewportMeta.js

function remove() {
  if (document.head && document.head.querySelectorAll('meta[name="viewport"]').length > 1) {
    // If a viewport meta tag already exists, we should revert this change so that the mobile
    // browser will fall back to the original meta tag.
    meta.removeAttribute('content');
  } else {
    // If this tag is the only viewport meta tag on the page then we should set the content to
    // an empty string so our viewport settings are removed.
    meta.setAttribute('content', '');
  }

  if (document.head) {
    document.head.removeChild(meta);
  }
}

and specifically

  if (document.head) {
    document.head.removeChild(meta);
  }

I'm not sure why but it requires a lot of step-in to just pull out of this if or is it a racing issue.

then we steps in
webpack:///src/handleSideEffects.jsx

    viewportMeta.setEnabled(next.device.isMobile && Boolean(next.visibleEmbIds.overlay));
  • Boolean(next.visibleEmbIds.overlay) is false
  • next.device.isMobile is true
export default {
  setEnabled(shouldBeEnabled: boolean): void {
    if (shouldBeEnabled && !isPresent()) {
      add();
    } else if (!shouldBeEnabled && isPresent()) {
      remove();
    }
  },
};

it goes back to remove() and this time actually change the layout to desktop.

There is an interesting comment in webpack:///src/handleSideEffects.jsx
after viewportMeta.setEnabled(next.device.isMobile && Boolean(next.visibleEmbIds.overlay));

which is

    if (showingOverlay && next.device.isIOS) {
      // iOS Safari seems to not always fire resize and scroll events after the viewport change that
      // appending the above meta tag causes, so we dispatch a quick series of setViewport and
      // setScrollPosition actions to ensure the state's viewport and scrollPosition properties are
      // up-to-date. This is important because in some cases on iOS, we use those values to position
      // the overlay.
      timer(0, 100).pipe(
        take(4),
        mergeMap(() => merge(createViewportChanges(), createCurrentScrollPosition()))
      )
        .subscribe(dispatch);
    }

I wonder if we have a similar case here but because we are not next.device.isIOS it doesn't go through this.

Let's put a breakpoint on viewportMeta.setEnabled(…),
then manually override: next.device.isIOS and set it to true. Ah maybe that worked.

Let's change the UA to be iOS.

ah nah changing the UA to be Safari iOS didn't solve it.

@wisniewskit it's all I can do for now.

@karlcow karlcow changed the title www.casio.com - Desktop site instead of mobile site when accessign the page www.casio.com - Desktop site instead of mobile site when accessing the page May 27, 2020
@karlcow
Copy link
Member

karlcow commented May 27, 2020

This is working for me.

@softvision-oana-arbuzov
Copy link
Member

I can confirm that.
image

Tested with:
Browser / Version: Firefox Preview Nightly 200526 (🦎 78.0a1-20200522094316)
Operating System: Samsung Galaxy S6 Edge (Android 7.0) - 1440 x 2560 pixels (~577 ppi pixel density)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
browser-fenix engine-gecko The browser uses the Gecko rendering engine priority-normal severity-important A non-core broken piece of functionality, not behaving the way you would expect. type-viewport
Projects
None yet
Development

No branches or pull requests

4 participants