otsukarehttps://www.otsukare.info/2023-09-06T17:51:00+09:00Thoughts after a day of workMolly2023-09-06T17:51:00+09:002023-09-06T17:51:00+09:00Karl Dubosttag:www.otsukare.info,2023-09-06:/2023/09/06/molly<p>Molly Holzschlag passed away.</p><p><a href="https://www.tucsonsentinel.com/local/report/090523_molly_holzschlag/">Molly passed away at 60.</a></p>
<p><img alt="Portrait de Molly Holzschlag" src="https://www.otsukare.info/images/20230806-molly.jpg"></p>
<p>A blog post of this nature is never easy. She was so larger than life that she puts a print on each of us, who have discovered the Web early on.</p>
<p>My first discovery of Molly Holzschlag was through the <a href="https://people.apache.org/~jim/NewArchitect/webtech/index.html">WebTechniques magazine published from 1996 to 2002</a>. This was a real magazine about the Web. You would recognize early writers like Laura Lemay, Lynda Weinman, etc. She had a column there called Integrated Design. She started writing it on <a href="https://people.apache.org/~jim/NewArchitect/webtech/1999/09/desi/index.html">Web Techniques. September 1999</a>.</p>
<blockquote>
<p>Style sheets are one of the most effective innovations for designers; they make it easier to manage style elements via a single, linked sheet. When the time comes for a minor style update, such as a change in the color of article headers, the change can be implemented throughout the site in a few seconds.</p>
</blockquote>
<p>Then she was part of the <a href="https://en.wikipedia.org/wiki/Web_Standards_Project">WaSP (Web Standards Project)</a>, including Jeffrey Zeldmann and others, an effort to bring interop in between browsers and educate Web developers on using Web Standards.</p>
<p>A <a href="http://web.archive.org/web/20000818092018/http://www.molly.com/molly/index.html">capture of Molly's site in 2000</a>.</p>
<p>I was hired at W3C in July 2000 to work on improving the quality of W3C specifications. And I had a long time interest in also improving the knowledge of W3C specs for the French community.</p>
<p>On May 2002, I was attending the <a href="https://web.archive.org/web/20100710142031/http://www2002.org/">World Wide Web Conference in Hawaii</a> and I met Molly there for the first time. We had a long discussion (seating on chairs near the pool) about evangelization efforts, the W3C, WasP and the role that each could play. Together with <a href="https://olivier.thereaux.net/">Olivier Théreaux</a> (working at W3C at that time), we had also a strong desire to have a better relationship of W3C with the Web developers community and were discussing similar efforts.</p>
<p>We created the <a href="https://lists.w3.org/Archives/Public/public-evangelist/">public-evangelist mailing-list at W3C</a>. She introduced <a href="https://lists.w3.org/Archives/Public/public-evangelist/2002Jul/0008.html">herself on the list</a>.</p>
<p>Then I met her regurlaly in my professional career, on conferences, at meetings and we even worked together in the Opera Developer Relations Team in 2011.</p>
<p>Today on Mastodon and blogs, you will see a lot of messages on how important she had been in the life of people from many continents, many places, for people who praised the Web profession as a craft.</p>
<p>Thanks for all the magical memories and your unconditional love for the Web.</p>
<p>Otsukare!</p>The lucky day of me falling hard professionally2023-08-31T08:05:00+09:002023-08-31T21:25:00+09:00Karl Dubosttag:www.otsukare.info,2023-08-31:/2023/08/31/career-mistakes<p>Yes, you will do mistakes in your career. This one taught me a lot of things.</p><p>Let me tell you a story…</p>
<p><img alt="Pawn of lucky cat (manekineko) in the air with my reflection in the window" src="https://www.otsukare.info/images/20230831-manekineko.jpg"></p>
<p>In my first professional year (~1995/1996) as a ~~web developer~~, well webmaster at that time, I was working on the BNP website. Yes, <strong>the</strong> <a href="https://mabanque.bnpparibas">BNP French bank website</a>, except at that time it was only a couple of hundreds static web pages (maybe around 300).</p>
<p>The client asked us to fix the footer on all these html files. The job was assigned to me.</p>
<p>I opened the local website FTP folder with all the files in it. I started to look at the HTML and noticed a simple search and replace would not do it.</p>
<p>Let's use <strong>Regex for parsing/fixing HTML</strong>. Haha.</p>
<p>Very proud of my regex, I executed it on all files. Sure I had done a good job! I dropped the folder in the FTP application and all files on the live site were replaced.</p>
<p>Oooops!</p>
<p>I had made a mistake in my regex. I replaced every characters in the HTML by character + space. The site was now displaying the raw ascii characters.</p>
<div class="highlight"><pre><span></span><code>< H T M L >
< H E A D >
< T I T L E > B N P < / T I T L E >
</code></pre></div>
<p>and so on. The roughly 300 files. I had no backup. Cold sweat.</p>
<p>We were around 6 or 7 people working in this Web agency as webmasters. I asked everyone</p>
<ol>
<li>to stop everything they were doing.</li>
<li>to not visit the BNP website.</li>
<li>to save locally every cached files in their browser history and/or their local backup if they had and send them to me.</li>
</ol>
<p>On a couple of hours we have been able to recreate the site and with a bit of manual work too.</p>
<p>That was one of my most formative mistakes at the beginning of the Web.</p>
<ol>
<li>Work on a backup.</li>
<li>Do not synchronize before checking locally.</li>
<li>Install a local web server on your computer.</li>
<li>Browser caching is cool!</li>
<li>Teams are awesome. You are not alone. You can reach out for help.</li>
<li>Create a better team process for working on sites.</li>
<li><a href="https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags"><strong>Do not use Regex for parsing HTML</strong></a></li>
</ol>
<p>Mistakes will happen. Learn from them.</p>
<p>Otsukare!</p>Webcompat Outreach, Mon Amour…2023-05-23T14:00:00+09:002023-05-25T07:10:00+09:00Karl Dubosttag:www.otsukare.info,2023-05-23:/2023/05/23/webcompat-outreach<p>About some of the challenges of webcompat outreach and what you can do.</p><p>I was listening a <a href="https://www.igalia.com/chats/baseline">podcast</a> by <a href="https://bkardell.com">Brian Kardell</a> and <a href="https://meyerweb.com">Eric Meyer</a>. Toward the end, they are mentioning the challenges of outreach in the context of broken Web sites.</p>
<p>Brian says:</p>
<blockquote>
<p>It would have to be, enough people would have to complain. A <strong>browser wouldn't tell a lie</strong> if they could reach out and get you to update it.</p>
</blockquote>
<p>I wrote in the past <a href="https://www.otsukare.info/2013/11/08/ua-override">about the need for browsers to lie to websites</a> and the consequences for both the websites.</p>
<ol>
<li>Websites fails to support a browser A for a reason X. Sometimes not enough market share for them to care.</li>
<li>The browser A lies to be able to get the right code path.</li>
<li>The websites analytics show that browser A is not accessing the website.</li>
<li>Goto 1.</li>
</ol>
<blockquote>
<p>And if you wanted to update my website or your website, that would be relatively easy. They would just send us an email and we'd be like, 'Oh, crap, let me fix that right away.'</p>
</blockquote>
<p>It's not that easy. It is still hard to contact individuals. It takes time. The person has sometimes no real control over their "personal website". And the Benefits/Cost Ratio is very low. (Note that Brian and Eric <a href="https://mastodon.cloud/@bkardell@toot.cafe/110418187943254668">were talking about their actual personal websites</a> and indeed this is easier to contact public tech savy people.)</p>
<blockquote>
<p>But when it comes to Wells Fargo, or Yahoo, or some big site with lots and lots and lots of people who go there…</p>
</blockquote>
<p>Here it depends on the category of websites. Yahoo! is a lot easier to contact, than certain types of websites:</p>
<ul>
<li>Bank</li>
<li>Casino</li>
<li>Illegal streaming</li>
<li>certain Adult content</li>
<li>Governments</li>
<li>All sites which are flyers or one-off marketing stunts</li>
</ul>
<p>Another parameter: culture!</p>
<p>The structure of business for creating websites and the relationships of the Web developers with their direct and indirect hierarchy is not the same depending on the regions of the world. For some Web developers it will be very hard to be able to challenge the decision making process with regards to a website. In some circumstances, the bottom-up approach of contacting will not work, and you would need to go to a top-down approach.</p>
<p>Brian continues:</p>
<blockquote>
<p>CNN.com, right. And can we actually reach them? Can we get them to change it? Even worse, for ones that are under the covers, they're the same, but you don't know. They resell, effectively. It's a website's package and it gets very, very hard to know who to reach. They're unresponsive, because they've sort of outsourced their website, really. So there's not always a person you can reach out to. But in the meantime, everybody's going to complain, so they'll lie. And those are the sites really. Those sites are going to be included every time. You know what I mean?The things that we estimate usage on are estimated from looking at the HP requests to lots and lots and lots of websites. And then it's extrapolated from there. But the set of websites is which ones are popularly loaded. And in the grand scheme of things, our websites are not destinations.</p>
</blockquote>
<p>So it's when I thought about the title of this post: <strong>Webcompat Outreach, Mon Amour</strong>. Last time, I used that reference, it put me in hot waters, because the person, reading this in a comment, thought I was literal and actually calling her "Mon Amour", while I was making a reference to <a href="https://en.wikipedia.org/wiki/Hiroshima_mon_amour">Hiroshima Mon Amour</a>, a movie by Alain Resnais, and written by Marguerite Duras. Culture differences as mentioned earlier. This poetic movie is subtly revealing our tensions at a global and personal level.</p>
<p><img alt="Still from the movie where the main actress says: Sometimes we have to avoid thinking about the problems life presents. Otherwise we'd suffocate." src="https://www.otsukare.info/images/20230523-hiroshima-mon-amour.gif"></p>
<p>Hence webcompat outreach where the simple minimal code mistakes or choices affects a large number of people. Each decisions we make have consequences on the balance of the ecosystem. We pour love into our art craft and still be constrained by the machinery of the administration.</p>
<p>I have written about outreach multiple times. You do not need to work for a big company to be able to contact a website, and every invidual can help by communicating clearly to people handling the website presenting issues. This is not an impossible task. It just takes patience, courage and resilience.</p>
<p>In <a href="https://www.otsukare.info/2016/02/05/bug-ready-for-outreach-howto">what do you need to do before doing outreach</a>, my last section, mentioned all the reasons why the outreach might fail. There are techniques to try to find people online and to track down who to contact. On the <a href="https://webcompat.com/">webcompat.com</a> website, I had written about <a href="https://webcompat.com/contributors/site-outreach">different techniques to find a way to reach the right person</a> and the attitudes you need to have:</p>
<blockquote>
<ul>
<li><strong>Be tactful</strong>: People we are trying to reach have their own set of constraints, bosses, economic choices etc. "Your web site is bad" will not lead anywhere, except NOT getting the site fixed.</li>
<li><strong>Be humble</strong>: We are no better, we also make mistakes in practice. Our own recommendations can become outdated as technical or economic circumstances change.</li>
<li><strong>Let it go</strong>: Sometimes outreach just doesn't work. The person at the end of the other line may say "no" or worse, may not answer. It can be very frustrating. It's okay. Accept it and move on.</li>
<li><strong>Be passionate</strong>: The passion is in being able to find the right contact in a company without harassing them. Every effort helps.</li>
<li><strong>Share with consideration</strong>: Share any contact you attempted or made in the issue comments section. It helps everyone to know the status so they can pitch in or not repeat work. That said - be careful to not disclose private information such as names and emails. You may simply say: "I contacted someone at $COMPANY", "Someone from $COMPANY said this…"</li>
</ul>
</blockquote>
<p>Otsukare!</p>Web Inspector Search Regex2023-05-09T10:20:00+09:002023-05-09T10:57:00+09:00Karl Dubosttag:www.otsukare.info,2023-05-09:/2023/05/09/web-inspector-regex<p>Web Inspector Search feature allows to use regex expression.</p><p>Finding the right keyword in a search among thousand of lines of CSS, JavaScript, HTML code can be dreadful. There are solutions.</p>
<p><img alt="A lot of bouddha sculpted in wood, which looks very similar" src="https://www.otsukare.info/images/20230509-bouddha.jpg"></p>
<p>I was searching for <code>navigator.userAgent</code> on the NYTimes website. All developer tools have search features. In Safari <a href="https://webkit.org/web-inspector/">Web Inspector</a>, Command + Shift + F will start the search tab.</p>
<p>The matched results for <code>userAgent</code> are <code>userAgent</code> but also:</p>
<ul>
<li><code>isInWebViewByUserAgent</code></li>
<li><code>userAgentData</code></li>
<li><code>getUserAgent</code></li>
<li><code>userAgentIndicatesApp</code></li>
<li><code>UserAgentClientHints</code></li>
</ul>
<p>I wanted to be able to reduce the search space. Let's try regex.</p>
<p>So I searched for</p>
<p><code>\.userAgent</code> to match only the strings starting with a dot. We can't match only <code>navigator.userAgent</code> because someone might have made a variable of it. But this is not enough. I also wanted to remove other references to an object with a trailing names, by avoiding any additional ASCII characters.</p>
<p><code>\.userAgent[^a-zA-Z]+</code></p>
<p>That's it.</p>
<p>To access this feature you need to go to Settings in Web Inspector, then General, then check Regular Expression in the search section.</p>
<p><img alt="Screenshot of the Web Inspector with the regex search for UserAgent" src="https://www.otsukare.info/images/20230509-web-inspector-regex.png"></p>
<p>Otsukare!</p>Blade Runner 20232023-02-03T16:30:00+09:002023-02-03T16:39:00+09:00Karl Dubosttag:www.otsukare.info,2023-02-03:/2023/02/03/blade-runner<p>Never Ending Story.</p><p><img alt="Graffiti of a robot on a wall with buildings in the background." src="https://www.otsukare.info/images/20230203-robot.jpg"></p>
<p>Webcompat engineers will never be over their craft. I've seen things you people wouldn't believe. Large websites broken off the shoulder of developer tools. I watched Compat-beams glitter in the dark near the Interoperability Gate. All those moments will be lost in time, like tears in rain. <a href="https://www.youtube.com/watch?v=NoAzpa1x7jU">Time to die</a>.</p>
<p>In other news: <a href="https://webkit.org/blog/13706/interop-2023/">Pushing Interop Forward in 2023</a></p>
<blockquote>
<p>Now we are pleased to announce this year’s Interop 2023 project! Once again, we are joining with Bocoup, Google, Igalia, Microsoft, and Mozilla to move the interoperability of the web forward.</p>
</blockquote>
<p>Otsukare!</p>Quirks, Site Interventions And Fixing Websites2023-01-16T23:11:00+09:002023-01-16T23:12:00+09:00Karl Dubosttag:www.otsukare.info,2023-01-16:/2023/01/16/webkit-quirks<p>Quirks are here to fix broken websites. What does that mean?</p><p>Jelmer recently asked : "<a href="https://front-end.social/@jelmerdemaat@mastodon.social/109681646047565553">What is Site Specific Hacks?</a>" in the context of the Web Inspector.</p>
<p><img alt="Red cinema building with windows and a sign cellphone repair." src="https://www.otsukare.info/images/20230116-repair.jpg"></p>
<p>Safari Technical Preview 161 shows a new button to be able to activate or deactivate Site Specific Hacks. But what are these?</p>
<p><img alt="Panel in the Web inspector helping to activate or deactivate some options." src="https://www.otsukare.info/images/20230116-webinspector.png"></p>
<h2>Site Specific Hacks?</h2>
<p>Site Specific Hacks are pieces of WebKit code (called Quirks internally) to change the behavior of the browser in order to repair for the user a broken behavior from a website.</p>
<p>When a site has a broken behavior and is then not usable by someone in a browser, there are a couple of choices:</p>
<ul>
<li>If the broken behavior is wide spread across the Web, and some browsers work with it, the standard specification and the implementation need to be changed.</li>
<li>If the broken behavior is local to one or a small number of websites, there are two non-exclusive options<ul>
<li><a href="https://www.otsukare.info/2015/05/11/how-to-contacts">Outreach</a></li>
<li><a href="https://github.com/WebKit/WebKit/blob/main/Source/WebCore/page/Quirks.cpp">Quirk</a> (WebKit), <a href="https://github.com/mozilla-extensions/webcompat-addon">Site Intervention</a> (Gecko), Patch (Presto)</li>
</ul>
</li>
</ul>
<p>Outreach improves the Web, but it is costly in time and effort. Often it's very hard to reach the right person, and it doesn't lead necessary to the expected result. Websites have also <a href="https://www.otsukare.info/2014/11/04/web-agencies-priorities-skills">their own business priorities</a>.</p>
<p>A site specific hack or a quirk in WebKit lingo means a fix to help the browser cope with a way of coding of the Website which is failing in a specific context. They are definitely bandaid and not a strategy of development. They should be really here to give the possibility for someone using a browser to have a good and fluid experience. Ideally, outreach would be done in parallel and we would be able to remove the site specific hack after a while.</p>
<h2>A Recent Example : FlightAware Webapp</h2>
<p>I recently removed a <a href="https://github.com/WebKit/WebKit/pull/8233">quirk in WebKit</a>, which was put in place in the past to solve an issue.</p>
<p>The bug was manifesting for a WebView on iOS applications with devices where <code>window.devicePixelRatio</code> is <code>3</code>.</p>
<p>with this function</p>
<div class="highlight"><pre><span></span><code><span class="k">if</span><span class="w"> </span><span class="p">(</span>
<span class="p">(</span><span class="nx">i</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nx">i</span><span class="p">.</span><span class="nx">canvas</span><span class="p">.</span><span class="nx">style</span><span class="p">.</span><span class="nx">transform</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="nx">e</span>
<span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="p">((</span><span class="k">this</span><span class="p">.</span><span class="nx">container</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">t</span><span class="p">),</span>
<span class="w"> </span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">context</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">i</span><span class="p">),</span>
<span class="w"> </span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">containerReused</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">!</span><span class="mf">0</span><span class="p">))</span>
<span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">containerReused</span><span class="w"> </span><span class="o">&&</span>
<span class="w"> </span><span class="p">((</span><span class="k">this</span><span class="p">.</span><span class="nx">container</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">null</span><span class="p">),</span>
<span class="w"> </span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">context</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">null</span><span class="p">),</span>
<span class="w"> </span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">containerReused</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">!</span><span class="mf">1</span><span class="p">)),</span>
<span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">container</span><span class="p">)</span>
<span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="p">(</span><span class="nx">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s2">"div"</span><span class="p">)).</span><span class="nx">className</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">o</span><span class="p">;</span>
<span class="kd">var</span><span class="w"> </span><span class="nx">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">n</span><span class="p">.</span><span class="nx">style</span><span class="p">;</span>
<span class="p">(</span><span class="nx">a</span><span class="p">.</span><span class="nx">position</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"absolute"</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="nx">a</span><span class="p">.</span><span class="nx">width</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"100%"</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="nx">a</span><span class="p">.</span><span class="nx">height</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"100%"</span><span class="p">);</span>
<span class="kd">var</span><span class="w"> </span><span class="nx">s</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="nx">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">li</span><span class="p">()).</span><span class="nx">canvas</span><span class="p">;</span>
<span class="nx">n</span><span class="p">.</span><span class="nx">appendChild</span><span class="p">(</span><span class="nx">s</span><span class="p">),</span>
<span class="w"> </span><span class="p">((</span><span class="nx">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">s</span><span class="p">.</span><span class="nx">style</span><span class="p">).</span><span class="nx">position</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"absolute"</span><span class="p">),</span>
<span class="w"> </span><span class="p">(</span><span class="nx">a</span><span class="p">.</span><span class="nx">left</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"0"</span><span class="p">),</span>
<span class="w"> </span><span class="p">(</span><span class="nx">a</span><span class="p">.</span><span class="nx">transformOrigin</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"top left"</span><span class="p">),</span>
<span class="w"> </span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">container</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">n</span><span class="p">),</span>
<span class="w"> </span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">context</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">i</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div>
<p>which is comparing the equivalence of two strings: <code>i.canvas.style.transform</code> with the value</p>
<div class="highlight"><pre><span></span><code>(matrix(0.333333, 0, 0, 0.333333, 0, 0)
</code></pre></div>
<p>and <code>e</code> with the value</p>
<div class="highlight"><pre><span></span><code>(matrix(0.3333333333333333, 0, 0, 0.3333333333333333, 0, 0)
</code></pre></div>
<p>The matrix string was computed by:</p>
<div class="highlight"><pre><span></span><code><span class="kd">function</span><span class="w"> </span><span class="nx">Je</span><span class="p">(</span><span class="nx">t</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="s2">"matrix("</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">t</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s2">", "</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s2">")"</span>
<span class="p">}</span>
</code></pre></div>
<p>So these two string clearly are different, then the code above was never executing.</p>
<p>in <a href="https://drafts.csswg.org/cssom/#serialize-a-css-component-value">CSSOM specification for serialization</a>, it is mentionned:</p>
<blockquote>
<p><code><number></code></p>
<p>A base-ten number using digits 0-9 (U+0030 to U+0039) in the shortest form possible, using "." to separate decimals (if any), rounding the value if necessary to not produce <strong>more than 6 decimals</strong>, preceded by "-" (<code>U+002D</code>) if it is negative.</p>
</blockquote>
<p>It was not always like this, in the past. The specification got changed at a point the implementations changed, and the issue surfaced once WebKit became compliant with the specification.</p>
<p>The old code was like this:</p>
<div class="highlight"><pre><span></span><code><span class="nx">e</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">renderFrame</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kd">function</span><span class="w"> </span><span class="p">(</span><span class="nx">t</span><span class="p">,</span><span class="w"> </span><span class="nx">e</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">r</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">t</span><span class="p">.</span><span class="nx">pixelRatio</span><span class="p">,</span>
<span class="w"> </span><span class="nx">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">t</span><span class="p">.</span><span class="nx">layerStatesArray</span><span class="p">[</span><span class="nx">t</span><span class="p">.</span><span class="nx">layerIndex</span><span class="p">];</span>
<span class="w"> </span><span class="o">!</span><span class="p">(</span><span class="kd">function</span><span class="w"> </span><span class="p">(</span><span class="nx">t</span><span class="p">,</span><span class="w"> </span><span class="nx">e</span><span class="p">,</span><span class="w"> </span><span class="nx">r</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">We</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span><span class="w"> </span><span class="nx">e</span><span class="p">,</span><span class="w"> </span><span class="mf">0</span><span class="p">,</span><span class="w"> </span><span class="mf">0</span><span class="p">,</span><span class="w"> </span><span class="nx">r</span><span class="p">,</span><span class="w"> </span><span class="mf">0</span><span class="p">,</span><span class="w"> </span><span class="mf">0</span><span class="p">);</span>
<span class="w"> </span><span class="p">})(</span><span class="k">this</span><span class="p">.</span><span class="nx">pixelTransform</span><span class="p">,</span><span class="w"> </span><span class="mf">1</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="nx">r</span><span class="p">,</span><span class="w"> </span><span class="mf">1</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="nx">r</span><span class="p">),</span>
<span class="w"> </span><span class="nx">qe</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">inversePixelTransform</span><span class="p">,</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">pixelTransform</span><span class="p">);</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">Je</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">pixelTransform</span><span class="p">);</span>
<span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">useContainer</span><span class="p">(</span><span class="nx">e</span><span class="p">,</span><span class="w"> </span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">n</span><span class="p">.</span><span class="nx">opacity</span><span class="p">);</span>
<span class="c1">// cut for brevity</span>
<span class="p">}</span>
</code></pre></div>
<p>Specifically this line could be fixed like this.</p>
<div class="highlight"><pre><span></span><code><span class="w"> </span><span class="p">})(</span><span class="k">this</span><span class="p">.</span><span class="nx">pixelTransform</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="mf">1</span><span class="o">/</span><span class="nx">r</span><span class="p">).</span><span class="nx">toFixed</span><span class="p">(</span><span class="mf">6</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="mf">1</span><span class="o">/</span><span class="nx">r</span><span class="p">).</span><span class="nx">toFixed</span><span class="p">(</span><span class="mf">6</span><span class="p">)</span><span class="w"> </span><span class="p">),</span>
</code></pre></div>
<p>That would probably help a lot. Note that Firefox, and probably chrome may have had the same issue on devices where <code>window.devicePixelRatio</code> is <code>3</code>.</p>
<p>Outreach worked and they changed the code, but in the meantime the quirk was here to help people have a good user experience.</p>
<h2>Why Deactivating A Quirk In The Web Inspector?</h2>
<p>Why does the Web Inspector give the possibility to deactivate the site specific hacks aka Quirks?</p>
<ol>
<li>Web developers for the impacted websites need to know if their code fix solve the current. So it's necessary for them to be able to understand what would be the behavior of the browser without the quirk.</li>
<li>Browser implementers and QA need to know if a quirk is still needed for a specific website. Deactivating them gives a quick way to tests if the quirk needs to be removed.</li>
</ol>
<h2>Could You Help WebKit Having Less Quirks?</h2>
<p>The main <a href="https://github.com/WebKit/WebKit/blob/main/Source/WebCore/page/Quirks.cpp">list of Quirks</a> is visible in the source code of WebKit. If you are part of a site for which WebKit had to create a quirk, do not hesitate to contact me on <a href="https://github.com/karlcow">GitHub</a> or by mail or on <a href="https://mastodon.cloud/@karlcow">mastodon</a>, and we could find a solution together to remove the Quirk in question.</p>
<p>Otsukare!</p>"Thousand" Values of CSS2022-10-25T12:00:00+09:002022-10-25T12:00:00+09:00Karl Dubosttag:www.otsukare.info,2022-10-25:/2022/10/25/css-values-definitions<p>Let's try to have a better grasp on the types of CSS values.</p><p><a href="https://www.w3.org/2022/09/TPAC/">W3C TPAC 2022</a> in Vancouver is over. It was strange to meet after these 3 years away. There would be a lot more to say about this. During the <a href="https://www.w3.org/Style/CSS/">CSS WG</a> meetings, participants are talking about <strong>all kind of CSS values</strong>. It's quickly confusing.</p>
<p>The processing order is explained in details in the <a href="https://w3c.github.io/csswg-drafts/css-cascade-5/#value-stages">Cascading and Inheritance Level 5</a></p>
<p><img alt="night on the beach in Vancouver." src="https://www.otsukare.info/images/20221025-vancouver.jpg"></p>
<h2>Actual Value</h2>
<p>There is not really a definition for the actual value.</p>
<blockquote>
<p>A used value is in principle ready to be used, but a user agent may not be able to make use of the value in a given environment. For example, a user agent may only be able to render borders with integer pixel widths and may therefore have to approximate the used width. Also, the font size of an element may need adjustment based on the availability of fonts or the value of the font-size-adjust property. The <strong>actual value</strong> is the used value after any such adjustments have been made.</p>
</blockquote>
<p>in <a href="https://w3c.github.io/csswg-drafts/css-cascade-5/#actual">4.6. Actual Values, CSS Cascading and Inheritance Level 5</a>, Editor’s Draft, 21 October 2022</p>
<p>if I had to rewrite this, I would probably say:</p>
<p>The <em>actual value</em> is the used value after any adjustments made depending for the computing environment context.</p>
<p>Think for example, about rounding adjustments when drawing on a screen for a certain resolution.</p>
<h2>Used Value</h2>
<blockquote>
<p>The <strong>used value</strong> is the result of taking the computed value and completing any remaining calculations to make it the absolute theoretical value used in the formatting of the document.</p>
</blockquote>
<p>in <a href="https://w3c.github.io/csswg-drafts/css-cascade-5/#used">4.5. Used Values, CSS Cascading and Inheritance Level 5</a>, Editor’s Draft, 21 October 2022</p>
<p>Let's reuse the example of the specification.</p>
<blockquote>
<p>For example, a declaration of <code>width: auto</code> can’t be resolved into a length without knowing the layout of the element’s ancestors, so the computed value is <code>auto</code>, while the used value is an absolute length, such as <code>100px</code>.</p>
</blockquote>
<h2>Computed Value</h2>
<blockquote>
<p>The <strong>computed value</strong> is the result of resolving the specified value as defined in the “Computed Value” line of the property definition table, generally absolutizing it in preparation for inheritance.</p>
</blockquote>
<p>in <a href="https://w3c.github.io/csswg-drafts/css-cascade-5/#computed">4.4. Computed Values, CSS Cascading and Inheritance Level 5</a>, Editor’s Draft, 21 October 2022</p>
<p>For example, when we specify the <code>font-size</code> of a paragraph, when the default font-size of the document is <code>16px</code>.</p>
<div class="highlight"><pre><span></span><code><span class="nt">p</span><span class="w"> </span><span class="p">{</span><span class="k">font-size</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="kt">em</span><span class="p">;}</span>
</code></pre></div>
<p>The computed value will be <code>32px</code>.</p>
<p>🚨 <a href="https://w3c.github.io/csswg-drafts/cssom-1/#dom-window-getcomputedstyle"><code>window.getComputedStyle(elt)</code></a> doesn't return systematically the computed value. It returns the resolved value (see below)</p>
<div class="highlight"><pre><span></span><code> <span class="p"><</span><span class="nt">p</span> <span class="na">style</span><span class="o">=</span><span class="s">"width:auto;"</span><span class="p">></span>confusing?<span class="p"></</span><span class="nt">p</span><span class="p">></span>
<span class="p"></</span><span class="nt">div</span><span class="p">></span>
</code></pre></div>
<div class="highlight"><pre><span></span><code><span class="kd">const</span><span class="w"> </span><span class="nx">para</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="s1">'p'</span><span class="p">);</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">usedValue</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">window</span><span class="p">.</span><span class="nx">getComputedStyle</span><span class="p">(</span><span class="nx">para</span><span class="p">).</span><span class="nx">width</span><span class="p">;</span>
</code></pre></div>
<p>The computed value will be <code>auto</code>, but the the resolved value will be the current width of the parent element.</p>
<h2>Specified Value</h2>
<blockquote>
<p>The <strong>specified value</strong> is the value of a given property that the style sheet authors intended for that element. It is the result of putting the cascaded value through the defaulting processes, guaranteeing that a specified value exists for every property on every element.</p>
</blockquote>
<p>in <a href="https://w3c.github.io/csswg-drafts/css-cascade-5/#computed">4.3. Specified Values, CSS Cascading and Inheritance Level 5</a>, Editor’s Draft, 21 October 2022</p>
<div class="highlight"><pre><span></span><code><span class="p"><</span><span class="nt">p</span> <span class="na">class</span><span class="o">=</span><span class="s">"a"</span><span class="p">></span>falls<span class="p"></</span><span class="nt">p</span><span class="p">></span>
<span class="p"><</span><span class="nt">p</span><span class="p">></span>and streams<span class="p"></</span><span class="nt">p</span><span class="p">></span>
</code></pre></div>
<p>with</p>
<div class="highlight"><pre><span></span><code><span class="nt">p</span><span class="w"> </span><span class="p">{</span><span class="k">color</span><span class="p">:</span><span class="w"> </span><span class="kc">green</span><span class="p">;}</span>
<span class="nt">p</span><span class="p">.</span><span class="nc">a</span><span class="w"> </span><span class="p">{</span><span class="k">color</span><span class="p">:</span><span class="w"> </span><span class="kc">red</span><span class="p">;}</span>
</code></pre></div>
<p>To extract the specified value</p>
<div class="highlight"><pre><span></span><code><span class="nb">document</span><span class="p">.</span><span class="nx">styleSheets</span><span class="p">[</span><span class="mf">0</span><span class="p">].</span><span class="nx">cssRules</span><span class="p">[</span><span class="mf">1</span><span class="p">].</span><span class="nx">style</span><span class="p">.</span><span class="nx">getPropertyValue</span><span class="p">(</span><span class="s1">'color'</span><span class="p">)</span>
</code></pre></div>
<p>will return <code>red</code>.</p>
<p>If you need access to the full declaration, use <code>cssRule.cssText</code></p>
<div class="highlight"><pre><span></span><code><span class="nb">document</span><span class="p">.</span><span class="nx">styleSheets</span><span class="p">[</span><span class="mf">0</span><span class="p">].</span><span class="nx">cssRules</span><span class="p">[</span><span class="mf">1</span><span class="p">].</span><span class="nx">cssText</span>
</code></pre></div>
<p>will return <code>p.a { color: red; }</code></p>
<p>To not be confused with</p>
<div class="highlight"><pre><span></span><code><span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="s1">'.a'</span><span class="p">).</span><span class="nx">style</span><span class="p">.</span><span class="nx">cssText</span>
</code></pre></div>
<p>which will return an empty string, because there is no style attribute on the element.</p>
<h2>Cascaded Value</h2>
<blockquote>
<p>The <strong>cascaded value</strong> represents the result of the cascade: it is the declared value that wins the cascade (is sorted first in the output of the cascade). If the output of the cascade is an empty list, there is no cascaded value.</p>
</blockquote>
<p>in <a href="https://w3c.github.io/csswg-drafts/css-cascade-5/#cascaded">4.2. Cascaded Values, CSS Cascading and Inheritance Level 5</a>, Editor’s Draft, 21 October 2022</p>
<div class="highlight"><pre><span></span><code><span class="p"><</span><span class="nt">p</span> <span class="na">class</span><span class="o">=</span><span class="s">"a"</span><span class="p">></span>falls<span class="p"></</span><span class="nt">p</span><span class="p">></span>
<span class="p"><</span><span class="nt">p</span><span class="p">></span>and streams<span class="p"></</span><span class="nt">p</span><span class="p">></span>
</code></pre></div>
<p>with</p>
<div class="highlight"><pre><span></span><code><span class="nt">p</span><span class="w"> </span><span class="p">{</span><span class="k">color</span><span class="p">:</span><span class="w"> </span><span class="kc">green</span><span class="p">;}</span>
<span class="nt">p</span><span class="p">.</span><span class="nc">a</span><span class="w"> </span><span class="p">{</span><span class="k">color</span><span class="p">:</span><span class="w"> </span><span class="kc">red</span><span class="p">;}</span>
</code></pre></div>
<p>The <strong>cascaded value</strong> for <code><p class="a"></code> is <code>red</code>. Note that the used value will be <code>rgb(255, 0, 0)</code>.</p>
<h2>Declared Value</h2>
<blockquote>
<p>Each property declaration applied to an element contributes a declared value for that property associated with the element.</p>
</blockquote>
<p>in <a href="https://w3c.github.io/csswg-drafts/css-cascade-5/#declared">4.1. Declared Values, CSS Cascading and Inheritance Level 5</a>, Editor’s Draft, 21 October 2022</p>
<h2>Initial Value</h2>
<blockquote>
<p>Each property has an initial value defined in the property’s definition table. If the property is not an inherited property and the cascade does not result in a value then the specified value of the property is its initial value.</p>
</blockquote>
<p>in <a href="https://w3c.github.io/csswg-drafts/css-cascade-5/#initial-values">7.1 Initial Values, CSS Cascading and Inheritance Level 5</a>, Editor’s Draft, 21 October 2022</p>
<p>For example, the <strong>initial value</strong> on <a href="https://w3c.github.io/csswg-drafts/css-backgrounds/#background-color"><code>background-color</code></a> is <code>transparent</code>. This is the color that you can find in the default CSS.</p>
<h2>Resolved Value</h2>
<p>This time, we changed specification.</p>
<blockquote>
<p><code>getComputedStyle()</code> was historically defined to return the "computed value" of an element or pseudo-element. However, the concept of "computed value" changed between revisions of CSS while the implementation of <code>getComputedStyle()</code> had to remain the same for compatibility with deployed scripts. To address this issue this specification introduces the concept of a resolved value.</p>
</blockquote>
<p>in <a href="https://w3c.github.io/csswg-drafts/cssom-1/#resolved-values">9. Resolved Values, CSS Object Model (CSSOM)</a>, Editor’s Draft, 18 October 2022</p>
<p>The resolved value is either the computed value or the used value. This is dependent of each property.</p>
<h2>Relative value</h2>
<p>This is not really defined, but this is mentioned in computed value explanations.</p>
<blockquote>
<p>A specified value can be either absolute (i.e., not relative to another value, as in red or 2mm) or relative (i.e., relative to another value, as in auto, 2em). Computing a relative value generally absolutizes it.</p>
</blockquote>
<p>in the <a href="https://w3c.github.io/csswg-drafts/css-cascade-5/#example-29410c97">example 12 of the section about computed Value</a>.</p>
<p>For example anything such as <code>em</code>, percentages, relative URLs, etc.</p>
<h2>Absolute Value</h2>
<p>Not defined but the term is used.The absolute value is a value which has no dependency on the environment, such as red or 3px.</p>
<p>If I have forgotten some. Let me know.</p>
<p>Otsukare!</p>Filter your mail in a dated space server side with Sieve2022-06-20T15:15:00+09:002022-06-20T15:20:00+09:00Karl Dubosttag:www.otsukare.info,2022-06-20:/2022/06/20/dated-space-mailbox-with-sieve<p>Dated space mailboxes is one of the strategies to filter email with high volumes. Here the techniques with Sieve.</p><p>When it comes to sort out your emails, there are many strategies. Since I have been working at W3C, I'm a fan of dated spaces. I apply this strategy to my emails using Sieve.</p>
<p><img alt="mailbox stuffed with old letters and papers." src="https://www.otsukare.info/images/20220620-mailbox-burp.jpg"></p>
<h2>Dated Space?</h2>
<p>A dated space is a way to organize the information by date folders. Here is an example on my folders.</p>
<p><img alt="organization by dates of folders." src="https://www.otsukare.info/images/20220620-dated-folders.png"></p>
<p>and here the same type of organization for mails.</p>
<p><img alt="organization by dates of folders." src="https://www.otsukare.info/images/20220620-dated-mailbox.png"></p>
<h3>Why would you do that?</h3>
<ul>
<li><strong>It creates a unique space</strong>. The arrow time is irreversible so there is no issue with creating new folders.</li>
<li><strong>It limits the number of items by folders</strong>. When a folder has too many items, it becomes harder to find what you need.</li>
<li>It is actually helpful, because <strong>our memory has a lot of anchors in time</strong> and we can find easily stuff by remembering when we created it. (a location-based could be an interesting experiment and has useful applications in some circumstances such as photos for example, but that's for another blog post.)</li>
<li><strong>OS search engines</strong>: Smart folders based on keywords, types, etc. will make it easier to find stuff. And the files can now belong in multiple contexts. Everything everywhere all at once.</li>
</ul>
<h2>Dated Space For Mail With Sieve</h2>
<p><a href="http://sieve.info/">Sieve</a> is a language for filtering e-mail messages. It resides on the server side. So it requires that your mail provider accepts that you can manage sieve rules for your own mail.</p>
<p>I filter all my incoming mails indifferently of their nature to a dated space. Everything is mixed. And I restructure my emails folders with smart mailboxes. Then I can suppress folders which are not valid anymore, create new ones, all of this without touching any emails.</p>
<h3>Sieve Script</h3>
<div class="highlight"><pre><span></span><code><span class="n">require</span><span class="w"> </span><span class="p">[</span><span class="s2">"fileinto"</span><span class="p">,</span><span class="w"> </span><span class="s2">"date"</span><span class="p">,</span><span class="w"> </span><span class="s2">"mailbox"</span><span class="p">,</span><span class="w"> </span><span class="s2">"variables"</span><span class="p">];</span>
<span class="c1"># filter emails based on the date and move them to a folder.</span>
<span class="c1"># mail from June 2022, will be saved into /2022/06</span>
<span class="c1"># set values for month and year</span>
<span class="k">if</span><span class="w"> </span><span class="n">currentdate</span><span class="w"> </span><span class="p">:</span><span class="n">matches</span><span class="w"> </span><span class="s2">"year"</span><span class="w"> </span><span class="s2">"*"</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">set</span><span class="w"> </span><span class="s2">"year"</span><span class="w"> </span><span class="s2">"${1}"</span><span class="p">;</span><span class="w"> </span><span class="p">};</span>
<span class="k">if</span><span class="w"> </span><span class="n">currentdate</span><span class="w"> </span><span class="p">:</span><span class="n">matches</span><span class="w"> </span><span class="s2">"month"</span><span class="w"> </span><span class="s2">"*"</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">set</span><span class="w"> </span><span class="s2">"month"</span><span class="w"> </span><span class="s2">"${1}"</span><span class="p">;</span><span class="w"> </span><span class="p">};</span>
<span class="c1"># mv the message into the right mail folder</span>
<span class="n">fileinto</span><span class="w"> </span><span class="p">:</span><span class="n">create</span><span class="w"> </span><span class="s2">"${year}/${month}"</span><span class="p">;</span>
<span class="n">stop</span><span class="p">;</span>
</code></pre></div>
<p>It's a very simple script and works like a charm. Sieve is a very powerful language. It's possible to do all kind of classifications.</p>
<p>Oh… and yes… my Inbox is obviously by the nature of the script always… 0.</p>
<p>Otsukare!</p>Get browsers version number on macOS (zsh)2022-06-10T07:00:00+09:002022-06-10T07:00:00+09:00Karl Dubosttag:www.otsukare.info,2022-06-10:/2022/06/10/get-browsers-version-macos-zsh<p>When testing in multiple browsers, it's not necessary pleasant to copy and paste the information in windows. Here a little zsh script.</p><p>I'm not sure why I had not written this before, but it kind of hit me when doing testing this week, that I could optimize a bit more my time.</p>
<p><img alt="statues in the forest with a red beanny." src="https://www.otsukare.info/images/20220610-jizo.jpg"></p>
<p>This is a shell (zsh) script and macOS only. It reads the <a href="https://gist.github.com/karlcow/b1d992df616bc6f4397fa96035731a20">version information of a list of browsers</a> and spills them out in a nice and ready to be copied and pasted in a bug report.</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/bin/zsh</span>
<span class="nv">APP_PATH</span><span class="o">=</span><span class="s2">"/Applications/"</span>
<span class="nv">INFO_PATH</span><span class="o">=</span><span class="s2">".app/Contents/Info.plist"</span>
<span class="nv">browsers</span><span class="o">=(</span><span class="s2">"Safari Technology Preview"</span><span class="w"> </span><span class="s2">"Firefox Nightly"</span><span class="w"> </span><span class="s2">"Google Chrome Canary"</span><span class="w"> </span><span class="s2">"Safari"</span><span class="w"> </span><span class="s2">"Firefox"</span><span class="w"> </span><span class="s2">"Google Chrome"</span><span class="w"> </span><span class="s2">"Microsoft Edge Canary"</span><span class="o">)</span>
<span class="k">for</span><span class="w"> </span>browser_name<span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="si">${</span><span class="p">(@k)browsers</span><span class="si">}</span><span class="p">;</span><span class="w"> </span><span class="k">do</span>
<span class="w"> </span><span class="nv">full_path</span><span class="o">=</span><span class="s2">"</span><span class="si">${</span><span class="nv">APP_PATH</span><span class="si">}${</span><span class="nv">browser_name</span><span class="si">}${</span><span class="nv">INFO_PATH</span><span class="si">}</span><span class="s2">"</span><span class="w"> </span><span class="p">;</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nb">test</span><span class="w"> </span>-f<span class="w"> </span><span class="s2">"</span><span class="nv">$full_path</span><span class="s2">"</span><span class="p">;</span><span class="w"> </span><span class="k">then</span>
<span class="w"> </span><span class="nv">browser_version</span><span class="o">=</span><span class="k">$(</span>defaults<span class="w"> </span><span class="nb">read</span><span class="w"> </span><span class="s2">"</span><span class="nv">$full_path</span><span class="s2">"</span><span class="w"> </span>CFBundleShortVersionString<span class="k">)</span><span class="p">;</span>
<span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"</span><span class="si">${</span><span class="nv">browser_name</span><span class="si">}</span><span class="s2"> </span><span class="si">${</span><span class="nv">browser_version</span><span class="si">}</span><span class="s2">"</span><span class="p">;</span>
<span class="w"> </span><span class="k">fi</span>
<span class="k">done</span>
</code></pre></div>
<p>What it looks like once rendered. I need to update a couple of things.</p>
<div class="highlight"><pre><span></span><code>Safari Technology Preview 15.4
Firefox Nightly 103.0a1
Safari 15.5
Firefox 99.0
Microsoft Edge Canary 104.0.1285.0
</code></pre></div>
<p>Otsukare!</p>How to make « cidre » of Normandy2022-05-16T21:00:00+09:002022-05-16T21:44:00+09:00Karl Dubosttag:www.otsukare.info,2022-05-16:/2022/05/16/normandy-cider<p>Sometimes, things are just part of your cultural tradition. Here a rough explanation on how to prepare a drink from Normandy, my region of origin.</p><p>While I'm living in Japan, I'm from the <a href="https://en.wikipedia.org/wiki/Normandy">Normandy region</a> in France. That's me as a child helping my grand father in an orchard.</p>
<p><img alt="child filling bags with apples." src="https://www.otsukare.info/images/20220516-karl.jpg"></p>
<p>This is a region which is traditionally known for cows and dairy products (milk, butter, cheese like Camembert, Pont-L'evêque, Livarot, Neufchâtel, etc.) and also a region which led to the <a href="https://fr.wikipedia.org/wiki/Cidre_de_Normandie">production of cidre</a> (French only). The origin is not that clear but probably, people from Normandy have started to make « cidre » in the 12th century. Some competing stories have been developed about the origin. But people were growing apples for a long time already and probably were fermenting them. And a craft emerged.</p>
<p>The Web is also rich of its individual crafts, developed along the way. Some techniques have been lost, some are thriving. A long series of errors and trials has been essential in perfecting the art of making Websites.</p>
<p>Fast forward a couple of centuries, and here an image on <strong>my great grand father</strong>, René. He is collecting the apples in a big bag from his field to prepare « cidre ».</p>
<p><img alt="Man filling a bag of apples in an orchard." src="https://www.otsukare.info/images/20220516-rene.jpg"></p>
<p>The name of the apples is a long poetic list:</p>
<p>Blanc Mollet, Girard, Cimetière de Blangy, Argile nouvelle, Fréquin rouge, Gros matois rouge, Bon Henri, Médaille d'or, Petit amer, Binet rouge, Bouquet, Joly rouge, Longue, Bedan, Bouteille, Moulin à vent, Grise Dieppois, Gilet rouge, Doux Veret (petit), Rouge Bruyère, Reine des Pommes, Doux-Evêque précoce, Marin Onfroy, etc.</p>
<p>Each of them have their own qualities: sweetness, acidity, taste, … Once we have a good mix, we need to wash them carefully and then put them in the grinder.</p>
<p><strong>My grand father</strong>, Jean, working at the grinder and we can see in the background the press in wood.</p>
<p><img alt="Man near the grinder with apples in a big barrel." src="https://www.otsukare.info/images/20220516-jean.jpg"></p>
<p><img alt="Grinder engraving." src="https://www.otsukare.info/images/20220516-broyeur.jpg"></p>
<p>Once the apples have been grinded, we need to let them with the juice exposed to the air for around 8 to 12 hours in a deep container covered by a cloth. The oxydation work will start. The must will get a better color, will be sweeter. The yeast will develop more rapidly. Containers must be as clean as possible.</p>
<p>Then will start the work with the press.</p>
<p><img alt="Press engraving." src="https://www.otsukare.info/images/20220516-press.jpg"></p>
<p>The must is layered in 15 to 20 centimeters high layers, separated by layers of straws that will drain the juice.</p>
<p><img alt="Press detail engraving." src="https://www.otsukare.info/images/20220516-press-installation.jpg"></p>
<p>Once the juice has been drawn, it is put in big barrels where the fermentation process starts. After a while, the juice will be put in bottle. My grand-father was used to go in the cave and to turn the bottles according to the moon phases. He had 3 types of « cidre » in his cave: Very sweet, rough, and something very rough that was basically impossible to drink. The colors were on the bottles: red, grey and blue, a simple spot of paint.</p>
<p>These techniques are getting lost with the new generations and the industrializations. I wish I had spent more time with him for having a better understanding of the craft.</p>
<p><img alt="Different types of apples." src="https://www.otsukare.info/images/20220516-apples.jpg"></p>
<p>Now, I probably have a better understanding of the Web than the process of making « cidre ». It's probably why today is my first day working for <a href="https://webkit.org/">Apple on the WebKit project</a> to continue my journey in making the Web awesome for everyone: Web Compatibility, standards and interoperability.</p>
<p><a href="https://gallica.bnf.fr/ark:/12148/bpt6k97981173/">Engravings coming from Le cidre by Labounoux and Touchard</a></p>
<h2>Comments</h2>
<p>If you have more questions, things I may have missed, different take on them. Feel free <a href="https://github.com/karlcow/otsukare.info/issues/13">to comment…</a>. Be mindful.</p>
<p>Otsukare!</p>Mozilla, Bye!2022-05-04T21:00:00+09:002022-05-10T17:30:00+09:00Karl Dubosttag:www.otsukare.info,2022-05-04:/2022/05/04/bye-mozilla<p>May 4 was my last at Mozilla after almost 9 years.</p><p>This year, 2022, May the 4th was my last day at Mozilla.</p>
<p><img alt="Trunk from an oak tree and its canopy." src="https://www.otsukare.info/images/20220504-chene.jpg"></p>
<blockquote>
<p>Alors, l'arbre et son rêveur, ensemble, s'ordonnent, grandissent. Jamais l'arbre, dans le monde du songe, ne s'établit comme un être achevé.
— <a href="http://classiques.uqac.ca/classiques/bachelard_gaston/poetique_de_espace_3e_edition/poetique_de_espace_3e_edition.pdf">Poétique de l'espace, Gaston Bachelard</a></p>
</blockquote>
<p>in English</p>
<blockquote>
<p>Then, together, the tree and its dreamer, take their places, grow tall. Never, in the dream world, does a tree appear as a completed being.
— <a href="https://archive.org/details/G.BachelardThePoeticsOfSpace/G.%2C%20Bachelard%2C%20The%20Poetics%20of%20Space/">The poetics of space, Gaston Bachelard</a></p>
</blockquote>
<p>I <a href="https://www.otsukare.info/2013/08/01/why-now">started</a> on July 2, 2013 on a 6 months contract at Mozilla to <a href="https://en.wikipedia.org/wiki/Firefox_OS">work on Firefox OS</a> on Web Compatibility issues. I was living in Montréal, Canada at the time.</p>
<p><a href="https://www.linkedin.com/in/lmandel">Lawrence Mandel</a> (now at Shopify) trusted and hired me. His first words on our Web Compatibility work at Mozilla were aligned with my ideas and stance for the open Web.</p>
<blockquote>
<p>We are here to make the Web more open, not only for making the Web usable on Firefox products. — Lawrence Mandel</p>
</blockquote>
<p>After these 6 months, I moved to Japan and I'm still living there. I'm currently in Tokyo. On the span of 8 years and 10 months, I focused my energy on this mission inside the <a href="https://wiki.mozilla.org/Compatibility">Web Compatibility</a>.</p>
<blockquote>
<p>A person should be able to use the Web with any devices and any browsers.</p>
</blockquote>
<p>I was not alone. The success of a project never relies on a single individual, but a full team of people dedicated to make this mission a reality. At the very beginning, we were three coming from Opera Software, we all had an experience on Web compatibility issues: <a href="https://miketaylr.com/posts/">Mike Taylor</a>, <a href="http://www.hallvord.com/">Hallvord R.M. Steen</a> and me. Then <a href="https://www.linkedin.com/in/stevenson-adam">Adam Stevenson</a> joined. None of the initial team is still at Mozilla. I miss working with <a href="https://www.linkedin.com/in/eric-tsai-9181603a">Eric Tsai</a> too. Some people (open contributors) have also <a href="https://webcompat.com/contributors">participated to the project</a> like Abdul Rauf, Alexa Roman, Kate Manning, Guillaume Demesy, Reinhart Previano.</p>
<p><a href="https://webcompat.com/">webcompat.com</a> was setup on purpose <strong>without Mozilla branding</strong> to invite the <a href="https://github.com/webcompat/webcompat.com/">participation of all browser implementers</a> (Apple, Google, Microsoft, Opera, etc.) on solving issues resulting from website mistakes or interoperability issues. Mozilla put the main effort into it and in return webcompat.com helped Mozilla and Firefox Core team to fix a lot of issues.</p>
<p>The current Web Compatibility team is composed of <a href="https://overengineer.dev/">Dennis Schubert</a> (Germany), <a href="https://github.com/jgraham">James Graham</a> (UK), <a href="https://www.linkedin.com/in/kberezina">Ksenia Berezina</a> (Canada), <a href="https://www.linkedin.com/in/arbuzov-oana-0293abb5">Oana Arbuzov</a> (Romania), <a href="https://www.linkedin.com/in/raul-bucata-38657b1b3/">Raul Bucata</a> (Romania) and <a href="https://www.linkedin.com/in/thomas-wisniewski-85844b16/">Thomas Wisniewski</a> (Canada). This team was distributed across three continents (two since I left), working around the clock to help solving Web compatibility issues. All the work done was in public, shared with others, written down and tracked in the open. This leveraged autonomy and responsibility from everyone in the team. Apart of a lack of a resource, my departure doesn't put in peril the work of the team. Even as I became the team manager 18 months ago, I was not a gatekeeper.</p>
<p>There is the Webcompat team… then there is the amazing group of Core Engineers who have the open Web deep in their heart. Many left Mozilla, but some of them are still there and they were instrumental in solving interoperability issues.</p>
<p>Emilio Cobos Álvarez, Daniel Holbert, Jonathan Kew, Masayuki Nakano, Makoto Kato, Brian Birtles, Boris Zbarsky, Hiroyuki Hikezoe, Botond Ballo, Olli Pettay, Henri Sivonen, Anne van Kesteren, Ting-Yu Lin, Cameron McCormack. These lists are dangerous, I keep forgetting people.</p>
<p>I could talk about all the things which have been solved around text input, CSS flexbox, JavaScript features, DOM and SVG, … but this starts to be long.</p>
<p>And finally the diagnosis ability of the Webcompat team would be nothing without the dedication of the <a href="https://firefox-dev.tools/">devtools and performance teams</a>. They helped us to work better, they develop amazing tools which are useful for the webcompat team and the web developers. They always care about what we do. Nicolas Chevobbe, Julien Wajsberg, Daisuke Akatsuka, Jan Odvarko (Honza), and many others …</p>
<p>But as Bachelard said above:</p>
<blockquote>
<p>Never, in the dream world, does a tree appear as a completed being.</p>
</blockquote>
<p>The new chapter is starting on <a href="https://www.timeanddate.com/eclipse/lunar/2022-may-16">May 16, 2022</a>. More information on that later apart of the lunar eclipse.</p>
<h2>Comments</h2>
<p>If you have more questions, things I may have missed, different take on them. Feel free <a href="https://github.com/karlcow/otsukare.info/issues/12">to comment…</a>. Be mindful.</p>
<p>Otsukare!</p>Encyclopedia Of Broken UserAgent String Detections2022-01-14T17:17:00+09:002022-02-16T21:14:00+09:00Karl Dubosttag:www.otsukare.info,2022-01-14:/2022/01/14/broken-ua-detection<p>Recording the way the User Agent string parsing is failing in scripts.</p><p>Did you detect the right user agent string?</p>
<p><img alt="cat hidden in a bamboo forest." src="https://www.otsukare.info/images/20220114-cat-bamboo.jpg"></p>
<p>This is not a comprehensive encyclopedia, but these are patterns we have met in the past for identifying user agent strings which are broken or future fail.</p>
<p>** Do not use these !** and if your code is using one form of these, please change it. Tell me if you found new ones.</p>
<h2>Comparing Strings Instead Of Numbers</h2>
<p>This was explained in details in <a href="https://miketaylr.com/posts/2021/03/firefox-version-520-works-in-slack.html">Slack is optimized for Firefox version 520</a></p>
<p>The version number of the userAgent is extracted as a string, not an integer.</p>
<div class="highlight"><pre><span></span><code><span class="kd">var</span><span class="w"> </span><span class="nx">browser_version</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"100"</span><span class="p">;</span>
<span class="kd">var</span><span class="w"> </span><span class="nx">support_min_version</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"90"</span><span class="p">;</span>
<span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">browser_version</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="nx">support_min_version</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"too old"</span><span class="p">);</span>
<span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"supported"</span><span class="p">);</span>
<span class="p">}</span>
<span class="c1">// too old instead of supported as a result</span>
</code></pre></div>
<p>A better pattern here is to use integer</p>
<div class="highlight"><pre><span></span><code><span class="kd">var</span><span class="w"> </span><span class="nx">browser_version</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">parseInt</span><span class="p">(</span><span class="s2">"100"</span><span class="p">,</span><span class="w"> </span><span class="mf">10</span><span class="p">)</span><span class="w"> </span><span class="c1">// the "100" as a string came from a detection early on</span>
<span class="kd">var</span><span class="w"> </span><span class="nx">support_min_version</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">90</span><span class="p">;</span><span class="w"> </span><span class="c1">// integer not a string;</span>
<span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">browser_version</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="nx">support_min_version</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"too old"</span><span class="p">);</span>
<span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"supported"</span><span class="p">);</span>
<span class="p">}</span>
<span class="c1">// goes to supported as expected</span>
</code></pre></div>
<h2>Substring Slicing According To Position</h2>
<p>The assumption here is that the substring representing the number is two characters after the slash. The <code>8</code> is for <code>Firefox/</code></p>
<div class="highlight"><pre><span></span><code><span class="nx">ua</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0"</span>
<span class="c1">// "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0"</span>
<span class="nx">start</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">ua</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">'Firefox'</span><span class="p">)</span>
<span class="c1">// 67</span>
<span class="nx">version</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">ua</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="nx">start</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">8</span><span class="p">,</span><span class="w"> </span><span class="nx">start</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">10</span><span class="p">)</span>
<span class="c1">// "10"</span>
</code></pre></div>
<p>A better pattern for this one is:</p>
<div class="highlight"><pre><span></span><code><span class="nx">ua</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0"</span>
<span class="c1">// "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0"</span>
<span class="nx">start</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">ua</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">'Firefox'</span><span class="p">)</span>
<span class="c1">// 67</span>
<span class="nx">ua</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="nx">start</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">'Firefox'</span><span class="p">.</span><span class="nx">length</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1</span><span class="p">)</span>
<span class="c1">// "100.0"</span>
<span class="nb">parseFloat</span><span class="p">(</span><span class="nx">ua</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="nx">start</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">'Firefox'</span><span class="p">.</span><span class="nx">length</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1</span><span class="p">))</span>
<span class="c1">// 100</span>
</code></pre></div>
<h2>Regex Matching Exactly Two Digits</h2>
<p>This is a fairly common mistake, most of the detection algorithm have been fixed when browsers switched their versions from one digit to two digits, but there is still code out there relying on fixed lengths.</p>
<div class="highlight"><pre><span></span><code><span class="kd">const</span><span class="w"> </span><span class="nx">ua_string</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:91.0) Gecko/20100101 Firefox/91.0"</span><span class="p">;</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">ua_100</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:100.0) Gecko/20100101 Firefox/100.0"</span><span class="p">;</span>
<span class="nx">ua_string</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/Firefox\/(\d\d)/</span><span class="p">);</span><span class="w"> </span><span class="c1">// ["Firefox/91", "91"]</span>
<span class="nx">ua_string</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/Firefox\/(\d{2})/</span><span class="p">);</span><span class="w"> </span><span class="c1">// ["Firefox/91", "91"]</span>
<span class="nx">ua_string</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/Firefox\/(\d\d)\./</span><span class="p">);</span><span class="w"> </span><span class="c1">// ["Firefox/91.", "91"]</span>
<span class="nx">ua_100</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/Firefox\/(\d\d)/</span><span class="p">);</span><span class="w"> </span><span class="c1">// ["Firefox/10", "10"]</span>
<span class="nx">ua_100</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/Firefox\/(\d{2})/</span><span class="p">);</span><span class="w"> </span><span class="c1">// ["Firefox/10", "10"]</span>
<span class="nx">ua_100</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/Firefox\/(\d\d)\./</span><span class="p">);</span><span class="w"> </span><span class="c1">// null</span>
</code></pre></div>
<p>A better pattern would be</p>
<div class="highlight"><pre><span></span><code><span class="nx">ua_string</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/Firefox\/(\d+)/</span><span class="p">);</span><span class="w"> </span><span class="c1">// ["Firefox/91", "91"]</span>
<span class="nx">ua_string</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/Firefox\/(\d+)/</span><span class="p">);</span><span class="w"> </span><span class="c1">// ["Firefox/100", "100"]</span>
</code></pre></div>
<h2>Detecting Firefox on iOS as Android.</h2>
<p>Many sites have a grid for the minimum version number supported for each browsers. The current Firefox User Agent string on iOS has this pattern.</p>
<p><code>Mozilla/5.0 (iPhone; CPU OS 14_4_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/33.0 Mobile/15E148 Safari/605.1.15</code></p>
<p>Notice that <code>FxiOS/33.0</code> means Firefox on iOS version 33. Web developers often used a up to date library that will return something like:</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">"ua"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Mozilla/5.0 (iPhone; CPU OS 14_4_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/33.0 Mobile/15E148 Safari/605.1.15"</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"browser"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Firefox"</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"33.0"</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"major"</span><span class="p">:</span><span class="w"> </span><span class="s2">"33"</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">"engine"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"WebKit"</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"605.1.15"</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">"os"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"iOS"</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"14.4.2"</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">"device"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">"vendor"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Apple"</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"model"</span><span class="p">:</span><span class="w"> </span><span class="s2">"iPhone"</span><span class="p">,</span>
<span class="w"> </span><span class="nt">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mobile"</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">"cpu"</span><span class="p">:</span><span class="w"> </span><span class="p">{},</span>
<span class="w"> </span><span class="nt">"gpu"</span><span class="p">:</span><span class="w"> </span><span class="p">{}</span>
<span class="p">}</span>
</code></pre></div>
<p>So far so good. The issue starts when the site says: "Oh. It's Firefox on Mobile, so it means this is Android. We support Firefox on Android starting Firefox/78". Then they block the access to the full site, or the video, or asking the user to upgrade their browsers while they are on the latest version of Firefox iOS.</p>
<p>A better pattern is to detect the OS and/or the engine this browser is working on, and adjust your support matrix. An even better pattern is to have the site handling graceful degradation whichever the version of the browser.</p>
<h2>Comments</h2>
<p>If you have more questions, things I may have missed, different take on them. Feel free <a href="https://github.com/karlcow/otsukare.info/issues/11">to comment…</a>. Be mindful.</p>
<p>Otsukare!</p>Browser regression and tools2021-11-17T09:31:00+09:002021-11-17T22:19:00+09:00Karl Dubosttag:www.otsukare.info,2021-11-17:/2021/11/17/bisecting-browser-regression<p>Browsers have tools to find out which commit created a regression.</p><p>Sometimes a new release of a nightly version of a browser creates what we call a regression. How do we find out what exactly broke the code?</p>
<p><img alt="Illustration of surgery tools." src="https://www.otsukare.info/images/20211117-bistouri.jpg"></p>
<h2>What is a regression?</h2>
<p>In simplified terms, there is a regression when a code used to work and is not working properly after a specific release. For websites, a webpage would stop having the right behavior after updating to a new version of the browser.</p>
<p>Something was working with commit 𝑛 of the browser and it stopped working with commit 𝑛+1.</p>
<h2>How do we try to catch regressions before production release?</h2>
<p>All browsers have different versions. The production release is the one that most people are using. The one which is advertised for people to download on websites and stores. But there are also beta versions and <strong>nightly</strong> versions.</p>
<p>The nightly version is a fresh working build with the latest modifications of the day. It's not considered reliable for your main usage. Even if browser implementers try hard to keep them stable, they may break. They may even damage your browser profile. <strong>Use them only if you understand the consequences</strong>.</p>
<ul>
<li><a href="https://www.google.com/chrome/canary/">Chrome Canary</a> (Blink) - No nightly release notes?</li>
<li><a href="https://www.mozilla.org/en-US/firefox/all/#product-desktop-nightly">Firefox Nightly</a> (Gecko) - <a href="https://blog.nightly.mozilla.org/">Release Notes</a></li>
<li><a href="https://webkit.org/downloads/">Safari Nightly</a> (WebKit) - <a href="https://developer.apple.com/safari/technology-preview/release-notes/">Release Notes only for Safari Tech Preview</a></li>
</ul>
<h2>How do we find out the exact commit which has broken the browser?</h2>
<p>You are now using commit 𝑛+𝑚 version which is broken. You want to find out the 𝑛+1 version which has broken the code.</p>
<p>You start <a href="https://en.wikipedia.org/wiki/Bisection_(software_engineering)">bisecting the code</a>. Let's say this is happening in between version 10 and 20 of the code.</p>
<ol>
<li>Verify this is working with 10</li>
<li>Check this is not working with 20.</li>
<li>Split the group in two. Pick up 15. Does the bug reproduce?
Yes. So the issue is in between 10 and 15
No. So the issue is in between 16 and 20</li>
<li>Take the new range and repeat and rinse, until you get a unique version.</li>
</ol>
<p>That can become time consuming. There are tools to help with this task.The tool will download the nightly builds being tested and help figure out which specific commit in the code has broken the code.</p>
<h2>Bisection tools</h2>
<ul>
<li><a href="https://www.chromium.org/developers/bisect-builds-py">Chrome</a></li>
<li><a href="https://mozilla.github.io/mozregression/">Firefox</a>. Probably the easiest to use of the 3. Well documented and even a version with a GUI</li>
<li><a href="https://github.com/WebKit/WebKit/blob/main/Tools/Scripts/bisect-builds">Safari</a></li>
</ul>
<p>Your turn! When you find out a broken Web page next time (when previously, it was working), follow these steps:</p>
<ol>
<li>open a bug</li>
<li>Run a regression tool</li>
<li>give the precise commit where it might have happened.</li>
</ol>
<p>This will speed up a lot the potential fix.</p>
<h2>Comments</h2>
<p>If you have more questions, things I may have missed, different take on them. Feel free <a href="https://github.com/karlcow/otsukare.info/issues/10">to comment…</a>. Be mindful.</p>
<p>Otsukare!</p>Webcompat issues and the bots!2021-10-26T21:43:00+09:002021-10-26T21:53:00+09:00Karl Dubosttag:www.otsukare.info,2021-10-26:/2021/10/26/webcompat-automation<p>Some ideas and contexts around auto-discovering webcompat issues.</p><p>Some ideas and contexts around auto-discovering webcompat issues.</p>
<p><img alt="Graffiti of a robot on a wall." src="https://www.otsukare.info/images/20211026-robots.jpg"></p>
<p>Recently <a href="https://briangrinstead.com/blog/">Brian Grinstead</a> asked me:</p>
<blockquote>
<p>Are you familiar with <a href="https://github.com/marco-c/autowebcompat">this</a>?</p>
</blockquote>
<p>which I answered: Yes since 2018. And I remembered the challenges and so probably it's worth to do a bit of history on identifying webcompat issues. The objectives being often:</p>
<ol>
<li>How to massively test websites and their different renderings across browsers?</li>
<li>How to reduce human time spent on manually testing the site?</li>
<li>Can we discover the type of issues?</li>
</ol>
<p>I have been doing webcompat work since October 2010 (when I started working at Opera Software with the <a href="https://www.youtube.com/watch?v=IZ6JrBqy0CU">amazing Opera devrel team</a>). There's no perfect technique, but there are a couple of things you can try.</p>
<h2>Screenshots Comparison</h2>
<p>We often associate webcompat issues with sites which are not looking the same in two different browsers. It's a simplistic approximation but can help in some type of webcompat issues.</p>
<ul>
<li>
<p><strong>Mobile versus desktop</strong></p>
<p>Some websites will adjust their content depending on the user agent strings. They will either deliver a specific content, or redirect to a domain which is friendly for mobile or desktop. This can be directly detected with the homepage of the website. You could quickly identify if a site sends the same design/content to Firefox Android, Safari iOS or a blink browser on Android. This is less and less meaningful, as many websites in the last ten years have switched to responsive design where the content automatically adjusts depending on the size of the screen.</p>
</li>
<li>
<p><strong>Rendering Issues</strong></p>
<p>This is slightly more complex. There might be multiple issues with regards to rendering. I'll talk about the caveats later. This could potentially identify a wrong color, a wrong position of the boxes, a difference in details such as scrollbars or boxes radius, etc.</p>
</li>
</ul>
<p>With a simple URLs list and using the <a href="https://w3c.github.io/webdriver/webdriver-spec.html">webdriver API</a>, it is possible to fetch websites for Gecko, WebKit and Blink and take a screenshot for each of them. It becomes very easy to test the top 1000 websites in a specific locale. You can discriminate visually quickly the screenshots which are different.</p>
<p><strong>But</strong> we said we wanted to be more effective. We can use a bit of maths for this. Let's make 𝑠¹ and 𝑠², the screenshots we want to compare, then we can use a simple library like <a href="https://docs.python.org/3/library/difflib.html">difflib</a> in python to compute the similarity of the images.</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">diff_ratio</span><span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="n">s2</span><span class="p">):</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">difflib</span><span class="o">.</span><span class="n">SequenceMatcher</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="n">s1</span><span class="p">,</span> <span class="n">s2</span><span class="p">)</span>
<span class="k">return</span> <span class="n">s</span><span class="o">.</span><span class="n">quick_ratio</span><span class="p">()</span>
</code></pre></div>
<p>Then it becomes easy to define the <code>diff_ratio</code> which is acceptable for the series of tests we run. After fixing a threshold this will identify the sites with potential issues. It will <strong>not identify the type of issues</strong>. It will <strong>not provide a diagnosis</strong>.</p>
<p>And the method has some limitations which are interesting to understand if we want to be effective in pre-filtering the issues.</p>
<h2>Some Limitations Around Screenshots Comparison</h2>
<p>The screenshots might be different but that doesn't necessary mean there is a webcompat issue. Here some cases:</p>
<ul>
<li>
<p><strong>Anti-Tracking Mechanisms</strong></p>
<p>Every browser has its own strategy with regards to tracking protection. These are browsers breaking websites on purpose to reduce users fingerprinting. Hence a screenshot for the same site might create different results.</p>
</li>
<li>
<p><strong>A/B Testing</strong></p>
<p>Some sites test A/B scenario for a more profitable user experience. They will send two different versions of the site to different users. If one browser is one pool and the other browser in another pool at the moment of the tests, the screenshots will be different.</p>
</li>
<li>
<p><strong>Android/iOS banner for apps</strong></p>
<p>Testing the rendering in between a browser on iOS and a browser on Android will create different results, as the banner for apps will display and link to different stores.</p>
</li>
<li>
<p><strong>Dynamic Content</strong> (News sites/Social Network)</p>
<p>There's a big category of websites where the content changes or offers rotations of the content in between each reload. Caroussels, ads, news article, user posts, etc. are all likely to modify the screenshots in between two queries in the same browser.</p>
</li>
<li>
<p><strong>Tier 1</strong></p>
<p>Some sites provide a different experience to different browsers. This one is more subtle to deal with. They rely more on a business decision. Compare for example the results of Google search on Firefox Android and Google Chrome. Google Chrome definitely receives the Tier 1. Other browsers receive different content. The diagnosis here is not technical, but business priorities.</p>
</li>
</ul>
<h2>Quick summary about autowebcompat.</h2>
<p><a href="https://github.com/marco-c/autowebcompat">autowebcompat</a>, that Brian was mentionning, is a nice project from <a href="https://marco-c.github.io/">Marco Castelluccio</a> to attempt to auto-detect web compatibility issues. Basically the code tries to learn if screenshots for a similar set of interactions in two different browsers create the same end result. The silverlining being that if there is a difference, there's probably something to better understand. The project used the issues already reported on <a href="https://webcompat.com/">webcompat.com</a>. In that sense it's already biaised by the fact that the issues have already been identified as being different. But it make possible to train a model on learning on what creates a webcompat issue.</p>
<h2>Training A Bot To Identify Valid Issues</h2>
<p>Recently, <a href="https://github.com/ksy36">Ksenia</a> (Mozilla Webcompat team) adjusted <a href="https://hacks.mozilla.org/2019/04/teaching-machines-to-triage-firefox-bugs/">BugBug</a> to make it work on GitHub. It helped the webcompat team to move away from the <a href="https://webcompat-ml.readthedocs.io/en/latest/index.html">old ML classifier</a> to the BugBug infrastructure.</p>
<p>It identifies already reported issues and closes the ones which have similar features than previous invalid bugs. Invalid here means not a webcompat issue. Some sites are broken in all browsers, that doesn't create a webcompat issue.</p>
<h2>Compatipede, Another Project For Auto Webcompat</h2>
<p><a href="https://github.com/seiflotfy/compatipede">Compatipede</a> is a project which predates autowebcompat (started in October 2013!) with the intent to identify more parameters and extend the scope of tests.</p>
<ul>
<li>Equal redirects</li>
<li>CSS style compatibility</li>
<li>Source code compatibility</li>
<li>Other custom tests</li>
</ul>
<p>This was quite interesting as it was trying to explore the unseen issues and avoid the pitfalls of screenshots.</p>
<p>It had also a modular architecture providing a <a href="https://github.com/seiflotfy/compatipede/tree/master/plugins">system of custom plugins</a> to run probes on the payloads sent by the website.</p>
<h2>SiteCompTester</h2>
<p>With the same spirit than Compatipede, <a href="https://github.com/hallvors/sitecomptester-extension">SiteCompTester</a> was an extension which made possible to target some type of issues and would surface bugs associated with a specific list of known issues. This makes it easier to diagnose a website.</p>
<h2>Template Extraction Mining</h2>
<p>The variability of content may be avoided by using a mechanism such as <a href="https://github.com/paulsmith/templatemaker">templatemaker</a>. This is a clever little tool which extracts the common features of a series of text and extract a template.</p>
<p>So let's say for a news website, we could imagine running template maker with one browser for a couple of days and extract its templates. And do the same in parallel with another browser. Then we would compare the templates instead of comparing two unique rendering of the websites. That would probably makes it possible to have a better understanding of certain features variability. This could be applied to markup, to JavaScript, to HTTP headers.</p>
<h2>Webcompat Auto-Detection Caveats</h2>
<p>The issue with auto-detection of webcompat issues is that we don't know what is broken before someone experience it in real life. The level of interactions it requires is really delicate.</p>
<p>And it's why the people working on triaging and diagnosis in the <a href="https://wiki.mozilla.org/Compatibility">Mozilla webcompat team</a> are top-notch.
* <a href="https://github.com/softvision-oana-arbuzov">Oana</a> and <a href="https://github.com/softvision-raul-bucata">Raul</a> are triaging the issues after poor description by most users.
* <a href="https://github.com/ksy36">Ksenia</a>, <a href="https://github.com/denschub">Dennis</a> and <a href="https://github.com/wisniewskit">Thomas</a> are diagnosing relentlessly minified obfuscated code to decipher what is breaking in the current site.</p>
<h2>Auto-Discovery Of Webcompat</h2>
<p>The auto-discovery may work in very specific use cases when we know what we try to identify as an issue. Let's say we already identify a pattern in one bug and we want to understand to which extend this bug is affecting other websites. Then using a framework going through the sites and searching for this pattern <strong>might reveal</strong> potential webcompat issues.</p>
<p>Targeted surveys are the key to understand the priority of some issues.</p>
<p>Otsukare!</p>When iOS will allow other browsers2021-09-27T09:20:00+09:002021-09-27T10:00:00+09:00Karl Dubosttag:www.otsukare.info,2021-09-27:/2021/09/27/ios-browsers-non-webkit<p>What happens when/if iOS authorizes other rendering engines?</p><p>User agent sniffing is doomed to fail. It has this thick layer of opacity and logic, where you are never sure that you will really get in the end.</p>
<p><img alt="Stuffed animal through the opaque glass of a window." src="https://www.otsukare.info/images/20210927-opacity.jpg"></p>
<p>This happens all the time and will happen again. It's often not only technical, but business related and just human. But let's focus on the detection of Firefox on iOS. Currently, <strong>on iOS, every browsers are using the same rendering engine</strong>. The one which is mandated by Apple. Be Chrome, Firefox, etc, <a href="https://duckduckgo.com/?q=WKWebView+browsers+chrome+firefox+ios&ia=web">they all use WKWebView</a>.</p>
<p>One of the patterns of user agent detections goes like this:</p>
<ol>
<li>Which browsers?
Firefox, Chrome, Safari, etc.</li>
<li>Which device type?
Mobile, Desktop, Tablet</li>
<li>Which browser version?</li>
</ol>
<p>You have 30s to guess what is missing in this scenario?</p>
<p>⁞</p>
<p>⁞</p>
<p>⁞</p>
<p>Yes, the OS. Is it iOS or Android? The current logic for some developers is that</p>
<ul>
<li>Safari + mobile = iOS</li>
<li>Firefox + mobile = Android</li>
</ul>
<p>As of today, Firefox</p>
<ul>
<li>on iOS is version 37</li>
<li>on Android is version 94</li>
</ul>
<p>So if the site has <a href="https://github.com/webcompat/web-bugs/issues/67610">minimum version support grid</a></p>
<div class="highlight"><pre><span></span><code><span class="kd">function</span><span class="w"> </span><span class="nx">l</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">t</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">window</span><span class="p">.</span><span class="nx">navigator</span><span class="p">.</span><span class="nx">userAgent</span><span class="p">,</span>
<span class="w"> </span><span class="nx">e</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">action</span><span class="o">:</span><span class="w"> </span><span class="s2">"none"</span><span class="p">,</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nx">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">c</span><span class="p">.</span><span class="nx">warn</span><span class="p">,</span>
<span class="w"> </span><span class="nx">o</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">c</span><span class="p">.</span><span class="nx">block</span><span class="p">;</span>
<span class="w"> </span><span class="nb">Object</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">s</span><span class="p">).</span><span class="nx">forEach</span><span class="p">(</span><span class="kd">function</span><span class="w"> </span><span class="p">(</span><span class="nx">n</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">t</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">n</span><span class="p">)</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="p">(</span><span class="nx">e</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">c</span><span class="p">[</span><span class="nx">s</span><span class="p">[</span><span class="nx">n</span><span class="p">]]);</span>
<span class="w"> </span><span class="p">});</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">r</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">a</span><span class="p">.</span><span class="nx">detect</span><span class="p">(</span><span class="nx">t</span><span class="p">);</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">(</span><span class="nx">r</span><span class="p">.</span><span class="nx">msie</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nx">r</span><span class="p">.</span><span class="nx">version</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="mf">11</span><span class="p">)</span><span class="w"> </span><span class="o">||</span>
<span class="w"> </span><span class="p">(</span><span class="nx">r</span><span class="p">.</span><span class="nx">safari</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nx">r</span><span class="p">.</span><span class="nx">version</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="mf">8</span><span class="p">)</span><span class="w"> </span><span class="o">||</span>
<span class="w"> </span><span class="p">(</span><span class="nx">r</span><span class="p">.</span><span class="nx">firefox</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nx">r</span><span class="p">.</span><span class="nx">version</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="mf">49</span><span class="p">)</span>
<span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="nx">o</span>
<span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="p">(</span><span class="nx">r</span><span class="p">.</span><span class="nx">chrome</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nx">r</span><span class="p">.</span><span class="nx">version</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="mf">21</span><span class="p">)</span><span class="w"> </span><span class="o">||</span>
<span class="w"> </span><span class="p">(</span><span class="nx">r</span><span class="p">.</span><span class="nx">firefox</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nx">r</span><span class="p">.</span><span class="nx">version</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="mf">26</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="o">!</span><span class="nx">r</span><span class="p">.</span><span class="nx">mobile</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="o">!</span><span class="nx">r</span><span class="p">.</span><span class="nx">tablet</span><span class="p">)</span><span class="w"> </span><span class="o">||</span>
<span class="w"> </span><span class="p">(</span><span class="nx">r</span><span class="p">.</span><span class="nx">safari</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nx">r</span><span class="p">.</span><span class="nx">version</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="mf">4</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nx">r</span><span class="p">.</span><span class="nx">mobile</span><span class="p">)</span><span class="w"> </span><span class="o">||</span>
<span class="w"> </span><span class="p">(</span><span class="nx">r</span><span class="p">.</span><span class="nx">safari</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nx">r</span><span class="p">.</span><span class="nx">version</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="mf">6</span><span class="p">)</span><span class="w"> </span><span class="o">||</span>
<span class="w"> </span><span class="p">(</span><span class="nx">r</span><span class="p">.</span><span class="nx">android</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nx">r</span><span class="p">.</span><span class="nx">version</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="mf">4</span><span class="p">)</span>
<span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="nx">n</span>
<span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="nx">e</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
<p>Here the site sees Firefox… so it must be Android, so it must be Gecko. They have set their minimum support for version 49. Firefox is then considered outdated. Safari minimum version on their grid is 8. So Firefox iOS (WebKitView) would have no issues!</p>
<h2>Fast Forward To The Future.</h2>
<p>When Apple authorizes different rendering engines on iOS (yes, I'm on the optimistic side, because I'm patient), I already foresee a huge webcompat issue. The web developers (who are currently right) will infer in some ways that <strong>Firefox on iOS can only be WebKitWebView</strong>. So the day Gecko is authorized on iOS, we can expect more breakages and ironically some of the webcompat bugs, we currently have will go away.</p>Today is my Mozilla 8 years anniversary2021-06-21T18:40:00+09:002021-06-21T22:00:00+09:00Karl Dubosttag:www.otsukare.info,2021-06-21:/2021/06/21/mozilla-eight-years<p>I have been working 8 years at Mozilla in Webcompat. What a team!</p><p>Eight years ago, I have started working at Mozilla.</p>
<p><img alt="Archer on a stone wall decoration." src="https://www.otsukare.info/images/20210621-archer.jpg"></p>
<h2>Hiring, a long process</h2>
<p>In <a href="https://www.linkedin.com/in/karldubost/">my employment history</a>, I have never tried to spread a large net to try to land a job, except probably for my first real job in 1995. I have always carefully chosen the company I wanted to work for. I probably <strong>applied ten times</strong> on the course of 10 years before landing a job at Mozilla.</p>
<p>When the Web Compatibility team was created, I applied to one of the positions available in 2013. In April 2013, from Montreal, I flew to Mountain View for a series of job interviews with different Mozilla employees. Most of the interviews were interesting but I remember one engineer was apparently not happy interviewing me and it didn't go very well. I don't remember who, but it left me with a bitter taste at the time. A couple of days later <strong>I was notified that I was not taken</strong> for the job. While disappointing, I was not surprised. I usually do not perform well during interviews, specifically when you have to demonstrate knowledge instead of articulating the way you work with knowledge. I find interviews a kind of theater.</p>
<p>But Mozilla came back to me and proposed me a 6 months contract, still in the Mozilla Web Compatibility team but for another role. It was not what I was initially interested by, but why not? It's when I met Lawrence Mandel, who would be my future manager if I landed the job. I liked the contact right away. <strong>I got an offer in June 2013</strong>. I signed.</p>
<p>Fast forward 8 years, I'm currently the manager of the Web Compatibility team.</p>
<h2>Without people, no Web Compatibility!</h2>
<p>The Web Compatibility team started with 3 persons: Mike Taylor, Hallvord R. M. Steen and myself and at its peak we were probably 10 persons, depending on how we count. We are currently 7 persons including myself. Talking about my 8 years anniversary <strong>doesn't make sense without mentioning the work of the team</strong>. My work is insignificant if we don't take the globability of what the team is achieving.</p>
<p><img alt="Figures on a stone wall decoration." src="https://www.otsukare.info/images/20210621-figures.jpg"></p>
<blockquote>
<p>« Et par contre, si je communique à mes hommes l’amour de la marche sur la mer, et que chacun d’eux soit ainsi en pente à cause d’un poids dans le cœur, alors tu les verras bientôt se diversifier selon leurs mille qualités particulières. Celui-là tissera des toiles, l’autre dans la forêt par l’éclair de sa hache couchera l’arbre. L’autre, encore, forgera des clous, et il en sera quelque part qui observeront les étoiles afin d’apprendre à gouverner. Et tous cependant ne seront qu’un. Créer le navire ce n’est point tisser les toiles, forger les clous, lire les astres, mais bien donner le goût de la mer qui est un, et à la lumière duquel il n’est plus rien qui soit contradictoire mais communauté dans l’amour. »</p>
<p>Antoine de Saint-Exupéry. « Citadelle. »</p>
</blockquote>
<p>Since the beginning of 2021,</p>
<p><a href="https://overengineer.dev/blog/">Dennis</a> has drastically reduced the number of old <a href="https://github.com/webcompat/web-bugs/issues?q=is%3Aopen+is%3Aissue+milestone%3Aneedsdiagnosis">diagnosis</a> that were on top (or at the bottom?) of our pile. He is also now the module owner for <a href="https://wiki.mozilla.org/Compatibility/Interventions_Releases">Site Interventions</a>, which help Mozilla to hotfix websites. When a site is broken and the outreach is unlikely to be successful, this one of the ways we have to fix the website on the fly so the people can continue to enjoy using troubled websites.</p>
<p><a href="https://github.com/jgraham">James</a> is the mind and the smooth operator behind <a href="https://web-platform-tests.org/">Web Platform Tests</a> at Mozilla. He is doing an amazing job at encouraging Mozilla engineers to develop more Web Platform tests. He makes sure that everything is synchronized with other vendors. Web Platform Tests are essential to be able to discover bugs in specifications and differences in implementations. He is also the core person for the <a href="https://w3c.github.io/webdriver-bidi/">work on BiDi</a> at Mozilla. BiDi is another important part of the puzzle of Web Compatibility. Testing manually websites is costly. Webdriver comes here to make it possible for automating the tests of websites functionalities. If the cost is lower, web developers can test their websites in more than one browser and discover and fix their webcompatibility issues before we discover them.</p>
<p><a href="https://github.com/ksy36">Ksenia</a> is the owner of <a href="https://github.com/webcompat/webcompat.com/">webcompat.com</a> and webcompat ML bot. The <a href="https://github.com/webcompat/webcompat.com/blob/89de7a00b2bc3981a918a588fbdc34d4c0a68234/docs/ml-process.md">ML bot</a> helps us to pre-filter the bug and determine if it's a valid webcompat issue. We receive around 700 and 800 bugs a week and that's a lot for our small team. We would not be able to manage without the bot. Tiredlessly she has improved the tools used for minimizing the boring part of the work we do and at the same time, found solutions for helping bug reporters to have a better experience.</p>
<p>Softvision team: <a href="https://github.com/softvision-oana-arbuzov">Oana</a> and <a href="https://github.com/softvision-raul-bucata">Raul</a>. I have a lot of respect for the people at Softvision helping Mozilla to do the triage of bugs. This task is sisyphean. Every week, 700 to 800 bugs come in. Luckily enough we have a bot for pre-triage, but when bugs are evaluated being valid. They decipher the old runes of bug reports to understand what the bug reporter suffered and they make it something more compelling for people who will be diagnosing. Previously, we had Ciprian and Sergiu.</p>
<p><a href="https://github.com/wisniewskit">Thomas</a> is the architect of the Site Interventions. He is also making sure that sites continue to work when tracking protection is blocking things. He has implemented lately <a href="https://blog.mozilla.org/security/2021/03/23/introducing-smartblock/">SmartBlock</a>. Thomas is this giant person who can touch everything in the Webcompat team, but still super caregiver when we do not understand something. He explains what he does and this is gold. It means that people can grow, evolve and be a better part of themselves.</p>
<h3>Contributors And Interns</h3>
<p>The project would be nothing without the contributors and interns who worked with us on making the site, the tools, the process better:</p>
<p><a href="http://github.com/haseebgit">Abdul</a>, <a href="https://github.com/calexity">Alexa</a>, <a href="https://github.com/brizental">Beatriz</a>, <a href="https://github.com/cch5ng">Carol</a>, <a href="https://github.com/deepthivenkat">Deepthi</a>, <a href="https://github.com/magsout">Guillaume</a>, <a href="https://github.com/laghee">Kate</a>, <a href="https://github.com/marimeireles">Mariana</a>, <a href="https://github.com/lockettm">mesha</a>, <a href="http://github.com/reinhart1010">Reinhart</a>, and more…</p>
<h3>Those Who Were</h3>
<p>And there are those who have been in the webcompat team and have been participants to its success: <a href="https://miketaylr.com/">Mike</a>, <a href="https://github.com/adamopenweb">Adam</a>, <a href="https://github.com/MDTsai">Eric</a>, <a href="https://github.com/hallvors">Hallvord</a>, <a href="https://github.com/zoepage">Ola</a>. I could write a lot more about it.</p>
<blockquote>
<p>« En ce qui concerne donc mon voisin, j’ai observé qu’il n’était point fertile d’examiner de son empire les faits, les états de choses, les institutions, les objets, mais exclusivement les pentes. Car si tu examines mon empire tu t’en iras voir les forgerons et les trouveras forgeant des clous et se passionnant pour les clous et te chantant les cantiques de la clouterie. Puis tu t’en iras voir les bûcherons et tu les trouveras abattant des arbres et se passionnant pour l’abattage d’arbres, et se remplissant d’une intense jubilation à l’heure de la fête du bûcheron, qui est du premier craquement, lorsque la majesté de l’arbre commence de se prosterner. Et si tu vas voir les astronomes, tu les verras se passionnant pour les étoiles et n’écoutant plus que leur silence. Et en effet chacun s’imagine être tel. Maintenant si je te demande : « Que se passe-t-il dans mon empire, que naîtra-t-il demain chez moi ? » tu me diras : « On forgera des clous, on abattra des arbres, on observera les étoiles et il y aura donc des réserves de clous, des réserves de bois et des observations d’étoiles. » Car myope et le nez contre, tu n’as point[…] »</p>
<p>Antoine de Saint-Exupéry. « Citadelle. »</p>
</blockquote>
<h2>Challenging The Comfort Of My Current Position</h2>
<p>When working long enough at a company that you like, it becomes easy to feel comfortable. So every couple of years, I put myself in the position of looking for another job, even eventually having job interviews with some companies. I try to limit these interviews to the strict necessary by carefully selecting the companies I apply to.</p>
<p>I want to be in a position where I have to choose in between staying at Mozilla and discovering a new area with interesting people and interesting areas of work. Sometimes areas that I have probably poor knowledge of. This is slightly tricky because many companies have a tendency to recruit people ready to fit in the machinery instead of people with an ability to work and learn.</p>
<p>So far I have been 8 years at Mozilla, but I want to continue to make Mozilla a choice to stay instead of a place which is comfortable. So I will continue to explore new opportunities as I have always done.</p>
<h2>Comments</h2>
<p>If you have more questions, things I may have missed, different take on them. Feel free <a href="https://github.com/karlcow/otsukare.info/issues/9">to comment…</a>. Be mindful.</p>
<p>Otsukare!</p>Browser Wish List - Tabs and bookmarks are the same thing2021-05-10T11:28:00+09:002021-05-10T21:13:00+09:00Karl Dubosttag:www.otsukare.info,2021-05-10:/2021/05/10/tabs-bookmarks-ui<p>I would love to have a better bookmarks and tabs management. This morning a simple sketch on what it would look like.</p><p>My browser is my like an office room with desk and shelves, where the information is accessible. Information is stacked, accessible, sometimes open and browsable at glance and some deep on the shelves. But how would I want to have access it in the browser.</p>
<p>Currently we bury the information of tabs and bookmarks in a big bind of context without giving any help for managing apart of having to go through the list of pages one by one. No wonder why people feel overwhelmed and try to limit the number of tabs they have opened. Because big numbers rely on external tools (Tree Style Tabs, Sidebery, Containers, etc) which do not go far enough to manage the tabs.</p>
<p><img alt="Binder of pages" src="https://www.otsukare.info/images/20210510-folder.jpg"></p>
<h2>Some contexts</h2>
<p>It started with a message from <a href="https://glandium.org/blog/">Glandium</a> sharing an article from Joseph Chee Chang with the title: <a href="https://joe.cat/CHI-browser-tabs/">When the Tab Comes Due</a>. Tabs! <a href="/2020/07/07/browser-tabs-time-machine">Love Tabs</a>. Reading the PDF brought some strong nodding.</p>
<blockquote>
<p><strong>Tabs should better reflect users’ complex task structures.</strong></p>
<p>One potential design space is to bootstrap such mental model repre-sentations with minimal user effort by identifying their intentionsusing their navigation patterns. For example, a set of tabs openedfrom a search engine query is likely to support the same information needs; or, a set of tabs opened from a top-10 list article arelikely competing options under the same category. Capturing andorganizing tabs using such structures has the potential of betterorienting users and providing better support for task progressionand resumption.</p>
<p><strong>Allow users to externalize their thoughts and synthesize information across tabs.</strong></p>
<p>More directly, a recent survey showed thataround half of their participants (49.4%, N=89) use spreadsheets togather evidence and take notes across multiple online informationsources to compare options (e.g., products or destinations) to helpthem make decisions. However, current browsers treat tabs asindividual silos and provide little support for cross-referencing andcollecting information between webpages. Using external tools,such as word documents and spreadsheets, creates a disconnectin users’ workspace, and can incur high cognitive and interactioncosts when trying to copy and paste information to synthesize themin a separate document</p>
</blockquote>
<h2>Sketch</h2>
<p>The article made me think about tabs <strong>and bookmarks</strong>, in our browsers UIs, these are separated. Probably it should not be. <strong>A bookmark is just a closed context, and a tab is just an opened context</strong>. But they are basically the same. The UI to access them is completely different, the information to filter them is also totally different. <strong>Why?</strong></p>
<p>So I was thinking how could both world be mixed together.</p>
<ul>
<li>Make the bookmarks more visual though thumbnails.</li>
<li>Make the tabs manageable through trees and categories and gives them the concept of dates (created and last opened) and show these dates.</li>
<li>Add on top of this full text search on the full set (or subcategory) of tabs/bookmarks (we need a new name).<ul>
<li>Search "Gardening" for tabs opened in between February 2021 and May 2021.</li>
<li>Search "Curry" for tabs in my Thailand category</li>
</ul>
</li>
<li>Give the notion of views<ul>
<li>By tree (the sketch below)</li>
<li>By timeline (Year, month, days). Think photo management software. Sure I opened this tab after this date, during this trip, etc.</li>
<li>By geolocation (tabs opened when I was at home or in this cafe) Sometimes we memorize the information through the external context we where in.</li>
<li>By labels or keywords that you may have added.</li>
<li>By automatic classification of content. Machine Learning is all the rage, why not using the capabilities that OS provides more and more for running Machine learning to classify the content or even embark one.</li>
</ul>
</li>
</ul>
<p><img alt="Sketch for tabs bookmarks" src="https://www.otsukare.info/images/20210510-tabs-bookmarks-large.jpg"></p>
<h2>Comments</h2>
<p>If you have more questions, things I may have missed, different take on them. Feel free <a href="https://github.com/karlcow/otsukare.info/issues/8">to comment…</a>. Be mindful.</p>
<p>Otsukare!</p>Get Ready For Three Digits User Agent Strings2021-04-20T17:20:00+09:002021-05-31T11:43:00+09:00Karl Dubosttag:www.otsukare.info,2021-04-20:/2021/04/20/ua-three-digits-get-ready<p>In 2022, Firefox and Chrome will reach a version number with three digits: 100. It's time to test. Help us!</p><p>In 2022, Firefox and Chrome will reach a version number with three digits: <code>100</code>.
<strong>It's time to get ready</strong> and extensively test your code, so your code doesn't return <code>null</code> or worse <code>10</code> instead of <code>100</code>.</p>
<p><img alt="Durian on sale" src="https://www.otsukare.info/images/20210420-durian.jpg"></p>
<h2>Some contexts</h2>
<p>The browser user agent string is <a href="/2014/03/31/ua-detection-use-cases">used in many circumstances</a>, on the server side with the <code>User-Agent</code> HTTP header and on the client side with <code>navigator.userAgent</code>. Browsers <a href="/2013/11/08/ua-override">lie about it</a>. Web apps and websites detection <a href="/2013/12/04/future-fail-js">do not cover all cases</a>. So browsers have to <a href="/2021/01/22/site-interventions-and-webdriver">modify the user agent</a> string on a site by site case.</p>
<h2>Browsers Release Calendar</h2>
<p>According to the <a href="https://wiki.mozilla.org/Release_Management/Calendar">Firefox release calendar</a>, during the first quarter of 2022 (probably March), Firefox Nightly will reach version 100. It will set Firefox stable release version around May 2022 (if it doesn't change until then).</p>
<p>And <a href="https://chromiumdash.appspot.com/schedule">Chrome release calendar</a> sets a current date of March 29, 2022.</p>
<h2>What Mozilla Webcompat Team is doing?</h2>
<p><a href="https://twitter.com/denschub">Dennis Schubert</a> started to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1672445">test JavaScript Libraries</a>, but this tests only the libraries which are up to date. And we know it, the Web is a legacy machine full of history.</p>
<p>The <a href="https://wiki.mozilla.org/Compatibility#Core_Team">webcompat team</a> will probably automatically test the top 1000 websites. But this is very rudimentary. It will not cover everything. Sites <a href="https://github.com/webcompat/web-bugs/issues/67866">always break in strange ways</a>.</p>
<h2>What Can You Do To Help?</h2>
<h3>Browse the Web with a <code>100</code> UA string</h3>
<ol>
<li>Change the user agent string of your favorite browser. For example, if the string is <code>Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:89.0) Gecko/20100101 Firefox/89.0</code>, change it to be <code>Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:100.0) Gecko/20100101 Firefox/100.0</code></li>
<li>If you notice something that is breaking because of the UA string, file a report on <a href="https://webcompat.com/">webcompat</a>. Do not forget to check that it is working with the normal UA string.</li>
</ol>
<h3>Automatic tests for your code</h3>
<p>If your web app has a JavaScript Test suite, add a profile with a browser having <code>100</code> for its version number and check if it breaks. Test <strong>both Firefox and Chrome</strong> (mobile and desktop) because the libraries have different code paths depending on the user agent. Watch out for code like:</p>
<div class="highlight"><pre><span></span><code><span class="kd">const</span><span class="w"> </span><span class="nx">ua_string</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Firefox/100.0"</span><span class="p">;</span>
<span class="nx">ua_string</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/Firefox\/(\d\d)/</span><span class="p">);</span><span class="w"> </span><span class="c1">// ["Firefox/10", "10"]</span>
<span class="nx">ua_string</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/Firefox\/(\d{2})/</span><span class="p">);</span><span class="w"> </span><span class="c1">// ["Firefox/10", "10"]</span>
<span class="nx">ua_string</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/Firefox\/(\d\d)\./</span><span class="p">);</span><span class="w"> </span><span class="c1">// null</span>
</code></pre></div>
<h3>Compare version numbers as integer not string</h3>
<p><a href="https://miketaylr.com/posts/2021/03/firefox-version-520-works-in-slack.html">Compare integer, not string</a> when you have decided to have a minimum version for supporting a browser, because</p>
<div class="highlight"><pre><span></span><code><span class="s2">"80"</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="s2">"99"</span><span class="w"> </span><span class="c1">// true</span>
<span class="s2">"80"</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="s2">"100"</span><span class="w"> </span><span class="c1">// false</span>
<span class="nb">parseInt</span><span class="p">(</span><span class="s2">"80"</span><span class="p">,</span><span class="w"> </span><span class="mf">10</span><span class="p">)</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="nb">parseInt</span><span class="p">(</span><span class="s2">"99"</span><span class="p">,</span><span class="w"> </span><span class="mf">10</span><span class="p">)</span><span class="w"> </span><span class="c1">// true</span>
<span class="nb">parseInt</span><span class="p">(</span><span class="s2">"80"</span><span class="p">,</span><span class="w"> </span><span class="mf">10</span><span class="p">)</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="nb">parseInt</span><span class="p">(</span><span class="s2">"100"</span><span class="p">,</span><span class="w"> </span><span class="mf">10</span><span class="p">)</span><span class="w"> </span><span class="c1">// true</span>
</code></pre></div>
<h2>Comments</h2>
<p>If you have more questions, things I may have missed, different take on them. Feel free <a href="https://github.com/karlcow/otsukare.info/issues/7">to comment…</a>. Be mindful.</p>
<p>Otsukare!</p>Maximizing Possible Outcomes In Simple Interfaces2021-03-29T12:00:00+09:002021-03-29T12:00:00+09:00Karl Dubosttag:www.otsukare.info,2021-03-29:/2021/03/29/dumb-down-danger<p>Let's keep the possibility of hackability when simplifying interfaces</p><p>Facing a complex system agency, designers (be graphics, software engineers, architects, etc.) will attempt to reduce the complexity by simplifying the interactions with the system. The percentage of interactions with the new design becomes the tool for measuring the efficacy of the new choices.</p>
<p><img alt="faucets and soaps" src="https://www.otsukare.info/images/20210329-robinets.jpg"></p>
<p>But what do we measure? Do we measure the success of the design or do we measure that we created only one way to do a task, and funnels a variety and diversity of interactions through the funnel of one way of doing things. We should be wary and careful of what we measure and the complexity of individuals in front of a system.</p>
<p>When we simplify a system of interactions to a certain minimalism, we often trade choices for reductionism. We maximize the simplicity to the point of dumbing everything down. But do we always help? Creativity, emergence of patterns often lie in the hackability of a system. When we reduce the options for someone to use the system in unexpected ways, we remove the possibility for people to own a craft, a skill. We make them serve the system, instead of the system serving them.</p>
<p>We should try to create simple interfaces that maximize the possibility for people to create (creative entropy), being empowered, being autonomous.</p>
<h2>See Also</h2>
<ul>
<li><a href="https://www.youtube.com/watch?v=CSru1QjpydI">Odyssée de l'hiver - Christian Fauré</a> (French)</li>
<li><a href="https://fvsch.com/calculators">Designing Calculator Apps</a></li>
</ul>
<h2>Comments</h2>
<p>If you have more questions, things I may have missed, different take on them. Feel free <a href="https://github.com/karlcow/otsukare.info/issues/6">to comment…</a>. Be mindful.</p>
<p>Otsukare!</p>Working With A Remote Distributed Team (Mozilla Edition)2021-03-16T17:35:00+09:002021-03-16T17:35:00+09:00Karl Dubosttag:www.otsukare.info,2021-03-16:/2021/03/16/working-tips-remote-team<p>These are my requirements and tips when working in a remote distributed team at Mozilla.</p><p>The <a href="https://www.mozilla.org/">Mozilla</a> <a href="https://wiki.mozilla.org/Compatibility">Webcompat team</a> has always been an internationally distributed team from the start (7+ years). I have been working this way for the last 20 years with episodes of in-office life.</p>
<p><img alt="Desk in a passage" src="https://www.otsukare.info/images/20210316-bureau.jpg"></p>
<h2>Priorities Of Scope</h2>
<p><strong>When sending messages to talk about something, always choose the most open forum first.</strong></p>
<h3>Why?</h3>
<p>It's <strong>always easier to restrict a part of a message to a more private discussion</strong>. Once a discussion starts in private, making its content available to a larger sphere extends the intimacy, privacy, secrecy. It becomes increasingly harder to know if we can share it more broadly.</p>
<p><strong>Everything you say, write, think might be interesting for someone out there</strong> in another Mozilla team, someone in Mozilla contributors community, someone out there in the world. I can't count the number of times I have been happy to learn through people discussing in the open, sharing what they do internally. It's inspiring. It extends your community. It solidifies the existence of your organization.</p>
<p><strong>When the scope is broad, the information becomes more resilient.</strong> More people know the information. You probably had to use a publishing system involving the persistence of the information.</p>
<h2>Information Broadly Accessible</h2>
<p><strong>Give it a URI, so it exists!</strong> or in the <a href="https://en.wikipedia.org/wiki/Cogito,_ergo_sum">famous words</a> of Descartes: "URI, ergo sum".</p>
<h3>Why?</h3>
<p>URI is this thing which starts with <code>http</code> or <code>https</code> that you are currently using to read this content. Once you gave a URI to a piece of content, you access to plenty of features:</p>
<ol>
<li>You can share through different medium (messages, mails, etc.)</li>
<li>You make the information easily searchable</li>
<li>You make the information more resilient with regards to time. Imagine someone joining your team later on. Or you have left and your email account which was cointaining all the interesting information is gone.</li>
</ol>
<p>You may want to create a <a href="https://www.w3.org/Consortium/Persistence">URI persistence policy</a> at the organization level.</p>
<h2>Messages How?</h2>
<p><strong>Context is everything!</strong></p>
<p>This applies to basically all messaging style (chat, email, etc.)</p>
<h3>Why?</h3>
<p>If you send a message addressing someone, think about this:</p>
<ol>
<li><strong>Who?</strong> Use the person handle in a shared chat.</li>
<li><strong>What?</strong> The topic you would like to discuss with enough context to make it possible for the person to answer. Share URIs to online documents.</li>
<li><strong>When?</strong> If there is a deadline, give it. It's a lot easier to reply at the appropriate time and remove the stress on both ends of the message.</li>
</ol>
<p><strong>note</strong>: I have written, a long time ago, a <a href="https://www.la-grange.net/2014/03/04/bien-gerer-mail">special guide for working with emails in French</a> and it has been <a href="http://www.koalie.net/Translations/Working-with-email/working-with-email.html">translated in English</a></p>
<p>Mozilla is a distributed community with a lot of different cultures (social, country, education, beliefs) and across all timezones. At Flickr, <a href="http://web.archive.org/web/20070425213445/http://www.hchamp.com/">Heather Champ</a> had a good reminder for the community: "Don't be a creep."</p>
<p>You may (will probably) do terrible blunders with regards to someone else. Address them right away when the person is making a comment about them. And if necessary, apologize in the same context, you made the mistake. When you are on the receiving part of the offensive message, address them with the person who made them right away in private. Seek for clarification and explain how it can have been hurtful. If it repeats, bring it up to the hierarchy ladder and/or <a href="https://www.mozilla.org/en-US/about/governance/policies/participation/">follow the community guidelines</a>.</p>
<h2>Chat (Matrix, IRC, Slack, …)</h2>
<ol>
<li><strong>Prefer [Public] over [Team channels] over [one to one] messages.</strong></li>
<li><strong>Choose Matrix over Slack.</strong></li>
<li><strong>Reply in threads.</strong></li>
</ol>
<h3>Why?</h3>
<p>When sending messages to share things about your work at Mozilla, use matrix over slack. It will be more accessible to the community and it will allow more participation.</p>
<p>That said be mindful. These systems do not have built-in web archives. That's a strength and a weakness. The strength part is that it allows a more casual tone on discussing stuff without realizing that you are saying today could become embarassing in 10 years. The weakness part is that there is valuable work discussions going on sometimes in chat. So if you think a discussion on chat was important enough that it deserves a permanent record, publish it in a more permanent and open space. (Exactly this blog post which started by a discussion on slack about someone inquiring about Team communications at Mozilla.)</p>
<h2>Reading Emails</h2>
<p><strong>Read Only Emails Sent To You.</strong></p>
<h3>Why?</h3>
<p>Ah emails… the most loved hating subject. I understand that mail clients can be infuriating, but mails are really an easy task. Probably the issue with emails is not that much the emails themselves, but the way we treat them. Again see my <a href="http://www.koalie.net/Translations/Working-with-email/working-with-email.html">guide for working with emails</a>.</p>
<p>I end up all my working days with all messages <strong>marked as read</strong>. I don't understand what INBOX 0 means. So here my recipes:</p>
<ol>
<li><strong>Deactivate mail notifications from all services</strong> except if you intent to keep these notifications as archived helping you to work with (example: github issue messages are my offline database that I can search.)</li>
<li><strong>Put all my mail for a month in a monthly folder</strong>. This month all my mails are going to <code>/2021/03</code> mailbox.</li>
<li><strong>Create virtual/smart mailboxes</strong> for each context where you need to access the emails. The benefit? The same email is then accessible from different contexts. Quick Tip to make the mailbox more performant, limit it to the last 6 weeks. smart mailboxes are easy to create, easy to destroy with changing contexts. Currently in Mail.app, I have around 50 to 100 smart mailboxes.</li>
<li><strong>Create a virtual mailbox which catches the messages where you are in To: or Cc:</strong>. <em>This</em> is your real inbox. You will discover that you do not receive that many emails in fact. This is the thing you should reply to. Mark as read everything else.</li>
<li><strong>Do not read the emails which are not directly addressed to you</strong>. This is difficult to understand for many people. But that's the good way of handling the volume. Think about your email as an archive of content which is searchable and the smart mailboxes as filter on what you might be interested in.</li>
<li><strong>Use an online archived mailing-list</strong>. Do not send emails to a group of people with giant list of <code>Cc:</code>. This is bad. It encourages top replies to keep context. There is always someone missing who needs to be added later. It doesn't resist time at all. <strong>Information belongs to the organization/context you are working on</strong>, not the people. You will be leaving one day the organization. New people will join. The information needs to be accessible.</li>
</ol>
<p>With these, you will greatly reduce your burden. And one last thing, probably which is conter-intuitive. For work, do not use emails on your mobile phone. Mail clients on mobile are not practical. Typing on a virtual keyboard on a small screen for emails is useless. Mails require space.</p>
<h2>Meetings Organizations</h2>
<p><strong>Meetings are for discussions</strong></p>
<h3>Why?</h3>
<p>If it's about information sharing, there are many ways of doing it in a better way. Publish a blog post, write it on a wiki, send it to the mailing-list of the context of your information. But do not create a meeting to just have one person talking all the time. Meetings are here for the interactions and picking ideas.</p>
<p>Here some recommendations for good meetings:</p>
<ol>
<li><strong>Have a regular non mandatory meeting time</strong>. What does it mean? The time is blocked, but if there is no agenda, there is no meeting.</li>
<li><strong>Have a published agenda</strong> at a regular URI where people can contribute to the agenda. On the Webcompat team, everyone can add an <a href="https://pad.0b101010.services/mozilla-webcompat-meeting-agenda">agenda item to our public agenda</a>, even contributors. Try to have the agenda, at least 24h before the time of the meeting.</li>
<li><strong>Have a scribe and a chair</strong>. The chair is the person who will be charge of animating the discussion during the meeting. The scribe will be the person taking notes of what is being said. The minutes are being taken live on the system and everyone can see what is being taken, hence can fix them. We <a href="https://wiki.mozilla.org/Compatibility/Meetings/Scribes">rotate scribes and chairs</a> at every meeting.</li>
<li><strong>Publish the meeting minutes online</strong>. This is important. it gives a regular URL that you can refer to in the future, that you can revisit or share with someone else in a different context. Webcompat has an archive of <a href="https://wiki.mozilla.org/Compatibility/Meetings">all minuted meetings</a> on Mozilla wiki. Example: <a href="https://wiki.mozilla.org/Compatibility/Meetings/2021-03-02">Minutes of March 2, 2021</a></li>
<li><strong>Break out big groups</strong>. When there is a meeting with a lot of people in one room and a couple of people online, the meeting is unbalanced and the body language (we social beings) take over and people online may become excluded. Separate the big local group in smaller groups or really as individuals so that everyone is like a remote person.</li>
<li><strong>Allow for people to participate</strong> once the meeting has finished. There are bug trackers, minutes, mailing-lists, etc. Give a deadline for commenting.</li>
</ol>
<h3>Meeting Times</h3>
<p>In a distributed team, the shape of Earth comes to crash into the fixed time reality of a meeting. You will not be able to satisfy everyone, but there are things to avoid the usual grumpiness, frustrations.</p>
<ol>
<li>If you organize a meeting from the US West Coast time, Fridays are forbidden. It's already Saturday in Asia-Pacific</li>
<li>If you organize a meeting from Asia-Pacific time, Mondays are forbidden. The US West Coast is still on Sunday.</li>
<li>Create a doodle to understand the distribution of time of people who can participate. Some people do not necessary work along the 9 to 5 schedule, some like to participate at night, some prefer very early meetings</li>
<li>If you can't fit everyone in one meeting because of time zones. Create two meetings or rotate the burden of meeting time.</li>
<li>Minutes the meeting, this will become handy for people who can't attend.</li>
</ol>
<h2>Wiki, Google Documents, Blog Post</h2>
<p><strong>Publish Online with a wide accessible scope</strong> if possible.</p>
<h3>Why?</h3>
<p>First rule at the start. If you create a Google docs, do not forget to set the viewing and sharing rights for the document. Think long term. For example, the wiki at Mozilla has been here for a longer time than Google Docs. Mozilla controls the URI space of the wiki, but not so much the one of Google Docs.</p>
<p>Having an URI for your information is key as said above.</p>
<h2>Comments</h2>
<p>If you have more questions, things I may have missed, different take on them. Feel free <a href="https://github.com/karlcow/otsukare.info/issues/5">to comment…</a>. Be mindful.</p>
<p>Otsukare!</p>Capping User Agent String - followup meeting2021-03-02T11:27:00+09:002021-03-02T11:27:00+09:00Karl Dubosttag:www.otsukare.info,2021-03-02:/2021/03/02/capping-user-agent-string<p>Capping User Agent string for Web Compatibility, a meeting and a status, and probably future work on evolving freezing user agent strings.</p><p>Web compatibility is about dealing with a constantly evolving biotope where things die slowly. And even when they disappear, they have contributed to the balance of the ecosystem and modified it in a way they keep their existence.</p>
<p><img alt="Ginko Dead leaves" src="https://www.otsukare.info/images/20210302-ginko.jpg"></p>
<p>A couple of weeks ago, I mentionned the steps which have been taken about <a href="https://www.otsukare.info/2021/02/15/capping-macos-user-agent">capping the User Agent String on macOS 11</a> for Web compatibility issues. Since then, Mozilla and Google organized a meeting to discuss the status and the issues related to this effort. We invited Apple but probably too late to find someone who could participate to the meeting (my bad). The <a href="https://pad.0b101010.services/capping-ua-string-2021-02-24">minutes of the meeting are publicly accessible</a>.</p>
<h2>Meeting Summary</h2>
<ul>
<li>Apple and Mozilla have both shipped already the macOS 11 UA capping</li>
<li>There is an <a href="https://groups.google.com/a/chromium.org/g/blink-dev/c/hAI4QoX6rEo/m/qQNPThr0AAAJ">intent to ship for Google</a> and Ken Russel is double checking that they can move forward with the release that would align chrome with Firefox and Safari.</li>
<li>Mozilla has not seen any obvious breakage since the change on the UA string. This is only deployed in nightly right now. <a href="http://tantek.com/">Tantek</a>: "My general philosophy is that the UA string has been abused for so long, freezing any part of it is a win."</li>
<li>Mozilla and Google agreed to find a venue for a more general public plans for UA reduction/freezing</li>
</ul>
<h2>Some additional news since the meeting</h2>
<ul>
<li>In the <a href="https://groups.google.com/a/chromium.org/g/blink-dev/c/hAI4QoX6rEo/m/qQNPThr0AAAJ">intent to ship for Google</a>, some <a href="https://groups.google.com/a/chromium.org/g/blink-dev/c/hAI4QoX6rEo/m/6ss--BikAQAJ">big queries on HTTP Archive</a> are being runned to check how wide is the issue. An interesting comment from Yoav saying that "79.4% of Unity sites out there are broken in Chrome".</li>
<li>We are very close to have a place for <strong>working with other browser vendors on UA reduction and freezing</strong>. More news soon (hopefully).</li>
</ul>
<p><a href="https://github.com/karlcow/otsukare.info/issues/4">To comment…</a></p>
<h2>Archived copy of the minutes</h2>
<p>This is to preserve a copy of the minutes in case they are being defaced or changed.</p>
<div class="highlight"><pre><span></span><code><span class="n">Capping</span><span class="w"> </span><span class="n">UA</span><span class="w"> </span><span class="k">string</span>
<span class="o">====</span>
<span class="p">(</span><span class="n">Minutes</span><span class="w"> </span><span class="n">will</span><span class="w"> </span><span class="n">be</span><span class="w"> </span><span class="n">public</span><span class="p">)</span>
<span class="nl">Present:</span><span class="w"> </span><span class="n">Mike</span><span class="w"> </span><span class="n">Taylor</span><span class="w"> </span><span class="p">(</span><span class="n">Google</span><span class="p">),</span><span class="w"> </span><span class="n">Karl</span><span class="w"> </span><span class="n">Dubost</span><span class="w"> </span><span class="p">(</span><span class="n">Mozilla</span><span class="p">),</span><span class="w"> </span><span class="n">Chris</span><span class="w"> </span><span class="n">Peterson</span><span class="w"> </span><span class="p">(</span><span class="n">Mozilla</span><span class="p">),</span><span class="w"> </span><span class="n">Aaron</span><span class="w"> </span><span class="n">Tagliaboschi</span><span class="w"> </span><span class="p">(</span><span class="n">Mozilla</span><span class="p">),</span><span class="w"> </span><span class="n">Kenneth</span><span class="w"> </span><span class="n">Russell</span><span class="w"> </span><span class="p">(</span><span class="n">Google</span><span class="p">),</span><span class="w"> </span><span class="n">Avi</span><span class="w"> </span><span class="n">Drissman</span><span class="w"> </span><span class="p">(</span><span class="n">Google</span><span class="p">),</span><span class="w"> </span><span class="n">Tantek</span><span class="w"> </span><span class="err">Ç</span><span class="n">elik</span><span class="w"> </span><span class="p">(</span><span class="n">Mozilla</span><span class="p">)</span>
<span class="p">###</span><span class="w"> </span><span class="n">Background</span>
<span class="o">*</span><span class="w"> </span><span class="n">Karl</span><span class="err">’</span><span class="n">s</span><span class="w"> </span><span class="n">summary</span><span class="o">/</span><span class="n">history</span><span class="w"> </span><span class="n">of</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">issue</span><span class="w"> </span><span class="n">so</span><span class="w"> </span><span class="n">far</span><span class="w"> </span><span class="n">on</span>
<span class="nl">https:</span><span class="c1">//www.otsukare.info/2021/02/15/capping-macos-user-agent</span>
<span class="o">*</span><span class="w"> </span><span class="n">What</span><span class="w"> </span><span class="n">Apple</span><span class="o">/</span><span class="n">Safari</span><span class="w"> </span><span class="n">currently</span><span class="w"> </span><span class="n">does</span>
<span class="n">Safari</span><span class="w"> </span><span class="n">caps</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">UA</span><span class="w"> </span><span class="k">string</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="mf">10.15.7</span><span class="p">.</span>
<span class="o">*</span><span class="w"> </span><span class="n">What</span><span class="w"> </span><span class="n">is</span><span class="w"> </span><span class="n">Mozilla</span><span class="w"> </span><span class="n">status</span><span class="w"> </span><span class="n">so</span><span class="w"> </span><span class="n">far</span>
<span class="n">Capped</span><span class="w"> </span><span class="n">UA</span><span class="err">’</span><span class="n">s</span><span class="w"> </span><span class="n">macOS</span><span class="w"> </span><span class="n">version</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="mf">10.15</span><span class="w"> </span><span class="n">in</span><span class="w"> </span><span class="n">Firefox</span><span class="w"> </span><span class="mh">87</span><span class="w"> </span><span class="k">and</span><span class="w"> </span><span class="n">soon</span><span class="w"> </span><span class="n">ESR</span><span class="w"> </span><span class="mh">78</span><span class="o">:</span><span class="w"> </span><span class="nl">https:</span><span class="c1">//bugzilla.mozilla.org/show_bug.cgi?id=1679929</span>
<span class="n">Capped</span><span class="w"> </span><span class="n">Windows</span><span class="w"> </span><span class="n">version</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="mh">10</span><span class="w"> </span><span class="p">(</span><span class="n">so</span><span class="w"> </span><span class="n">we</span><span class="w"> </span><span class="n">can</span><span class="w"> </span><span class="n">control</span><span class="w"> </span><span class="n">when</span><span class="w"> </span><span class="k">and</span><span class="w"> </span><span class="n">how</span><span class="w"> </span><span class="n">we</span><span class="w"> </span><span class="n">bump</span><span class="w"> </span><span class="n">Firefox</span><span class="p">'</span><span class="n">s</span><span class="w"> </span><span class="n">Windows</span><span class="w"> </span><span class="n">OS</span><span class="w"> </span><span class="n">version</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">Microsoft</span><span class="w"> </span><span class="n">ever</span><span class="w"> </span><span class="n">bumps</span><span class="w"> </span><span class="n">Windows</span><span class="p">'</span><span class="n">s</span><span class="w"> </span><span class="n">version</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="nl">https:</span><span class="c1">//bugzilla.mozilla.org/show_bug.cgi?id=1693295</span>
<span class="p">###</span><span class="w"> </span><span class="n">What</span><span class="w"> </span><span class="n">is</span><span class="w"> </span><span class="n">Google</span><span class="w"> </span><span class="n">status</span><span class="w"> </span><span class="n">so</span><span class="w"> </span><span class="n">far</span>
<span class="nl">Ken:</span><span class="w"> </span><span class="n">We</span><span class="w"> </span><span class="n">have</span><span class="w"> </span><span class="mh">3</span><span class="w"> </span><span class="n">LGTMs</span><span class="w"> </span><span class="n">on</span><span class="w"> </span><span class="n">blink</span><span class="o">-</span><span class="n">dev</span><span class="p">,</span><span class="w"> </span><span class="n">but</span><span class="w"> </span><span class="n">some</span><span class="w"> </span><span class="n">folks</span><span class="w"> </span><span class="n">had</span><span class="w"> </span><span class="n">concerns</span><span class="p">.</span><span class="w"> </span><span class="n">We</span><span class="w"> </span><span class="n">know</span><span class="w"> </span><span class="n">there</span><span class="p">'</span><span class="n">s</span><span class="w"> </span><span class="n">broad</span><span class="w"> </span><span class="n">breakage</span><span class="w"> </span><span class="n">because</span><span class="w"> </span><span class="n">of</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="n">issue</span><span class="p">.</span><span class="w"> </span><span class="n">It</span><span class="p">'</span><span class="n">s</span><span class="w"> </span><span class="k">not</span><span class="w"> </span><span class="n">just</span><span class="w"> </span><span class="n">Unity</span><span class="p">,</span><span class="w"> </span><span class="k">and</span><span class="w"> </span><span class="n">it</span><span class="p">'</span><span class="n">s</span><span class="w"> </span><span class="n">spread</span><span class="w"> </span><span class="n">across</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">lot</span><span class="w"> </span><span class="n">of</span><span class="w"> </span><span class="n">other</span><span class="w"> </span><span class="n">sites</span><span class="p">.</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="n">think</span><span class="w"> </span><span class="n">we</span><span class="w"> </span><span class="n">should</span><span class="w"> </span><span class="n">land</span><span class="w"> </span><span class="n">this</span><span class="p">.</span><span class="w"> </span><span class="n">Apple</span><span class="w"> </span><span class="n">has</span><span class="w"> </span><span class="n">already</span><span class="w"> </span><span class="n">made</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="n">change</span><span class="p">.</span><span class="w"> </span><span class="n">Our</span><span class="w"> </span><span class="n">CL</span><span class="w"> </span><span class="n">is</span><span class="w"> </span><span class="n">ready</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">land</span><span class="p">.</span>
<span class="nl">Avi:</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="n">have</span><span class="w"> </span><span class="n">no</span><span class="w"> </span><span class="n">specific</span><span class="w"> </span><span class="n">concerns</span><span class="p">.</span><span class="w"> </span><span class="n">It</span><span class="w"> </span><span class="n">aligns</span><span class="w"> </span><span class="n">with</span><span class="w"> </span><span class="n">our</span><span class="w"> </span><span class="n">future</span><span class="w"> </span><span class="n">goals</span><span class="p">.</span><span class="w"> </span><span class="n">It</span><span class="w"> </span><span class="n">is</span><span class="w"> </span><span class="n">unfortunate</span><span class="w"> </span><span class="n">it</span><span class="w"> </span><span class="n">brings</span><span class="w"> </span><span class="n">us</span><span class="w"> </span><span class="n">ahead</span><span class="w"> </span><span class="n">of</span><span class="w"> </span><span class="n">our</span><span class="w"> </span><span class="n">understood</span><span class="w"> </span><span class="n">schedule</span><span class="p">.</span>
<span class="nl">Mike:</span><span class="w"> </span><span class="n">Moz</span><span class="w"> </span><span class="n">is</span><span class="w"> </span><span class="n">on</span><span class="w"> </span><span class="n">board</span><span class="p">.</span><span class="w"> </span><span class="n">Google</span><span class="w"> </span><span class="n">seems</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">be</span><span class="w"> </span><span class="n">on</span><span class="w"> </span><span class="n">board</span><span class="p">.</span>
<span class="nl">Kenneth:</span><span class="w"> </span><span class="n">If</span><span class="w"> </span><span class="n">there</span><span class="w"> </span><span class="n">are</span><span class="w"> </span><span class="n">any</span><span class="w"> </span><span class="n">objections</span><span class="w"> </span><span class="n">from</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">Chromium</span><span class="w"> </span><span class="n">side</span><span class="p">,</span><span class="w"> </span><span class="n">there</span><span class="w"> </span><span class="n">has</span><span class="w"> </span><span class="n">been</span><span class="w"> </span><span class="n">plenty</span><span class="w"> </span><span class="n">of</span><span class="w"> </span><span class="kt">time</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">react</span><span class="p">.</span>
<span class="nl">Mike:</span><span class="w"> </span><span class="n">Have</span><span class="w"> </span><span class="n">there</span><span class="w"> </span><span class="n">any</span><span class="w"> </span><span class="n">breakage</span><span class="w"> </span><span class="n">reports</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">Mozilla</span><span class="w"> </span><span class="n">after</span><span class="w"> </span><span class="n">landing</span><span class="o">?</span>
<span class="nl">Karl:</span><span class="w"> </span><span class="n">Not</span><span class="w"> </span><span class="n">yet</span><span class="p">.</span><span class="w"> </span><span class="n">I</span><span class="p">'</span><span class="n">ve</span><span class="w"> </span><span class="n">seen</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">lot</span><span class="w"> </span><span class="n">of</span><span class="w"> </span><span class="n">reports</span><span class="w"> </span><span class="n">related</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">Cloudinary</span><span class="p">,</span><span class="w"> </span><span class="n">etc</span><span class="p">,</span><span class="w"> </span><span class="n">which</span><span class="w"> </span><span class="n">are</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">larger</span><span class="w"> </span><span class="n">concern</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">Apple</span><span class="p">.</span><span class="w"> </span><span class="n">For</span><span class="w"> </span><span class="n">Firefox</span><span class="p">,</span><span class="w"> </span><span class="n">there</span><span class="w"> </span><span class="n">was</span><span class="w"> </span><span class="n">no</span><span class="w"> </span><span class="n">breakage</span><span class="w"> </span><span class="n">with</span><span class="w"> </span><span class="n">regards</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">thing</span><span class="w"> </span><span class="n">that</span><span class="w"> </span><span class="n">was</span><span class="w"> </span><span class="n">released</span><span class="w"> </span><span class="n">last</span><span class="w"> </span><span class="n">week</span><span class="p">.</span><span class="w"> </span><span class="n">It</span><span class="p">'</span><span class="n">s</span><span class="w"> </span><span class="k">not</span><span class="w"> </span><span class="n">yet</span><span class="w"> </span><span class="n">in</span><span class="w"> </span><span class="k">release</span><span class="p">.</span><span class="w"> </span><span class="n">There</span><span class="p">'</span><span class="n">s</span><span class="w"> </span><span class="n">still</span><span class="w"> </span><span class="n">plenty</span><span class="w"> </span><span class="n">of</span><span class="w"> </span><span class="kt">time</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">back</span><span class="w"> </span><span class="n">it</span><span class="w"> </span><span class="n">out</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">needed</span><span class="p">.</span>
<span class="nl">Chris:</span><span class="w"> </span><span class="n">Was</span><span class="w"> </span><span class="n">there</span><span class="w"> </span><span class="n">an</span><span class="w"> </span><span class="n">issue</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">Duo</span><span class="w"> </span><span class="n">Mobile</span><span class="o">?</span>
<span class="nl">Karl:</span><span class="w"> </span><span class="n">We</span><span class="w"> </span><span class="n">didn</span><span class="p">'</span><span class="n">t</span><span class="w"> </span><span class="n">have</span><span class="w"> </span><span class="n">any</span><span class="w"> </span><span class="n">reports</span><span class="w"> </span><span class="n">like</span><span class="w"> </span><span class="n">this</span><span class="p">.</span><span class="w"> </span><span class="n">But</span><span class="w"> </span><span class="n">we</span><span class="w"> </span><span class="n">saw</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">mention</span><span class="w"> </span><span class="n">online</span><span class="p">...</span><span class="w"> </span><span class="n">from</span><span class="w"> </span><span class="n">what</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="n">understood</span><span class="p">.</span><span class="w"> </span><span class="n">Apple</span><span class="w"> </span><span class="n">had</span><span class="w"> </span><span class="n">modified</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">UA</span><span class="w"> </span><span class="k">string</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">be</span><span class="w"> </span><span class="mf">10.15</span><span class="p">.</span><span class="w"> </span><span class="n">Then</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">OS</span><span class="w"> </span><span class="n">evolved</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="mf">10.16</span><span class="p">.</span><span class="w"> </span><span class="n">Duo</span><span class="w"> </span><span class="n">had</span><span class="w"> </span><span class="n">an</span><span class="w"> </span><span class="n">issue</span><span class="w"> </span><span class="n">with</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">disparity</span><span class="w"> </span><span class="n">between</span><span class="w"> </span><span class="mf">10.15.7</span><span class="w"> </span><span class="n">in</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">OS</span><span class="w"> </span><span class="k">and</span><span class="w"> </span><span class="mf">10.15.6</span><span class="w"> </span><span class="n">in</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">browser</span><span class="p">.</span><span class="w"> </span><span class="n">Since</span><span class="w"> </span><span class="n">then</span><span class="p">,</span><span class="w"> </span><span class="n">they</span><span class="w"> </span><span class="n">modifed</span><span class="w"> </span><span class="k">and</span><span class="w"> </span><span class="n">there</span><span class="p">'</span><span class="n">s</span><span class="w"> </span><span class="n">no</span><span class="w"> </span><span class="n">other</span><span class="w"> </span><span class="n">issue</span><span class="p">.</span>
<span class="nl">Karl:</span><span class="w"> </span><span class="n">On</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">Firefox</span><span class="w"> </span><span class="n">side</span><span class="p">,</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">we</span><span class="w"> </span><span class="n">have</span><span class="w"> </span><span class="n">breakage</span><span class="p">,</span><span class="w"> </span><span class="n">we</span><span class="w"> </span><span class="n">still</span><span class="w"> </span><span class="n">have</span><span class="w"> </span><span class="n">possibility</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="k">do</span><span class="w"> </span><span class="n">site</span><span class="o">-</span><span class="n">specific</span><span class="w"> </span><span class="n">UA</span><span class="w"> </span><span class="n">interventions</span><span class="p">.</span>
<span class="nl">Ken:</span><span class="w"> </span><span class="n">did</span><span class="w"> </span><span class="n">you</span><span class="w"> </span><span class="p">(</span><span class="n">tantek</span><span class="p">)</span><span class="w"> </span><span class="n">have</span><span class="w"> </span><span class="n">concerns</span><span class="w"> </span><span class="n">about</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="n">change</span><span class="o">?</span><span class="w"> </span><span class="n">The</span><span class="w"> </span><span class="n">review</span><span class="w"> </span><span class="n">sat</span><span class="w"> </span><span class="n">there</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="k">while</span><span class="p">.</span>
<span class="nl">Tantek:</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="n">didn</span><span class="p">'</span><span class="n">t</span><span class="w"> </span><span class="n">have</span><span class="w"> </span><span class="n">any</span><span class="w"> </span><span class="n">problems</span><span class="w"> </span><span class="n">with</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">freezing</span><span class="w"> </span><span class="n">MacOS</span><span class="w"> </span><span class="n">version</span><span class="w"> </span><span class="n">per</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">comments</span><span class="w"> </span><span class="n">in</span><span class="w"> </span><span class="n">our</span><span class="w"> </span><span class="n">bugzilla</span><span class="w"> </span><span class="n">on</span><span class="w"> </span><span class="n">that</span><span class="p">.</span><span class="w"> </span><span class="n">My</span><span class="w"> </span><span class="n">general</span><span class="w"> </span><span class="n">philosophy</span><span class="w"> </span><span class="n">is</span><span class="w"> </span><span class="n">that</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">UA</span><span class="w"> </span><span class="k">string</span><span class="w"> </span><span class="n">has</span><span class="w"> </span><span class="n">been</span><span class="w"> </span><span class="n">abused</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">so</span><span class="w"> </span><span class="n">long</span><span class="p">,</span><span class="w"> </span><span class="n">freezing</span><span class="w"> </span><span class="n">any</span><span class="w"> </span><span class="n">part</span><span class="w"> </span><span class="n">of</span><span class="w"> </span><span class="n">it</span><span class="w"> </span><span class="n">is</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">win</span><span class="p">.</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="n">don</span><span class="p">'</span><span class="n">t</span><span class="w"> </span><span class="n">even</span><span class="w"> </span><span class="n">think</span><span class="w"> </span><span class="n">we</span><span class="w"> </span><span class="n">need</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="mh">1</span><span class="o">:</span><span class="mh">1</span><span class="w"> </span><span class="n">replacement</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">everything</span><span class="w"> </span><span class="n">that</span><span class="p">'</span><span class="n">s</span><span class="w"> </span><span class="n">in</span><span class="w"> </span><span class="n">there</span><span class="w"> </span><span class="n">today</span><span class="p">.</span>
<span class="nl">Chris:</span><span class="w"> </span><span class="n">The</span><span class="w"> </span><span class="n">long</span><span class="w"> </span><span class="n">review</span><span class="w"> </span><span class="kt">time</span><span class="w"> </span><span class="n">was</span><span class="w"> </span><span class="n">unrelated</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">reservations</span><span class="p">,</span><span class="w"> </span><span class="n">we</span><span class="w"> </span><span class="n">were</span><span class="w"> </span><span class="n">sorting</span><span class="w"> </span><span class="n">out</span><span class="w"> </span><span class="n">ownership</span><span class="w"> </span><span class="n">of</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="k">module</span><span class="p">.</span>
<span class="p">###</span><span class="w"> </span><span class="n">macOS</span><span class="w"> </span><span class="mf">11.0</span><span class="w"> </span><span class="n">compat</span><span class="w"> </span><span class="nl">issues:</span>
<span class="n">Unity</span><span class="err">’</span><span class="n">s</span><span class="w"> </span><span class="n">UA</span><span class="w"> </span><span class="n">parsing</span><span class="w"> </span><span class="n">issue</span>
<span class="n">Cloudinary</span><span class="err">’</span><span class="n">s</span><span class="w"> </span><span class="n">Safari</span><span class="w"> </span><span class="n">WebP</span><span class="w"> </span><span class="n">issue</span>
<span class="n">Firefox</span><span class="w"> </span><span class="k">and</span><span class="w"> </span><span class="n">Chrome</span><span class="w"> </span><span class="n">send</span><span class="w"> </span><span class="err">“</span><span class="nl">Accept:</span><span class="w"> </span><span class="n">image</span><span class="o">/</span><span class="n">webp</span><span class="err">”</span><span class="w"> </span><span class="n">header</span><span class="p">.</span>
<span class="p">###</span><span class="w"> </span><span class="n">Recurring</span><span class="w"> </span><span class="n">sync</span><span class="w"> </span><span class="n">on</span><span class="w"> </span><span class="n">UA</span><span class="w"> </span><span class="n">Reduction</span><span class="w"> </span><span class="n">efforts</span>
<span class="n">Which</span><span class="w"> </span><span class="n">public</span><span class="w"> </span><span class="n">arena</span><span class="w"> </span><span class="n">should</span><span class="w"> </span><span class="n">we</span><span class="w"> </span><span class="n">have</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="n">discussion</span><span class="o">?</span>
<span class="nl">Mike:</span><span class="w"> </span><span class="n">we</span><span class="w"> </span><span class="k">do</span><span class="w"> </span><span class="n">have</span><span class="w"> </span><span class="n">public</span><span class="w"> </span><span class="n">plans</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">UA</span><span class="w"> </span><span class="n">reduction</span><span class="o">/</span><span class="n">freezing</span><span class="p">.</span><span class="w"> </span><span class="n">These</span><span class="w"> </span><span class="n">might</span><span class="w"> </span><span class="n">evolve</span><span class="p">.</span><span class="w"> </span><span class="n">It</span><span class="w"> </span><span class="n">would</span><span class="w"> </span><span class="n">be</span><span class="w"> </span><span class="n">cool</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">be</span><span class="w"> </span><span class="n">able</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">meet</span><span class="w"> </span><span class="n">in</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">future</span><span class="w"> </span><span class="n">with</span><span class="w"> </span><span class="n">other</span><span class="w"> </span><span class="n">vendors</span><span class="w"> </span><span class="k">and</span><span class="w"> </span><span class="n">discuss</span><span class="w"> </span><span class="n">about</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">options</span><span class="p">.</span>
<span class="n">Chris</span><span class="w"> </span><span class="o">&</span><span class="w"> </span><span class="nl">Karl:</span><span class="w"> </span><span class="n">Usual</span><span class="w"> </span><span class="n">standards</span><span class="w"> </span><span class="n">forums</span><span class="w"> </span><span class="n">would</span><span class="w"> </span><span class="n">be</span><span class="w"> </span><span class="n">good</span><span class="p">.</span><span class="w"> </span><span class="n">People</span><span class="w"> </span><span class="n">have</span><span class="w"> </span><span class="n">opinions</span><span class="w"> </span><span class="n">on</span><span class="w"> </span><span class="n">venues</span><span class="p">.</span>
</code></pre></div>
<p>Otsukare!</p>The Benefits Of Code Review For The Reviewer2021-02-24T15:55:00+09:002021-02-24T20:27:00+09:00Karl Dubosttag:www.otsukare.info,2021-02-24:/2021/02/24/code-review-benefits<p>Code Review is an essential part of the process of publishing code. We often talk about the benefits of code review for projects and for people writing the code. I want to talk about the benefits for the person actually reviewing the code.</p><p>Code Review is an essential part of the process of publishing code. We often talk about the benefits of code review for projects and for people writing the code. I want to talk about the benefits for the person actually reviewing the code.</p>
<p><img alt="Path in a bamboo garden" src="https://www.otsukare.info/images/20210224-bambous.jpg"></p>
<h1>Understanding The Project</h1>
<p>When doing code review, we don't necessarily have a good understanding of the project, or at least the same level of understanding than the person who has written the code.</p>
<p>Reviewing is a good way to piece together all the parts that makes this project work.</p>
<h1>Learning How To Better Code</h1>
<p>A lot of the reviews I have been have involved with taught me on how to become a better developer. Nobody has full knowledge of a language, an algorithm construct, a data structure. When reviewing we learn as much as we help. For things, which seem unclear, we dive into the documentation to better understand the intent. We can put into competition the existing knowledge with the one brought by the developer.</p>
<p>We might bring a new solution to the table that we didn't know existed. A review is not only discovering errors or weaknesses of a code, it's how to improve the code by exchanging ideas with the developer.</p>
<h1>Instant Gratification</h1>
<p>There is a feel good opportunity when doing good code reviews. Specifically, when the review helped to improve both the code and the developer. Nothing better than the last comment of a developer being happy of having the code merged and the feeling of improving skills.</p>
<p><a href="https://github.com/karlcow/otsukare.info/issues/3">To comment…</a></p>
<p>Otsukare!</p>Capping macOS User Agent String on macOS 112021-02-15T12:00:00+09:002021-03-02T11:27:00+09:00Karl Dubosttag:www.otsukare.info,2021-02-15:/2021/02/15/capping-macos-user-agent<p>MacOS 11 and a story of breakage.</p><p class="note">Update on 2021-03-02: <a href="/2021/03/02/capping-user-agent-string">Capping User Agent String - followup meeting</a></p>
<p>This is to keep track and document the sequence of events related to macOS 11 and another cascade of breakages related to the change of user agent strings. <strong>There is no good solution</strong>. One more time it shows how sniffing User Agent strings are both dangerous (future fail) and source of issues.</p>
<p>Brace for impact!</p>
<p><img alt="Lion foot statue" src="https://www.otsukare.info/images/20210215-foot.jpg"></p>
<h2>Capping macOS 11 version in User Agent History</h2>
<ul>
<li>
<p><strong>2020-06-25</strong> OPENED <strong>WebKit</strong> <a href="https://bugs.webkit.org/show_bug.cgi?id=213622">213622 - Safari 14 - User Agent string shows incorrect OS version</a></p>
<p>A reporter claims it breaks many websites but without giving details about which websites. There's a mention about VP9</p>
<blockquote>
<p>browser supports vp9</p>
</blockquote>
<p>I left a <a href="https://bugs.webkit.org/show_bug.cgi?id=213622#c7">comment</a> there to get more details.</p>
</li>
<li>
<p><strong>2020-09-15</strong> OPENED <strong>WebKit</strong> <a href="https://bugs.webkit.org/show_bug.cgi?id=216593">216593 - [macOS] Limit reported macOS release to 10.15 series</a>.</p>
<div class="highlight"><pre><span></span><code><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">osVersion</span><span class="p">.</span><span class="n">startsWith</span><span class="p">(</span><span class="s">"10"</span><span class="p">))</span>
<span class="w"> </span><span class="n">osVersion</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">"10_15_6"</span><span class="n">_s</span><span class="p">;</span>
</code></pre></div>
<p>With <a href="https://bugs.webkit.org/show_bug.cgi?id=216593#c5">some comments</a> in the review:</p>
<blockquote>
<p>preserve original OS version on older macOS at Charles's request</p>
</blockquote>
<p>I suspect this is the <a href="https://www.charlesproxy.com/">Charles</a>, the proxy app.</p>
<p>2020-09-16 FIXED</p>
</li>
<li>
<p><strong>2020-10-05</strong> OPENED <strong>WebKit</strong> <a href="https://bugs.webkit.org/show_bug.cgi?id=217364">217364 - [macOS] Bump reported current shipping release UA to 10_15_7</a></p>
<blockquote>
<p>On macOS Catalina 10.15.7, Safari reports platform user agent with OS version 10_15_7. On macOS Big Sur 11.0, Safari reports platform user agent with OS version 10_15_6. It's a bit odd to have Big Sur report an older OS version than Catalina. Bump the reported current shipping release UA from 10_15_6 to 10_15_7.</p>
</blockquote>
<p>The issue here is that macOS 11 (Big Sur) reports an older version number than macOS 10.15 (Catalina), because the <a href="https://bugs.webkit.org/show_bug.cgi?id=216593">previous bug</a> harcoded the string number.</p>
<div class="highlight"><pre><span></span><code><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">osVersion</span><span class="p">.</span><span class="n">startsWith</span><span class="p">(</span><span class="s">"10"</span><span class="p">))</span>
<span class="w"> </span><span class="n">osVersion</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">"10_15_7"</span><span class="n">_s</span><span class="p">;</span>
</code></pre></div>
<p>This is still harcoded because in <a href="https://bugs.webkit.org/show_bug.cgi?id=217364#c4">this comment</a>:</p>
<blockquote>
<p>Catalina quality updates are done, so 10.15.7 is the last patch version. Security SUs from this point on won’t increment the patch version, and does not affect the user agent.</p>
</blockquote>
<p>2020-10-06 FIXED</p>
</li>
<li>
<p><strong>2020-10-11</strong> <strong>Unity</strong> <a href="https://issuetracker.unity3d.com/issues/unity-webgl-builds-do-not-run-on-macos-big-sur">[WebGL][macOS] Builds do not run when using Big Sur</a></p>
<p><code>UnityLoader.js</code> is the culprit.</p>
<p>They fixed it on January 2021(?). But there are a lot of legacy codes running out there which could not be updated.</p>
<p>Irony, there’s no easy way to detect the unity library to create a site intervention that would apply to all games with the issue. Capping the UA string will fix that.</p>
</li>
<li>
<p><strong>2020-11-30</strong> OPENED <strong>Webkit</strong> <a href="https://bugs.webkit.org/show_bug.cgi?id=219346">219346 - User-agent on macOS 11.0.1 reports as 10_15_6 which is older than latest Catalina release</a>.</p>
<p>It was closed as a duplicate of <a href="https://bugs.webkit.org/show_bug.cgi?id=217364">217364</a>, but there's an interesting description:</p>
<blockquote>
<p>Regression from 216593. That rev hard codes the User-Agent header to report MacOS X 10_15_6 on macOS 11.0+ which <strong>breaks Duo Security UA sniffing OS version check</strong>. Duo security check fails because latest version of macOS Catalina is 10.15.7 but 10.15.6 is being reported.</p>
</blockquote>
</li>
<li>
<p><strong>2020-11-30</strong> OPENED <strong>Gecko</strong> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1679929">1679929 - Cap the User-Agent string's reported macOS version at 10.15</a></p>
<p>There is a patch for Gecko to cap the user agent string the same way that Apple does for Safari. This will solve the issue with Unity Games which have been unable to adjust the code source to the new version of Unity.</p>
<div class="highlight"><pre><span></span><code><span class="c1">// Cap the reported macOS version at 10.15 (like Safari) to avoid breaking</span>
<span class="c1">// sites that assume the UA's macOS version always begins with "10.".</span>
<span class="kt">int</span><span class="w"> </span><span class="n">uaVersion</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">majorVersion</span><span class="w"> </span><span class="o">>=</span><span class="w"> </span><span class="mi">11</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">minorVersion</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mi">15</span><span class="p">)</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="mi">15</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">minorVersion</span><span class="p">;</span>
<span class="c1">// Always return an "Intel" UA string, even on ARM64 macOS like Safari does.</span>
<span class="n">mOscpu</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">nsPrintfCString</span><span class="p">(</span><span class="s">"Intel Mac OS X 10.%d"</span><span class="p">,</span><span class="w"> </span><span class="n">uaVersion</span><span class="p">);</span>
</code></pre></div>
<p>It should land very soon, this week (week 8, February 2021), on Firefox Nightly 87. We can then monitor if anything is breaking with this change.</p>
</li>
<li>
<p><strong>2020-12-04</strong> OPENED <strong>Gecko</strong> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1680516">1680516 - [Apple Chip - ARM64 M1] Game is not loaded on Gamearter.com</a></p>
<p>Older versions of Unity JS used to run games are broken when the macOS version is <code>10_11_0</code> in the user agent string of the browser.</p>
<p>The Mozilla webcompat team proposed to fix this with a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1682238">Site Intervention for gamearter specifically</a>. This doesn't solve the other games breaking.</p>
</li>
<li>
<p><strong>2020-12-14</strong> OPENED <strong>Gecko</strong> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1682238">1682238 - Override navigator.userAgent for gamearter.com on macOS 11.0</a></p>
<p>A quick way to fix the issue on Firefox for gamearter was to release a site intervention by the <a href="https://wiki.mozilla.org/Compatibility/">Mozilla webcompat team</a></p>
<div class="highlight"><pre><span></span><code><span class="s2">"use strict"</span><span class="p">;</span>
<span class="cm">/*</span>
<span class="cm">* Bug 1682238 - Override navigator.userAgent for gamearter.com on macOS 11.0</span>
<span class="cm">* Bug 1680516 - Game is not loaded on gamearter.com</span>
<span class="cm">*</span>
<span class="cm">* Unity < 2021.1.0a2 is unable to correctly parse User Agents with</span>
<span class="cm">* "Mac OS X 11.0" in them, so let's override to "Mac OS X 10.16" instead</span>
<span class="cm">* for now.</span>
<span class="cm">*/</span>
<span class="cm">/* globals exportFunction */</span>
<span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">navigator</span><span class="p">.</span><span class="nx">userAgent</span><span class="p">.</span><span class="nx">includes</span><span class="p">(</span><span class="s2">"Mac OS X 11."</span><span class="p">))</span><span class="w"> </span><span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">info</span><span class="p">(</span>
<span class="w"> </span><span class="s2">"The user agent has been overridden for compatibility reasons. See https://bugzilla.mozilla.org/show_bug.cgi?id=1680516 for details."</span>
<span class="p">);</span>
<span class="kd">let</span><span class="w"> </span><span class="nx">originalUA</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">navigator</span><span class="p">.</span><span class="nx">userAgent</span><span class="p">;</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">defineProperty</span><span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">navigator</span><span class="p">.</span><span class="nx">wrappedJSObject</span><span class="p">,</span><span class="w"> </span><span class="s2">"userAgent"</span><span class="p">,</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">get</span><span class="o">:</span><span class="w"> </span><span class="nx">exportFunction</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">originalUA</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/Mac OS X 11\.(\d)+;/</span><span class="p">,</span><span class="w"> </span><span class="s2">"Mac OS X 10.16;"</span><span class="p">);</span>
<span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="nb">window</span><span class="p">),</span>
<span class="w"> </span><span class="nx">set</span><span class="o">:</span><span class="w"> </span><span class="nx">exportFunction</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span><span class="w"> </span><span class="p">{},</span><span class="w"> </span><span class="nb">window</span><span class="p">),</span>
<span class="p">});</span>
<span class="p">}</span>
</code></pre></div>
</li>
<li>
<p><strong>2020-12-16</strong> OPENED <strong>WebKit</strong> <a href="https://bugs.webkit.org/show_bug.cgi?id=219977">219977 - WebP loading error in Safari on iOS 14.3</a></p>
<p>In <a href="https://bugs.webkit.org/show_bug.cgi?id=219977#c6">this comment</a>, <a href="https://cloudinary.com/">Cloudinary</a> explains they try to avoid the issue with the system bug with UA detection.</p>
<blockquote>
<p>Cloudinary is attempting to work around this issue by turning off WebP support to affected clients.</p>
<p>If this is indeed about the underlying OS frameworks, rather than the browser version, as far as we can tell it appeared sometime after MacOS 11.0.1 and before or in 11.1.0. All we have been able to narrow down on the iOS side is ≥14.0.</p>
<p>If you have additional guidance on which versions of the OSes are affected, so that we can prevent Safari users from receiving broken images, it would be much appreciated!</p>
</blockquote>
<p><a href="https://ericportis.com/about/">Eric Portis</a> (Cloudinary) created some tests:
* <a href="https://ericportis.com/etc/broken-webps/">WebPs that break in iOS ≥ 14.3 & MacOS ≥ 11.1 </a>
* <a href="https://ericportis.com/etc/tiny-webps/">Tiny WebP</a></p>
<p>The issue seems to <a href="https://community.cloudflare.com/t/fully-transparent-png-file-that-was-converted-webp-format-desnt-work-on-safari-14-0-2/231297/8">affect CloudFlare</a></p>
</li>
<li>
<p><strong>2021-01-05</strong> OPENED <strong>WebKit</strong> <a href="https://bugs.webkit.org/show_bug.cgi?id=220330">WebP failures [ Big Sur ] fast/images/webp-as-image.html is failing</a></p>
</li>
<li>
<p><strong>2021-01-29</strong> OPENED <strong>Blink</strong> <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=1171998">1171998 - Nearly all Unity WebGL games fail to run in Chrome on macOS 11 because of userAgent</a></p>
</li>
<li>
<p><strong>2021-02-06</strong> OPENED <strong>Blink</strong> <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=1175225">1175225 - Cap the reported macOS version in the user-agent string at 10_15_7</a></p>
<blockquote>
<p>Colleagues at Mozilla, on the Firefox team, and Apple, on the Safari team, report that there are a long tail of websites broken from reporting the current macOS Big Sur version, e.g. 11_0_0, in the user agent string:</p>
<p>Mac OS X 11_0_0</p>
<p>and for this reason, as well as slightly improving user privacy, have decided to cap the reported OS version in the user agent string at 10.15.7:</p>
<p>Mac OS X 10_15_7</p>
</blockquote>
</li>
<li>
<p><strong>2021-02-09</strong> <strong>Blink</strong> <a href="https://groups.google.com/a/chromium.org/g/blink-dev/c/hAI4QoX6rEo/m/qQNPThr0AAAJ">Intent to Ship: User Agent string: cap macOS version number to 10_15_7</a></p>
<p><a href="https://github.com/kenrussell">Ken Russell</a> sends an intent to cap macOS in the Chrome (blink) user agent string to 10_15_7 to follow on the steps of Apple and Mozilla. In the intent to ship, there is a discussion on solving the issue with Client Hints. <code>Sec-CH-UA-Platform-Version</code> would be a possibility, <strong>but</strong> <a href="https://wicg.github.io/ua-client-hints/">Client Hints</a> is not yet deployed across browsers and there is not yet a full consensus about it. This is a specification pushed by Google and partially implemented by Google on Chrome.</p>
<ul>
<li>Mozilla - <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=935216">935216 - Implement Client-Hints HTTP header</a></li>
<li>Apple. I didn't find any Client-Hints bug for WebKit, except this partial proposal to <a href="https://bugs.webkit.org/show_bug.cgi?id=145380">implement images DPR through Client-Hints</a>. I'm not sure what is the status for Apple.</li>
</ul>
<p><a href="https://twitter.com/myakura">Masataka Yakura</a> shared with me (Thanks!) two threads on the Webkit-dev mailing-list. One from <a href="https://lists.webkit.org/pipermail/webkit-dev/2020-May/thread.html#31195">May 2020</a> and another one from <a href="https://lists.webkit.org/pipermail/webkit-dev/2020-November/thread.html#31571">November 2020</a>.</p>
<p>In May, <a href="https://lists.webkit.org/pipermail/webkit-dev/2020-May/031198.html">Maciej said</a>:</p>
<blockquote>
<p>I think there’s a number of things in the spec that should be cleaned up before an implementation ships enabled by default, specifically around interop, privacy, and protection against UA lockouts. I know there are PRs in flight for some of these issues. I think it would be good to get more of the open issues to resolution before actually shipping this.</p>
</blockquote>
<p>And in November, <a href="https://lists.webkit.org/pipermail/webkit-dev/2020-November/031571.html">Maciej</a> did another round of spec review with <a href="https://github.com/WICG/ua-client-hints/issues/151">one decisive issue</a>.</p>
<p>Note that Google has released, <strong>last year</strong>, on January 14, 2020 an <a href="https://groups.google.com/a/chromium.org/g/blink-dev/c/A4wxFpvqUfA/m/g7iccl9ICgAJ">Intent to Ship: Client Hints infrastructure and UA Client Hints</a> and this was <a href="https://chromium-review.googlesource.com/c/chromium/src/+/2525742"><strong>enabled a couple of days ago</strong></a> on February 11, 2021.</p>
</li>
</ul>
<p>And I'm pretty sure the story is not over. There will be probably more breakages and more unknown bugs.</p>
<p>Otsukare!</p>Browser Wish List - Bookmark This Selection2021-02-12T10:34:00+09:002021-02-23T12:10:00+09:00Karl Dubosttag:www.otsukare.info,2021-02-12:/2021/02/12/bookmarks-selection<p>I often want to bookmark a part of a text more than a page.</p><p>Some of us are <a href="https://www.nytimes.com/2016/03/06/arts/music/bob-dylans-secret-archive.html">keeping notes</a> of bread and crumbs fallen everywhere. A dead leaf, a piece of string, a forgotten note washed away on a beach, and things read in a book. We collect memories and inspiration.</p>
<p>All browsers have a feature called "Bookmark This Page". It is essentially the same poor badly manageable tool on every browsers. If you do not want to rely on a third party service, or an addon, what the browser has to offer is not very satisfying.</p>
<p><strong>Firefox</strong> gives a possibility to change the name, to choose where to put it and to add tags at the moment we save it.</p>
<p><img alt="Firefox Menu for bookmarking a page" src="https://www.otsukare.info/images/20210212-bookmark-page-firefox.jpg"></p>
<p><strong>Edge</strong> follows the same conventions without the tagging.</p>
<p><img alt="Edge Menu for bookmarking a page" src="https://www.otsukare.info/images/20210212-bookmark-page-edge.jpg"></p>
<p><strong>Safari</strong> offers something slightly more evolved with a Description field.</p>
<p><img alt="Safari Menu for bookmarking a page" src="https://www.otsukare.info/images/20210212-bookmark-page-safari.jpg"></p>
<p>but <strong>none of them is satisfying</strong> for the Web drifters, the poets collecting memories, the archivists and the explorers. And it's unfortunate because it looks like such a low hanging fruit. It ties very much in my previous post about <a href="https://www.otsukare.info/2020/07/07/browser-tabs-time-machine">Browser Time Machine</a>.</p>
<h2>Bookmark This Selection</h2>
<p>What I would like from the bookmark feature in the browser is the ability to not only bookmark the full page but <strong>be able to select a piece of the page that is reflected in the bookmark</strong>, be through the normal menu as we have seen above or through the contextual menu of the browser.</p>
<p><img alt="Firefox Contextual menu after selecting a text" src="https://www.otsukare.info/images/20210212-bookmark.jpg"></p>
<p>Then once the bookmarks are collected I can do full text searches on all the collected texts.</p>
<p>And yes, some add-ons exist, but I just wish the feature was native to the browser. And I do not want to rely on a third party service. My quotes are mine only and should not necessary be shared with a server on someone's else machine.</p>
<p><a href="https://getmemex.com/">Memex</a> which has very interesting features, but it is someone else service.
<a href="https://getpocket.com/en/pocket-and-firefox">Pocket</a> (even if it belongs to Mozilla) is not answering my needs. I need to open an account, and it is someone's else server.</p>
<p><a href="https://github.com/karlcow/otsukare.info/issues/2">To comment</a></p>
<p>Otsukare!</p>Whiteboard Reactionaries2021-02-11T20:50:00+09:002021-02-11T21:21:00+09:00Karl Dubosttag:www.otsukare.info,2021-02-11:/2021/02/11/whiteboard-reactionaries<p>When serious topics need to be addressed seriously.</p><p>The eminent <a href="https://miketaylr.com/posts/">Mike Taylor</a> has dubbed us with <a href="https://twitter.com/miketaylr/status/1359608630979485700">one</a> of his knightly tweets. Something something about</p>
<blockquote>
<p>new interview question: on a whiteboard, re-implement the following in React (using the marker color of your choice)</p>
</blockquote>
<p><a href="https://www.brucelawson.co.uk/">Sir Bruce Lawson OM (Oh My…)</a>, a never ending disco knight, has <a href="https://www.brucelawson.co.uk/2021/get-that-dream-tech-gig-by-solving-mike-taylrs-silicon-valley-whiteboard-interview-question/">commented about Mike's tweet</a>, pointing out that:</p>
<blockquote>
<p>the real test is your choice of marker colour. So, how would you go about making the right choice? Obviously, that depends where you’re interviewing.</p>
</blockquote>
<p>I simply and firmly disagree and throw my gauntlet at Bruce's face. Choose your weapons, time and witnesses.</p>
<p>The important part of this tweet is how Mike Taylor points out how the Sillycon Valley industry is a just a pack of die-hard stick-in-the-mud reactionaries who have promoted the whiteboard to the pinnacle of one's dull abilities to regurgitate the most devitalizing Kardashianesque answers to stackoverflow problems. Young programmers! Rise! In front of the whiteboard, just walk out. Refuse the tiranny of the past, the chalk of ignorance.</p>
<p>Where are the humans, the progress? Where are the shores of the oceans, the Célestin Freinet, Maria Montessori and A. S. Neill, the lychens, the moss and the humus, the sap of imagination, the liberty of our creativity.</p>
<p>Otsukare!</p>