Tags: ip

1016

sparkline

Tuesday, May 23rd, 2017

Going offline at Indie Web Camp Düsseldorf

I’ve just come back from a ten-day trip to Germany. The trip kicked off with Indie Web Camp Düsseldorf over the course of a weekend.

IndieWebCamp Düsseldorf 2017

Once again the wonderful people at Sipgate hosted us in their beautiful building, and once again myself and Aaron helped facilitate the two days.

IndieWebCamp Düsseldorf 2017

Saturday was the BarCamp-like discussion day. Plenty of interesting topics were covered. I led a session on service workers, and that’s also what I decided to work on for the second day—that’s when the talking is done and we get down to making.

IndieWebCamp Düsseldorf 2017 IndieWebCamp Düsseldorf 2017 IndieWebCamp Düsseldorf 2017 IndieWebCamp Düsseldorf 2017

I like what Ethan is doing on his offline page. He shows a list of pages that have been cached, but instead of just listing URLs, he shows a title and description for each page.

I’ve already got a separate cache for pages that gets added to as the user browses around my site. I needed to figure out a way to store the metadata for those pages so that I could then display it on the offline page. I came up with a workable solution, and interestingly, it involved no changes to the service worker script at all.

When you visit any blog post, I put metadata about the page into localStorage (after first checking that there’s an active service worker):

if (navigator.serviceWorker && navigator.serviceWorker.controller) {
  window.addEventListener('load', function() {
    var data = {
      "title": "A minority report on artificial intelligence",
      "description": "Revisiting Spielberg’s films after a decade and a half.",
      "published": "May 7th, 2017",
      "timestamp": "1494171049"
    };
    localStorage.setItem(
      window.location.href,
      JSON.stringify(data)
    );
  });
}

In my case, I’m outputting the metadata from the server, but you could just as easily grab some from the DOM like this:

var data = {
  "title": document.querySelector("title").innerText,
  "description": document.querySelector("meta[name='description']").getAttribute("contents")
}

Meanwhile in my service worker, when you visit that same page, it gets added to a cache called “pages”. Both localStorage and the cache API are using URLs as keys. I take advantage of that on my offline page.

The nice thing about writing JavaScript on my offline page is that I know the page will only be seen by modern browsers that support service workers, so I can use all sorts of fancy from ES6, or whatever we’re calling it now.

I start by looping through the keys of the “pages” cache (that’s right—the cache API isn’t just for service workers; you can access it from any script). Then I check to see if there is a corresponding localStorage key with the same string (a URL). If there is, I pull the metadata out of local storage and add it to an array called browsingHistory:

