Jono Shields

Making a Chrome Extension

First Steps

I had this idea when I was making a sidebar for my blog, it was like if a waterfall was rainbows, wouldn’t it be cool if every website was this joyous?

So I started off making a Bookmarklet (a browser bookmark that contains javascript). The idea is pretty simple and just adds a pretty animated canvas to the DOM.

rainbow.js

(function(){
  var body=document.getElementsByTagName("body");
  var canvas=document.createElement("canvas");
  document.body.appendChild(canvas);
  
  ...
  // Note : This needs to be url encoded to be run as a bookmarklet.
  // Full source : 
  // https://github.com/foopod/rainbows-for-all/blob/master/rainbow.js
  
})();

Just drag and drop this great emoji link into your bookmark bar or just click it to see its effects.

So that worked really nicely and I was really happy with it, but I want rainbows on every page and I don’t want to have to click a bookmark every time.

Wrapping it in a Chrome Extenion

Enter Chrome Extensions.

Looks easy right? That is what I thought too!

And for something simple like this it was pretty easy. But when I came to add a toggle button to my extension all I found was pain and hardship.

First off you have to make a manifest.json to declare information about your app. This has things like icons, permissions and the scripts that will be executed.

manifest.json

{
  "name": "Rainbows For All",
  "version": "1.0",
  "description": "Rainbowify your browsing experience!",
  "permissions": ["<all_urls>"],
  "content_scripts": [{
      "js": ["addContent.js"],
      "matches": ["<all_urls>"]
  }],
  "icons": { 
    "16": "icon-16.png",
    "32": "icon-32.png",
    "48": "icon-48.png",
    "128": "icon-128.png" },
  "web_accessible_resources": ["rainbow.js"],
    "browser_action": {
   "default_icon": {
       "32": "icon-32.png"
       },
   "default_title": "Rainbows!"
},
  "manifest_version": 2
}

Above you will notice two scripts, addContent.js and rainbow.js. The content_scripts run as part of the chrome extension itself, whereas web_accessible_resources are files that your chrome extension can access.

rainbow.js is just my bookmarklet script from above. addContent.js is the chrome extension itself, all it does is add my rainbow script to the DOM in <script> tags.

addContent.js

var rainbowInstallService = document.createElement('script');
rainbowInstallService.src = chrome.extension.getURL('rainbow.js');
(document.head||document.documentElement).appendChild(rainbowInstallService);
rainbowInstallService.onload = function() {
    if(rainbowInstallService.parentNode != null){
        rainbowInstallService.parentNode.removeChild(rainbowInstallService);
    }
};

So aside from all the images my extension is just these three files (manifest.json, addContent.js and rainbow.js).

