RSSAmplifier

Blog

Rob Dodson

robdodson.meRSS feed ↗72 posts

Latest posts

How I Built My Mobile Second Brain

In my last post, My Second Brain Never Worked. Then I Gave It a Gardener , I mentioned that putting my Obsidian vault on a VPS with Claude Code permanently running on it, and being able to access it from my phone, was the real “ah ha” moment for me. A few people asked how I set that up, so here’s the full walkthrough. The idea is simple: rent a cheap DigitalOcean droplet, sync your vault using…

My Second Brain Never Worked. Then I Gave It a Gardener.

I always wanted a second brain. The thought of it seems so alluring: organize all of your thoughts, make connections, discover new ideas, build your personal knowledge graph! But I could never seem to get the promise of the second brain to materialize because of the maintenance work. If you follow productivity gurus on YouTube they all recommend the same strategy: Step 1 - Dump all of your…

Your AI Chatbot Is a Gatekeeper

I really love the personal finance app Monarch . I used Mint for years but always felt vaguely icky about how their business model required trying to get me to sign up for credit cards. With Monarch, I pay them an annual fee, and they keep track of all of my finances in one place—perfect! Recently they launched an AI chatbot. On the surface this seems like a cool feature, like my own little…

Clawdbot's Missing Layers

In 1994, Pizza Hut launched PizzaNet , one of the first—and possibly best named—online ordering platforms. But they had one problem: convincing customers to type their credit card numbers into a website. Who would be crazy enough to do that? No encryption, no standards, no recourse if something went wrong. Fast forward to today: we buy groceries, cars, and houses online without a second thought.…

Joining Voltus to work on climate!

When I left Google back in October of 2021, I did so because I wanted to find a job working on climate change. After a lot of reasearch and interviewing (which I wrote about at the time ) I finally found a role that felt perfect for me. So a couple weeks back, I joined the team at Voltus , with a mission to make the grid smarter and more resilient. What does Voltus do? Voltus offers a number of…

Why I'm turning my home into a virtual power plant

On September 9th 2020, I woke up to find that the sky outside of my window looked like this: Smoke from nearby wildfires was trapped over the Bay Area, making the region look like the surface of Mars. It’s hard to describe the feeling of walking around my neighborhood with it looking like the set of Blade Runner, but the one thing I can say is that it made the immediacy of climate change…

Finding a job in climate as a front-end engineer

In October 2021, I left my job at Google to see if I could find a role in climate tech. When I left, I didn’t have a job lined up, nor did I know how to go about finding a job in climate, so I wanted to write this post to share what I learned along the way. I’m happy to say that I have since found a new role in the climate space (something I’ll write about soon) and hopefully the information below…

How I work

I’m always fascinated by learning the productivity tools that people use. I’m on a bit of an asymptotic quest to be efficient during the day so I can feel good about disconnecting in the evening. In this post, I’ve done a write-up on tools and techniques I use in my day-to-day work. This is a snapshot of my process in 2021, but I may revise it in the future. Todoist Pinboard Aggressively closing…

Command palettes for the web

A while back I was working with a fellow Googler to try and improve the accessibility for one of our apps. In the scenario, a user needed to click some UI, which then opened a panel, where the user needed to click more UI to perform an action. Helping a screen reader navigate these various UI states is a tricky technique known as focus management .Focus management is when you manually direct the…

Easily upgrade Ghost 0.x to 2.0

Over the weekend I updated my ancient Ghost blog to version 2.0. This was harder than I expected so I wanted to share the strategy that worked for me. This will require nuking your old server—which sounds scary, but is so much easier than upgrading it in place. If all you’re doing is running Ghost then it may be no big loss—it wasn’t for me at least 😛 If you’re doing a bunch of other stuff on…

Which elements support shadow DOM?

Oliver on twitter asked : Is there a list somewhere of which HTML elements can and can’t have a shadow DOM? As it turns out, there is! (Big thanks to Anne van Kesteren for showing us the way ). If context object ’s local name is not a valid custom element name , article , aside , blockquote , body , div , footer , h1 , h2 , h3 , h4 , h5 , h6 , header , main , nav , p , section , or span , then…

Why you can't test a screen reader (yet)!

When I first started to learn about accessibility I wanted to write automated tests to ensure that assistive technology devices, like screen readers, were interpreting my pages correctly. Because I’m not a daily screen reader user, I figured it would be easy for a regression to slip in unnoticed. This idea, testing a screen reader, proved much harder than I thought. It’s actually a bit of a holy…

Hello, 2018!

