planet.webcompat.com

Mike Taylor's Web Log by Mike Taylor at

The other day I was doing some research on DOM methods and properties that Chrome implements, and has a usecounter for, but don't exist in Firefox.

defaultstatus caught my eye, because like, there's also a use counter for defaultStatus.

(The discerning reader will notice there's a lowercase and a lowerCamelCase version. The less-discerning reader should maybe slow down and start reading from the beginning.)

As far as I know, there's no real spec for these old BOM (Baroque Object Model) properties. It's supposed to allow you to set the default value for window.status, but it probably hasn't done anything in your browser for years.

image of some baroque art shit

Chrome inherited lowercase defaultstatus from Safari, but I would love to know why Safari (or KHTML pre-fork?) added it, and why Opera, Firefox or IE never bothered. Did a site break? Did someone complain about a missing status on a page load? Did this all stem from a typo?

DOMWindow.idl has the following similar-ish comments over the years and probably more, but nothing that points to a bug:

This attribute is an alias of defaultStatus and is necessary for legacy uses. For compatibility with legacy content.

It's hard to pin down exactly when it was added. It's in Safari 0.82's kjs_window.cpp. And in this "old" kde source tree as well. It is in current KHTML sources, so that suggests it was inherited by Safari after all.

Curious to see some code in the wild, I did some bigquerying with BigQuery on the HTTPArchive dataset and got a list of ~3000 sites that have a lowercase defaultstatus. Very exciting stuff.

There's at least 4 kinds of results:

1) False-positive results like var foo_defaultstatus. I could re-run the query, but global warming is real and making Google cloud servers compute more things will only hasten our own destruction.

2) User Agent sniffing, but without looking at navigator.userAgent. I guess you could call it User Agent inference, if you really cared to make a distinction.

Here's an example from some webmail script:

O.L3 = function(n) {
    switch (n) {
        case 'ie':
            p = 'execScript';
            break;
        case 'ff':
            p = 'Components';
            break;
        case 'op':
            p = 'opera';
            break;
        case 'sf':
        case 'gc':
        case 'wk':
            p = 'defaultstatus';
            break;
    }
    return p && window[p] !== undefined;
}

And another from some kind of design firm's site:

browser = (function() {
    return {
        [snip]
        'firefox': window.sidebar,
        'opera': window.opera,
        'webkit': undefined !== window.defaultstatus,
        'safari': undefined !== window.defaultstatus && typeof CharacterData != 'function',
        'chrome': typeof window.chrome === 'object',
        [snip]
    }
})();

3a) Enumerating over global built-ins. I don't know why people do this. I see some references to Babel, Ember, and JSHint. Are we making sure the scripts aren't leaking globals? Or trying to overwrite built-ins? Who knows.

3b) Actual usage, on old sites. Here's a few examples:

<body background="images/bvs_green_bkg.gif" bgcolor="#598580" text="#A2FF00" onload="window.defaultstatus=document.title;return true;">
<body onload="window.defaultstatus='Индийский гороскоп - ведическая астрология, джйотиш онлайн.'">

This one is my favorite, and not just because the site never calls it:

function rem() {
  window.defaultstatus="ok"
}

OK, so what have we learned? I'm not sure we've learned much of anything, to be honest.

If Chrome were to remove defaultstatus the code using it as intended wouldn't break—a new global would be set, but that's not a huge deal. I guess the big risk is breaking UA sniffing and ended up in an unanticipated code-path, or worse, opting users into some kind of "your undetected browser isn't supported, download Netscape 2" scenario.

Anyways, window.defaultstatus, or window.defaultStatus for that matter, isn't as cool or interesting as Caravaggio would have you believe. Thanks for reading.

otsukare by Karl Dubost at

So on January 7, 2019, I wrote the first edition of "They Fixed It!"

This is a new chapter. I'll try to move forward in a semi-regular basis.

Let's see what are the cool things which have been fixed since that last report and helps webcompat to be better on the Web.

Thanks to them!

Otsukare!

Mike Taylor's Web Log by Mike Taylor at

Happy new years.

We got really, really close to being able to ship window.event, but had to back that out from shipping to Firefox 65 release in Bug 1520756 (like we had to do in 63).

Back in 2014's classic post "Why FF says that window.event is undefined? (call function with added event listener)*" I mentioned the global event that Gecko never supported (because it was a non-standard IE-ism). Years passed and things didn't get better—mostly because WebKit and thus Blink inherited said IE-ism—so we added some hot legacy garbage to the DOM Standard and got it implemented in Firefox.

Things looked really promising on mobile until our desktop beta population started reporting bugs against banks and government sites (especially in India). Like, "can't type in this input" kinds of bugs.

Bug 1479964 has the details, but the basic gist is as follows (inside a keypress event handler):

var keyCode = window.event ? event.keyCode : event.which;

The presence of window.event presumes you can get a non-zero keyCode from the event object, and then you can take that and do something amazing on your bank and government login form.

Let's look at the Blink source to see how they handle keyCode inside a keypress handler:

  // Firefox: 0 for keydown/keyup events, character code for keypress
  // We match Firefox
  if (type() == EventTypeNames::keypress)
    char_code_ = key.text[0];

  if (type() == EventTypeNames::keydown || type() == EventTypeNames::keyup)
    key_code_ = key.windows_key_code;
  else
    key_code_ = char_code_;

For keypress, they set charCode to something meaningful, but also set keyCode to charCode. So that's what we're trying to do now. Like most things that break websites, there isn't like, a spec for any of this stuff yet (but if someone wants to take care of that, be my guest, probably good to read over JavaScript Madness: Keyboard Events as you tackle that).

