Closed Bug 923360 Opened 11 years ago Closed 10 years ago

Unable to toggle widgets (comments, gallery, search) on mobile wired.com

Categories

(Web Compatibility :: Site Reports, defect)

Other
Android
defect
Not set
normal

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: miketaylr, Unassigned)

References

()

Details

(Whiteboard: [mobile-compat-form][mobify][clientsniff] [country-all][sitewait])

Site: http://www.wired.com/rawfile/2013/10/mauricio-palos/
Unable to toggle Disqus mobile comments on mobile wired.com

:: Steps To Reproduce

1. Go to http://www.wired.com/rawfile/2013/10/mauricio-palos/
2. At the bottom, click/tap on SHOW COMMENTS

:: Expected Result

Comments are toggled

:: Actual Result

Nothing happens

:: Additional Information

Software Version: A
Reporter's User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:27.0) Gecko/20100101 Firefox/27.0
Something fishy going on at the server level. If I spoof as Firefox for Android 7 with Chrome (the latest they have), clicking on <div id="comments-toggle">SHOW COMMENTS</div> does nothing. Then with the same Chrome, spoof as Safari iOS 6 and clicking toggles the comments.

Unsure why spoofing the UA in desktop Firefox refuses to give me the mobile version of the page...

I suspect there's something wrong in the touch event detection, but haven't dug in yet. They're using Mobify (and Zepto), so those may be the culprits.
(though that makes nearly zero sense, as you can reproduce it being broken and not from within Chrome)
Still haven't figure this one out quite yet (fun times when there's 94 scripts to consider).

They're using an older version of Zepto (coming from Mobify) that doesn't recognize the Firefox for Android UA as anything other than "not webkit": https://gist.github.com/miketaylr/fbb6a7787e91b4dd775b/raw/24a107cf84d9ee44614e5e00de0a5b9bd13cd54d/gistfile1.txt

(As of today Zepto does recognize FF4A as an android browser though.)
Quick update before I fall asleep and forget:

DISQUS is a red-herring (sorry DISQUS guys)--it turns out basically every interactive widget it broken (Gallery button, hamburger menu, search).

If you look at http://cdn.mobify.com/sites/wired/production/mobify.js and search for "-toggle" you'll find all the areas where this is broken.

There's some chained write method that sets up all the event handling: (just an excerpt)

write("<!-- gallery thumbs & disqus comments toggle -->").write('<script>(function(e){function t(){e("ul.gallery-thumbnails").toggleClass("on")}function n(){e("#disqus_thread").toggleClass("on")}e("#gallery-toggle").tap(t),e("#comments-toggle").tap(n)})(Mobify.$),function(e){"ontouchend"in window||e(document).delegate("body","click",function(t){e(t.target).trigger("tap")})}(window.Zepto)</script>')write("<!-- gallery thumbs & disqus comments toggle -->").write('<script>(function(e){function t(){e("ul.gallery-thumbnails").toggleClass("on")}function n(){e("#disqus_thread").toggleClass("on")}e("#gallery-toggle").tap(t),e("#comments-toggle").tap(n)})(Mobify.$),function(e){"ontouchend"in window||e(document).delegate("body","click",function(t){e(t.target).trigger("tap")})}(window.Zepto)</script>')

So i need to look into why triggering these "tap"s is failing and if it's the older Zepto's fault or if there's a conflict elsewhere.

It's worth noting that Mobify.config.os is "android" and Mobify.config.smartphone and Mobify.config.touch are both "true".

Time for sleep ...zzzzzz
Summary: Unable to toggle Disqus mobile comments on mobile wired.com → Unable to toggle widgets (comments, gallery, search) on mobile wired.com
Hi Roman, just found you over in 754404. Any insight as to what's going on here?
See Also: → 754404
Whiteboard: [mobile-compat-form] → [mobile-compat-form][mobify]
In http://cdn.mobify.com/sites/wired/production/mobify.js, right near the top:

i = !navigator.userAgent.match(/webkit/i),
        s = function (e, n) {
            var r = t[e] = t[e] || [];
            r.push(n)
        }, o = e.ark = {
            store: function (e, t, n) {
                typeof e == "function" && (n = t, t = e, e = r()),
                !n && t.call ? (i && s(e, t), t()) : s(e, t)
            },
...


In the e.ark.store function, if you're Webkit i is false so in (i && s(e, t), t()), t gets called (when t is a function, otherwise s(e,t) is called).

If you're not WebKit, i is true, so s(e,t) is called before t()... and somehow that breaks everything. This is the limit of my current understanding though. store gets called 5 times and e has the following values "jquery", "lib", "combo", "util", "enhance".

Changing i to true causes everything to work as expected in Firefox for Android. But I don't know what bug or behavior they're trying to work around in whatever they think they're identifying with !navigator.userAgent.match(/webkit/i).

We should reach out to Mobify, not Wired, IMO.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Whiteboard: [mobile-compat-form][mobify] → [mobile-compat-form][mobify][clientsniff][contactready]
Whiteboard: [mobile-compat-form][mobify][clientsniff][contactready] → [mobile-compat-form][mobify][clientsniff][contactready] [country-all]
Small observation on the run:
The non-webkit code

(i && s(e, t), t()) 

will both store a reference to the function (in an array) *and* run it immediately, while the webkit-code:

 s(e, t)

will only store the reference. If that reference is used to call the method at a later point it will be run twice. Might mess things up? Did you try commenting out ", t()"?
Mike: look at https://github.com/mobify/mobifyjs/blob/v1.1-windows-phone-compat/api/ark.js

Some guesswork: Mobify for some reason uses document.open() and document.write() to (re)-generate a document. They do this from timeouts in a few places (according to some source code comments I noticed elsewhere it's because doing document.open() syncronously will mess up logging - I assume contents of some calls to console.log() will get dropped on the floor when they do open()?)

Now, calling document.write() from a timeout is of course to set yourself up for a race condition. *If* the document is fully parsed when the timeout runs, the document will  be blown away and replaced  by the new stuff - if not, the document.write() content will be appended to the document being parsed. If, say, the parser is waiting for a slow loading external script later in the document there's basically no way you can predict where the document.write() content will end up - as a new document or at a random place in the existing one..

Roman, do you think race conditions caused by document.write() in timeouts might cause the problems we're seeing on Wired?

This test might be relevant.
https://github.com/mobify/mobifyjs/blob/89ec4e5f8f0a85d6e371abd0d6a7fe782f81bfd8/tests/capture.html#L305
See Also: → 950471
When document.open() / document.write() overwrites the old document, most browsers will create a new ES environment. Apparently, WebKit does not, and apparently this behaviour makes things a lot simpler for what Mobify.js is trying to do. They need to work around the behaviour of the other engines - Mobify tries to store a list of scripts that need re-creating in the new document in the Mobify.ark feature - but the workaround code is somewhat buggy..

1) The "combo" part of Mobify - starting here:

Mobify.ark.store("combo", function () {
    (function (e, t) {
        var n = function (e, t) {
            var n = a[e.split("#")[0]];

contains </script> tags. If "combo" is stored in Mobify.ark.store() to be re-created in the document.write() output, the </script> tags will break the script being written into the new page, so things will fall apart.

2) The script tags are being output in a somewhat odd order, I think - for example, there's first the a.js tag (marked async) which does not define window.Mobify, immediately afterwards is an inline script:

 <script>var Zepto=Mobify.$</script>

which causes the first of many "foo isn't defined" errors. The order (per the code on github) depends on doing for...in over the properties of an object.
Whiteboard: [mobile-compat-form][mobify][clientsniff][contactready] [country-all] → [mobile-compat-form][mobify][clientsniff] [country-all]
A fix for issue #1 is in progress: https://github.com/mobify/mobifyjs/pull/227

as for #2, I don't think I understand this fully yet - seems the scripts are added in the same order (more or less) in other browsers. Maybe Mobify.ark simply fails to do what it aims to, and a site as complex as wired.com will only survive document.open() / write() in browsers that keep the old ES environment? Maybe it's a race condition because some of those scripts have @async properties set and thus may run in different orders on different implementations?
Flags: needinfo?(roman) → needinfo?(shawnjan)
Seems wired.com fix isn't far off - response from Mobify devs:

> We've fixed the issues, both in mobify.js as well as issues with their
> project itself. One of our account managers should be contacting them soon
> to let them know about the fixes! I will keep you in the loop on any
> progress for them accepting the changes and deploying them to production :)

Not deployed quite yet but hopefully soon! :-)
See Also: → 956915
Whiteboard: [mobile-compat-form][mobify][clientsniff] [country-all] → [mobile-compat-form][mobify][clientsniff] [country-all][sitewait]
Comments and search are working for me, formatting is still a little off (another bug for that). Didn't find a gallery to test.
Yessss! Wired.com is readable in Firefox for Android again! Thanks Mobify and Wired!

Some lesser issues will be or are bugged. TBC..
Status: NEW → RESOLVED
Closed: 10 years ago
Flags: needinfo?(shawnjan)
Resolution: --- → FIXED
Awesome! Good to know they pushed up our fixes :)
See Also: → 1456313
Product: Tech Evangelism → Web Compatibility
Component: Mobile → Site Reports
You need to log in before you can comment on or make changes to this bug.