Goodbye, 2017 Politics The year opened with a lot of protests and rallies. We rallied at the SF city hall, the Women’s March in Oakland, at San Francisco Airport, and even at the Google Campus. It was intense. When the riot police showed up at SFO while folks were banging on the security barriers I wondered if it was only a matter of time before they tear gassed us. Thankfully that didn’t happen.…

The future of accessibility for custom elements

When users of assistive technology, like a screen reader, navigate a web page, it’s vitally important that the semantic meaning of the various controls is communicated. For example, if a screen reader visits a login button: < button > Sign in </ button > —it would announce, “Sign in, button”. This tells the user about the affordance available to them—whether something is a button that may be…

How to use Polymer with Webpack

Introduction Over the last year I’ve had a number of discussions with mid to large sized companies who are interested in creating common UI libraries that all of their teams can share. Often these teams are on different stacks (React, Vue, Angular, etc.) so using something like Web Components and Polymer makes sense, as all of these frameworks can consume and communicate with Web Components. Most…

Don&#39;t use jQuery plugins with Shadow DOM

This is a post I should have written a loooong time ago… tl;dr: jQuery plugins don’t work inside of Shadow DOM because typically they try to query for something starting at the document level and the shadow root blocks this. A super handwavy explanation of jQuery plugins (featuring shitty drawings) jQuery plugins work by latching on to an element, stamping a template inside of it, and then (often…

Regarding the broken promise of Web Components

After reading an article titled The broken promise of Web Components and typing out the world’s longest comment response I figured it’d be better if I try to distill my thoughts into a blog post. I’ll address each of the points raised by the author as their own section. After years of effort Web Components have been a waste of time Something I’ve learned from working with the Chrome team is that…

Custom Elements That Work Anywhere

Safari Tech Preview 17 now has Custom Elements “enabled everywhere” , meaning it won’t be long before they’re shipping in a stable version. Since more browsers are starting to adopt Custom Elements, I thought it would be a good time to share some of the patterns I’ve learned from building and speaking about them over the past few years. In The Case for Custom Elements I pointed out that Custom…

Building better accessibility primitives

As the sites we build increasingly become more app-like it’s important that the platform keep up and give component authors the tools they need to build rich accessible experiences. Recently I’ve run into two situations where it was extremely difficult for me to add proper keyboard support to the components I was building. After a lot of experimentation and research it became clear that maybe…

Setting up Android Studio on Yosemite

I’ve set out to learn some of the Android framework this quarter, which means setting up Java and the lastest version of Android Studio. As it happens, I formatted my laptop today and did a clean install of Yosemite so my machine is about as stock as they come. As I was setting up Android Studio, I ran into some hiccups and thought I’d document them for anyone else running into similar issues.…

@font-face doesn&#39;t work in Shadow DOM

I was building custom elements with Polymer the other day, and I thought it would be cool to include Font Awesome for some sweet icon goodness. Everything was going great, until I switched over to Chrome to check my work. I did some digging and manged to turn up this thread on the Polymer mailing list. The Fix I had a bit of an “aha moment” when I remembered that the Shadow DOM is encapsulating…

Exploring HTML Imports

Web Components have come a long way in the past few months and one of the technologies that I’m most interested in is HTML Imports (or “imports”, for short). Imports allow you to load additional documents into your page without having to write a bunch of ajax. This is great for Custom Elements where you might want to import a suite of new tags. I spent the day playing with imports and thought it…

nth-child is weird

I ran into a CSS gotcha today and it brought up an interesting (and important) question: What’s the difference between nth-child and nth-of-type ? Comparing two things or one Take a look at this sample code to get a feel for what we’re talking about. < style > p:nth-child(2) { background-color : green ; } </ style > < div > < p > This paragraph is not green </ p > < p > This paragraph *is* green…

RequireJS: Embracing the Awesomness of AMD Modules

Over the past few weeks I put together this talk for my team at GE to help get everyone on the same page with AMD modules. I figured it’d be cool if I removed any GE specific stuff and open sourced the presentation, so here it is! The video is around 35 minutes long and there’s a slide deck available on Github that has clickable links and whatnot. Enjoy! Slidedeck on Github

HTML5 Template Tag: Introduction

Our first template There’s a great HTML5Rocks article on the subject of the template tag and I’m going to steal some of their examples. Let’s start by making a template for an image placeholder. < template id = " kitten-template " > < img src = " " alt = " random kitten image " /> < h3 class = " title " > </ h3 > </ template > < div id = " kittens " > </ div > < script > const template = document…

Asynchronous Grunt Tasks

Update: Thanks to @waynemoir for updating the example source to work with Grunt ~0.4. After my last post @stevensacks tweeted at me that he was having issues getting node FileSystem commands to work in grunt. After a bit of poking around I noticed that there was no call to grunt’s async method, which was probably preventing the process from finishing properly. So today’s post is a primer on async…

A RequireJS multi-page shimmed site: How-To

I’ve been working with RequireJS a lot lately and found it really improves the way I manage my code. I had previous experience with Require in the context of some of my Backbone posts, but I’d never used it on a more traditional multi-page site before. The process of setting up Require on a multi-page site can be pretty confusing, so I thought I would put together this tutorial to help out others…

JavaScript Design Patterns: Factory

Table of Contents Factories encapsulate and separate object creation from the rest of your code. In situations where the creation of an object can be complex or subject to change a factory can act as a nice buffer to help keep things tidy. Without proper planning Factories can lead to class explosions; as a result the pattern can be both a blessing and a curse depending on how it’s used. Formal…

JavaScript Design Patterns: Decorator Update

Yesterday’s post drew a lot of traffic from Reddit and with it came some really good feedback. If you haven’t read the previous post please do so first and then come back here. I want to go through some of what was said so I can refine my examples and also clear up any confusion. That prototype example sucked! OK let me start off by apologizing for even including that second example (the Sale…

JavaScript Design Patterns: Decorator

Table of Contents Update: Part 2 has been posted! A Decorator is an object which adds functionality to another object dynamically. It can be used to enhance the behavior of an object without requiring the author to reopen its class. While Decorators might feel a little weird to implement in static languages they’re extremely simple in JavaScript due to the ease with which JS passes around…

JavaScript Design Patterns: Observer

Table of Contents Observer is one of the most popular design patterns and chances are you’re probably already using it. If you’ve ever written an event listener with addEventListener or used one of jQuery’s many versions: on , delegate , live , click , etc… then you should already be comfortable with the concept. In a nutshell the Observer pattern allows a Subject to publish updates to a group of…

JavaScript Design Patterns: Iterator

Table of Contents If you’re coming from Ruby or Java you probably think of an Iterator as an object which gives you a consistent interface for traversing a collection of some kind. If you’re coming from JavaScript or Actionscript you probably just think of an iterator as the i value in a for loop. The term has mixed meanings but in this case we’re refering to the former, an object which gives us a…

JavaScript Design Patterns: Singleton

Table of Contents Ah yes the Singleton, a pattern whose name lives in infamy. For the uninitiated a little explanation is in order. A Singleton is an object which can only be instantiated one time. Repeated calls to its constructor return the same instance and in this way one can ensure that they don’t accidentally create, say, two Users in a single User application. Doesn’t sound too bad, right?…

JavaScript Design Patterns: Strategy

Table of Contents The Strategy pattern is one of my personal favorites and you’ve probably seen or used it in some fashion without even knowing it. Its primary purpose is to help you separate the parts of an object which are subject to change from the rest of the static bits. Using Strategy objects versus subclasses can often result in much more flexible code since you’re creating a suite of…

JavaScript Design Patterns: Table of Contents

Creational Abstract Factory Builder Factory Method Object Pool Prototype Singleton Structural Adapter Bridge Composite Decorator Facade Flyweight Private Class Data Proxy Behavioral Chain of Responsibility Command Interpreter Iterator Mediator Memento Null Object Observer State Strategy Template Method Visitor Monad Pattern / Promises I’ve been trying to think up a new chain since coming back from…

Ending My First Chain

Note to readers: Since writing this post I’ve gone back and hidden a bunch of the posts that I created during this chain because they were bitrotting. Their URLs will still work but they now have a big warning at the top. Why did I do it? Everything started because of a blog post written by a fellow named Chris Strom. Chris wrote every single day, for a year, and in that time he managed to self…

Sublime Snippet Basics

Yesterday I covered some tips and tricks I’ve learned over the past few months of using Sublime. Something I didn’t touch on is Sublime’s Snippet architecture. Essentially a snippet is a little piece of code that gets executed when you type some characters and hit the tab key. For instance I have a snippet that spits out console.log() whenever I type lg and press tab . One clever feature of…

Sublime Text 2 Tips and Shortcuts

I’ve been using Sublime Text 2 for probably two months now and in that time I’ve discovered tons of useful tricks. I figured I should start writing them down for anyone who might be interested. I’ll try to explain the bits that seem esoteric because there are a lot of cool commands which only work in certain contexts. Finding your preferences One of the first things you want to do with Sublime is…

Publish your Node library to npm

Alright, contuing from yesterday we want to take our little Node module and make it available to the world as a really awesome command line tool. The first thing we need to do is register an NPM account. npm adduser Fill in your credentials and it should be ready to go. If we have any dependencies they should be added to our package.json file. Our simple compliment program doesn’t need any extra…

How to Run a Node Script from the Command Line

First write some code Make a new directory called compliment and create two files inside of it: comliment.js and package.json . In compliment.js we’re just going to print out some kind words. #! /usr/bin/env node console.log ( 'you. are. AWESOME!' ) ; Simple enough right? Just make sure you include that shebang up at the top which directs the system to use Node to execute our script. Package it up…

How To Write a Command Line Ruby Gem

So yesterday we saw how to setup and run ruby scripts as executables from the command line. While this is pretty rad, it definitely has its limitations. For one, it’s not very portable and secondly it just isn’t very flexible or powerful. If we stuck with this approach we’d need to write our own semantic versioning, we’d have to setup a way to make sure that all of our required 3rd party gems get…

Writing a Command Line Tool in Ruby

Yesterday I tried to do a post on creating your first Ruby Gem as a command line tool. It didn’t go very well. In an effort to better understand what goes on with command line tools I’m going to start from the most basic, a ruby script that is in our PATH . I’ve previously added the folder ~/bin to my PATH so I know that if I drop an executable script in there I should be able to run it by just…

Let&#39;s Talk SMACSS

In an effort to further my understanding of CSS best practices I’ve ended up with two sort of looming frameworks: OOCSS and SMACSS. After reading up on both I feel more drawn toward SMACSS, most likely because it features a lumberjack on its site. I want to give a quick summary of what SMACSS has to offer. In so doing I’m going to borrow liberally from the documentation and then explain my…

CSS Semantics: Best Practices

CSS is, for me, one of the most challenging and nerve wracking aspects of my job. With most programming languages there are frameworks and guides and heuristics that all make up a suite of best practices. CSS doesn’t really have anything like this and as a result it’s kind of a mish-mash of good rules to follow, definite don’ts, and lots and lots of grey area. Since I’m starting a new CSS heavy…

Building a Countdown Timer with Socket.io pt. 3

Today’s the day we wrap up our countdown timer and deploy it to Heroku. But before we launch this puppy we need to clean house a little and spice up the visual appeal. Getting Started Click here for part 1. Click here for part 2. Refactoring the Stopwatch While the Stopwatch from our last post worked OK there are a spots that can be improved. For starters I’d like to separate the formatting of the…

Building a Countdown Timer with Socket.io pt. 2

Continuing from yesterday’s post we started out with a rather crude timer and today I want to upgrade it to a full fledged model, Stopwatch , which dispatches events for the view to hook on to. Getting Started Click here for part 1. Click here for part 3. Extend Node’s EventEmitter We want to extend Node’s EventEmitter object in order for our Stopwatch to dispatch its tick events. Following this…

Building a Countdown Timer with Socket.io

Yesterday I put together a very simple Node/Socket.io application and showed how to deploy it to Heroku. Today I’m going to keep going with that app to see if I can get the functionality that I want. The app is a basic stopwatch so that shouldn’t be too hard. If you want to catch up checkout yesterday’s article which explains setting everything up. Getting Started Click here for part 2. Click here…

Make Your Own jQuery Deferreds and Promises

Last week I did a post on how to load an Underscore template using jQuery’s Deferred method . I got some great feedback from folks and decided I should do a follow up showing how to create your own Deferreds. What’s a Deferred again…? So, quick summary time. jQuery has a neat little Object called a Deferred which is basically a wrapper around a function or a group of functions. Let’s say that you…

How to use EJS in Express

Update: If you’re starting a fresh project with Express it’s much easier to just run express --ejs . That will scaffold out an Express app for you with EJS ready to go! Here’s a quick explanation of how to use EJS instead of Jade in your Express projects. This is super easy and covered well in the documentation but I wanted to put it here since that’s what I worked on today :) To start I’ll create…

Using jQuery Deferred to Load an Underscore Template

Today’s post is meant to scratch an itch I had the other day regarding templates. My friend wanted to load an underscore template along with some JSON data but wasn’t sure what the best approach would be. Since I’m using Backbone Boilerplate I’ve gotten used to having my template loading method already stubbed out for me. Here’s the one they use: fetchTemplate : function ( path , done ) { var JST…