But like I wrote in the title, everything is terrible. We discovered late in the 65 beta cycle that Atlassian Confluence was busted. Like, "can't type the period in a comment" busted.

The reason it's broken there is due to some code that tries to handle delete and backspace key presses in selections, and sometimes prevent that from happening (I guess?).

// Webkit will fire keyDown and keyUp for backspace and delete (even if one is suppressed).
ed.onKeyDown.add(deleteAndBackspaceKeyHandling);
ed.onKeyUp.add(deleteAndBackspaceKeyHandling);
tinymce.isGecko && ed.onKeyPress.add(deleteAndBackspaceKeyHandling);

So you've got 3 event listeners trying to do the same thing, but only Firefox sees the keypress one.

function deleteAndBackspaceKeyHandling(ed, e) {
    var keyCode = e.keyCode;
    ...

    if (!ed.selection.isCollapsed()) {
        addCursorTargetParagraphsToContent(ed.getBody());
    } else if (keyCode === KEY_CODE.BACKSPACE && someOtherJunk()) {
        tinymce.dom.Event.prevent(e);
    } else if (keyCode === KEY_CODE.DELETE && someOtherJunk()) {
        tinymce.dom.Event.prevent(e);
    }
    return true;
}

KEY_CODE.BACKSPACE is 46. 46 is the code for a PERIOD in a keypress event, but the code for BACKSPACE in keydown/keyup events. So in Firefox, and Firefox only, it thinks it's seeing a backspace and prevents the default action (which is to let the user type the period).

Confluence is especially tricky because they offer a self-hosted version in addition to their cloud-hosted thing. Breaking intranet webapps is a non-starter, so we've prevented this set of changes from shipping to release (again). And we'll try to come up with some creative hack so we can fix a ton of mobile sites but not break outdated intranet Confluence instances.

Anyways, like I said, happy new years or whatever.

otsukare by Karl Dubost at

This is a new chapter. I'll try to move forward in a semi-regular basis. The work done by the awesome core engineers of Mozilla is essential. Some of the things they fix or explain have direct impact on the web compatibility work. A couple of years ago at Mozilla Hands. I gave a lightning talk called "They fixed it". I quickly put forward to the audience all the (webcompat) cool bugs which had been fixed by Core engineers.

  • The site Channel NewsAsia is using a transform with a rotation for their headers when scrolling the content. The headers had a wider gap in Firefox than Chrome. An issue was reported. Brian Birtles digged into the isssue. He explained in details why the interpolation looks worse in Firefox than Chrome. Firefox has implemented the new specification. Web developers rely on an old version of the algorithm in Chrome. Chrome will change soon(?) and it will be equally broken. That was quite cool, Brian. Thanks!
  • I will probably write often about the Virtual Viewport and associated issues. Basically to make it short, Chrome/Safari have the notion of a virtual viewport in addition to the device viewport. This creates a series of different behavior for websites on Chrome vs Firefox on Android. We had a lot of webcompat issues about it. So as I said I will talk more about it in the future. In the mean time big big shout out to Hiroyuki Ikezoe and Botond Ballo
  • Orthogonal to the Virtual viewport I just mentionned, there's work to expose the Visual Viewport API. Jan Henning just before christmas 2018 fixed Implement event handlers of the Visual Viewport API. This is part of the Visual Viewport interface. Thanks.

otsukare by Karl Dubost at

Identifying the origin of the issue

On webcompat, we try to diagnose bugs reported about sites, we do not have the original sources. If we are lucky, web developers have included a way to reach the original JavaScript source files (through sourcemap). But modern websites have often a series of optimization layers (with multiple minifications).

To check during the investigation, that we thought was right we need to play with the code. With real CSS files (as opposed to CSS in JavaScript), it is easy to hand make a working solution. With JavaScript it's near impossible apart of just observing why it fails and guessing how it could work.

How do we overcome the lack of access to JavaScript?

One possible solution is to create a local proxy on your laptop and to use a man in the middle technique to capture the HTTP requests and replace the website JavaScript HTTP request by a call to a local file of your choice. On macOs for example, you could use Charles Proxy or on Unix you may want to use MITM

This is tedious and not always successful, specifically when JavaScript is written and minified on the fly.

Last week, a lunch in Tokyo

During a lunch with Jason Laster (@jasonlaster11), Brian Birtles (@brianskold) and Arai-san (@arai_unmht), I was specifically discussing about my woes when debugging websites and how cool it would be to just be able edit the JavaScript file inside the devtools debugger. Arai-san said « Oh but I have something a bit similar to this. » So I told them… « Ship it! »

The afternoon went on with the current work in the Mozilla Tokyo office. But just before dinner, Arai-san decided to be my hero. They worked during the afternoon on packaging properly their tool and makes it an add-on for the Firefox devtools.

And indeed it was shipped by the end of the day! Discover Developer In The Middle. You can select a resource, prettify it in your favorite editor, change some logic, save it inside the UI and just reload the page. Magical and so much more practical.

This is the first version, please do use it! Try it and send feedback about the tool.

Thanks Arai-san!

Post-Scriptum

I never stop to be amazed by the quality, expertise and kindness of the Mozilla Japan team. I'm coming to the office once a week, because I live a bit far from the Tokyo office, but I'm definitely blessed to meet them every week.

Otsukare!

When Can I Use updates by Alexis Deveria at

CSS overflow property: Originally a single property for controlling overflowing content in both horizontal & vertical directions, the `overflow` property is now a shorthand for `overflow-x` & `overflow-y`. The latest version of the specification also introduces the `clip` value that blocks programmatic scrolling.

Subscriptions