const browsingHistory = [];
caches.open('pages')
.then( cache => {
  cache.keys()
  .then(keys => {
    keys.forEach( request => {
      let data = JSON.parse(localStorage.getItem(request.url));
        if (data) {
          data['url'] = request.url;
          browsingHistory.push(data);
      }
    });

Then I sort the list of pages in reverse chronological order:

browsingHistory.sort( (a,b) => {
  return b.timestamp - a.timestamp;
});

Now I loop through each page in the browsing history list and construct a link to each URL, complete with title and description:

let markup = '';
browsingHistory.forEach( data => {
  markup += `
<h2><a href="${ data.url }">${ data.title }</a></h2>
<p>${ data.description }</p>
<p class="meta">${ data.published }</p>
`;
});

Finally I dump the constructed markup into a waiting div in the page with an ID of “history”:

let container = document.getElementById('history');
container.insertAdjacentHTML('beforeend', markup);

All those steps need to be wrapped inside the then clause attached to caches.open("pages") because the cache API is asynchronous.

There you have it. Now if you’re browsing adactio.com and your network connection drops (or my server goes offline), you can choose from a list of pages you’ve previously visited.

The current situation isn’t ideal though. I’ve got a clean-up operation in my service worker to limit the number of items stored in my “pages” cache. The cache never gets bigger than 35 items. But there’s no corresponding clean-up of metadata stored in localStorage. So there could be a lot more bits of metadata in local storage than there are pages in the cache. It’s not harmful, but it’s a bit wasteful.

I can’t do a clean-up of localStorage from my service worker because service workers can’t access localStorage. There’s a very good reason for that: the localStorage API is synchronous, and everything that happens in a service worker needs to be asynchronous.

Service workers can access indexedDB: it’s asynchronous. I could use indexedDB instead of localStorage, but I’m not a masochist. My best bet would be to use the localForage library, which wraps indexedDB in the simple syntax of localStorage.

Maybe I’ll do that at the next Homebrew Website Club here in Brighton.

Monday, May 22nd, 2017

Sponsoring Patterns Day

It didn’t take long for Patterns Day to sell out (in the sense of the tickets all being sold; not in the sense of going mainstream and selling out to The Man).

I’m very pleased about the ticket situation. It certainly makes my life easier. Now I can concentrate on the logistics for the day, without having to worry about trying to flog tickets AKA marketing.

But I also feel bad. Some people who really, really wanted to come weren’t able to get tickets in time. This is usually because they work at a company where to have to get clearance for the time off, and the cost of the ticket. By the time the word came down from on high that they’ve got the green light, the tickets were already gone. That’s a real shame.

There is, however, a glimmer of hope on the horizon. There is one last chance to get tickets for Patterns Day, and that’s through sponsorship.

Here’s the deal: if I can get some things sponsored (like recordings of the talks, tea and coffee for the day, or an after-party), I can offer a few tickets in return. I can also offer your logo on the Patterns Day website, your logo on the slide between talks, and a shout-out on stage. But that’s pretty much it. I can’t offer a physical stand at the event—there just isn’t enough room. And I certainly can’t offer you a list of attendee details for your marketing list—that’s just wrong.

In order of priority, here’s what I would love to get sponsored, and here’s what I can offer in return:

  1. £2000: Sponsoring video recordings of the talks—4 tickets. This is probably the best marketing opportunity for your company; we can slap your logo at the start and end of each video when they go online.
  2. £2000: Sponsoring tea and coffee for attendees for the day—4 tickets. This is a fixed price, set by the venue.
  3. £2000+: Sponsoring an after-party near the conference—4 tickets. Ideally you’d take care of booking a venue for this, and you can go crazy decking it out with your branding. Two pubs right across from the conference venue have upstairs rooms you can book: The Joker, and The Hare And Hounds.

There you have it. There’s no room for negotiation, I’m afraid, but I think they’re pretty good deals. Remember, by sponsoring Patterns Day you’ll also have my undying gratitude, and the goodwill of all my peers coming to this event.

Reckon you can convince your marketing department? Drop me a line, let me know which sponsorship option you’d like to snap up, and those four tickets could be yours.

Are we making the web too complicated? | Seldo.Com Blog

Laurie Voss on the trade-off between new powerful web dev tools, and the messiness that abusing those tools can bring:

Is modern web development fearsomely, intimidatingly complicated? Yes, and that’s a problem. Will we make it simpler? Definitely, but probably not as soon as you’d like. Is all this new complexity worthwhile? Absolutely.

I agree that there’s bound to be inappropriate use of technologies, but I don’t agree that we should just accept it:

Are there some people using a huge pile of JavaScript and a monstrous build chain to throw together a single-pager web site with one box that collects an email address? For sure. And that’s silly and unnecessary. But so what? The misuse of technology does not invalidate it.

I think we can raise our standards. Inappropriate use of technology might have been forgivable ten years ago, but if we want web development to be taken seriously as a discipline, I think we should endeavour to use our tools and technologies appropriately.

But we can all agree that the web is a wonderful thing:

Nobody but nobody loves the web more than I do. It’s my baby. And like a child, it’s frustrating to watch it struggle and make mistakes. But it’s amazing to watch it grow up.

Friday, May 19th, 2017

Presentation: Accessibility in a Responsive World, A11Y Days 2017

There are some great hands-on accessibility patterns in this talk transcript from Scott.

Friday, May 12th, 2017

Uncensorable Wikipedia on IPFS

I think this might be the first large-scale practical demonstration of the InterPlanetary File System: routing around the damage of Turkey’s censorship of Wikipedia.

Thursday, May 4th, 2017

Going offline. — Ethan Marcotte

Ethan has added a service worker to his site and he’s got a nifty little recipe for showing a list of saved-for-offline articles.

Monday, May 1st, 2017

Offline Web Applications | Udacity

This is a free online video course recorded by Jake a couple of years back. It’s got a really good step-by-step introduction to service workers, delivered in Jake’s typically witty way. Some of the details are a bit out of date, and I must admit that I bailed when it got to IndexedDB, but I highly recommend giving this a go.

There’s also a free course on web accessibility I’m planning to check out.

Springer Nature frontend playbook: house style guide

I like it when organisations share their in-house coding styles. This one from Springer Nature not only has guides for HTML, CSS, and JavaScript, but it also has a good primer on progressive enhancement.

Tuesday, April 25th, 2017

Replacing Disqus with Github Comments · Gazoo.vrv

If you’re using Disqus to power the comments on your blog, you might like to know that it’s pulling on loads of nasty tracking scripts. Bad for privacy and bad for performance.

Friday, April 21st, 2017

Brighton digital companies just did something brilliant… | Declan Cassidy

A write-up of the BrightSparks programme that Clearleft is taking part in.

Each company agreed to help support one local child from a low-income family, on free school meals or with a yearly household income of under £25k.

Tuesday, April 18th, 2017

Offline-first for Your Templated Site (Part Two)

I’m really interested in this idea of service-worker side templating (I know that Glenn is working on something really, really cool in this area too). Can’t wait for part three of this series! (hint, hint, Jeff)

Back to the Cave – Frank Chimero

Frank has published the (beautifully designed) text of his closing XOXO keynote.

Saturday, April 15th, 2017

Inclusively Hidden | scottohara.me

Comparing different ways to hide content accessibly:

There are three reasons behind hiding content in an interface, and it’s important to identify what those reasons are, as they will correlate with the appropriate technique needed to hide such content.

  1. Temporarily Hidden Content
  2. Purposefully Visually Hidden Content
  3. Purposefully Visual-Only Content

Thursday, April 13th, 2017

Digital Assistants, Facebook Quizzes, And Fake News! You Won’t Believe What Happens Next | Laura Kalbag

A great presentation from Laura on how tracking scripts are killing the web. We can point our fingers at advertising companies to blame for this, but it’s still developers like us who put those scripts onto websites.

We need to ask ourselves these questions about what we build. Because we are the gatekeepers of what we create. We don’t have to add tracking to everything, it’s already gotten out of our control.

Wednesday, April 12th, 2017

A Todo List

A great step-by-step walkthrough by Heydon of making an accessible to-do list, the “Hello World” of JavaScript frameworks.

There’s a lot of great knowledge in here that can be applied to plenty of other interface elements too.

Sunday, April 2nd, 2017

Balance

This year’s Render conference just wrapped up in Oxford. It was a well-run, well-curated event, right up my alley: two days of a single track of design and development talks (see also: An Event Apart and Smashing Conference for other events in this mold that get it right).

One of my favourite talks was from Frances Ng. She gave a thoroughly entertaining account of her journey from aerospace engineer to front-end engineer, filled with ideas about how to get started, and keep from getting overwhelmed in the world of the web.

She recommended taking the time to occasionally dive deep into a foundational topic, pointing to another talk as a perfect example; Ana Balica gave a great presentation all about HTTP. The second half of the talk was about HTTP 2 and was filled with practical advice, but the first part was a thoroughly geeky history of the Hypertext Transfer Protocol, which I really loved.

While I’m mentoring Amber, we’ve been trying to find a good balance between those deep dives into the foundational topics and the hands-on day-to-day skills needed for web development. So far, I think we’ve found a good balance.

When Amber is ‘round at the Clearleft office, we sit down together and work on the practical aspects of HTML, CSS, and (soon) JavaScript. Last week, for example, we had a really great day diving into CSS selectors and specificity—I watched Amber’s knowledge skyrocket over the course of the day.

But between those visits—which happen every one or two weeks—I’ve been giving Amber homework of sorts. That’s where the foundational building blocks come in. Here are the questions I’ve asked so far:

  • What is the difference between the internet and the web?
  • What is the difference between GET and POST?
  • What are cookies?

The first question is a way of understanding the primacy of URLs on the web. Amber wrote about her research. The second question was getting at an understanding of HTTP. Amber wrote about that too. The third and current question is about state on the web. I’m looking forward to reading a write-up of that soon.

We’re still figuring out this whole mentorship thing but I think this balance of research and exercises is working out well.

Thursday, March 30th, 2017

Creating my first HTTP server in node.js | Charlotte Jackson, Front-end developer

Charlotte’s step-by-step account of setting up a Node server is going to be invaluable if and when I get around to dipping my toes in those waters.

Sunday, March 26th, 2017

LA Times and ads | Nelson’s log

A lot has been written about the future of journalism, the importance of businesses like the LA Times being profitable as a way to protect American democracy. I agree with that in theory. But this sort of incompetence and contempt for readers makes me completely uninterested in helping their business.

Like Craig says…

Thursday, March 23rd, 2017

Modern JavaScript for Ancient Web Developers

Speaking as an ancient web developer myself, this account by Gina of her journey into Node.js is really insightful. But I can’t help but get exhausted just contemplating the yak-shaving involved in the tooling set-up:

The sheer number of tools and plugins and packages and dependencies and editor setup and build configurations required to do it “the right way” is enough to stall you before you even get started.

Retrofit Your Website as a Progressive Web App — SitePoint

Turning your existing website into a progressive web “app”—a far more appealing prospect than trying to create an entirely new app-shell architecture:

…they are an enhancement of your existing website which should take no longer than a few hours and have no negative effect on unsupported browsers.