It would have been cool to have built it in a way that allowed the user to turn it on and off. But the Chrome API is quite confusing (read : it was late at night). Also not that many stack overflow posts :(

Source code is here.

Thanks for visiting!


Migrating my blog

Reflection

It has been almost a year since I started my blog on Tumblr, and although I haven’t always been consistent, I have managed to pump out on average two posts a month. I have talked about games I have been working on, personal adventures (i.e. stoicism, intermittent fasting) and lots of random little protoypes I have made.

But with the new year comes a time of reflection.

The reason I started was to have a dev log for the game I was making (Homage). But now, nearly 6 months since I touched that game I am still writing posts. Part of me really enjoys the writing aspect, part of me wants to gain some readers and part of me just wants to document the cool stuff I get to work on. Looking back on my posts from the last year I am really happy with some and cringe at others. Moving forward my aim is to improve the quality of my posts even if it does mean that I won’t write as many. I want to write posts that I would want to read.

Gross now on to real stuff

Tumblr was great when I started. I wanted a CMS with a nice public API so I could do just about anything with my own posts. Tumblr gave me this and more, I could create additional pages and I could style things exactly how I wanted by adding any custom html/css/js.

But I have unfortunately outgrown Tumblr. And this is why…

  1. Mobile Themes. Tumblr never uses your own theme on mobile, which means an inconsistent feeling across desktop and mobile if you don’t use their default theme.
  2. Posting. Even though I could easily create a new post, if I wanted anything that was out of the ordinary (say an embedded youtube video) then I had to resort to using their very average html editor.
  3. Flexibility. One thing I always wanted was a way to display the projects that I worked on, but I could never find a nice way to do this.

Moving to Jekyll

Hardest part -> Setting up rbenv on my laptop just right.

After that I cloned the Hyde Jekyll theme, made some minor changes to support Jekyll 3.x and I was flying. When I did this there were a few outstanding pull requests for these updates which made it super easy.

Next I imported all my Tumblr posts, Jekyll Import supports 37 different blogging platforms. And exporting my posts took no time at all, the only let down was having the image grabbing not work. So all the images are still hosted on Tumblr for now.

And with that I had a simple static site that was responsive. I had one of my Tumblr issues fixed already, I could have consistency across all platforms and could style it as much as I want.

One of the other reasons (for ditching Tumblr) was already solved too. By switching to Jekyll I could write all my posts in either md or html or even put html in my md. I still had a CMS if I chose to edit my posts on github.com (lets just forget about the terrible file editing experience on mobile for now) and I could use my text editor of choice for doing my posts on desktop.

My last point about flexability had been solved too, with Jekyll I have the ability to create my own collections, these are flexible objects that can be used site wide.

Just define the collection in your _config.yml.

collections:
    - projects

Then created a new .md file for each of my projects.

---
layout: page
title: Hashbrowns
tagline: Print your Jira tickets on Hashbrowns
date: 2017-01-24
link: http://jira.hashbrown.club/
---

That time that Jono wanted to print his JIRA tickets on Hashbrowns to impress everyone at work.

All I needed to do was make a page that looped through them all and displayed some of their contents.

<!-- Displays Projects in correct order -->
{% for project in site.projects reversed %}
  <div class="project">
    <h4 class="project-title">
      <a href="{{ project.link }}">
        {{ project.title }}
      </a>
        {{ project.date | date_to_string }}
    </h4>
      {{project.content}}
  </div>
{% endfor %}

For my purposes Jekyll has been a lot more flexible. It has extra benefits too…

  • Everything is under version control (Github).
  • I can add literally anything that I want to the site (no longer have to play by Tumblr’s rules).
  • Custom 404 page.

Later days.


Chowtime V2!

I have been working on Chowtime quite a bit and it is proving to be pretty handy for what I needed.

In the last week I have

  • Added a tool to visualize your eating habits.
  • Revamped the UI to make it a little more intuitive.
  • Enabled Web App features.
  • Moved to a hosting provider with Lets Encrypt integration.

Visualization

I got around to creating the tool I was talking about in the last blog post.

image

The largest most outer ring is today and each successive ring going inwards are previous days. I really like this as it shows a lot of information in an intuitive way, but it was a pain in the butt to make and still doesn’t support fasting periods of more than 24 hours. So I want to fix that, but also add a log where someone can see any extra information they have added using the experimental diary feature.

New UI

The toggle button was beginning to annoy me, with the diary feature the button had up to 3 functions which was not intuitive at all. Now you simply click the panda to toggle eating and not eating, the diary has its own submit button and the experiments now use a much nicer toggle button.

image

As you can see above it is way easier to get to the visualization, in the past it was buried in the FAQ. The next step might be to embed the visualization into this page so you don’t have to move back and forth. The button to export is still hidden in the FAQ though, but I feel like that is fine because users don’t need it very often.

image

Web App

So to give the best experience possible for mobile users I added meta tags to allow for Chowtime to function as a web app. It was actually super simple and below shows just how easy it is to support Android and iOS.

image

This basically means that users can add it to their homescreen and it will function similarly to a native app. It will have a lovely app icon and launch nicely with a splash screen and no browser bar. Yay!

New Hosting

Google Chrome will actually recommend users to add the web app to the homescreen if it meets a few simple requirements. One of them is to have a service worker registered for the app and to have it served over https. But unfortunately Github Pages does not support SSL for custom domains.

Enter Netlify. Netlify supports HTTPS for custom domains, has integrated Lets Encrypt and allows easy CI from a github repo. It’s all so simple and totally free for prototyping. I am sure performance doesn’t live up to the SSDs of Digital Ocean, but it does the job and I haven’t noticed any especially slow load times. Although I might run some performance tests now that I have the same web app on both GH Pages and Netlify.

Either way having SSL is a huge improvement for everyone. So its a win in my books.

Thanks for reading you pretty things!