Twitter is using PWA shortcuts
I accidentally discovered that Twitter has implemented PWA shortcuts, a feature that allows websites and web apps to provide users with quick access to common actions. This is a great step towards bridging the gap between web and native applications, allowing websites to provide a more app-like experience. Read More
I lead the Chrome Developer Relations team at Google.
We want people to have the best experience possible on the web without having to install a native app or produce content in a walled garden.
Our team tries to make it easier for developers to build on the web by supporting every Chrome release, creating great content to support developers on web.dev, contributing to MDN, helping to improve browser compatibility, and some of the best developer tools like Lighthouse, Workbox, Squoosh to name just a few.
I love to learn about what you are building, and how I can help with Chrome or Web development in general, so if you want to chat with me directly, please feel free to book a consultation.
I'm trialing a newsletter, you can subscribe below (thank you!)
View Source for Safari on iOS with Shortcuts
I created a shortcut for iOS that lets you view the source code of web pages in Safari and Chrome. It's a workaround for the lack of a built-in view-source feature on these mobile browsers. The shortcut shares the URL to a third-party website I built which then displays the source code. Because it uses a third-party site, it won't reflect the current state of the page if you are logged in or have specific cookies set. Hopefully, Safari and Chrome will eventually bring back a native view-source option. Read More
Quick Console bookmarklet for Desktop and Mobile
This blog post introduces a simple bookmarklet that provides quick access to a webpage's JavaScript console logs, warnings, and errors directly on desktop and mobile devices. It eliminates the need for connecting to Chrome DevTools, especially useful for quick debugging on mobile. The bookmarklet creates a small, expandable element at the bottom of the page that displays console outputs and keeps a running tally. It intercepts calls to console.log, console.warn, and console.error, displaying the messages in the created element while preserving their appearance in actual DevTools. While not a full DevTools replacement, it's a handy tool for quick insights and debugging on the go. Read More
Use Bookmarklets on Chrome on Android
For years, I thought bookmarklets weren't supported on Chrome for Android. Turns out, they are! You just need to access your bookmarks through the address bar, not the Bookmarks menu. This method retains the page context, allowing your bookmarklets to execute JavaScript properly. This opens up new possibilities for customizing web pages on Android. Read More
Quick Picture in Picture Bookmarklet
I created a simple bookmarklet for quickly enabling Picture-in-Picture mode for videos, even on sites that disable it. Drag the "Quick PIP" bookmarklet link to your bookmarks bar. When clicked, it activates PIP for the first actively playing video on the page or in any same-origin iframe. The bookmarklet's code is concise and avoids polluting the global scope. It efficiently finds the first playing video and requests Picture-in-Picture mode. Read More
Getting a list of Blink Components
This post provides a quick way to retrieve and filter the list of Blink components from a JSON file hosted by Chromium. The provided JavaScript snippets demonstrate how to fetch and process the component list, filtering for entries that begin with "Bli". The next step is figuring out how to programmatically get a list of OWNERS. Read More
River Dee in Llangollen before and after heavy rain
I love driving through North Wales, especially Llangollen, a town nestled by the River Dee. In summer, the river's flow is gentle enough to paddle in (with caution!). But after a recent heavy rain (post-Storm Dennis), the river transformed! The power and height of the water were incredible, almost reaching the footpath wall. Check out Llangollen - it's worth a visit, rain or shine! Read More
Scroll to text bookmarklet
Just saw that Scroll To Text Fragment is launching in Chrome 81! This feature lets you link to specific text within a page, which is awesome. I created a bookmarklet that grabs your selected text and generates a link using the new :~:text=
fragment identifier. Drag the "Find in page" link to your bookmarks bar to try it out. The bookmarklet currently selects whole words, but I'm planning on adding some logic to handle partial word selections better. You can also easily modify the bookmarklet to copy the generated link to the clipboard instead of opening a new window.
Read More
What do you want from a Web Browser Developer Relations team?
Celebrating my 10th anniversary at Google working on Chrome and leading a Developer Relations team. As we plan for the next few years, I'm reflecting on how we can improve Developer Satisfaction. Inspired by recent feedback on Apple's developer relations, I'm curious to hear your thoughts on what a web browser developer relations team should prioritize. What can we do more of? Less of? How can we best support you and your team? Share your opinions, especially broad strategic ideas. Read More
Thinking about Developer Satisfaction and Web Developers
This post discusses the importance of developer satisfaction, particularly for web developers, and how the MDN Web Developer Needs Assessment has influenced Chrome's web platform priorities for 2020. My hypothesis is that improving the web platform will lead to increased developer satisfaction, more content creation, and happier end-users. Based on the MDN survey data, key areas for improvement include browser compatibility, testing, documentation, debugging, framework integration, and privacy & security. Chrome is committed to working with the web ecosystem to address these challenges and increase developer productivity and satisfaction. We'll share more specific plans in the coming weeks and welcome your feedback on these focus areas and how Chrome can better engage with the developer community. Read More
Hiring: Chrome Privacy Sandbox Developer Advocate — 🔗
It's looking like 2020 will be a big year for Privacy across the web and our team (Chrome) is no exception.
Chrome has a rather large number of projects that are coming in the following years that will continue to improve the privacy of all users on the web and we need the help of an awesome Developer Advocate to ensure that the entire cross-browser privacy story is heard, understood and implemented across the web.
The Developer Advocate role will help to accelerate the adoption of security and privacy related primitives from all browsers (think about all the great work browsers like Firefox, Safari, Brave etc are doing) across the web ecosystem and to make sure that our engineering and product teams are prioritising the needs of users and developers. It's not going to be easy, because a lot of these changes impact the way developers build sites today; for example, the Same-Site change that is landing in Chrome imminently requires developers of widgets and anything that is hosted on a 3rd party origin meant to be used in a 1st party context, to declare that the correct SameSite
attribute, lest they be automatically set to SameSite=Lax
, which will restrict their usage slightly.
There's going to be a lot of work to do, so being able to work with companies, frameworks and libraries in the ecosystem is going to be a key part of this role.
If you're interested, my email is paulkinlan@google.com - or you can apply on the Job posting directly.
Correct image orientation for images - Chrome 81
Chrome 81 finally fixes a long-standing bug where images taken in portrait mode on phones were displayed in landscape. Now, images will respect the orientation from the EXIF data by default, unless overridden with the CSS attribute image-orientation: none
. Check out the demo!
Read More
Light fork of SimpleImage for Editor.js — 🔗
I love Editor.js. It's a nice simple block editor that I use to write these posts. It has a host of good plugins that enable you to extend the capabilities of the editor, such as the SimpleImage tool that allows you to add images to the editor without having to upload them.
It's the SimpleImage that I briefly want to talk about. It's a good tool, but it has two problems, 1) I can only drag images on to the editor, I can't "add" an image; 2) It uses base64 data URL's to host the image, this is a waste of memory and it should be using blob URLs.
I wrote a simple fork that addresses these two pain points. The first is that it uses less memory because it uses blob URLs. The second is that now you can add images in when adding in a new Block to the editor.
In fact, the following images are added using this new way.
Airhorner with added Web USB — 🔗
This new year Andre Bandarra left me a little surprise on my desk: A physical airhorner built with Web USB!
Check it out, well actually it will be hard, Andre created a small sketch for an Arduino Uno that connects over USB that is not yet available, however the code on the site is rather neat and not too complex if you are experienced with any form of USB programming.
Andre's code connects to the device and waits for the user to approve, configures the connection, and then continuously reads from the device looking for the string 'ON' (which is a flag that is set when the button is pressed).
const HardwareButton = function(airhorn) {
this.airhorn = airhorn;
this.decoder = new TextDecoder();
this.connected = false;
const self = this;
this._loopRead = async function() {
if (!this.device) {
console.log('no device');
return;
}
try {
const result = await this.device.transferIn(2, 64);
const command = this.decoder.decode(result.data);
if (command.trim() === 'ON') {
airhorn.start({loop: true});
} else {
airhorn.stop();
}
self._loopRead();
} catch (e) {
console.log('Error reading data', e);
}
};
this.connect = async function() {
try {
const device = await navigator.usb.requestDevice({
filters: [{'vendorId': 0x2341, 'productId': 0x8057}]
});
this.device = device;
await device.open();
await device.selectConfiguration(1);
await device.claimInterface(0);
await device.selectAlternateInterface(0, 0);
await device.controlTransferOut({
'requestType': 'class',
'recipient': 'interface',
'request': 0x22,
'value': 0x01,
'index': 0x00,
});
self._loopRead();
} catch (e) {
console.log('Failed to Connect: ', e);
}
};
this.disconnect = async function() {
if (!this.device) {
return;
}
await this.device.controlTransferOut({
'requestType': 'class',
'recipient': 'interface',
'request': 0x22,
'value': 0x00,
'index': 0x00,
});
await this.device.close();
this.device = null;
};
this.init = function() {
const buttonDiv = document.querySelector('#connect');
const button = buttonDiv.querySelector('button');
button.addEventListener('click', this.connect.bind(this));
button.addEventListener('touchend', this.connect.bind(this));
if (navigator.usb) {
buttonDiv.classList.add('available');
}
};
this.init();
};
If you are interested in what the Arduino side of things looks like, Andre will release the code soon, but it's directly inspired by the WebUSB examples for Arduino.
Matsushima, Miyagi
Matsushima, Miyagi is a beautiful seaside town an hour from Sendai. Famous for its fresh oysters, islands, and red bridges, it's a charming place to visit. While the 2011 tsunami impacted the area, the town has recovered remarkably well. I found the quiet, cold atmosphere when I went added to its appeal. Read More
Yamadera, Yamagata
I took a day trip to the 1000-year-old Yamadera Temple in Yamagata, Japan. The climb to the top wasn't too difficult and offered breathtaking views of the valley. It was a quiet day with few other visitors, unlike busier weekends and holidays. The oldest building there is around 400 years old. Read More
Modern Mobile Bookmarklets with the ShareTarget API
Mobile devices lack the bookmarklet functionality found in desktop browsers. However, the ShareTarget API offers a potential workaround. This API allows web apps to be installed and receive native share actions, similar to how the Twitter PWA handles shared links and files. By leveraging this API, developers can create mini-apps that perform actions on shared data. This approach involves defining how to receive data in a manifest file and handling the request in a service worker. I've created examples for Hacker News, Reddit, and LinkedIn demonstrating how to utilize the ShareTarget API. While not a perfect replacement for desktop bookmarklets, this offers a new level of hackability for mobile web experiences. Read More
Pixel 4XL Infrared sensor via getUserMedia
The Pixel 4 XL's infrared camera, used for face detection, can be accessed through the standard getUserMedia API. A live demo showcasing this can be found at the provided link. Using the IR camera via getUserMedia blocks the phone's face unlock feature. This post invites readers to brainstorm potential applications of user-accessible infrared camera capabilities. An update mentions Francois Beafort's contribution to Blink, adding 'infrared' to the camera name if the device supports it, making camera identification more convenient. Read More
Sunset over Tokyo from Shibuya
Snapped a quick pic of a stunning Tokyo sunset from my Shibuya office window. Read More
Harlech Castle
Had a wonderful time exploring the magnificent Harlech Castle in North Wales with my kids. The castle is well-preserved and steeped in history, perched atop a hill with breathtaking views of Snowdonia and the Irish Sea. Unlike my previous visit to Carlisle Castle, this trip was purely focused on enjoying the stunning scenery. Read More