<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Dan Matthew</title><description>Notes and thoughts from Dan Matthew, an accessibility and design systems consultant</description><link>https://danmatthew.co.uk/</link><item><title>Global Accessibility Awareness Day 2026</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Thu, 21 May 2026 19:02:02 GMT</pubDate><content:encoded>&lt;p&gt;It&apos;s Thursday 21st of May 2026 and it&apos;s the &lt;a href=&quot;https://accessibility.day/&quot;&gt;15th Global Accessibility Awareness Day&lt;/a&gt;. Like a lot of other awareness campaigns, this is often a day when organisations make a big song and dance about how they are supporting persons with disabilities, only to not give a toss the day after.&lt;/p&gt;
&lt;p&gt;The latest &lt;a href=&quot;https://webaim.org/projects/million/&quot;&gt;WebAIM Million report&lt;/a&gt; tells us:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The number of detected errors increased 10.1% since the 2025 analysis which found 51 errors/page.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&apos;s pretty shocking that things are getting worse when it has only gotten easier to write and test for well-engineered frontends. I wonder if the emergence of LLM-generated code has had a hand in this. If the majority of code is inaccessible, and LLMs are being trained on this output, it&apos;s going to be the most likely thing they generate when prompted to the next time. The well is forever poisoned.&lt;/p&gt;
&lt;p&gt;If you&apos;re involved in creating content for the web - whether that&apos;s design, coding, or copywriting - take a beat and have a think about what you could do better.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you design, consider how someone who doesn&apos;t use a mouse might operate your fancy user interface.&lt;/li&gt;
&lt;li&gt;If you code, reach for the rich palette of HTML before creating a widget using divs. It does a lot of the heavy lifting, honest.&lt;/li&gt;
&lt;li&gt;If you write, don&apos;t forget to describe the contents of images and rich media you include.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Weeknotes: 2025-05-17</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sun, 17 May 2026 17:56:27 GMT</pubDate><content:encoded>&lt;p&gt;Spent a long weekend in Vienna where I spent time enjoying the tasty treats in the &lt;a href=&quot;https://en.wikipedia.org/wiki/Stadtpark,_Vienna&quot;&gt;Stadtpark&lt;/a&gt; at the &lt;a href=&quot;https://www.genussregionen.at&quot;&gt;Genuss Festival&lt;/a&gt;. Did you know Austria has a &lt;a href=&quot;https://en.wikipedia.org/wiki/Weinviertel&quot;&gt;Wine Quarter&lt;/a&gt;?! The rest of the time was spent exploring the city, visiting its many museums around the &lt;a href=&quot;https://www.wien.info/en/museumsquartier-overview-architecture-tour-431168&quot;&gt;Museumsplatz &lt;/a&gt;including the &lt;a href=&quot;https://en.wikipedia.org/wiki/Pieter_Bruegel_the_Elder&quot;&gt;Pieter Bruegel&lt;/a&gt; exhibition at the &lt;a href=&quot;https://www.wien.info/en/art-culture/museums-exhibitions/top-museums/kunsthistorisches-museum-350470#&quot;&gt;Kunsthistorisches Museum&lt;/a&gt;. Many a chuckle was had at early interpretations of animals artists had clearly not seen – but who am I to judge? The crux of the trip was around a performance of &lt;a href=&quot;https://en.wikipedia.org/wiki/Gustav_Mahler&quot;&gt;Mahler&apos;s&lt;/a&gt; &lt;a href=&quot;https://open.spotify.com/album/2PCu6ocEbTwFmjcBN8kuwO?si=SbXN3_FrSmG8T4MWgQC27Q&quot;&gt;8th Symphony&lt;/a&gt; at the &lt;a href=&quot;https://konzerthaus.at/de&quot;&gt;Konzerthaust&lt;/a&gt;. Vienna was hit by huge thunderstorms that afternoon, and it was possible to hear the thunder inside the venue.&lt;/p&gt;
&lt;p&gt;Favourite restaurant - hooray for having outdoor space on a Sunday evening! - was &lt;a href=&quot;https://www.mast.wine&quot;&gt;MAST&lt;/a&gt;: we enjoyed the six course Chef&apos;s Choice (&lt;a href=&quot;https://www.mast.wine/files/Dinner-MAST.pdf&quot;&gt;PDF menu&lt;/a&gt;) and accompanying wine flight…&lt;/p&gt;
</content:encoded></item><item><title>Accessible design guidelines</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Wed, 06 May 2026 21:33:13 GMT</pubDate><content:encoded>&lt;h2&gt;Operating and Navigating&lt;/h2&gt;
&lt;h3&gt;Don&apos;t design for mouse interactions alone&lt;/h3&gt;
&lt;p&gt;Anything that can be done with a mouse should also work with a keyboard. Or a pointer. Or a switch. Or with eye tracking.&lt;/p&gt;
&lt;h3&gt;Design what keyboard interactions look like&lt;/h3&gt;
&lt;p&gt;Design what it looks like when an element receives keyboard focus. Most interactive elements automatically receive focus. When building complex user interface controls, focus might move within it e.g. radio buttons, tabs, media player.&lt;/p&gt;
&lt;h3&gt;Think about the tab order&lt;/h3&gt;
&lt;p&gt;In what order does a user tab through an interface? Don’t spring surprises on the user. Embrace the principle of KISS.&lt;/p&gt;
&lt;p&gt;Ensure there are no keyboard traps whereby a user reaches a dead-end. It should be possible to move through the entire page using Tab, Shift + Tab, Escape, and the arrow keys.&lt;/p&gt;
&lt;h3&gt;Targets should be large enough&lt;/h3&gt;
&lt;p&gt;Make sure targets are at least 24px by 24px. Mobile interface guidelines suggest 44px by 44px. Somebody who struggles with fine motor control has a real tough time activating tiny interactive elements.&lt;/p&gt;
&lt;h3&gt;Skip links&lt;/h3&gt;
&lt;p&gt;Make it easy for the user to skip past long and repetitive sections. Menus, carousels, lists: give a keyboard user a way to bypass these sections and quickly move around the page.&lt;/p&gt;
&lt;h3&gt;Links should be recognisable&lt;/h3&gt;
&lt;p&gt;Don&apos;t remove link underlines from links in body text. They&apos;re a recognised convention, and an easy way to use something other than colour.&lt;/p&gt;
&lt;h3&gt;Naming things&lt;/h3&gt;
&lt;p&gt;Include text labels for inputs and form elements. We can use an icon for search inputs.&lt;/p&gt;
&lt;h3&gt;Auto-playing content&lt;/h3&gt;
&lt;p&gt;If content automatically plays – think audio, video, carousels – it should respect user preferences by default. It should provide a way to pause operation within the first three controls.&lt;/p&gt;
&lt;h2&gt;Colour&lt;/h2&gt;
&lt;h3&gt;Colour contrast&lt;/h3&gt;
&lt;p&gt;Text should have colour contrast of at least 4.5:1 between foreground and background. User interface components such as buttons need to offer at least 3:1 between the component and its background – in all states:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Default&lt;/li&gt;
&lt;li&gt;Hover&lt;/li&gt;
&lt;li&gt;Focus&lt;/li&gt;
&lt;li&gt;Selected&lt;/li&gt;
&lt;li&gt;Unselected&lt;/li&gt;
&lt;li&gt;Active&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Use of colour&lt;/h3&gt;
&lt;p&gt;Don&apos;t use colour as the only way to communicate information.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Broke: invalid text input only has a red border&lt;/li&gt;
&lt;li&gt;Woke: invalid text input has a red border, an obvious icon, and a useful error message telling the user how to fix the problem.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Typography&lt;/h2&gt;
&lt;h3&gt;Font size&lt;/h3&gt;
&lt;p&gt;While there&apos;s no &quot;one-size, fits all&quot;, the browser default of 16px is a good place to start. By using fluid units such as ems, our user can set the font size to their preferences. Make sure you&apos;ve thought about how text might wrap within your design: we don&apos;t want text bursting out of containers and causing horizontal scrolling.&lt;/p&gt;
&lt;h3&gt;Legibility&lt;/h3&gt;
&lt;p&gt;Avoid typefaces which have ambiguity between characters such as IL1. If possible, use alternative glyphs to use the single-storey &apos;a&apos;, dotted or slashed zero etc.&lt;/p&gt;
&lt;h3&gt;Numbers&lt;/h3&gt;
&lt;p&gt;Turn on tabular numbers to ensure each digit uses a fixed-width: this helps keep columns aligned, and helps prevent jiggling as numbers update.&lt;/p&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Vox: &lt;a href=&quot;https://vox.publicissapient.com/home/accessibility-checklist-for-user-experience-designers&quot;&gt;Accessibility checklist for UX designers  &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Vox: &lt;a href=&quot;https://vox.publicissapient.com/home/accessibility-checklist-for-visual-designers&quot;&gt;Accessibility checklist for visual designers  &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Vox: &lt;a href=&quot;https://vox.publicissapient.com/home/reviewing-a-design-for-accessibility-compliance&quot;&gt;Reviewing a design or wireframe for accessibility compliance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Deque: &lt;a href=&quot;https://www.deque.com/blog/give-site-focus-tips-designing-usable-focus-indicators/&quot;&gt;Designing accessible focus indicators   &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://accessiblenumbers.com/&quot;&gt;Accessible Numbers &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Calculate how many of your audience have a disability: &lt;a href=&quot;https://design.education.gov.uk/tools/how-many-users&quot;&gt;How many people&lt;/a&gt;?&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.microsoft.com/design/inclusive/&quot;&gt;Microsoft Inclusive Design toolkit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.getstark.co/&quot;&gt;Stark plugin for Figma &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.paciellogroup.com/resources/contrastanalyser/&quot;&gt;Colour Contrast Analyser  &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://chrome.google.com/webstore/detail/nocoffee/jjeeggmbnhckmgdhmgdckeigabjfbddl&quot;&gt;NoCoffee&lt;/a&gt; – browser plugin to simulate visual impairments&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://toolness.github.io/accessible-color-matrix/&quot;&gt;Accessible colour palette builder &lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>How to perform an accessibility design review</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Tue, 05 May 2026 20:28:47 GMT</pubDate><content:encoded>&lt;p&gt;This is an adaptation of something I wrote to help designers on project I worked on between Spring 2024 and Winter 2025. Maybe you&apos;ll find it useful too!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;When to review?&lt;/h2&gt;
&lt;p&gt;As the saying goes, “the best time to &lt;s&gt;plant a tree&lt;/s&gt; review accessibility is 20 years ago. The second best time is now”. Don&apos;t wait! Review early and often.&lt;/p&gt;
&lt;p&gt;It&apos;s much easier to catch critical issues early in your process before too much time, effort, or money has been invested in a solving a particular problem.&lt;/p&gt;
&lt;h2&gt;Quick checklist&lt;/h2&gt;
&lt;p&gt;For any new component:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Have you annotated the headings on your feature? (Do you even annotate?)&lt;/li&gt;
&lt;li&gt;Have you defined the focus/tabbing order on your feature?&lt;/li&gt;
&lt;li&gt;Have you added screen reader labels for elements that are not focusable (e.g. dynamic content changes; images and their alternative text)&lt;/li&gt;
&lt;li&gt;Does the text meet colour contrast requirements? (4.5:1 for body text; 3:1 for large text)&lt;/li&gt;
&lt;li&gt;Do graphic objects meet colour contrast requirements (3:1)? What about elements of user interface used to identify controls?&lt;/li&gt;
&lt;li&gt;With colour removed, can you still make sense of the design? You&apos;re not relying on colour, are you?&lt;/li&gt;
&lt;li&gt;Can all revealable information (tooltips, accordions) be accessed with a keyboard or a mouse&amp;gt;&lt;/li&gt;
&lt;li&gt;If a user doubles the text size, is the page still usable?&lt;/li&gt;
&lt;li&gt;If the viewport is reduced in size, is everything usable without introducing horizontal scrolling?&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Basic expectations&lt;/h2&gt;
&lt;h3&gt;The design uses an accessibility-first approach&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;We create better products for everyone when we consider people are are different to use.&lt;/li&gt;
&lt;li&gt;Consider situations for people using assistive technologies ahead of design review
&lt;ul&gt;
&lt;li&gt;Use Cards for Humanity and consider whether your design will meet the needs of the generated pairing&lt;/li&gt;
&lt;li&gt;Use Maya Benari&apos;s Empathy Maker for another set of scenarios&lt;/li&gt;
&lt;li&gt;Test your design with a random Empathy Prompt. Will it still work?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Consider the question: &quot;Who am I willing to exclude?&quot; when solving a problem. For example, hiding content behind a hover interaction means a whole swathe of keyboard and touchscreen users won&apos;t be given access to the same to perform tasks. The constituents of that audience might surprise you.&lt;/li&gt;
&lt;li&gt;Accessibility is about removing barriers. It&apos;s better to design inclusively and not introduce them at all.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Accessibility annotations included&lt;/h3&gt;
&lt;p&gt;Use an annotation kit or plugin – I like eBay&apos;s Include – to call out basic accessibility features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Page title&lt;/li&gt;
&lt;li&gt;Landmarks&lt;/li&gt;
&lt;li&gt;Headings&lt;/li&gt;
&lt;li&gt;Links&lt;/li&gt;
&lt;li&gt;Buttons&lt;/li&gt;
&lt;li&gt;Alternative text for images, data visualisations, and rich media&lt;/li&gt;
&lt;li&gt;Focus &amp;amp; reading order - if different from the default top-to-bottom, left-to-right flow in LTR scripts.&lt;/li&gt;
&lt;li&gt;Naming of UI components&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Defined interactions for custom components&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Any custom components modifying or combining interactions need clear direction on the desired keyboard and screen reader experience. For example, a Carousel:
&lt;ul&gt;
&lt;li&gt;Will the arrow keys operate the carousel?&lt;/li&gt;
&lt;li&gt;Does the spacebar pause the carousel?&lt;/li&gt;
&lt;li&gt;What interactions should be documented with testing instructions?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Contrast meets requirements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;All text and interactive elements should meet contrast requirements
&lt;ul&gt;
&lt;li&gt;Text is 4.5:1&lt;/li&gt;
&lt;li&gt;UI components are 3:1&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use the Colour Contrast Analyser to check each state of the component:
&lt;ul&gt;
&lt;li&gt;Default (or “Resting”, as I&apos;ve recently heard it called)&lt;/li&gt;
&lt;li&gt;Hover&lt;/li&gt;
&lt;li&gt;Focus&lt;/li&gt;
&lt;li&gt;Read-only&lt;/li&gt;
&lt;li&gt;Valid&lt;/li&gt;
&lt;li&gt;Error&lt;/li&gt;
&lt;li&gt;Loading&lt;/li&gt;
&lt;li&gt;Other?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Logical headings&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The h1 is the meaningful title of the page&lt;/li&gt;
&lt;li&gt;Major sections are titled with h2&lt;/li&gt;
&lt;li&gt;If the design calls for h4, h5, and h6 we might want to reconsider the information architecture of the page.&lt;/li&gt;
&lt;li&gt;Decouple headings from styles
&lt;ul&gt;
&lt;li&gt;Component libraries must decouple styles and style names from heading levels&lt;/li&gt;
&lt;li&gt;When heading levels are directly coupled to size, developers will use heading levels out of order to make text bigger or smaller.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Use plain language&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Plain language makes content easier for all users to consume and understand.&lt;/li&gt;
&lt;li&gt;Avoid using idioms or implying jokes: this can be difficult for people who speak English as a second language.&lt;/li&gt;
&lt;li&gt;Avoid technical jargon.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Vertical layout for forms&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Folks using screen magnifiers will zoom in on their screen. This means they can only see a portion of the layout. Adhering to a single column makes it easier for somebody to follow the edge of the form as they complete their task, and helps minimise content (such as validation indicators) from being missed&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Alt text conventions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Define alt text when the image adds meaning to the page: it could supply information, or help set the tone.&lt;/li&gt;
&lt;li&gt;Good alt text allows anyone who can&apos;t see the screen to describe it to somebody else. Imagine describing its contents to a friend.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Sufficient contrast and text size&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Components should also account for somebody increasing the font size of their browser in order to make content easier to read.&lt;/li&gt;
&lt;li&gt;This is where text truncation as a content strategy can fall down: suddenly the last few characters of a label are now visible as “ME…”. What does that even mean? One of the few situations where someone using an assistive technology will get the better experience.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Colour perception accommodation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Don&apos;t use colour as the only way of conveying content: any indicator dots would benefit from some sort of shape change to help disambiguate them.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Large target size&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Prefer large target areas to help folks with motor disabilities. The WCAG define this at 24px x 24px at AA, but measures for iOS and Android are more generous at 44 x 44 points.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Focus states&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Included keyboard focus as a default in the design system, alongside others, e.g. Checkbox:
&lt;ul&gt;
&lt;li&gt;Unchecked&lt;/li&gt;
&lt;li&gt;Unchecked + hover&lt;/li&gt;
&lt;li&gt;Unchecked + focus&lt;/li&gt;
&lt;li&gt;Checked&lt;/li&gt;
&lt;li&gt;Checked + hover&lt;/li&gt;
&lt;li&gt;Checked + focus&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The focus state must be obvious: both colour contrast but also dimensions. A 2px outline is a good start. Modern browsers allow focus rings to follow the border radius of an element.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Logical focus order&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Developers can use logical properties in CSS to ensure layouts reflect the preferences including locale and language of the user.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Responds to user preferences&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;One of the challenges of designing for the web, but also the property that makes it incredibly robust, is that it is not a fixed canvas. Of course a layout might be designed for 1280 x 720, but the browser window might be a different size, the orientation might be portrait, the user might want to turn off all animations - if only to save battery - or might be consuming the website via a portable Braille device. Think about how content might reflect those preferences and ensure you&apos;ve considered ways to help make it work.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Weeknotes: 2026-05-03</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sun, 03 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hooray for a Bank Holiday weekend! Boo for the fine weather of the week turning mixed. Typical.&lt;/p&gt;
&lt;p&gt;This week has been full of disparate ideas bouncing around in my brain and realising how they can all link together. I&apos;ve learnt about &lt;a href=&quot;https://www.openpolicyagent.org&quot;&gt;Open Policy Agent&lt;/a&gt; and how to &lt;a href=&quot;https://www.openpolicyagent.org/docs/policy-language&quot;&gt;define policies in Rego&lt;/a&gt;; I&apos;ve been delving into Gitlab pipelines and investigating &lt;a href=&quot;https://github.com/github/spec-kit&quot;&gt;Spec-Driven Development.&lt;/a&gt; I&apos;ve been introduced to the &lt;a href=&quot;https://artificialintelligenceact.eu/the-act/&quot;&gt;EU Artificial Intelligence Act&lt;/a&gt; and I&apos;m discovering the wide world of Salesforce.&lt;/p&gt;
&lt;p&gt;This week&apos;s bird sightings have included my first(?) &lt;a href=&quot;https://www.rspb.org.uk/birds-and-wildlife/starling&quot;&gt;Starlings&lt;/a&gt; and - according to Merlin - a lone &lt;a href=&quot;https://www.rspb.org.uk/birds-and-wildlife/goldfinch&quot;&gt;Goldfinch&lt;/a&gt;, sat on top of a tree, silhouetted by the early morning sun.  The nesting Robins continue to visit, and a pair of Blackbirds have displayed their ruthless approach to destroying grubs. Full on dismemberment.&lt;/p&gt;
</content:encoded></item><item><title>Weeknotes: 2026-04-26</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sun, 26 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Another week down. What&apos;s new?&lt;/p&gt;
&lt;p&gt;I was excited to see a pair of robins have deemed our nest box - protected by a fringe of overgrown climbing plants - worthy of their home. I&apos;ve been watching the two of them bring little bits of fluff to make it their own. How long will they spend making the nest? When do they lay their eggs? How long do they brood? When&apos;s Springwatch back on? I feel like I&apos;ve hit middle-age in the past few months: I&apos;ve discovered my green fingers; I enjoy watching birds; and I&apos;m started developing a taste for wine.&lt;/p&gt;
&lt;p&gt;Good news for those readers who consume this using RSS or JSON feed: I&apos;ve fixed up the feeds. Enjoy!&lt;/p&gt;
</content:encoded></item><item><title>Weeknotes: 2026-04-19</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sun, 19 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;Week 3 of the new accessibility job. I&apos;m not sure if I&apos;m allowed to share where it is? If we&apos;re connected on LinkedIn you&apos;ll know, but I&apos;ve yet to finish all the training materials that are on the backlog so I&apos;ll play it safe. It&apos;s different, to be sure. Now the team is large enough that everyone can bring a different perspective or skillset: I&apos;m getting to concentrate on design systems, developer productivity, and helping them shift left. In time, I&apos;d like to continue to help smooth the gap between design and development: I&apos;ve got ideas.&lt;/li&gt;
&lt;li&gt;I saw a production of To Kill A Mockingbird at the Hippodrome in Birmingham: it&apos;s been a while since I&apos;ve seen a play rather than a musical or ballet on stage. Confession: I&apos;ve not read the book or seen the Gregory Peck film in full. While the entire cast was strong, the actor who played Scout hit all the right notes.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Weeknotes: 2026-03-29</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sun, 29 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I had somewhat restful week off between jobs, before starting a new accessibility role tomorrow (Monday 30th March). The weather was changeable, but it was nice to spend some time in the garden and bring some order to it after the winter. Plenty of leaves to be swept and branches to be picked up.&lt;/p&gt;
&lt;p&gt;The local birds seem to be enjoying the food I&apos;m putting out for them, and there&apos;s something rewarding about just idling and watching them. Thus far, I&apos;ve seen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Long-tailed tits&lt;/li&gt;
&lt;li&gt;Blue tits&lt;/li&gt;
&lt;li&gt;Great tits&lt;/li&gt;
&lt;li&gt;House sparrows&lt;/li&gt;
&lt;li&gt;Robins&lt;/li&gt;
&lt;li&gt;Pigeons&lt;/li&gt;
&lt;li&gt;Magpies&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I have spotted some blackcaps in the trees behind the garden, but they seem less fussed about my offerings. The long-tailed tits were the first visitors to the feeder, but I&apos;ve not seen them for a while; the pigeons observe from afar and will wait for the sparrows to make a mess; the robin makes an afternoon pitstop; the magpies bully the smaller birds away.&lt;/p&gt;
&lt;p&gt;I enjoyed a walk and pint in the sunshine on Thursday, before attempting to update the sealant around the shower: the old stuff is a pain to remove through a combination of manual and chemical tooling.&lt;/p&gt;
</content:encoded></item><item><title>Weeknotes: 2025-12-28</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sun, 28 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;Two weeks off work over the Christmas break: I&apos;m glad to turn my brain off.&lt;/li&gt;
&lt;li&gt;Received some news on Christmas Eve which I&apos;ve been pondering over.&lt;/li&gt;
&lt;li&gt;Caught up with &lt;a href=&quot;https://tv.apple.com/gb/show/pluribus/umc.cmc.37axgovs2yozlyh3c2cmwzlza&quot;&gt;Pluribus&lt;/a&gt; and &lt;a href=&quot;https://www.netflix.com/title/80057281&quot;&gt;Stranger Things&lt;/a&gt;. One was significantly better than the other.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Weeknotes: 2025-11-30</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sun, 30 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;Spent the start of the week in Amsterdam. Long day travelling home on Wednesday, with strikes in Belgium adding an extra 90 minutes to the 4 ½ hour journey from Amsterdam Centraal to London St Pancras. Plus the subsequent 80 minutes on the train from London to Leamington.&lt;/li&gt;
&lt;li&gt;Thought I&apos;d given my hip/groin enough rest but an exploratory run on Saturday caused it to flare up again.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>danmatthew dot co dot uk at 20</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Wed, 28 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;20 years of owning danmatthew.co.uk. 20 years of hosting a website here (RIP hosting partners). 20 years of not using it particularly effectively.&lt;/p&gt;
&lt;p&gt;Still, it&apos;s my website. It&apos;s my space to noodle with, to learn about web technologies, to share what I like.&lt;/p&gt;
&lt;p&gt;There are many like it, but this one is mine.&lt;/p&gt;
&lt;p&gt;Happy birthday!&lt;/p&gt;
</content:encoded></item><item><title>Glofox Data Breach March 2020</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Tue, 25 May 2021 16:32:11 GMT</pubDate><content:encoded>&lt;p&gt;Have you heard of a company called &lt;a href=&quot;https://www.glofox.com&quot;&gt;Glofox&lt;/a&gt;? Their software provides the booking system for gyms and fitness studios.&lt;/p&gt;
&lt;p&gt;They suffered a data breach in March 2020, &lt;a href=&quot;https://duckduckgo.com/?q=glofox+data+breach&quot;&gt;but haven&apos;t said much about it&lt;/a&gt;. &lt;a href=&quot;https://www.glofox.com/blog/category/news/&quot;&gt;Nothing I could find&lt;/a&gt;. &lt;a href=&quot;https://www.irishtimes.com/business/technology/irish-start-up-glofox-investigates-possible-data-breach-1.4414837&quot;&gt;Others have, however&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Glofox has not responded to media requests for comment on a possible security breach but it has, in recent days, responded to individuals on Twitter who posed questions to the company after being informed its website had been compromised.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Lame. I was under the impression that under data protection legislation, organisations must contact the appropriate body and make a public statement as soon as they have knowledge of a breach. As an Irish company, they should have reported it to the &lt;a href=&quot;https://www.dataprotection.ie/&quot;&gt;Data Protection Commission&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;From 25 May 2018, the General Data Protection Regulation (GDPR) introduces a requirement for organisations to report personal data breaches to the relevant supervisory authority, where the breach presents a risk to the affected individuals. Organisations must do this within72 hours of becoming aware of the breach.&lt;/p&gt;
&lt;p&gt;Where a breach is likely to result in a high risk to the affected individuals, organisations must also inform those individuals without undue delay.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Whoops. Did Glofox pass this responsibility on to their customers, or are they not bothered? Note the date of the Irish Times report: November 2020.&lt;/p&gt;
&lt;p&gt;In January 2021 I was alerted to the breach thanks to a service called &lt;a href=&quot;https://haveibeenpwned.com/PwnedWebsites#Glofox&quot;&gt;Have I Been Pwned&lt;/a&gt;. It&apos;s integrated in my password manager, &lt;a href=&quot;https://1password.com/&quot;&gt;1Password&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Since the Glofox dashboard does not offer a way to delete an account, it took an email to &lt;a href=&quot;mailto:dataprivacy@glofox.com&quot;&gt;dataprivacy@glofox.com&lt;/a&gt; to do so.&lt;/p&gt;
&lt;p&gt;It&apos;s taken until May for the first spam emails to arrive at the compromised email addresses: both hawking a Norton Antivirus subscription which needs renewing. Do you think it leads to a legitimate website?&lt;/p&gt;
&lt;p&gt;If you&apos;re going to look after personal data, get your shit together. Mistakes happen, but don&apos;t try and hide it.&lt;/p&gt;
</content:encoded></item><item><title>Access local server from Parallels VM</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sun, 09 May 2021 18:28:53 GMT</pubDate><content:encoded>&lt;p&gt;I was struggling to access a development server on my host machine from a Windows 10 virtual machine (VM). Despite sharing a network, turns out the trick is not to use the host IP address, but  that of the bridged network the VM has created. For Parallels, that address tends to be &lt;code&gt;10.211.55.2&lt;/code&gt;&lt;/p&gt;
</content:encoded></item><item><title>Netlify CMS</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sun, 17 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve been experimenting with services such as &lt;a href=&quot;https://www.contentful.com/&quot;&gt;Contentful&lt;/a&gt;, &lt;a href=&quot;https://prismic.io/&quot;&gt;Prismic&lt;/a&gt;, and finally &lt;a href=&quot;http://sanity.io&quot;&gt;Sanity&lt;/a&gt;. Currently, each post on this site is a Markdown file, and it is converted into a HTML page by 11ty when the site is built. The &quot;content-as-a-service&quot; platforms return data over the wire, and each record in the GraphQL response is turned into the post it represents.&lt;/p&gt;
&lt;p&gt;However, I think I prefer to keep each post as a file, all wrapped up on Github, so it&apos;s back to &lt;a href=&quot;https://www.netlifycms.org&quot;&gt;Netlify CMS&lt;/a&gt; for me.&lt;/p&gt;
</content:encoded></item><item><title>Pharmaceuticals</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Tue, 08 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I thought I was an OK runner. I trained hard over the course of 2018 and aimed to get under 1:40 at the Great North Run. I ran 1:31, and then a few weeks later went 1:27 at Birmingham&apos;s Great Run.&lt;/p&gt;
&lt;p&gt;Since that purple patch, running has gotten harder and harder because my asthma has become harder to control.&lt;/p&gt;
&lt;p&gt;While I&apos;ve had a blue &quot;rescue&quot; inhaler to hand since I was a child, I&apos;ve quickly progressed through the various steroids over the past two years:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Beclometasone 400mg (&lt;em&gt;Clenil Modulite&lt;/em&gt;, brown)&lt;/li&gt;
&lt;li&gt;Fluticasone (&lt;em&gt;Flutiform&lt;/em&gt;, white)&lt;/li&gt;
&lt;li&gt;Beclometasone 100 &lt;em&gt;micro&lt;/em&gt;-grams (&lt;em&gt;Fostair 100&lt;/em&gt;, pink)&lt;/li&gt;
&lt;li&gt;Beclometasone 200 &lt;em&gt;micro&lt;/em&gt;-grams (&lt;em&gt;Fostair 200&lt;/em&gt;, pink)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&apos;ve been on the Fostair 200 for over a year now, in conjunction with another corticosteroid called Ciclesonide.&lt;/p&gt;
&lt;p&gt;Now because my blood tests show high levels of &lt;em&gt;eosinophils&lt;/em&gt; the assumption is that I&apos;m allergic to something, so I pair those with the following tablets to try and tamp down those naughty cells in my body which are flaring up and causing constriction:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1x montelukast 10mg&lt;/li&gt;
&lt;li&gt;2x theophylline 200mg (&lt;em&gt;Uniphyllin&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition, I&apos;ve also had a spell on Spiriva Respimat – often given to COPD patients - which delivers 3 micrograms of tiotropium bromide monohydrate. I tend to be the youngest in the clinic waiting room when I visit the consultant. From &lt;a href=&quot;https://www.coventrywarksapc.nhs.uk/mf.ashx?ID=c52e4489-fdb1-4606-820c-be9e236bc06a&quot;&gt;this NHS worksheet&lt;/a&gt;, I&apos;m at the &quot;Seek specialist advice&quot; stage of progression.&lt;/p&gt;
&lt;p&gt;I don&apos;t particularly wish to be taking steroids for any longer than necessary. Because of this constant barrage of steroids, I suffer from oral thrush (yum yum), and my voice has changed in tone. I get frequent upper-respiratory infections, and each morning I get to hock up my lungs like a 20-a-day smoker. I&apos;ve had several doses of an oral steroid and antibiotics, but was one course shy of being invited to another clinic to take an injected medicine.&lt;/p&gt;
&lt;p&gt;What really gets my goat is how it affects my ability to exercise: I can be working and breathing hard, but as soon as an interval ends and my body relaxes – BANG: here comes the constriction. Classic exercise-induced bronchitis symptoms.&lt;/p&gt;
&lt;p&gt;While I know I this is still a case of extreme privilege, I would love to discover a route out because a lot of my self-worth was tied up in running.&lt;/p&gt;
</content:encoded></item><item><title>Weeknotes: 2020-10-25</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sun, 25 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;m super consistent with writing these, eh?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There&apos;s been a glut of televised cycling with the condensed racing calendar, so we&apos;ve had the Ronde van Vlaanderen, the climax of the Giro d&apos;Italia, and the start of La Vuelta in the space of the past week.&lt;/li&gt;
&lt;li&gt;That helps, because I&apos;ve been feeling rather sorry for myself when it comes to exercise. I&apos;ve been suffering from &quot;something&quot; for nigh-on a month. Whatever it is, it&apos;s taking a long time to kick and is making activity difficult.&lt;/li&gt;
&lt;li&gt;Really enjoyed reading &lt;a href=&quot;https://www.goodreads.com/book/show/54501445-mismatch&quot;&gt;Kat Holmes&apos; &lt;em&gt;Mismatch&lt;/em&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Finished watching &lt;a href=&quot;https://www.netflix.com/title/81237854&quot;&gt;The Haunting of Bly Manor on Netflix&lt;/a&gt;. Not as creepy as Hill House.&lt;/li&gt;
&lt;li&gt;It&apos;s been a week for Australian film: watched Justin Kurzel&apos;s adapatation of &lt;em&gt;The True History of the Ned Kelly gang&lt;/em&gt;, and Jennifer Kent&apos;s &lt;em&gt;The Nightingale&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>inaccessible.css</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sat, 19 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I made a stylesheet to drop into your project in order to highlight #a11y flaws: it&apos;ll stick an obnoxious outline on any offending elements. I&apos;m sure there are plenty more selectors to create, so PRs are more than welcome.&lt;/p&gt;
</content:encoded></item><item><title>Styling visited links</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Thu, 06 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;TIL: visited links can only be styled with a small subset of styles. Surprisingly, text-decoration is not amongst them.&lt;/p&gt;
</content:encoded></item><item><title>Creating Github Releases With Lerna</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sat, 01 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Reducing the number of manual steps needed to get code live is a good thing. This is how I create Github releases from the CI process.&lt;/p&gt;
&lt;h2&gt;Lerna&lt;/h2&gt;
&lt;p&gt;Lerna is a tool to manage a monorepo. It can automate releases on Github when the version of a package changes, which is one less task to perform manually.&lt;/p&gt;
&lt;h2&gt;Circle CI&lt;/h2&gt;
&lt;p&gt;Circle is a continuous integration solution. In this scenario, Circle is configured to run the test suite for each component after a commit. Once the tests pass, Lerna will increment the version number of the component, using the &lt;a href=&quot;https://www.conventionalcommits.org/en/v1.0.0/&quot;&gt;Conventional Commits specification&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Creating a release&lt;/h2&gt;
&lt;h3&gt;Circle Config&lt;/h3&gt;
&lt;p&gt;Here is a workflow definition with two discrete jobs. The first runs the tests; the second runs &lt;code&gt;lerna version&lt;/code&gt; against the desired components.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;version: 2.1
orbs:
  node: circleci/node@1.1.6
jobs:
  build-and-test:
    executor:
      name: node/default
    docker:
      - image: circleci/node:latest-browsers
    resource_class: small
    steps:
      - checkout
      - node/with-cache:
          steps:
            - run: npm install
            - run: npm test

release:
    docker:
      - image: circleci/node
    resource_class: small
    steps:
      - checkout
      - node/with-cache:
          steps:
            - add_ssh_keys:
                fingerprints:
                  - &quot;F1:NG:3R:PR:1N:T&quot;
            - run: npx lerna bootstrap --hoist --ci
            - run: npx lerna version --no-private --conventional-commits --create-release github --yes

workflows:
    build-and-test:
      jobs:
        - build-and-test
        - release:
            filters:
              branches:
                only: main
            requires:
              - build-and-test
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All the interesting work is contained within this instruction:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npx lerna version --no-private --conventional-commits --create-release github --yes
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lerna will increment the version of public packages using the Conventional Commits spec, before creating a Github release, and it won&apos;t need any prompting to do so.&lt;/p&gt;
&lt;h3&gt;Creating a deploy key&lt;/h3&gt;
&lt;p&gt;In order to modify the project repository, Circle will need an SSH key with write access: a &quot;deploy key&quot;. The public key is added from the project&apos;s &lt;code&gt;settings/keys&lt;/code&gt; screen on Github; the private half is added to Circle via Project Settings -&amp;gt; SSH Keys. You&apos;ll know if you got it right, because you&apos;ll avoid the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lerna ERR! lerna ERROR: The key you are authenticating with has been marked as read only.
lerna ERR! lerna fatal: Could not read from remote repository.
lerna ERR! lerna
lerna ERR! lerna Please make sure you have the correct access rights
lerna ERR! lerna and the repository exists.
lerna ERR! lerna
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Adding an access token&lt;/h3&gt;
&lt;p&gt;While the machine might be authenticated, Lerna will need to identify itself as working with the correct permissions. Thus the addition of &lt;code&gt;GH_TOKEN&lt;/code&gt; available to it. A new access token can be created from within &lt;a href=&quot;https://github.com/settings/tokens/&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Publishing the release&lt;/h2&gt;
&lt;p&gt;When a build goes green on the main branch, a &lt;a href=&quot;https://github.com/danielmatthew/accessible-web-components/releases&quot;&gt;new release will appear automatically on Github&lt;/a&gt;. The release notes will be filled automatically, and the changelog for each package will have been updated at the same time. There does appear to be a slight bug with the version number. My understanding is that &lt;code&gt;fix&lt;/code&gt; commits will increment the patch number when using semantic versioning, but the component has increased from &lt;code&gt;0.2.0&lt;/code&gt; to &lt;code&gt;0.2.1&lt;/code&gt; with a single &lt;code&gt;chore&lt;/code&gt; commit…&lt;/p&gt;
&lt;h2&gt;Next steps&lt;/h2&gt;
&lt;p&gt;Lerna&apos;s &lt;code&gt;publish&lt;/code&gt; command works the same as &lt;code&gt;version&lt;/code&gt;, but automates publishing to NPM.&lt;/p&gt;
</content:encoded></item><item><title>Weeknotes: 2020-08-01</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sat, 01 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;I spent a day off watching a series of talks from &lt;a href=&quot;https://www.youtube.com/c/JAMstackConf&quot;&gt;JAMstack Conf&lt;/a&gt;, before getting wet and wild out on the bike: that was not a pleasurable experience.&lt;/li&gt;
&lt;li&gt;This week I have been getting to grips with Figma. DesignLab&apos;s &lt;a href=&quot;https://trydesignlab.com/figma-101-course/introduction-to-figma/&quot;&gt;Introduction to Figma&lt;/a&gt;, alongside &lt;a href=&quot;https://www.youtube.com/watch?v=p0H4NW5ILto&quot;&gt;Sketch Together&apos;s video content&lt;/a&gt; have been useful.&lt;/li&gt;
&lt;li&gt;This resulted in the illustration at the beginning of the page, inspired by &lt;a href=&quot;https://www.risd.edu&quot;&gt;RISD&apos;s&lt;/a&gt; work for the 2006 Winter Olympics. I wanted to play with animation, and SVG will make that easier to achieve.&lt;/li&gt;
&lt;li&gt;At Talis, we&apos;ve been working hard to improve the interactive states of our interface elements &lt;a href=&quot;https://www.w3.org/WAI/WCAG21/Understanding/non-text-contrast&quot;&gt;to correct issues with contrast&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;I played my first-ever game of Fortnite on Switch, and took the Victory Royale. I think I&apos;ve peaked for 2020.&lt;/li&gt;
&lt;li&gt;Rode RLSCC&apos;s bash again this week and beat last week&apos;s time by a couple of minutes. I&apos;ve started adding some run training back into the schedule to maintain that fitness.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>CircleCI Node Images with Browsers</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Mon, 27 Jul 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Building a Node project with Circle and want access to browser binaries? The default &lt;code&gt;circleci/node&lt;/code&gt; image doesn&apos;t come with them installed, which threw a spanner in the works when attempting to run some tests. Circle maintain an exhaustive list of images one can use: any Node version appended with &lt;code&gt;-browsers&lt;/code&gt; will come installed with Chrome, Firefox, OpenJDK v11, and Geckodriver.&lt;/p&gt;
</content:encoded></item><item><title>Using continuous integration to build, test, and publish with Netlify</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sun, 26 Jul 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Last week, Chris Coyier &lt;a href=&quot;https://css-tricks.com/develop-preview-test/&quot;&gt;published a post on CSS Tricks which covered an approach to the simplest of testing set-ups&lt;/a&gt;: ensuring the website loads and displays some content. A &quot;smoke test&quot;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Just one super basic integration goes a long way. If your site spins up, returns a page, and renders stuff on it that you expect, a lot is going right.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I&apos;ve been meaning to add some level of test coverage to this website for a while now. I&apos;d been wanting to run builds against Lighthouse CI to ensure that anything that breaks the performance budget or fails one of the automated accessibility tests doesn&apos;t make it into production.&lt;/p&gt;
&lt;p&gt;Thanks to &lt;a href=&quot;https://docs.cypress.io/guides/getting-started/writing-your-first-test.html#Step-1-Visit-a-page&quot;&gt;some well-written documentation&lt;/a&gt;, it was easy to get Cypress installed and configured to test against my local development server.&lt;/p&gt;
&lt;h2&gt;The test&lt;/h2&gt;
&lt;p&gt;Per the docs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/// &amp;lt;reference types=&quot;Cypress&quot; /&amp;gt;

describe(&apos;Home page&apos;, () =&amp;gt; {
  it(&apos;successfully loads&apos;, () =&amp;gt; {
    cy.visit(&apos;/&apos;);

    cy.get(&apos;h1&apos;).should(&apos;contain&apos;, &apos;Dan Matthew&apos;);
  });
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cypress will look for a configuration file in the directory, and it&apos;s in this &lt;code&gt;cypress.json&lt;/code&gt; where a &lt;code&gt;baseUrl&lt;/code&gt; can be defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;baseUrl&quot;: &quot;http://localhost:8080&quot;,
  &quot;ignoreTestFiles&quot;: &quot;cypress/integration/examples/*.js&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each call to &lt;code&gt;.visit()&lt;/code&gt; will use the &lt;code&gt;baseUrl&lt;/code&gt; as its root. While it&apos;s set to &lt;code&gt;localhost&lt;/code&gt; here, we&apos;ll want to change it later on, for reasons that will become apparent.&lt;/p&gt;
&lt;h2&gt;Testing against a local web server&lt;/h2&gt;
&lt;p&gt;Netlify expects tests to be run elsewhere, since every commit to the linked VCS causes a build and publish. I&apos;d &lt;a href=&quot;/notes/deploying-with-travis/&quot;&gt;used Travis CI previously&lt;/a&gt;, so thought I&apos;d pick up where I left off. I wanted it to operate like my local development environment, where I&apos;d run &lt;code&gt;npx eleventy serve&lt;/code&gt; and then spawn Cypress in the background: &lt;code&gt;npm run serve:ci &amp;amp;&amp;amp; npm test&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This &lt;a href=&quot;https://travis-ci.com/github/danielmatthew/website/builds/176151683&quot;&gt;did not work as anticipated&lt;/a&gt;. &lt;code&gt;serve&lt;/code&gt; was never going to end, and Cypress was never going to be started 😂. The Cypress docs even warned against this, and do &lt;a href=&quot;https://docs.cypress.io/guides/guides/continuous-integration.html#Solutions&quot;&gt;cover a number of solutions&lt;/a&gt;, but pig-headedly I didn&apos;t want to install yet another package.&lt;/p&gt;
&lt;p&gt;Time to rethink.&lt;/p&gt;
&lt;h2&gt;Building a Deploy Preview with the Netlify CLI&lt;/h2&gt;
&lt;p&gt;With Netlify in control of builds, I&apos;d configured it to use a couple of &lt;a href=&quot;https://docs.netlify.com/configure-builds/build-plugins/&quot;&gt;Build Plugins&lt;/a&gt;. I didn&apos;t realise that these can be installed locally as devDependencies and they&apos;ll operate on the generated site just as they do on live. This meant using the CLI became a plausible alternative – just as soon as automatic builds were turned off.&lt;/p&gt;
&lt;p&gt;This setting can be found at https://app.netlify.com/sites/{YOUR_SITE_NAME}/settings/deploys. Look for &quot;Build Settings&quot;, and then &quot;Stop builds&quot;. The following warning is displayed:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Netlify will never build your site. You can build locally via the CLI and then publish new deploys manually via the CLI or the API.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now the onus is on the developer 😬. In this case, we&apos;ll get Travis to perform this task for us. With the simplest of configurations each commit will build the site, but only those pushed to &lt;code&gt;main&lt;/code&gt; will trigger a deploy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;language: node_js
node_js:
  - &quot;node&quot;
cache: npm
script:
  - npx netlify build
deploy:
  cleanup: false
  provider: script
  script: npx netlify deploy
  on:
    branch: main
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The boffins out there will know that this implementation is naive: it doesn&apos;t run any tests; and it&apos;s going to give me a green build each time, which is nice for the ego, less so for confirming that the site renders. That &lt;code&gt;build&lt;/code&gt; script might have only succeeded in pumping out a broken site if something&apos;s gone screwy in development.&lt;/p&gt;
&lt;h2&gt;Testing a Deploy Preview with Cypress&lt;/h2&gt;
&lt;p&gt;One of the neat things about Netlify is that each branch will get built and published with a unique URL. This makes it easy to visit the preview in a browser and ensure it works as expected. How can we access that URL and provide it to Cypress?&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://cli.netlify.com/commands/deploy&quot;&gt;documentation for &lt;code&gt;deploy&lt;/code&gt;&lt;/a&gt; offers a hint:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;alias (option) - Specifies the alias for deployment. Useful for creating predictable deployment URL&apos;s&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Very useful indeed, Netlify. But what to use as our alias? I don&apos;t know how long branch deploys exist, so it didn&apos;t seem sensible to use a hard-coded string. It turns out that Travis surfaces a number of environment variables: I opted for &lt;code&gt;$TRAVIS_JOB_ID&lt;/code&gt; because it seemed like it&apos;s probably going to be unique…&lt;/p&gt;
&lt;p&gt;First off however, the branch build is going to have to be deployed: &lt;code&gt;npx netlify deploy --alias $TRAVIS_JOB_ID&lt;/code&gt;. Then Cypress is invoked: &lt;code&gt;npx cypress run --env host=$TRAVIS_JOB_ID--danmatthew.netlify.app --spec \&quot;cypress/integration/home_page.spec.js\&quot; --headless&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;--env&lt;/code&gt; flag in the &lt;code&gt;cypress run&lt;/code&gt; command overrides the &lt;code&gt;baseUrl&lt;/code&gt; from &lt;code&gt;cypress.json&lt;/code&gt; and ensures we are testing the latest deploy.&lt;/p&gt;
&lt;p&gt;In the logs of previous builds I&apos;d seen:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If everything looks good on your draft URL, deploy it to your main site URL with the --prod flag.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Alrighty, then!&lt;/p&gt;
&lt;p&gt;🚨 Uh-oh. Cypress crashed: &lt;a href=&quot;https://github.com/cypress-io/cypress/issues/3957&quot;&gt;apparently the spec flag doesn&apos;t play nicely with CI environments&lt;/a&gt;. Ah well, don&apos;t have to worry about running all the tests if there&apos;s only one test…&lt;/p&gt;
&lt;p&gt;With that resolved, the build failed again. &lt;code&gt;--env host&lt;/code&gt; is completely the wrong flag, and to set the baseUrl from the environment is done thusly:
&lt;code&gt;CYPRESS_BASE_URL=https://$TRAVIS_JOB_ID--danmatthew.netlify.app npx cypress run --headless --config-file false&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;With that done, our config looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;os: linux
dist: xenial
language: node_js
node_js:
  - &quot;node&quot;
cache:
  npm: true
  directories:
    - ~/.cache
script:
  - npx netlify build
  - npx netlify deploy --alias $TRAVIS_JOB_ID
  - CYPRESS_BASE_URL=https://$TRAVIS_JOB_ID--danmatthew.netlify.app npx cypress run --headless --config-file false
deploy:
  cleanup: false
  provider: script
  script: npx netlify deploy --prod
  on:
    branch: main
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;…and we get a succesful build.&lt;/p&gt;
&lt;h2&gt;Use the Netlify provider, stupid&lt;/h2&gt;
&lt;p&gt;There&apos;s me, using multiple steps under the &lt;code&gt;script&lt;/code&gt; phase, when Travis provides its own deploy step for Netlify projects.&lt;/p&gt;
&lt;p&gt;Perhaps the &lt;a href=&quot;https://docs.travis-ci.com/user/deployment-v2/#supported-providers&quot;&gt;documentation needs to be clearer&lt;/a&gt; because it references &lt;a href=&quot;https://app.netlify.com/drop&quot;&gt;Netlify Drop&lt;/a&gt;, which at first glance looks like a different mechanism entirely. When I looked closer at the required arguments, I realised they were identical to the CLI commands I was using earlier.&lt;/p&gt;
&lt;p&gt;Using the provider means the deploy stage of our &lt;code&gt;travis.yml&lt;/code&gt; takes this form:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;deploy:
  cleanup: false
  provider: netlify
  site: $NETLIFY_SITE_ID
  auth: $NETLIFY_AUTH_TOKEN
  prod: true
  edge: true
  on:
    branch: main
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There we go: we&apos;ve got a CI tool taking care of testing our builds. If the tests pass, the site will be set live. If not, we can go visit the deploy preview and see what&apos;s gone wrong.&lt;/p&gt;
&lt;h2&gt;Bonus: Automating Github releases&lt;/h2&gt;
&lt;p&gt;Doing this isn&apos;t strictly necessary, but I wanted to play with the &lt;a href=&quot;https://semantic-release.gitbook.io/semantic-release/&quot;&gt;semantic-release&lt;/a&gt; package and see what it could do. I had intended to incorporate it into the Accessible Web Components project, but I discovered Lerna could perform both actions for me, which rendered it superfluous.&lt;/p&gt;
&lt;p&gt;To &lt;a href=&quot;https://github.com/danielmatthew/website/releases&quot;&gt;publish a new release on Github&lt;/a&gt;, we can add a &lt;code&gt;run&lt;/code&gt; property to the deploy stage, or make it a little more obvious with the &lt;code&gt;after_deploy&lt;/code&gt; stage:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if tag IS blank
after_deploy:
  - npx semantic-release
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The conditional there is to prevent yet another build when semantic-release creates the tag. It took me a while to figure out why I was seeing three builds…&lt;/p&gt;
&lt;p&gt;Like many other tools, semantic-release supports many configuration options. In this case, I didn&apos;t want the package being pushed to npm, so it was necessary to override the default plugins with the following in my &lt;code&gt;releaserc&lt;/code&gt; file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;branches&quot;: &quot;main&quot;,
  &quot;plugins&quot;: [
    &quot;@semantic-release/commit-analyzer&quot;,
    &quot;@semantic-release/release-notes-generator&quot;,
    &quot;@semantic-release/github&quot;
  ]
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Added orientation support to tabs component</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sat, 25 Jul 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;With the release of &lt;a href=&quot;https://github.com/danielmatthew/accessible-web-components/releases&quot;&gt;v0.2.0&lt;/a&gt;, I&apos;ve added support for changing the orientation of the &lt;a href=&quot;https://danmatthew.co.uk/notes/accessible-web-components-tabs/&quot;&gt;tabs component&lt;/a&gt;. The presence of a boolean &lt;code&gt;vertical&lt;/code&gt; attribute will set &lt;code&gt;aria-orientation=&apos;vertical&apos;&lt;/code&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Accessible Web Components: Tabs</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sun, 12 Jul 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;The web component&lt;/h2&gt;
&lt;p&gt;I&apos;ve finally published my first NPM package: a &lt;a href=&quot;https://www.npmjs.com/package/@accessible-web-components/tabs&quot;&gt;web component to represent a tabbed interface&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://v505e.csb.app&quot;&gt;View the demo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rock and roll.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It might not be the most fashionable of side projects - or technologies - but I felt that a wrapping up the desired behaviour of a tabbed interface into a bog-standard web component might do some good. If it saves another developer spending an afternoon doing the same thing, or makes the life of the user a little easier, then I&apos;d consider that worthwhile.&lt;/p&gt;
&lt;p&gt;The component follows the behaviours specified in the &lt;a href=&quot;https://www.w3.org/TR/wai-aria-practices-1.2/#tabpanel&quot;&gt;WAI-ARIA Authoring Practices document&lt;/a&gt;. It can be styled with CSS to suit its environment, and will display as a single column should there be a hitch. Alas, web components &lt;em&gt;do&lt;/em&gt; require JavaScript in order to be registered, and it certainly requires JS in order to enhance the markup with the required ARIA attributes.&lt;/p&gt;
&lt;h3&gt;Usage&lt;/h3&gt;
&lt;h4&gt;JavaScript&lt;/h4&gt;
&lt;p&gt;Import the three components, and tell the browser about them:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { AwcTabs, AwcTab, AwcPanel } from &quot;@accessible-web-components/tabs&quot;;

window.customElements.define(&quot;awc-tabs&quot;, AwcTabs);
window.customElements.define(&quot;awc-tab&quot;, AwcTab);
window.customElements.define(&quot;awc-panel&quot;, AwcPanel);
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;HTML&lt;/h4&gt;
&lt;p&gt;It takes the following structure.  Add as many tabs and panels as are required.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;awc-tabs&amp;gt;
  &amp;lt;awc-tab role=&quot;heading&quot; slot=&quot;tab&quot;&amp;gt;Tab 1&amp;lt;/awc-tab&amp;gt;
  &amp;lt;awc-panel role=&quot;region&quot; slot=&quot;panel&quot;&amp;gt;
    &amp;lt;h2&amp;gt;My first tab&amp;lt;/h2&amp;gt;
    &amp;lt;p&amp;gt;Here is some text…&amp;lt;/p&amp;gt;
    &amp;lt;ul&amp;gt;
      &amp;lt;li&amp;gt;…and a list&amp;lt;/p&amp;gt;
    &amp;lt;/ul&amp;gt;

    &amp;lt;button type=&quot;button&quot;&amp;gt;I am a focusable element within the tab&amp;lt;/button&amp;gt;
  &amp;lt;/awc-panel&amp;gt;
  &amp;lt;awc-tab role=&quot;heading&quot; slot=&quot;tab&quot;&amp;gt;Tab 2&amp;lt;/awc-tab&amp;gt;
  &amp;lt;awc-panel role=&quot;region&quot; slot=&quot;panel&quot;&amp;gt;Content 2&amp;lt;/awc-panel&amp;gt;
  &amp;lt;awc-tab role=&quot;heading&quot; slot=&quot;tab&quot;&amp;gt;Tab 3&amp;lt;/awc-tab&amp;gt;
  &amp;lt;awc-panel role=&quot;region&quot; slot=&quot;panel&quot;&amp;gt;Content 3&amp;lt;/awc-panel&amp;gt;
&amp;lt;/awc-tabs&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To the 67 brave souls who have downloaded it since yesterday morning: &lt;s&gt;you are brave&lt;/s&gt; thanks &lt;s&gt;for being my guinea pigs&lt;/s&gt;!. I&apos;ve put the package level as a pre-release, at &lt;code&gt;0.0.0-alpha.3&lt;/code&gt;. I don&apos;t think it&apos;s going to break your project, but there are a few more features I want to include before it goes to &lt;code&gt;0.0.1&lt;/code&gt;. I guess it would help if I wrote some tests, and I can certainly improve the documentation.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Side projects, eh? Gotta love &apos;em.&lt;/p&gt;
&lt;p&gt;Four years ago, I made the first commit in a Github repository called &lt;a href=&quot;https://github.com/danielmatthew/accessible-web-components/commit/3c7089a62c9459f7be782ca4a0985f54ef0b330e&quot;&gt;Accessible Web Components&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The following year, in March 2017, I gave a &lt;a href=&quot;https://pusher.com/sessions/meetup/hydrahack/web-components-and-me&quot;&gt;talk at HydraHack&lt;/a&gt; about my plan to create a whole series of components. As a fellow speaker that night, I&apos;m hopeful &lt;a href=&quot;https://twitter.com/nivims&quot;&gt;Nivi&apos;s&lt;/a&gt; offer of feedback still stands!&lt;/p&gt;
&lt;p&gt;The first component – &lt;a href=&quot;https://www.w3.org/TR/wai-aria-practices-1.2/#alert&quot;&gt;an alert message&lt;/a&gt; – was the &quot;Hello world!&quot; I used to play with various frameworks. It moved across Polymer, Polymer v2, Stencil, a custom element, Vue, and finally LitElement. The &lt;a href=&quot;https://github.com/danielmatthew/accessible-web-components/tree/master/alert&quot;&gt;Polymer version still lives in the repository&lt;/a&gt;, complete with its use of &lt;a href=&quot;https://www.w3.org/TR/html-imports/&quot;&gt;HTML Imports&lt;/a&gt;. It&apos;s a shame that particular spec got shot down: it feels awkward defining component templates inside the JavaScript.&lt;/p&gt;
&lt;p&gt;Then, with the plan to create a whole series of these components, I thought a monorepo would be a good idea. I installed &lt;a href=&quot;https://github.com/lerna/lerna/&quot;&gt;Lerna&lt;/a&gt;, and spent way too much time getting its configuration &lt;em&gt;just&lt;/em&gt; so.&lt;/p&gt;
&lt;p&gt;With Lerna just about sussed, I turned to the guidelines suggested by the &lt;a href=&quot;https://open-wc.org/index.html&quot;&gt;open-wc&lt;/a&gt; project when it comes to publishing. I&apos;ve been using their linting and commit standards for some time, but the project has really been evolving: I&apos;ve used their generator to scaffold the next component in the series.&lt;/p&gt;
&lt;p&gt;Finally, it was time to publish. Again, it took too long figuring out how to create an organisation on NPM, such that the package name could be in the format: &lt;code&gt;@accessible-web-components/&amp;lt;blah&amp;gt;&lt;/code&gt;. While it sounds trivial, I thought it worth keeping this and future components grouped together right from the start.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Despite it being a fairly trivial piece of software, I&apos;m excited yet nervous at the thought of third parties using something I&apos;ve written. I&apos;m looking forward to constructive criticism to help shape it and make the web a richer, and more accessible platform.&lt;/p&gt;
</content:encoded></item><item><title>Goodbye Gatsby; Hello Eleventy!</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sun, 05 Jul 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hello there! It&apos;s been a good while since anything new content has appeared on this website, and while I&apos;ve tinkered with the splash page on occasion, it&apos;s not displayed anything more than my name in a &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Some thoughts on &apos;v3&apos;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I&apos;ve gotten rid of &lt;a href=&quot;https://www.gatsbyjs.org&quot;&gt;Gatsby&lt;/a&gt;. It wasn&apos;t long after I upgraded to v2 that I noticed the site no longer rendered if JS was disabled; something I had appreciated in v1.&lt;/li&gt;
&lt;li&gt;The site now runs on &lt;a href=&quot;https://www.11ty.dev&quot;&gt;Eleventy&lt;/a&gt;, and uses &lt;a href=&quot;https://twitter.com/hankchizljaw&quot;&gt;Andy Bell&apos;s&lt;/a&gt; &lt;a href=&quot;https://hylia.website&quot;&gt;Hylia Starter Kit&lt;/a&gt; to get me going. I expect to be hacking away at it over the next week.&lt;/li&gt;
&lt;li&gt;I wanted to place to display my photos. Yes, I know there&apos;s only a single photo being displayed. It&apos;s a shot of the &lt;a href=&quot;https://en.wikipedia.org/wiki/Molino_Stucky&quot;&gt;Molino Stucky&lt;/a&gt; in Venice. I&apos;m using &lt;a href=&quot;https://cloudinary.com&quot;&gt;Cloudinary&lt;/a&gt; to host the image and apply transforms based on device DPI, orientation, and screen width.&lt;/li&gt;
&lt;li&gt;I want the site to feel fast. It&apos;s preconnecting to third-party origins (Cloudinary, Google Fonts, Speedcurve), and preloading the most important assets. I&apos;m inlining the first blast of CSS, then &lt;a href=&quot;https://www.filamentgroup.com/lab/load-css-simpler/&quot;&gt;loading the rest asynchronously&lt;/a&gt;. &lt;a href=&quot;https://www.webpagetest.org/result/200703_BQ_692dc3c1922a505eb90b3a3ca14c76a0/1/details/#waterfall_view_step1&quot;&gt;Benchmarking the site on Web Page Test&lt;/a&gt;, it surprised me &lt;a href=&quot;https://www.webpagetest.org/result/200703_23_f52e3ba3fbeae8474b248fe75200090d/1/details/#waterfall_view_step1&quot;&gt;how much slower the site performed when this wasn&apos;t done&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Speedcurve was mentioned above. Thought I&apos;d have a play and see how the site performs over time. Additionally, I only just found out that one doesn&apos;t need to use Chrome to play with Lighthouse: &lt;a href=&quot;https://adactio.com/journal/16523&quot;&gt;Jeremy Keith&lt;/a&gt; put together a bookmarklet to send the current document over to the &lt;a href=&quot;https://googlechrome.github.io/lighthouse/viewer/&quot;&gt;Lighthouse viewer&lt;/a&gt;. In the same vein, &lt;a href=&quot;https://lighthouse-metrics.com&quot;&gt;Lighthouse Metrics&lt;/a&gt; seems a neat way to keep tabs on performance.&lt;/li&gt;
&lt;li&gt;I want to begin publishing accessibility audits of some of my favourite sites. At &lt;a href=&quot;https://talis.com&quot;&gt;Talis&lt;/a&gt;, I&apos;ve been spending a good chunk of time reviewing and improving the accessibility of our products ahead of September&apos;s &amp;lt;abbr title=&quot;The Public Sector Bodies (Websites and Mobile Applications) (No. 2) Accessibility Regulations 2018&quot;&amp;gt;&lt;a href=&quot;http://www.legislation.gov.uk/uksi/2018/952/contents/made&quot;&gt;PSBAR&lt;/a&gt;&amp;lt;/abbr&amp;gt; deadline. While I&apos;ve been championing accessibility internally since I started, it has felt like a struggle to get cross-functional buy-in until recently.&lt;/li&gt;
&lt;li&gt;When not working on improving our accessibility, the recent focus has been on relaunching our website. I am extremely grateful for &lt;a href=&quot;http://timber.github.io&quot;&gt;Timber&lt;/a&gt;, which made working with WordPress a much more pleasurable experience. Something that irks me is that I tried hard to keep the site snappy, but as third-party plugins have been enabled to support desired functionality - &quot;buy, don&apos;t build&quot; is the mantra - more and more external resources get pulled in. Even the WordPress core functionality dumps a load of crap in, which has to be manually disabled via the theme&apos;s &lt;code&gt;functions.php&lt;/code&gt;. &lt;em&gt;Le sigh.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Preload, Prefetch, and Preconnect</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sat, 09 Dec 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Working on a Polymer project recently, I got to experiment with serving the content from Firebase Hosting, which now &lt;a href=&quot;https://firebase.googleblog.com/2016/09/http2-comes-to-firebase-hosting.html&quot;&gt;offers support for HTTP/2 and Server Push&lt;/a&gt;. Server Push allows content to be delivered speculatively: content is delivered whether or not the user has it already, and in some cases it might not be required at all.&lt;/p&gt;
&lt;h2&gt;Preload&lt;/h2&gt;
&lt;p&gt;To take advantage of this ability though, I needed to declare the assets I wanted to be pushed down. In my &lt;code&gt;firebase.json&lt;/code&gt; file I declared:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;headers&quot;: [{
  &quot;key&quot;: &quot;Link&quot;,
  &quot;value&quot;: &quot;&amp;lt;my-app.js&amp;gt;;rel=preload;as=script&quot;
}]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which instructed Firebase to serve the file with the appropriate &lt;code&gt;Link&lt;/code&gt; header. It&apos;s possible to do the same when referencing resources via a &lt;a href=&quot;https://html.spec.whatwg.org/multipage/links.html#external-resource-link&quot;&gt;&lt;code&gt;link&lt;/code&gt;&lt;/a&gt; element too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;link rel=&quot;preload&quot; href=&quot;foo.js&quot; as=&quot;script&quot;&amp;gt;
&amp;lt;link rel=&quot;preload&quot; href=&quot;bar.css&quot; as=&quot;style&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you inspect this site, you&apos;ll see that Gatsby does this for me in production. Coupled with HTTP/2 on Cloudfront, visitors should experience a fairly snappy load. Essentially, all assets for a page are transferred in a single round trip, though it does mean if you&apos;re a repeat visitor (hi mum!), I&apos;m probably using bandwidth unneccessarily. &lt;a href=&quot;https://medium.com/reloading/preload-prefetch-and-priorities-in-chrome-776165961bbf&quot;&gt;Addy Osmani&lt;/a&gt; suggests that:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Use Push when you know the precise loading order for resources and have a service worker to intercept requests that would cause cached resources to be pushed again.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I guess that&apos;s next on my to-do list with &lt;a href=&quot;https://github.com/GoogleChrome/workbox&quot;&gt;Workbox&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Prefetch&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;link rel=&quot;prefetch&quot; href=&quot;/font.woff2&quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Prefetch is another resource hint developers can take advantage of. Prefetch tells the browser that a resource will be needed on the next page, or navigation. Resources marked as such will be treated as a much lower-priority fetch than those with &lt;code&gt;preload&lt;/code&gt;, and it&apos;s up to the browser to make the call as to whether it will load it or not. I&apos;ve seen a pattern where a webfont is set to be pre-fetched so that it doesn&apos;t block rendering on the first load, but is available right away when a visitor navigates to a new page.&lt;/p&gt;
&lt;h2&gt;Preconnect&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;link rel=&quot;preconnect&quot; href=&quot;/page2&quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Preconnect can be used to &apos;warm-up&apos; the connection to a resource in order to &lt;a href=&quot;https://www.igvita.com/2015/08/17/eliminating-roundtrips-with-preconnect/&quot;&gt;&quot;eliminate the costly DNS, TCP, and TLS roundtrips from the critical path of the actual request&quot;&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;All of these techniques can be used in an attempt to improve the performance of your site but it&apos;s a trade-off between second-guessing the behaviour of your guests, while not exhausting their bandwidth unneccessarily – especially for those on metered connections.&lt;/p&gt;
&lt;h3&gt;Sources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;https://caniuse.com/#search=pre&lt;/li&gt;
&lt;li&gt;https://www.w3.org/TR/resource-hints/&lt;/li&gt;
&lt;li&gt;https://www.w3.org/TR/preload/&lt;/li&gt;
&lt;li&gt;https://medium.com/reloading/preload-prefetch-and-priorities-in-chrome-776165961bbf&lt;/li&gt;
&lt;li&gt;https://css-tricks.com/prefetching-preloading-prebrowsing/&lt;/li&gt;
&lt;li&gt;https://blog.cloudflare.com/announcing-support-for-http-2-server-push-2/&lt;/li&gt;
&lt;li&gt;https://firebase.googleblog.com/2016/09/http2-comes-to-firebase-hosting.html&lt;/li&gt;
&lt;li&gt;http://www.bramstein.com/writing/preload-hints-for-web-fonts.html&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Automating the Build Process with Travis-CI</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Mon, 20 Nov 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Updated 9th December to illustrate latest iteration of Travis.yml&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Before I ported this site over to &lt;a href=&quot;https://www.gatsbyjs.org&quot;&gt;Gatsby&lt;/a&gt;, it was powered by good old &lt;a href=&quot;https://github.com/jekyll/jekyll&quot;&gt;Jekyll&lt;/a&gt;. I&apos;d make an edit, run &lt;code&gt;jekyll build&lt;/code&gt;, then push the output to S3 with &lt;a href=&quot;https://github.com/laurilehmijoki/s3_website&quot;&gt;&lt;code&gt;s3_website&lt;/code&gt;&lt;/a&gt;. Not exactly onerous, but I noticed that I&apos;d be drafting posts, or updating the structure of the site and then not pushing them live in a timely manner. &lt;em&gt;(And what do you know, it&apos;s happened again! – Ed., December 2nd)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Cue a Continuous Integration (CI) solution – although it took me many attempts to get it right. And by right, I mean it at least:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;builds the site&lt;/li&gt;
&lt;li&gt;deploys to S3&lt;/li&gt;
&lt;li&gt;invalidates the CloudFront distribution.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Attempt #1: Use the default S3 provider&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.travis-ci.com&quot;&gt;Travis&apos;&lt;/a&gt; documentation is pretty, pretty, pretty good. I think you could just about get away with this, if you&apos;re happy to serve straight from the S3 bucket:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;language: node_js
node_js:
 - &quot;8&quot;
script:
 - yarn build
deploy:
  provider: s3
  access_key_id: $AWS_ACCESS_KEY_ID
  secret_access_key: $AWS_SECRET_ACCESS_KEY
  bucket: danmatthew.co.uk
  region: $AWS_DEFAULT_REGION
  # Prevent Travis from deleting your built site so it can be uploaded.
  skip_cleanup: true
  # Path to a directory containing your built site.
  local_dir: public
  on:
    branch: master
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because I have both &lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;yarn.lock&lt;/code&gt; in my repository, Travis is smart enough to figure I want to use Yarn to run during the &lt;code&gt;install&lt;/code&gt; phase.&lt;/p&gt;
&lt;p&gt;I like this implementation, but Travis is only concerned with S3 here. I have a Cloudfront distribution sat in front of this bucket in the hope of saving a few pence and making the site feel snappy. Sure, I could manually log in to AWS and invalidate the distribution or do it via the command line, but y&apos;know: let&apos;s automate it.&lt;/p&gt;
&lt;h2&gt;Attempt #2: Use AWS CLI to invalidate the Cloudfront distribution&lt;/h2&gt;
&lt;p&gt;This is where it feels messy, and there are a bunch of extra steps to mess up. AWS CLI is installed via Pip, so this implementation needs to be driven by Python.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;language: python
python: 3.6
sudo: required
dist: trusty
env:
 - TRAVIS_NODE_VERSION=&quot;8&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I had to explicitly specify the version of Python, because the default appeared to be 2.4 and I ran into issues… Java-related, &lt;em&gt;possibly?&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;This is where it starts to be a blend of different tasks, and I&apos;m piecing together instructions from various sources.&lt;/p&gt;
&lt;h3&gt;Install Yarn&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;before_install:
  - curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
  - echo &quot;deb https://dl.yarnpkg.com/debian/ stable main&quot; | sudo tee /etc/apt/sources.list.d/yarn.list
  - sudo apt-get -qq update
  - sudo apt-get -y install yarn
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Install NVM&lt;/h3&gt;
&lt;p&gt;As it&apos;s not provided by default, I need to install Node and NPM in order to install my site&apos;s dependencies and then build it. I figured NVM would be the most sensible approach:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;install:
 - rm -rf ~/.nvm &amp;amp;&amp;amp; git clone https://github.com/creationix/nvm.git ~/.nvm &amp;amp;&amp;amp; (cd ~/.nvm &amp;amp;&amp;amp; git checkout `git describe --abbrev=0 --tags`) &amp;amp;&amp;amp; source ~/.nvm/nvm.sh &amp;amp;&amp;amp; nvm install $TRAVIS_NODE_VERSION
 - pip install awscli
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I discover afterwards that the ugly &lt;code&gt;$TRAVIS_NODE_VERSION&lt;/code&gt; environment variable could have been avoided by &lt;a href=&quot;https://docs.travis-ci.com/user/languages/javascript-with-nodejs/&quot;&gt;specifying the version in the project&apos;s &lt;code&gt;.nvmrc&lt;/code&gt; file&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As the Travis cycle goes &lt;code&gt;install&lt;/code&gt;, &lt;code&gt;script&lt;/code&gt;, &lt;code&gt;deploy&lt;/code&gt;, next up is…&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;before_script:
  npm install
script:
  npm run build
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;(Travis experts – could those commands just have been listed sequentially in the &lt;code&gt;script&lt;/code&gt; block?)&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;Configure S3 bucket&lt;/h3&gt;
&lt;p&gt;We use the same &lt;code&gt;deploy&lt;/code&gt; block as before:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;deploy:
  provider: s3
  access_key_id: $AWS_ACCESS_KEY_ID
  secret_access_key: $AWS_SECRET_ACCESS_KEY
  bucket: danmatthew.co.uk
  region: $AWS_DEFAULT_REGION
  # Prevent Travis from deleting your built site so it can be uploaded.
  skip_cleanup: true
  # Path to a directory containing your built site.
  local_dir: public
  on:
    branch: master
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Blow away the old Cloudfront distribution&lt;/h3&gt;
&lt;p&gt;When this succeeds, we can now use the AWS CLI to ensure that Cloudfront serves the latest version of these files:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;after_deploy:
 # Allow `awscli` to make requests to CloudFront.
 - aws configure set preview.cloudfront true
 # Invalidate every object in the targeted distribution.
 - test $TRAVIS_BRANCH = &quot;master&quot; &amp;amp;&amp;amp; aws cloudfront create-invalidation --distribution-id $CLOUDFRONT_DISTRIBUTION_ID --paths &quot;/*&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Inspecting the bucket, I notice that Travis doesn&apos;t doesn&apos;t sync the files – i.e. only new files are added; old ones are deleted. It might not be an issue in practice, but I quite like keeping my buckets tidy… 😒&lt;/p&gt;
&lt;p&gt;Next!&lt;/p&gt;
&lt;h2&gt;Attempt #3: Use s3_website&lt;/h2&gt;
&lt;p&gt;I mentioned in the intro that when publshing the website from my computer I used the s3_website gem. I know it, it does all the tasks I want it to, and it&apos;s straightforward to configure.&lt;/p&gt;
&lt;p&gt;(Although, I fib: since upgrading to Sierra, I&apos;ve not been &lt;s&gt;able&lt;/s&gt; inclined to deploy since it requires a Java installation which I really don&apos;t want to do. I know, weaksauce.)&lt;/p&gt;
&lt;p&gt;So, we go again! Now, we&apos;re sacking off a Python-based deployment pipe in favour of a Ruby powered process:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;language: ruby
rvm: 2.2
sudo: required
dist: trusty
# Again with the redundant env var
env:
 - TRAVIS_NODE_VERSION=&quot;8&quot;
before_install:
  - curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
  - echo &quot;deb https://dl.yarnpkg.com/debian/ stable main&quot; | sudo tee /etc/apt/sources.list.d/yarn.list
  - sudo apt-get -qq update
  - sudo apt-get -y install yarn
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Install s3_website&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;install:
  - . $HOME/.nvm/nvm.sh
  - nvm install stable
  - nvm use stable
  - gem install s3_website
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Push to S3&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;before_script:
 - yarn
script:
 - yarn build
after_script:
 - test $TRAVIS_BRANCH = &quot;master&quot; &amp;amp;&amp;amp; s3_website push
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Boom. All my &lt;code&gt;s3_website&lt;/code&gt; settings are configured in environment variables and my &lt;code&gt;s3_website.yml&lt;/code&gt; config, so that one line in the &lt;code&gt;after_script&lt;/code&gt; block pushes to the correct bucket and invalidates the Cloudfront distribution.&lt;/p&gt;
&lt;p&gt;Looking back over it, I think I&apos;d be quite happy to sack off the yarn installation and reply on NPM. Again I wonder whether the blocks can be consolidated into one and the commands listed sequentially? I&apos;m not experienced enough with Travis to know what benefits I get from splitting the commands into the different stages, especially since this particular deployment process is not exactly complicated. Perhaps so the process can fail earlier if necessary?&lt;/p&gt;
&lt;h2&gt;Proposed attempt #4: Use AWS CLI for everything&lt;/h2&gt;
&lt;p&gt;I suspect I could probably do all of the above with the AWS CLI, though it will need switching back over to Python again. Woe is me 😩.&lt;/p&gt;
&lt;h2&gt;Attemp #5: Concise&lt;/h2&gt;
&lt;p&gt;…whereupon I decided to sack off Yarn, and after configuring Travis to build PR and branch merges, whitelist the &lt;code&gt;master&lt;/code&gt; branch:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;branches:
  only:
    - master
language: ruby
rvm: 2.2
sudo: required
dist: trusty
cache:
  - npm
install:
  - . $HOME/.nvm/nvm.sh
  - nvm install stable
  - nvm use stable
  - gem install s3_website
before_script:
  - npm install
script:
  - npm run build
after_script:
  - s3_website push
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Hide An Element From A Screenreader</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Wed, 04 Oct 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I recently discovered that it&apos;s not enough to rely on either &lt;code&gt;role=&quot;presentation&quot;&lt;/code&gt; or &lt;code&gt;aria-hidden=&quot;true&quot;&lt;/code&gt; to remove an element from the accessibility tree. Just like CSS quirks, in order to ensure an element is truly hidden from screenreaders across operating systems and browsers, you will want to double-up on the attributes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  &amp;lt;!-- Tested with macOS, Voiceover, and Chrome 63 --&amp;gt;

  &amp;lt;!-- Will be announced --&amp;gt;
  &amp;lt;div&amp;gt;I am a presentation element. I don&apos;t add anything more than a visual flourish.&amp;lt;/div&amp;gt;

  &amp;lt;!-- Will be announced in Voiceover, but not in JAWS --&amp;gt;
  &amp;lt;div role=&quot;presentation&quot;&amp;gt;I am a presentation element. I don&apos;t add anything more than a visual flourish.&amp;lt;/div&amp;gt;

  &amp;lt;!-- Voiceover will ignore this element; JAWS won&apos;t --&amp;gt;
  &amp;lt;div aria-hidden=&quot;true&quot;&amp;gt;I am a presentation element. I don&apos;t add anything more than a visual flourish.&amp;lt;/div&amp;gt;

  &amp;lt;!-- Voiceover will ignore this element --&amp;gt;
  &amp;lt;div aria-hidden=&quot;true&quot; role=&quot;presentation&quot;&amp;gt;I am a presentation element. I don&apos;t add anything more than a visual flourish.&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;http://output.jsbin.com/zaqiboc&quot;&gt;You can view the demo at JSBin&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>npm 101 – Version Ranges</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Mon, 25 Jan 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The following is a snippet from this site&apos;s &lt;code&gt;package.json&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  &quot;devDependencies&quot;: {
    &quot;bower&quot;: &quot;^1.6.5&quot;,
    &quot;grunt&quot;: &quot;~0.4.5&quot;,
    &quot;grunt-contrib-imagemin&quot;: &quot;~0.9.4&quot;,
    &quot;grunt-contrib-sass&quot;: &quot;~0.9.2&quot;,
    &quot;grunt-contrib-watch&quot;: &quot;~0.6.1&quot;,
    &quot;matchdep&quot;: &quot;~0.3.0&quot;
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As per the JSON spec, we&apos;ve got a series of key/value pairs making up the &lt;code&gt;devDependencies&lt;/code&gt; object: the name of the package we want installed for those working on the project, and the version number of that package. However, using &lt;code&gt;npm install &amp;lt;package&amp;gt;&lt;/code&gt; will leave odd extra characters in the generated file. So what do they mean?&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Indicator&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;^&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Caret range&lt;/td&gt;
&lt;td&gt;Allows minor and patch updates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;~&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Tilde range&lt;/td&gt;
&lt;td&gt;Allows patch-level changes if minor version is specified&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;It&apos;s possible to add configure your project to help ensure only a specific version of a package is added. Create a file called &lt;code&gt;.npmrc&lt;/code&gt;, and specify &lt;code&gt;save-exact=true&lt;/code&gt;. As a bonus, you can also added &lt;code&gt;save=true&lt;/code&gt; to make sure that any new installs are added to your projects&apos; &lt;code&gt;package.json&lt;/code&gt;&lt;/p&gt;
</content:encoded></item><item><title>Column Sizing and Captions in Safari</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Mon, 07 Dec 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;p class=&quot;message&quot;&amp;gt;
&amp;lt;em&amp;gt;Updated 25/09/2016:&amp;lt;/em&amp;gt; It still appears to be an issue in Safari 10.0 (macOS Sierra).
&amp;lt;/p&amp;gt;&lt;/p&gt;
&lt;p&gt;A couple of weeks ago, I encountered an odd rendering issue with Safari and column widths. I had planned to write about it, lest the afternoon I spent trying to debug it be of use to anyone who stumbles across this post. Before I could get round to it, lo and behold: I&apos;ve fallen victim to it again! Safari on OSX - both Yosemite and El Capitan - does not like the following scenario:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.col-checkbox {
  width: 28px;
}

.col-content {
  width: auto;
}

.col-action-btn {
  width: 60px;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;table class=&quot;table table-striped&quot;&amp;gt;
 &amp;lt;caption class=&quot;sr-only&quot;&amp;gt;My caption to describe the table&amp;lt;/caption&amp;gt;
  &amp;lt;colgroup&amp;gt;
    &amp;lt;col class=&quot;col-checkbox&quot;&amp;gt;
    &amp;lt;col class=&quot;col-content&quot;&amp;gt;
    &amp;lt;col class=&quot;col-action-btn&quot;&amp;gt;
  &amp;lt;/colgroup&amp;gt;
  &amp;lt;thead&amp;gt;
  &amp;lt;tr&amp;gt;
    &amp;lt;th&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;span&amp;gt;
          &amp;lt;input type=&quot;checkbox&quot;&amp;gt;
        &amp;lt;/span&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/th&amp;gt;
    &amp;lt;th&amp;gt;Two&amp;lt;/th&amp;gt;
    &amp;lt;th&amp;gt;Three&amp;lt;/th&amp;gt;
  &amp;lt;/th&amp;gt;
&amp;lt;/tr&amp;gt;
&amp;lt;/thead&amp;gt;
&amp;lt;tbody&amp;gt;
  &amp;lt;tr&amp;gt;
    &amp;lt;td&amp;gt;&amp;lt;input type=&quot;checkbox&quot;&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;Content&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;Content&amp;lt;/td&amp;gt;
  &amp;lt;/tr&amp;gt;
&amp;lt;/tbody&amp;gt;
&amp;lt;/table&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Safari refuses to apply the column widths specified in the stylesheet, and instead splits the columns based on their content, flagrantly ignoring the authors instructions.&lt;/p&gt;
&lt;p&gt;It seems to be related to the &lt;code&gt;sr-only&lt;/code&gt; class applied to the &lt;code&gt;caption&lt;/code&gt;. This utility class hides the element from those who can see the table contents as a whole, but provides a useful description for those using assistive technologies. Within this class, the &lt;code&gt;position: absolute&lt;/code&gt; declaration used to remove the element from the document flow causes the bug. But strangely, it only happens when applied to &lt;code&gt;caption&lt;/code&gt;: were one to use a &lt;code&gt;span&lt;/code&gt; here, Safari will respect the column widths.&lt;/p&gt;
&lt;p&gt;&amp;lt;!-- &lt;img src=&quot;/public/img/src/safari-table-bug.png&quot; alt=&quot;Screenshot illustrating the table rendering bug in Safari&quot; /&gt; --&amp;gt;&lt;/p&gt;
&lt;p&gt;I&apos;ve not been able to replicate in other desktop browsers: Chrome, Firefox, and Opera split the columns as desired, though Mobile Safari renders the table as per its desktop cousin. The Internet seems to have a scarcity of other reports, which makes me wonder if I have encountered a bug. Or maybe nobody else is combining this class with table captions, column widths - defined using classes, since the &lt;code&gt;width&lt;/code&gt; attribute is obsolete - and Safari. I wonder at what point does it become a Safari / Webkit bug? I have a demo of it available on &lt;a href=&quot;http://jsbin.com/sabisa/embed?html,output&quot;&gt;JSBin&lt;/a&gt; and the various permutations are easily replicable.&lt;/p&gt;
</content:encoded></item><item><title>Truthy and Falsy Values in JavaScript</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sun, 06 Dec 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A common activity when writing code is to check whether a result is true or false before using it. You may have seen the following pattern: used to assign a default value to a parameter, should it be omitted.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function chosenColour(colour) {
  colour = colour || &quot;blue&quot;;

  // Colour related code goes here
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When a non-boolean value is used in this logical OR operation, it is coerced to become one. If the value on the left is empty - or false - the value on the right will be used as a replacement.&lt;/p&gt;
&lt;p&gt;It&apos;s possible to discover how a value will be interpreted by passing it as an argument to &lt;code&gt;Boolean()&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Boolean(3) // true
Boolean(&apos;foo&apos;) // true
Boolean({}) // true
Boolean([]) // true

Boolean(undefined) // false
Boolean(null) // false
Boolean(false) // false
Boolean(&apos;&apos;) // false
Boolean(NaN) // false
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Two forms of IIFE</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Thu, 22 Oct 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;TIL there are two ways of creating an IIFE - and there&apos;s &lt;a href=&quot;https://stackoverflow.com/questions/8774425/vs-in-javascript-closures&quot;&gt;heated discussion&lt;/a&gt; between parties as to why they have chosen their preferred style. Douglas Crockford prefers the second structure here, as the first &lt;a href=&quot;https://twitter.com/paul_irish/status/176187448420864000&quot;&gt;&quot;looks like dog balls&quot;&lt;/a&gt;. If you use &lt;a href=&quot;http://www.jslint.com/&quot;&gt;JSLint&lt;/a&gt;, you&apos;ll be encouraged to adopt the latter style - it suggests the parentheses that invoke the function should sit within those that contain it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(function(){
  function foo() {
    // I&apos;m not polluting the global scope!
  }
})();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(function(){
  function bar() {
    // Nor am I!
  }
}());
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Check whether a DOM element exists using jQuery</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Mon, 29 Jun 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A straightforward little post: if you want to detect whether a DOM element actually exists on the page (perhaps you&apos;re flying in the blind), you can write &lt;code&gt;if ($(&apos;selector&apos;).length) { // Foo }&lt;/code&gt;. If the element is present, it&apos;ll evaluate to &lt;code&gt;true&lt;/code&gt; and you can work from there.&lt;/p&gt;
</content:encoded></item><item><title>JavaScript&apos;s Ternary Operator</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Wed, 27 May 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;p class=&quot;lead&quot;&amp;gt;When you&apos;ve been writing code for a good while, you start looking at ways to speed up the process. Perhaps the most obvious method to achieve this is to write fewer lines of code.&amp;lt;/p&amp;gt;&lt;/p&gt;
&lt;p&gt;A typical &lt;code&gt;if/else&lt;/code&gt; statement looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var foo = 10,
    bar = 20,
    baz;

if (foo &amp;gt; bar) {
  baz = foo;
} else {
  baz = bar;
}

console.log(baz); // 20
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Look at that: five lines of code. We can do better than that, right?&lt;/p&gt;
&lt;p&gt;Right!&lt;/p&gt;
&lt;p&gt;JavaScript offers a ternary operator that takes three values: &lt;code&gt;condition ? expr1 : expr2&lt;/code&gt;. The above code can be condensed to the following.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var foo = 10,
    bar = 20,
    baz;

baz = foo &amp;gt; bar ? foo : bar;

console.log(baz); // 20
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What we&apos;re saying is that if &lt;code&gt;foo&lt;/code&gt; is greater than &lt;code&gt;bar&lt;/code&gt;, &lt;code&gt;baz&lt;/code&gt; is assigned the value of 10. If not, &lt;code&gt;baz&lt;/code&gt; is 20.&lt;/p&gt;
&lt;p&gt;Personally, I&apos;ve found that a major drawback of using syntax like this is that the code becomes harder to parse when reading through it. Your mileage may vary, but just like omitting the braces of single-line &lt;code&gt;if&lt;/code&gt; statements, it takes just that extra beat of brain-power to comprehend.&lt;/p&gt;
</content:encoded></item><item><title>Each, Map, and Reduce</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Fri, 22 May 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;p class=&quot;lead&quot;&amp;gt;Functional programming (FP) aims to create predictable code by eliminating so-called &amp;lt;a href=&quot;https://programmers.stackexchange.com/questions/40297/what-is-a-side-effect&quot;&amp;gt;side effects&amp;lt;/a&amp;gt;, bringing with it  confidence that the same code with the same arguments will produce the same results. In order to achieve this, developers rely on &amp;lt;i&amp;gt;higher-order functions&amp;lt;/i&amp;gt;: functions that operate on other functions.&amp;lt;/p&amp;gt;
&amp;lt;p class=&quot;lead&quot;&amp;gt;JavaScript provides the developer with a number of useful functions that can be used to apply FP principles to their development.&amp;lt;/p&amp;gt;&lt;/p&gt;
&lt;h2&gt;forEach()&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;forEach()&lt;/code&gt; takes an array, iterates over its values and applies the specified function on them. It can be considered an abstracted version of the basic &lt;code&gt;for&lt;/code&gt; loop: we don&apos;t define a counter, check the length of the array, tell it how to increment (or decrement, for that matter), nor have to define a new variable within the loop body to store the current element.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var foo = [
  &apos;Tom&apos;,
  &apos;Dick&apos;,
  &apos;Harry&apos;
];

foo.forEach(function(name) {
  return name + &apos; smells&apos;;
});

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While the applied function can be created on the spot, we can also provide a function that has been written earlier in the hopes of adhering to the principle of &lt;a href=&quot;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&quot;&gt;DRY&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;forEach()&lt;/code&gt; (and the functions mentioned below) were &apos;only&apos; standardised in 2009, so aren&apos;t available in older browsers. Should you rather not write a polyfill yourself, &lt;a href=&quot;https://lodash.com/&quot;&gt;lodash&lt;/a&gt; (or &lt;a href=&quot;http://underscorejs.org/&quot;&gt;Underscore&lt;/a&gt;) provide an interface to the same functionality:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var foo = [
  &apos;Tom&apos;,
  &apos;Dick&apos;,
  &apos;Harry&apos;
];

_.each(foo, function(name) {
  return name + &apos; smells&apos;;
});

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Interestingly, &lt;a href=&quot;http://benmccormick.org/2014/11/12/underscore-vs-lodash/&quot;&gt;Ben McCormick&lt;/a&gt; tells us that the two libraries are both faster than their native counterparts in this case:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A little research indicates that this is because native functions optimize for sparse arrays and have more weird corner cases that they handle. In any case, the performance difference is pretty startling across the board.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While the native implementation is currently only available on arrays, lodash&apos;s implementation is designed to operate on any kind of collection, including object literals and NodeLists.&lt;/p&gt;
&lt;h2&gt;map()&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;map()&lt;/code&gt; method takes an array, iterates over its contents, applies a function to all of its elements, and returns a new array with the transformed values.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var foo = [
  &apos;Tom&apos;,
  &apos;Dick&apos;,
  &apos;Harry&apos;,
];

// Native
var bar = foo.map(function(name) {
  return name + &apos; smells&apos;;
});

// lodash
var bar = _.map(foo, function() {
  return name + &apos; smells&apos;;
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This helps streamline the process of avoiding &apos;side effects&apos; - the function isn&apos;t altering our original array, so it can be used again without mishap.&lt;/p&gt;
&lt;h2&gt;reduce()&lt;/h2&gt;
&lt;p&gt;When we want to get just a single value from an array, we can turn to &lt;code&gt;reduce()&lt;/code&gt;. This method aggregates all values in a collection and returns a single value from them: whether that be a miniumum, maximum, average, or what-have-you.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;reduce()&lt;/code&gt; takes a transformative function, and an intial value it should start computing with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var foo = [
  {name: &apos;Tom&apos;, age: 20},
  {name: &apos;Dick&apos;, age: 30},
  {name: &apos;Harry&apos;, age: 40}
];

var totalAge = function(result, person) {
  return result + person.age;
};

// Native
var total = foo.reduce(totalAge, 0); // 90

// lodash
var total = _.reduce(foo, totalAge, 10); // 100 - we started with 10 and continued summing from there.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The functions featured above are useful additions to a developer&apos;s toolkit. That these are higher-order functions means that they allow developers to write code that is simple to comprehend. There is no mess of code dealing with initialising loops to wade through. As these functions work on the output of other functions, they can be chained together quite trivially. Here&apos;s &lt;a href=&quot;https://lodash.com/docs#chain&quot;&gt;lodash&apos;s example for its &lt;code&gt;.chain()&lt;/code&gt; function&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var users = [
  { &apos;user&apos;: &apos;barney&apos;,  &apos;age&apos;: 36 },
  { &apos;user&apos;: &apos;fred&apos;,    &apos;age&apos;: 40 },
  { &apos;user&apos;: &apos;pebbles&apos;, &apos;age&apos;: 1 }
];

var youngest = _.chain(users)
  .sortBy(&apos;age&apos;)
  .map(function(chr) {
    return chr.user + &apos; is &apos; + chr.age;
  })
  .first()
  .value();
// → &apos;pebbles is 1&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Straightforward, self-documenting code.&lt;/p&gt;
</content:encoded></item><item><title>Using JavaScript&apos;s bind() function</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Thu, 30 Apr 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;p class=&quot;lead&quot;&amp;gt;Since it was introduced in 2009’s ECMAScript 5 (ES5) specification, all functions have the &amp;lt;code&amp;gt;bind()&amp;lt;/code&amp;gt; method. Using it creates a new function that calls the original with some arguments already fixed. This is known as a &quot;partial function application&quot;.&amp;lt;/p&amp;gt;&lt;/p&gt;
&lt;h2&gt;Using &lt;code&gt;bind&lt;/code&gt; to set parameters&lt;/h2&gt;
&lt;p&gt;Partially applying a function using &lt;code&gt;bind()&lt;/code&gt; allows us to fill in arguments before the function is called. In the following example, &lt;code&gt;bind()&lt;/code&gt; is used to create a new function that takes &lt;code&gt;add()&lt;/code&gt;, but only requires a single parameter: &lt;code&gt;x&lt;/code&gt; is always going to be 1:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function add(x, y) {
  return x + y;
}

var plus1 = add.bind(null, 1);
console.log(plus1(5)); // 6
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Using &lt;code&gt;bind&lt;/code&gt; to set &lt;code&gt;this&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;bind()&lt;/code&gt; can also be used to allow the developer to specify the context in which &lt;code&gt;this&lt;/code&gt; must be used. In the example above, we passed &lt;code&gt;null&lt;/code&gt;. In the next, we don&apos;t pass any additional arguments, but provide the function an object. As we &lt;a href=&quot;/2015/04/24/this-and-that-in-javascript/&quot;&gt;learnt previously&lt;/a&gt;, &lt;code&gt;this&lt;/code&gt; is bound explicitly when set this way.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function foo(something) {
  console.log(this.a, something);
  return this.a + something;
}

var obj = {
  a: 2,
};

var bar = foo.bind(obj);

var b = bar(3); // 2 3
console.log(b); // 5
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>this and that in JavaScript</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Fri, 24 Apr 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;p class=&quot;lead&quot;&amp;gt;When looking at code written by others, you may wonder why JavaScript developers will often alias &amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt; as &amp;lt;code&amp;gt;that&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;self&amp;lt;/code&amp;gt;, within a function. Why is this? Surely &amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt; always refers to the current object?&amp;lt;/p&amp;gt;&amp;lt;p class=&quot;lead&quot;&amp;gt;Short story: nope.&amp;lt;/p&amp;gt;&lt;/p&gt;
&lt;h2&gt;What&apos;s &lt;code&gt;this&lt;/code&gt;?&lt;/h2&gt;
&lt;p&gt;Unlike other languages where it refers to values stored in instance properties, the &lt;code&gt;this&lt;/code&gt; keyword is dynamically bound based on how a particular function is executed. Because of its shifting nature, it can be tricky to keep track of what &lt;code&gt;this&lt;/code&gt; might be referring to when it is called. With a little understanding of the rules behind &lt;code&gt;this&lt;/code&gt;, we can be more confident when writing our code.&lt;/p&gt;
&lt;p&gt;There are four rules that help us figure out what &lt;code&gt;this&lt;/code&gt; may be at a particular point in time, and these rules are based on the call-site of the function.&lt;/p&gt;
&lt;h3&gt;1: Default Binding&lt;/h3&gt;
&lt;p&gt;When our function is invoked of its own accord, &lt;em&gt;ala&lt;/em&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function foo() {
  console.log(this.a);
}

var a = 2;

foo(); // 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The call to &lt;code&gt;this.a&lt;/code&gt; resolves to the global variable of the same name. If  we were running in strict mode - &lt;a href=&quot;http://www.nczonline.net/blog/2012/03/13/its-time-to-start-using-javascript-strict-mode/&quot;&gt;and you should&lt;/a&gt; - we would find that it would be undefined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function foo() {
  console.log(this.a);
}

var a = 2;

foo(); // &apos;this&apos; is undefined
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2: Implicit Binding&lt;/h3&gt;
&lt;p&gt;When calling a function as an object method, its call site now has some context and the object in question should be used for the function&apos;s &lt;code&gt;this&lt;/code&gt; binding.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function foo() {
  console.log(this.a);
}

var obj = {
  a: 2,
  foo: foo
};

obj.foo(); // 2
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3: Explicit Binding&lt;/h3&gt;
&lt;p&gt;We can use the &lt;code&gt;call()&lt;/code&gt; and &lt;code&gt;apply()&lt;/code&gt; utilities to force a function to use a particular object for its &lt;code&gt;this&lt;/code&gt; binding. For both utilities, the first parameter is the object to use. &lt;a href=&quot;/2014/01/05/call-and-apply&quot;&gt;As we&apos;ve discovered previously&lt;/a&gt; &lt;code&gt;call()&lt;/code&gt; takes a list of parameters, while &lt;code&gt;apply()&lt;/code&gt; is given an array as its second argument.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function foo() {
  console.log(this.a);
}

var obj = {
  a: 2,
};

foo.call(obj); // 2
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Hard Binding&lt;/h4&gt;
&lt;p&gt;Both implicit and explicit binding lose their &lt;code&gt;this&lt;/code&gt; binding when passed around. The following pattern helps ensure that this doesn&apos;t happen:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function foo() {
  console.log(this.a);
}

var obj = {
  a: 2,
};

var bar = function() {
  foo.call(obj);
};

bar(); // 2
setTimeout(bar, 100); // 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The new &lt;code&gt;bar()&lt;/code&gt; function calls &lt;code&gt;foo()&lt;/code&gt; with &lt;code&gt;this&lt;/code&gt; bound to our object. &lt;code&gt;bar()&lt;/code&gt; can be passed around, as it is to &lt;code&gt;setTimeout()&lt;/code&gt;, and yet &lt;code&gt;this&lt;/code&gt; remains 2.&lt;/p&gt;
&lt;p&gt;It might get a little tiresome wrapping functions for this purpose, so ES5 (&lt;a href=&quot;https://kangax.github.io/compat-table/es5/&quot;&gt;supported natively in IE9+, or with ES5-shim&lt;/a&gt;) gives us &lt;code&gt;bind()&lt;/code&gt;: a utility that returns a new function that calls the original, with &lt;code&gt;this&lt;/code&gt; set as required.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function foo(something) {
  console.log(this.a, something);
  return this.a + something;
}

var obj = {
  a: 2,
};

var bar = foo.bind(obj);

var b = bar(3); // 2 3
console.log(b); // 5
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4: new Binding&lt;/h3&gt;
&lt;p&gt;When using &lt;code&gt;new&lt;/code&gt; to create a new object, the new object is set as the &lt;code&gt;this&lt;/code&gt; binding.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function foo(a) {
  this.a = a;
}

var bar = new foo(2);
console.log(bar.a); // 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, if the function is called:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;with &lt;code&gt;new&lt;/code&gt;, &lt;code&gt;this&lt;/code&gt; is the new object;&lt;/li&gt;
&lt;li&gt;using &lt;code&gt;call&lt;/code&gt;, &lt;code&gt;apply&lt;/code&gt;, or &lt;code&gt;bind&lt;/code&gt;, &lt;code&gt;this&lt;/code&gt; is the specified object;&lt;/li&gt;
&lt;li&gt;as it being a method of an object, &lt;code&gt;this&lt;/code&gt; is that object;&lt;/li&gt;
&lt;li&gt;in standard execution, &lt;code&gt;this&lt;/code&gt; is either the &lt;code&gt;global&lt;/code&gt; object, or will be &lt;code&gt;undefined&lt;/code&gt; if using strict mode.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Why &lt;code&gt;that&lt;/code&gt;, then?&lt;/h2&gt;
&lt;p&gt;&amp;lt;!-- So why use &lt;code&gt;that&lt;/code&gt;? We know that JavaScript has lexical scope, and new scopes are only created when a function is called.  --&amp;gt;&lt;/p&gt;
&lt;p&gt;Each function call gets its own &lt;code&gt;this&lt;/code&gt; binding. When a function is executed inside another, we no longer have access to the original &lt;code&gt;this&lt;/code&gt; value. By aliasing it as &lt;code&gt;that&lt;/code&gt; or &lt;code&gt;self&lt;/code&gt; at the top level, we can retain a reference to the original value and make it visible to inner functions.&lt;/p&gt;
&lt;p&gt;As for the reasoning behind this convention, &lt;a href=&quot;http://www.crockford.com/javascript/private.html&quot;&gt;Douglas Crockford&lt;/a&gt; states that:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;...This is a workaround for an error in the ECMAScript Language Specifications which causes &lt;code&gt;this&lt;/code&gt; to be set incorrectly for inner functions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While it&apos;s a useful trick to have in the toolbox, JavaScript does give us utilities to avoid having to use it in the first place. We can take advantage of the functionality JavaScript gives us with &lt;code&gt;call()&lt;/code&gt;, &lt;code&gt;apply()&lt;/code&gt;, and &lt;code&gt;bind()&lt;/code&gt; in order to explicitly tell a function the context it will be running in.&lt;/p&gt;
</content:encoded></item><item><title>setTimeout and setInterval</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Tue, 21 Apr 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;p class=&quot;lead&quot;&amp;gt;JavaScript features a couple of useful utilities that allow the developer to schedule code to run outside of the normal execution flow.&amp;lt;/p&amp;gt;&lt;/p&gt;
&lt;h2&gt;setTimeout&lt;/h2&gt;
&lt;p&gt;In order to run a function after a specific delay, we use &lt;code&gt;setTimeout()&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function doSomething(message) {
  console.log(message);
}

var myTimeout = setTimeout(doSomething, 2000, &quot;lol&quot;);

// Two seconds later...
// lol
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Timeouts can be cancelled using &lt;code&gt;clearTimeout()&lt;/code&gt; and passing the ID of the timeout in question. In the above example, to prevent our applicating from printing &lt;code&gt;lol&lt;/code&gt;, we could set up a button which called &lt;code&gt;clearTimeout(myTimeout)&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;setInterval&lt;/h2&gt;
&lt;p&gt;If you want to call a function repeatedly, &lt;code&gt;setInterval()&lt;/code&gt; is the more appropriate tool. It looks very similar:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function doSomethingElse(message) {
  console.log(message);
}

var myInterval = setInterval(doSomethingElse, 5000, &quot;See you in five...&quot;);

// Every five seconds...
// See you in five...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As with timeouts, we can run &lt;code&gt;clearInterval()&lt;/code&gt; to call a halt to proceedings when we are done with it.&lt;/p&gt;
&lt;h2&gt;Debouncing&lt;/h2&gt;
&lt;p&gt;Imagine a searchbox that offers suggestions as you type. On each &lt;code&gt;keydown&lt;/code&gt; event, a function is run that makes a network request. If the user enters a long query quickly, the browser (and remote server!) may quickly become overwhelmed and end up feeling unresponsive.&lt;/p&gt;
&lt;p&gt;To overcome this, we can implement &lt;code&gt;setTimeout()&lt;/code&gt; in order to &lt;em&gt;debounce&lt;/em&gt; the event: we prevent it from happening too often.
Instead of calling the function on each keypress, we wait for an opportune moment - perhaps a slight pause. When events occur closer than our timeout delay, the timeout from the previous keypress is cancelled and a new one is executed.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var myTextBox = document.querySelector(&apos;[type=&quot;search&quot;]&apos;);
var myTimeout;

myTextBox.addEventListener(&quot;keydown&quot;, function() {
  clearTimeout(myTimeout);
  myTimeout = setTimeout(function() {
    // Query remote server
  }, 500);
});
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>last-child in CSS</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Wed, 08 Apr 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The &lt;code&gt;:last-child&lt;/code&gt; psuedo-selector allows the developer to target the last child element of its parent. But you need to qualify it with the element that you are targetting. Something that has caught me out in the past has been applying the selector to the parent itself:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/* Nope - this won&apos;t work and you&apos;ll feel silly */
ul:last-child {
  border-bottom: none;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It kind of makes sense, right? I want the last child of that unordered list. But no: pseudo-selectors, such as &lt;code&gt;:last-child&lt;/code&gt;, &lt;code&gt;:hover&lt;/code&gt;, and &lt;code&gt;:checked&lt;/code&gt; work on the &lt;em&gt;state&lt;/em&gt; of the specified element.&lt;/p&gt;
&lt;p&gt;In the common scenario of wanting to style the last element in a list differently, you can use the following code example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;li {
  border-bottom: 1px solid #f3f3f3;
}

li:last-child {
  border-bottom: none;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When that list element finds itself as the &lt;code&gt;:last-child&lt;/code&gt; of its parent, the browser will remove its border.&lt;/p&gt;
</content:encoded></item><item><title>JavaScript&apos;s &apos;let&apos; keyword</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Wed, 01 Apr 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Good news everybody! ES6 (or ES2015) introduces the &lt;code&gt;let&lt;/code&gt; keyword. This allows the developer to attach a variable to the scope of whatever code block - code between &lt;code&gt;{&lt;/code&gt; and &lt;code&gt;}&lt;/code&gt; - it resides in. Block scope rather than function scope!&lt;/p&gt;
</content:encoded></item><item><title>JavaScript Constants</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Thu, 26 Mar 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The new ES6 JavaScript standard finally allows developers to declare variables using the handy &lt;code&gt;const&lt;/code&gt; keyword. This prevents the value from being reassigned - somewhat reassuring if that&apos;s a requirement.&lt;/p&gt;
&lt;p&gt;That said, values declared with &lt;code&gt;const&lt;/code&gt; can still be modified after the fact: they&apos;re not immutable. If you&apos;re after that particular bit of functionality, you can still fall back on the &lt;code&gt;.freeze&lt;/code&gt; property that objects have access to. If you&apos;re using strict mode - and why not? - you&apos;ll receive a TypeError, unless you look to see whether the object &lt;code&gt;.isFrozen&lt;/code&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Shadowing And Hoisting In JavaScript</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sun, 25 Jan 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Shadowing&lt;/h2&gt;
&lt;p&gt;To &quot;shadow&quot; a variable is to create a new variable with the same name as one that exists in a higher scope. In JavaScript, a new scope is created when writing a function. When resolving a variable, JavaScript starts at the innermost scope and searches outwards.&lt;/p&gt;
&lt;h2&gt;Hoisting&lt;/h2&gt;
&lt;p&gt;Hoisting, on the other hand, is a behaviour which results in variables being raised, or &apos;hoisted&apos;, to the top of the scope - the function - in which they have been defined. It&apos;s recommended to declare all of your variables at the top of a function in order to avoid overwriting a value.&lt;/p&gt;
</content:encoded></item><item><title>Checking Date Equality in JavaScript</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Wed, 16 Apr 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Checking whether one date is equal to another is made difficult because of the way object equality works in JavaScript. Object equality isn&apos;t tested by the internal value of the object, but by identity. If the date object isn&apos;t a straight copy, it isn&apos;t considered equal. The following example will never return &lt;code&gt;true&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function isChristmas(dateToTest){
  var christmas = new Date(&quot;12/25/2014&quot;);
  return (dateToTest === christmas);
}

console.log(isChristmas(new Date(&quot;12/25/2014&quot;))); // False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To make the &lt;code&gt;isChristmas&lt;/code&gt; function work, we need to check equality in a different way. We use the &lt;code&gt;getTime&lt;/code&gt; method that is available on Date object, and compare the values it returns. &lt;code&gt;getTime&lt;/code&gt; returns an integer representing the number of milliseconds since midnight of the epoch: January 1st, 1970.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function isChristmas(dateToTest){
  var christmas = new Date(&quot;12/25/2014&quot;);
  return (dateToTest.getTime() === christmas.getTime());
}

console.log(isChristmas(new Date(&quot;12/25/2014&quot;))); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But! If we happen to compare against a &lt;code&gt;Date&lt;/code&gt; object that occurs on the same day, but a different hour, we&apos;ll run into trouble - because the time elapsed since the epoch will be different.&lt;/p&gt;
&lt;p&gt;A work around here might be to check our date against the year, month and day, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function isChristmas(dateToTest){
  return (dateToTest.getFullYear() === 2014) &amp;amp;&amp;amp;
  (dateToTest.getMonth() === 11) &amp;amp;&amp;amp;
  (dateToTest.getDate() === 25);
}

console.log(isChristmas(new Date(&quot;12/25/2014 12:00&quot;))); // True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But then this is glossing over the complexities that daylight savings and timezones introduce.&lt;/p&gt;
&lt;p&gt;TL;DR: Be aware that there are &apos;gotchas&apos; when comparing dates. Use &lt;a href=&quot;http://momentjs.com&quot;&gt;Moment.js&lt;/a&gt; to avoid them and make your life easier.&lt;/p&gt;
</content:encoded></item><item><title>Substring, Substr, and Slice.</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Mon, 03 Mar 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When dealing with strings in JavaScript, there are several options available when needing to return a particular section:&lt;/p&gt;
&lt;h2&gt;Substring&lt;/h2&gt;
&lt;p&gt;This function can accept two parameters: the first an integer between 0 and the length of the string; the second an integer between 0 and the length of the string. &lt;code&gt;substring&lt;/code&gt; returns a subset of a string between one index and another, or if the second parameter is omitted, through to the end of the string. A useful feature of this implementation is that if the first parameter is larger than the second, the effect of &lt;code&gt;substring&lt;/code&gt; will be as if the arguments were swapped.&lt;/p&gt;
&lt;h2&gt;Substr&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;substr&lt;/code&gt; is a variant of &lt;code&gt;substring&lt;/code&gt;. The difference here is that while the first parameter defines the first character, the second specifies the number of characters to return.&lt;/p&gt;
&lt;h2&gt;Slice&lt;/h2&gt;
&lt;p&gt;Both arrays and strings boast a &lt;code&gt;slice&lt;/code&gt; method. The arguments it will accept are integers to define the the start and end points of the extraction. Again, if the end point is omitted, the function will keep going until the end of the string. A benefit is that the second argument can be a negative value, which will allow the operation to begin counting from the end. On top of this, &lt;code&gt;slice&lt;/code&gt; will return a new string.&lt;/p&gt;
&lt;h3&gt;References&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://devdocs.io/javascript/global_objects/string/substring&quot;&gt;http://devdocs.io/javascript/global_objects/string/substring&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://devdocs.io/javascript/global_objects/string/substr&quot;&gt;http://devdocs.io/javascript/global_objects/string/substr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://devdocs.io/javascript/global_objects/string/slice&quot;&gt;http://devdocs.io/javascript/global_objects/string/slice&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Closures 101</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Mon, 03 Feb 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;I updated this post on the 16th February in order to clarify my writing and thoughts.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;What is a closure?&lt;/h2&gt;
&lt;p&gt;In computer science:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;a closure is a first-class function with free variables that are bound in the lexical environment. Such a function is said to be &quot;closed over&quot; its free variables. A closure is defined within the scope of its free variables, and the extent of those variables is at least as long as the lifetime of the closure itself.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A higher-level definition is that&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A closure is a function defined within another scope that has access to all the variables within the outer scope.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And just in case, think of it as:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;...like keeping a copy of the all the local variables, just as they were when a function exited.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Closures are a strange concept to get to grips with, but once this core concept is understood they&apos;re relatively easy to understand: a closure is created when a developer accesses variables outside of the immediate lexical scope.&lt;/p&gt;
&lt;h2&gt;An example of a closure in action&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;function makeAdder(a) {
  return function(b) {
    return a + b;
  };
}

x = makeAdder(5);
y = makeAdder(20);

x(6); // 11
y(7); // 27
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;http://jsfiddle.net/95PTq/&quot;&gt;JSFiddle demo&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;What happens in a closure?&lt;/h2&gt;
&lt;p&gt;When &lt;code&gt;makeAdder&lt;/code&gt; is called, a new scope is created with one property: &lt;code&gt;a&lt;/code&gt; - the argument passed to the function. It also returns the anonymous function declared within it. This returned function maintains a reference back to that original scope. This scope will persist and escape being garbage collected until there are no more references to that function.&lt;/p&gt;
&lt;p&gt;Take a look at what happens when we log &lt;code&gt;x&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function(b){
  return a + b;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So when we call &lt;code&gt;x&lt;/code&gt; and pass an argument, that&apos;s going straight into the anonymous function &lt;code&gt;makeAdder&lt;/code&gt; returned the first time. Because we know a closure is a combination of a function and its scope&lt;/p&gt;
&lt;p&gt;Since we are then able to all &lt;code&gt;y&lt;/code&gt;, we discover that we have ended up with two different copies of &lt;code&gt;makeAdder&lt;/code&gt;&apos;s local variables: one in which &lt;code&gt;a&lt;/code&gt; is 5, and another where &lt;code&gt;a&lt;/code&gt; is 20.&lt;/p&gt;
&lt;h2&gt;When would I use a closure?&lt;/h2&gt;
&lt;p&gt;The technique is often used to prevent against contaminating higher levels of &lt;a href=&quot;http://danmatthew.co.uk/2013/05/18/variable-scope-in-javascript/&quot;&gt;scope&lt;/a&gt; - data is kept tucked away. Along these lines, a closure can be used to help practise encapsulation: an object can return its public methods and variable, while keeping those intended to be private hidden and inaccessible to the rest of the codebase.&lt;/p&gt;
&lt;p&gt;You may have taken advantage of one without realising it, as they&apos;re a key concept when implementing an &apos;Immediately-Invoked Function Expression&apos; (IIFE). Using an IIFE within a module, as per the &lt;a href=&quot;http://www.addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript&quot;&gt;Module Pattern&lt;/a&gt;, ensures that the module is self-contained.&lt;/p&gt;
&lt;p&gt;An intelligent developer will&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;use closures to create additional scopes that can be used to group interrelated and dependent code in a way that minimises the risk of accidental interaction.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Useful reading&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://howtonode.org/why-use-closure&quot;&gt;http://howtonode.org/why-use-closure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jibbering.com/faq/notes/closures/&quot;&gt;http://www.jibbering.com/faq/notes/closures/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/111102/how-do-javascript-closures-work&quot;&gt;http://stackoverflow.com/questions/111102/how-do-javascript-closures-work&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures?redirectlocale=en-US&amp;amp;redirectslug=JavaScript%2FGuide%2FClosures&quot;&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures?redirectlocale=en-US&amp;amp;redirectslug=JavaScript%2FGuide%2FClosures&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://learn.jquery.com/javascript-101/closures/&quot;&gt;http://learn.jquery.com/javascript-101/closures/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example&quot;&gt;http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Event Delegation In JavaScript</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Mon, 27 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;First, some markup:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;ul id=&quot;list&quot;&amp;gt;
  &amp;lt;li id=&quot;item-1&quot;&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;li id=&quot;item-2&quot;&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;!-- A little while later - hope this is automated! --&amp;gt;
  &amp;lt;li id=&quot;item-99&quot;&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;li id=&quot;item-100&quot;&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;What is event delegation?&lt;/h2&gt;
&lt;p&gt;In the example above, it&apos;s inefficient for both the browser and the developer to write event listeners for a large number of elements - particularly if these elements are being generated dynamically. Event delegation entails attaching a single listener to the parent element, then checking the target element  as it bubbles up through the document structure.&lt;/p&gt;
&lt;h2&gt;What are the advantages?&lt;/h2&gt;
&lt;p&gt;Writing less code, for one, and less code means fewer opportunities for bugs to arise. It also means that when elements are removed, we don&apos;t run into the risk of forgetting  rid ourselves of their event listeners. Too many of those floating around in memory - particularly in complex web applications - can cause problems for the browser.&lt;/p&gt;
&lt;h2&gt;How do I implement event delegation?&lt;/h2&gt;
&lt;p&gt;Here&apos;s a no-frills example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;document.getElementById(&apos;list&apos;).addEventListener(&apos;click&apos;, function(e) {
  if (e.target) {
    console.log(e.target.id); // Prints item id
  }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;http://jsfiddle.net/heQkz/&quot;&gt;See this example in action&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Get The Day Of The Week In JavaScript</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Mon, 27 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;pre&gt;&lt;code&gt;var now = new Date();
var day = now.getDay();
// 1 (Monday)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It might not straight up give us &quot;Monday&quot;, but it&apos;s a useful method to know.&lt;/p&gt;
</content:encoded></item><item><title>JavaScript Feature Detection</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sun, 26 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Some JavaScript features just don&apos;t work in certain browsers. While it used to be a common practice to &apos;sniff&apos; the user-agent string of the browser, &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Browser_Detection_and_Cross_Browser_Support&quot;&gt;this is now frowned-upon&lt;/a&gt;. The preferred approach is for developers to implement feature detection. That is, testing the ability of the browser to carry out the desired task. If the feature is not supported, we write our code intelligently in order to cater for this eventuality.&lt;/p&gt;
&lt;p&gt;In Mark Pilgrim&apos;s &lt;em&gt;Dive Into HTML5&lt;/em&gt;, he documents a selection of techniques:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Checking for the existence of a property on a global object&lt;/li&gt;
&lt;li&gt;Creating an element and checking for the property on that&lt;/li&gt;
&lt;li&gt;Calling a method on a generated element and examining the value it returns&lt;/li&gt;
&lt;li&gt;Setting a property on an element to a particular value and checking to see whether it has retained this value&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A common example of the first technique is when writing an AJAX function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var xmlHttp;
if (window.XMLHttpRequest) {
  xmlHttp = new XMLHttpRequest();
} else {
  // Figure out which ActiveX control to set up for Internet Explorer
  var XmlHttpVersions = new Array(
  &apos;MSXML2.XMLHTTP.6.0&apos;,
  &apos;MSXML2.XMLHTTP.5.0&apos;,
  &apos;MSXML2.XMLHTTP.4.0&apos;,
  &apos;MSXML2.XMLHTTP.3.0&apos;,
  &apos;MSXML2.XMLHTTP&apos;,
  &apos;Microsoft.XMLHTTP&apos;);

  for (var i = 0; i &amp;lt; XmlHttpVersions.length &amp;amp;&amp;amp; !xmlHttp; i++){
    try {
      xmlHttp = new ActiveXObject(XmlHttpVersions[i]);
    } catch(e) {
      // Here be dragons
    }
   }
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Thankfully, libraries such as &lt;a href=&quot;http://modernizr.com&quot;&gt;Modernizr&lt;/a&gt; can be implemented in order to reduce the amount of boilerplate that needs to be written. It has an API that can be queried to easily check for feature support. If they&apos;re not present, we can write a fallback so that the user&apos;s experience isn&apos;t compromised:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Determine if font-face is supported
if (Modernizr.fontface) {
  // Do something
} else {
  // No fancy fonts
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;References&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://diveintohtml5.info/detect.html&quot;&gt;http://diveintohtml5.info/detect.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.quirksmode.org/js/support.html&quot;&gt;http://www.quirksmode.org/js/support.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.quirksmode.org/js/support.html&quot;&gt;http://jibbering.com/faq/notes/detect-browser/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/magazine/hh475813.aspx&quot;&gt;http://msdn.microsoft.com/en-us/magazine/hh475813.aspx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://learn.jquery.com/code-organization/feature-browser-detection/&quot;&gt;http://learn.jquery.com/code-organization/feature-browser-detection/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Ensure A Table Fills Its Containing Element</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Fri, 24 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;pre&gt;&lt;code&gt;table {
  table-layout: fixed; // Default is auto
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I was wondering what the correct CSS property was to control this requirement. Setting a width on the table element was doing precisely zip. That is until we set the above.&lt;/p&gt;
</content:encoded></item><item><title>Linked Lists</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Thu, 23 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;p class=&quot;message&quot;&amp;gt;This is one of a series based around understanding a number of core Computer Science concepts - &amp;lt;a href=&quot;/2014/01/22/path-to-mastery/&quot;&amp;gt;please read the original post for the intentions behind it&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;&lt;/p&gt;
&lt;p&gt;A linked list is often used to implement data structures including lists, stacks, queues, and associated arrays.
It&apos;s constructed from a list of nodes which when linked together represent a sequence. Each node is built of its data and a pointer to the next node in the sequence. Elements can be inserted or removed at any position.&lt;/p&gt;
&lt;p&gt;In JavaScript, a linked list could look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// A single node
var node1 = {
	data: null,
	next: null
};

// Add data to node
node1.data = 12;

// Create another node
var node2 = {
	data: null,
	next: null
};

// Link (aha!) first node to second
node1.next = node2;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will soon become rather unwieldy to manually manage, so at this point we&apos;ll need to write a function that can do the grunt work for us:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;add an item&lt;/li&gt;
&lt;li&gt;retrieve an item&lt;/li&gt;
&lt;li&gt;remove an item&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As above, our representation of a list will need to have properties which reveal its length and the first item in the list.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function linkedList() {
  this.length = 0;
  this.head = null;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In order to add an item to the list, we will need to traverse the list until we find the desired location. If the list is empty, we create a new node and assign it to our lists &lt;code&gt;head&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;add: function(data) {
  var node = {
    date: data,
    next: null
  },
    current;

  if (this.head === null) {
    this.head = node;
  } else {
    current = this.head;
    while (current.next) {
      current = current.next;
    }
    current.next = node;
  }
  this.length++;
},
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;retrieve: function(index) {
  // Check index not out of bounds
  if (index &amp;gt; -1 &amp;amp;&amp;amp; index &amp;lt; this.length){
    var current = this.head,
      i = 0;

    while (i++ &amp;lt; index){
      current = current.next;
    }

    return current.data;
  } else {
    return null;
  }
},
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Loops in Sass</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Thu, 23 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Sass makes it dead simple to automate repetitive tasks we might encounter when writing CSS.&lt;/p&gt;
&lt;h2&gt;Sass &apos;For&apos; loop&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;@for $i from 1 through 100 {
  .box:nth-child(#{i}) {
    // Properties
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Sass &apos;Each&apos; loop&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;@each $member in john, paul, george, ringo {
  .bandmember.#{$member} {
    background url(&quot;images/#{$member}.png&quot;);
  }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>The Path to Mastery</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Wed, 22 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;After reading &lt;a href=&quot;https://medium.com/i-m-h-o/56ed7faaad58&quot;&gt;Zach Wentz&apos;s Medium post on CodeSchool&lt;/a&gt;, I resolved to reminding myself of the concepts I&apos;d encountered while studying for my Computer Science degree.&lt;/p&gt;
&lt;p&gt;Wentz&apos;s key point is that:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To truly master the art of programming, we must learn the techniques available to us, not just the tools. Data structures, algorithms, design patterns, and computer science concepts are what I’m talking about here.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Of them, some came back incredibly quickly, while others were new - and I&apos;m glad to have refreshed my memory, because they are genuinely interesting topics.&lt;/p&gt;
&lt;p&gt;I&apos;ve been drafting a series of posts that cover each of the topics Wentz suggested - I hope they&apos;re of use.&lt;/p&gt;
&lt;h2&gt;Data Structures&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/2014/01/23/linked-lists&quot;&gt;Linked Lists&lt;/a&gt; (22/01)&lt;/li&gt;
&lt;li&gt;Binary Trees&lt;/li&gt;
&lt;li&gt;Tries&lt;/li&gt;
&lt;li&gt;Stacks&lt;/li&gt;
&lt;li&gt;Queues&lt;/li&gt;
&lt;li&gt;Vectors/ArrayLists&lt;/li&gt;
&lt;li&gt;Hash Tables&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Algorithms&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Breadth First Search&lt;/li&gt;
&lt;li&gt;Depth First Search&lt;/li&gt;
&lt;li&gt;Binary Search&lt;/li&gt;
&lt;li&gt;Merge Sort&lt;/li&gt;
&lt;li&gt;Quick Sort&lt;/li&gt;
&lt;li&gt;Tree Insert/Find&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Concepts&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Bit Manipulation&lt;/li&gt;
&lt;li&gt;Singleton Design Pattern&lt;/li&gt;
&lt;li&gt;Object-Orientated Programming&lt;/li&gt;
&lt;li&gt;Factory Design Pattern&lt;/li&gt;
&lt;li&gt;Memory (Stack vs Heap)&lt;/li&gt;
&lt;li&gt;Recursion&lt;/li&gt;
&lt;li&gt;Big-O Time&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Flavours of Linux</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Tue, 21 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;For whatever reason, I have found myself looking after two VPS set-ups: the first running CentOS with &lt;a href=&quot;http://swbroadband.co.uk&quot;&gt;South West Broadband&lt;/a&gt;, the second an Ubuntu droplet over at &lt;a href=&quot;http://digitalocean.com&quot;&gt;Digital Ocean&lt;/a&gt;. Thing is, after learning the basics of server configuration, and getting comfortable with the way CentOS does things, I&apos;ve only gone and confused myself by flitting between the variants. Common tasks are carried out in quite different ways.&lt;/p&gt;
&lt;p&gt;For instance, CentOS uses &lt;code&gt;yum&lt;/code&gt; as its package manager; Ubuntu has &lt;code&gt;apt-get&lt;/code&gt;. When configuring Apache on CentOS, it is restarted using &lt;code&gt;/etc/init.d/httpd restart&lt;/code&gt; (which I&apos;ve aliased to the slightly snappier &lt;code&gt;reboot&lt;/code&gt;). Back in Ubuntu-land, this operation is done with &lt;code&gt;service apache2 restart&lt;/code&gt;, but don&apos;t forget to activate any new hosts with &lt;code&gt;a2ensite&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Below is a short table describing the commands I&apos;ve found useful as a website owner:&lt;/p&gt;
&lt;p&gt;&amp;lt;table&amp;gt;
&amp;lt;thead&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Task&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;CentOS&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Ubuntu&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;/thead&amp;gt;
&amp;lt;tbody&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Change password&amp;lt;/td&amp;gt;&amp;lt;td colspan=&quot;2&quot;&amp;gt;&amp;lt;code&amp;gt;passwd&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Add a user&amp;lt;/td&amp;gt;&amp;lt;td colspan=&quot;2&quot;&amp;gt;&amp;lt;code&amp;gt;adduser USERNAME&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Delete a user&amp;lt;/td&amp;gt;&amp;lt;td colspan=&quot;2&quot;&amp;gt;&amp;lt;code&amp;gt;userdel USERNAME&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Remove user directory&amp;lt;/td&amp;gt;&amp;lt;td colspan=&quot;2&quot;&amp;gt;&amp;lt;code&amp;gt;rm -rf /home/USERNAME&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Delete user and their home directory&amp;lt;/td&amp;gt;&amp;lt;td colspan=&quot;2&quot;&amp;gt;&amp;lt;code&amp;gt;userdel -r USERNAME&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Webroot&amp;lt;/td&amp;gt;&amp;lt;td colspan=&quot;2&quot;&amp;gt;&amp;lt;code&amp;gt;/var/www&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Edit virtual hosts&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;/etc/httpd/conf/httpd.conf&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;/etc/apache2/sites-available/site-name&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Enable virtual host&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;N/A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;a2ensite site-name&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Reboot Apache&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;/etc/init.d/httpd restart&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;service apache2 restart&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Install package&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;yum install package&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;apt-get package&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Find IP address&amp;lt;/td&amp;gt;&amp;lt;td colspan=&quot;2&quot;&amp;gt;&amp;lt;code&amp;gt;ifconfig eth0&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;PS - Sorry for not using your favourite distro, or for doing things in an incredibly convoluted manner. Feel free to correct me on Twitter with any tips and tricks you&apos;ve picked up!&lt;/em&gt;&lt;/p&gt;
</content:encoded></item><item><title>Using Grunt to Compile Sass</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sun, 19 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A quick snippet from my &lt;code&gt;gruntfile.js&lt;/code&gt; that illustrates how I&apos;m using Grunt to watch my Sass directory for changes, before compiling and outputting minified CSS.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;grunt.initConfig({
  watch: {
    css: {
      files: [&apos;public/sass/**/*.scss&apos;],
      tasks: [&apos;buildcss&apos;]
    }
  },
  sass: {
    build: {
      options: {
        style: &apos;compressed&apos;
      },
      files: {
        &apos;public/css/styles.css&apos;:&apos;public/sass/styles.scss&apos;
      }
    }
  }
});

grunt.registerTask(&apos;buildcss&apos;, [&apos;sass&apos;]);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When coding, use &lt;code&gt;grunt watch&lt;/code&gt; to keep track of changes, or run &lt;code&gt;grunt buildcss&lt;/code&gt; to manually compile the files.&lt;/p&gt;
</content:encoded></item><item><title>Exclude folders in Jekyll</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sat, 18 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;After experimenting with Grunt, I noticed that the deploy was taking rather a long time - it turned out that Jekyll was bundling my &apos;node_modules&apos; directory (all 32MB of it!) into its compiled site folder. However, I can avoid this in future by adding: &lt;code&gt;exclude: node_modules&lt;/code&gt; to my &lt;code&gt;_config.yml&lt;/code&gt; file.&lt;/p&gt;
</content:encoded></item><item><title>Access URL Query Parameters With JavaScript</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Fri, 10 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I was recently tasked with building a promotional page for &lt;a href=&quot;http://didlr.com/promotions/year-of-donuts?username=dan&quot;&gt;Didlr&lt;/a&gt; which needed to feature a personalised call to action. Typically, this would have been done server-side, but as visitors would be landing on the page via one of the mobile apps, we&apos;d have to append the username when delivering the ads with our API. Thus, I would have to access this information on the client. And this is how I did it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (queryString(&apos;username&apos;)) {
	userName = queryString(&apos;username&apos;);
} else {
	userName = &apos;Your username goes here&apos;;
}

function queryString(key) {
	var url = window.location.href,
		keyValues = url.split(/[\?&amp;amp;]+/);

	for (i = 0; i &amp;lt; keyValues.length; i++) {
		keyValue = keyValues[i].split(&apos;=&apos;);

		if (keyValue[0] == key) {
			return keyValue[1];
		}
	}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is certainly more than one way to skin a cat (as the saying goes), and were I a wee bit more comfortable with regular expressions I&apos;m guessing that my &lt;code&gt;queryString()&lt;/code&gt; function could be a little more elegant.  The solution here grabs the URL, then adds items to an array when we encounter either an ampersand or a question mark. We loop over that array, and for each item contained within, we break it apart to return the value associated with the specified key.&lt;/p&gt;
&lt;p&gt;On StackOverflow, an alternative solution is as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function getParameterByName(name) {
  name = name.replace(/[\[]/, &quot;\\\[&quot;).replace(/[\]]/, &quot;\\\]&quot;);
  var regex = new RegExp(&quot;[\\?&amp;amp;]&quot; + name + &quot;=([^&amp;amp;#]*)&quot;),
    results = regex.exec(location.search);

  return results == null ? &quot;&quot; : decodeURIComponent(results[1].replace(/\+/g, &quot; &quot;));
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>call() and apply()</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sun, 05 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;&lt;code&gt;apply()&lt;/code&gt; invokes the named function with an array of arguments&lt;/li&gt;
&lt;li&gt;&lt;code&gt;call()&lt;/code&gt; requires the arguments to be listed explicitly&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first argument in both methods allows us to specify what &lt;code&gt;this&lt;/code&gt; refers to within that function.&lt;/p&gt;
&lt;p&gt;These methods allow the user to write a method once, and then inherit it within another object - without having to rewrite the method for the new object.&lt;/p&gt;
&lt;p&gt;A handy mnemonic to remember how to use each is as follows:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Think of &lt;em&gt;a&lt;/em&gt; in &lt;code&gt;apply()&lt;/code&gt; as an &lt;em&gt;array&lt;/em&gt; of arguments&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Think of &lt;em&gt;c&lt;/em&gt; in &lt;code&gt;call()&lt;/code&gt; as &lt;em&gt;columns&lt;/em&gt; of arguments&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>Replace Contents Of Element In JavaScript</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sun, 15 Dec 2013 00:00:00 GMT</pubDate><content:encoded>&lt;pre&gt;&lt;code&gt;// Native
element.textContent = &quot;Your text here&quot;; // IE9+
element.innerHTML = content;
element.innerText = &quot;Another example string&quot;; // MS proprietary method; not supported in Firefox

// jQuery
.text(&quot;Your text here&quot;);
.html(&quot;&amp;lt;p&amp;gt;A message for you&amp;lt;/p&amp;gt;&quot;);
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Remove Child Nodes In JavaScript</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Wed, 11 Dec 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;After discovering whether an element has children, one may want to go ahead and remove them. The brutalist approach involves setting the node&apos;s &lt;code&gt;innerHTML&lt;/code&gt; property to an empty string.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div id=&quot;box&quot;&amp;gt;
  &amp;lt;h1&amp;gt;Hello&amp;lt;/h1&amp;gt;
&amp;lt;/div&amp;gt;

var box = document.getElementById(&apos;box&apos;);
if (box.firstChild) {
  box.innerHTML = &apos;&apos;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Another option is to grab the &lt;code&gt;firstChild&lt;/code&gt; and then remove it like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;while (box.firstChild) {
  box.removeChild(box.firstChild);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The results on &lt;a href=&quot;http://jsperf.com/innerhtml-vs-removechild&quot;&gt;jsperf&lt;/a&gt; indicate that removeChild is the faster of the two techniques, and also the more robust: the &lt;code&gt;innerHTML&lt;/code&gt; technique won&apos;t work on XML markup.&lt;/p&gt;
&lt;p&gt;But wait! As usual, there is another alternative. Check out:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;while (box.hasChildNodes()) {
	box.removeChild(box.lastChild);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It&apos;s really just a variant on the method above: ensuring that &lt;code&gt;box&lt;/code&gt; still has children and removing them from the bottom instead of the top.&lt;/p&gt;
</content:encoded></item><item><title>Finding Child Elements In JavaScript</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Tue, 10 Dec 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;There are several techniques that allow us to discover if a particular DOM element has any children - whether there are any nodes contained within.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Warning: Nodes are usually, but not always HTML elements: the text inside a list element, for example.&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (element.firstChild) {
	// It has at least one
}

if (element.hasChildNodes()) {
	// Element has at least one
}

if (element.childNodes.length) {
	// Again, has at least one...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div id=&quot;box&quot;&amp;gt;
  &amp;lt;h1&amp;gt;Hello&amp;lt;/h1&amp;gt;
&amp;lt;/div&amp;gt;

var box = document.getElementById(&apos;box&apos;);

console.log(box.firstChild);
// Returns NodeList

console.log(box.hasChildNodes());
// Returns true

console.log(box.childNodes)
// Returns array
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Adding a meta tag with JavaScript</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Wed, 25 Sep 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Sometimes there isn&apos;t any other option but to use JS to alter markup when one doesn&apos;t have control over the  source. One Wapple user needed help ensuring that the viewport was being controlled - and for whatever reason - it was not being implemented which resulted in a sub-par experience for the customer. I was able to conjure up a teeny script which I dropped into her site:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var meta;

if (document.createElement &amp;amp;&amp;amp; (meta = document.createElement(&apos;meta&apos;))) {
  meta.name = &apos;viewport&apos;;
  meta.content = &apos;width=320&apos;;
  document.getElementsByTagName(&apos;head&apos;)[0].appendChild(meta);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Quite a straightforward slice of DOM manipulation, but it had the desired effect.&lt;/p&gt;
</content:encoded></item><item><title>DOM Selectors 101</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sat, 22 Jun 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;There are a variety of methods available that allow us to grab elements that are present in the Document Object Model (DOM).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;getElementById()
// Browser support: all
getElementsByClassName()
// IE9 +
getElementsByTagName()
// All
getElementsByName()
// All
querySelector()
// IE8 +
querySelectorAll()
// IE8 +
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The objects - in the loose sense of the word - that are returned are not arrays, but HTMLCollections. Other HTMLCollections include &lt;code&gt;document.images&lt;/code&gt; and &lt;code&gt;document.forms&lt;/code&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Numbers In JavaScript</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sun, 02 Jun 2013 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;The basics&lt;/h2&gt;
&lt;p&gt;Because JavaScript is a dynamically-typed language, we can declare a new number variable just as we would any other type: with the use of the &lt;code&gt;var&lt;/code&gt; keyword, a name, the assignment operator, and optionally, its value.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Declare variable as integer
var a = 123;
// Negative number
var b = -123;
// We can use decimal points, too
var c = 1.5;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In JavaScript, there is no difference between number types: we can&apos;t specify that one particular number is an integer, while another is a double. As far as the specification goes, all numbers are &quot;double-precision 64-bit format IEEE 754 values&quot;. Because operations will always return a floating-point number, the JavaScript developer needs to watch out for rounding errors when using decimals. The result may not always be what is expected, as the following illustrates:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0.1 + 0.2;
// 0.30000000000000004
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Weird, huh? This is because those numbers can&apos;t be represented exactly in binary form, and those representations are truncated by the implementation.
When dealing with operations that require a high degree of accuracy - hello financial transactions! - it&apos;s recommended to manually round the result, or shift the decimal so that £1.53 becomes 153 pence.&lt;/p&gt;
&lt;p&gt;Representing large monetary values in pence will eventually become unwieldy, so it&apos;s handy to know that they can be represented in scientific form. 1,000,000 will become 1E6: 1 to the power of 6.&lt;/p&gt;
&lt;p&gt;A further pitfall is that numbers beginning with a 0 are interpreted as octals. In a similar manner, numbers starting with &lt;code&gt;0x&lt;/code&gt; will be interpreted as hexadecimal - base 16. It&apos;s a sensible idea to always sanitise user inputs and double-check strings before working with a number which may be in a different base to what is expected.&lt;/p&gt;
&lt;h2&gt;Operators&lt;/h2&gt;
&lt;p&gt;In JavaScript, our operators include &lt;code&gt;+&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;, &lt;code&gt;*&lt;/code&gt;, and &lt;code&gt;/&lt;/code&gt;: the usual suspects. Division in Javascript can return floating point numbers
The modulo operator (&lt;code&gt;%&lt;/code&gt;) is used to return the remainder after division of two operands. 15 % 10 = 5.
When it comes the order of operations, JavaScript adheres to BODMAS: operands wrapped in parentheses are always evaluated first.&lt;/p&gt;
&lt;p&gt;It is possible to compare numbers using &lt;code&gt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;=&lt;/code&gt;, &lt;code&gt;&amp;gt;=&lt;/code&gt;, &lt;code&gt;===&lt;/code&gt; (equality) and &lt;code&gt;!==&lt;/code&gt; (not equal to).&lt;/p&gt;
&lt;h2&gt;Parsing Numbers From Strings&lt;/h2&gt;
&lt;p&gt;In order to extract a number from a string, JavaScript&apos;s provides a function called &lt;code&gt;parseInt(value [, base])&lt;/code&gt;. This function will work through the characters of the string until it finds a character that is not a numeral in the specified base. Thus:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;parseInt(&quot;abc123&quot;, 10); // NaN
parseInt(&quot;123abc&quot;, 10); // 123
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When using it, it&apos;s sensible to get in the habit of adding a base as the second (optional) argument. While most implementations will deliver a decimal if you omit it, you do run the risk of ending up with an octal or hexadecimal number.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;parseInt(&quot;123abc&quot;, 2); // 1 (Only that first character is accepted in binary)
parseInt(&quot;123abc&quot;, 8); // 83
parseInt(&quot;123abc&quot;, 16); // 11946485
parseInt(&quot;0123abc&quot;); // 123 (Current implementation no longer interprets as an octal
parseInt(&quot;0x123abc&quot;); // 11946485
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On occasions, complex strings can result in &lt;code&gt;NaN&lt;/code&gt;: Not a Number. Before working on the result of a &lt;code&gt;parseInt&lt;/code&gt; function, it&apos;s wise to check for the presence of &lt;code&gt;NaN&lt;/code&gt; using &lt;code&gt;isNaN()&lt;/code&gt;. To complicate matters, &lt;code&gt;NaN&lt;/code&gt; is not equal to itself.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;isNaN(NaN) // true
NaN === NaN // false
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To carry out similar operations with floating-point numbers, we can use the aptly-titled &lt;code&gt;parseFloat()&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Methods&lt;/h2&gt;
&lt;p&gt;JavaScript comes with a robust assortment of methods to manipulate your numbers - all are name-spaced under the Math object.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Math.random()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Generates a random number between its default bounds of 0 and 1. It is seeded with the current time.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Math.round()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rounds the supplied number to the nearest whole number&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Math.floor()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rounds the number down&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Math.ceil()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rounds number up&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Math.pow(base, exponent)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns the result of the base to the power of its exponent: eg. &lt;code&gt;Math.pow(2, 3) == 8&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Math.sqrt()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns the square root of the supplied argument&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</content:encoded></item><item><title>JavaScript Callbacks</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Tue, 28 May 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A callback is a method designated to handle the response of an AJAX call once it gets back to your method.
JavaScript methods are treated as first-class objects, which means that they can be passed around just like objects, and they can be attached to all manner of events.
Callbacks are used to prevent operation being blocked until the initial operation is completed.
Callbacks are useful when the function needs to perform actions before the callback is executed, or when the function does not have meaningful return values to act on.&lt;/p&gt;
</content:encoded></item><item><title>Function declarations versus function expressions</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Thu, 23 May 2013 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;Function declaration&lt;/h3&gt;
&lt;p&gt;A function declaration is written like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function example() {}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A declared function is evaluated at parse-time - when the browser&apos;s Javascript engine gives it the once-over to see what it contains - and thus are loaded before any code is executed.
In practical terms, this function can now be called at anytime: perhaps in code that is defined before the function. This is due to the idea of hoisting: a facet of the language that allows variables to be &apos;hoisted&apos; to the top of the scope in which it is defined, regardless of where it&apos;s placed. As it happens, a variable is created with the same name as the function.&lt;/p&gt;
&lt;h3&gt;Function expression&lt;/h3&gt;
&lt;p&gt;A function expression looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var example = function() {}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This kind of function is evaluated at run-time and means that &lt;code&gt;example()&lt;/code&gt; can&apos;t be called until the JS engine has reached that point in your code. If it&apos;s referenced before that, you&apos;ll get an error.&lt;/p&gt;
&lt;p&gt;In reality, they&apos;re incredibly similar functionality wise. Just make sure you&apos;re aware of how the Javascript interpreter is going to load them.&lt;/p&gt;
&lt;h3&gt;Function constructor&lt;/h3&gt;
&lt;p&gt;This is a concept that was new to me before writing this - so perhaps the self-documentation idea does have merits!
It is possible to write:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var example = new Function() {}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, Mozilla&apos;s Developer Network advises against this approach because:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;it needs the function body as a string, which may prevent optimizations&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In JavaScript: The Good Parts, Douglas Crockford recommends that JS authors use function expressions because&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;it makes it clear &lt;em&gt;foo&lt;/em&gt; is a variable containing a function value. It is important to understand that functions are values.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Coming from a &apos;classical&apos; Computer Science background, I was initially more comfortable with function declarations. In practice, I prefer the aesthetics of the function expression: it improves legibility no end. You just need to remember that you can&apos;t call the function before it&apos;s been declared!&lt;/p&gt;
&lt;p&gt;A few things to bear in mind:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A function name cannot be changed, but a variable to which a function is assigned &lt;em&gt;can&lt;/em&gt; be reassigned.&lt;/li&gt;
&lt;li&gt;The function name can only be used within the function&apos;s body.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Strings in JavaScript</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sat, 18 May 2013 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Escape Characters&lt;/h2&gt;
&lt;p&gt;There are some useful ways to format strings in JavaScript:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A literal backslash would be written as &lt;code&gt;\\&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;To start a new line, &lt;code&gt;\n&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;To insert a tab, we use &lt;code&gt;\t&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Concatenating Strings&lt;/h2&gt;
&lt;p&gt;It&apos;s possible to join two (or more strings) like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var hello = &quot;Hello &quot;;
var world = &quot;world!&quot;;

var helloWorld = hello + world;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This technique is useful for being able to break one long string over several lines for ease of editing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var longString = &quot;Hello, this could be a &quot; +
  &quot;rather long string if &quot; +
	&quot;allowed to run on one &quot; +
	&quot;line.&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Methods&lt;/h2&gt;
&lt;p&gt;JavaScript&apos;s String class gives us a healthy number of methods that allow us to manipulate them. These include:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;length&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A property to describe the length of the string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;indexOf()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Allows us to discover where a particular string exists&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;charAt(index)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Used to discover the character at the specified index. &lt;em&gt;Don&apos;t forget indexes are zero-based!&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;substr(start, length)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns a snippet of the original string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;toLowerCase()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns a new string that is all lower case.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;toUpperCase()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns a new string that is in upper case.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Comparing Strings&lt;/h2&gt;
&lt;p&gt;By calculating the ASCII values of each character, JavaScript can help us determine if one string is equal to another.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var first = &quot;Hello&quot;;
var second = &quot;hello&quot;;

if (first === second) {
  console.log(&apos;Strings are equal&apos;);
} else {
  console.log(&apos;Strings are different&apos;);
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Variable Scope in JavaScript</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Sat, 18 May 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Variables belong to a scope, and that particular scope determines where a variable can be used. Scope is delineated with &lt;code&gt;{&lt;/code&gt; and &lt;code&gt;}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;A function can use a variable declared outside of it, since it is available globally:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var world = &quot;world&quot;;

function sayHello() {
  var hello = &quot;Hello &quot;;
  console.log(hello + world);
}

sayHello();
// Hello world
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But trying to invoke a function&apos;s variable from outside will result in an error: &lt;code&gt;hello is not defined&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Be careful when defining global variables - you don&apos;t want to mistakenly overwrite a value you are relying on. There are techniques to try and counter the possibility of this happening: concepts such as &lt;a href=&quot;http://danmatthew.co.uk/2014/02/03/closures-101&quot;&gt;closures&lt;/a&gt;, or design patterns like the &lt;a href=&quot;http://yuiblog.com/blog/2007/06/12/module-pattern/&quot;&gt;module pattern&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>The Difference Between Methods And Functions</title><link>https://danmatthew.co.uk/notes/undefined/</link><guid isPermaLink="true">https://danmatthew.co.uk/notes/undefined/</guid><pubDate>Fri, 10 May 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Often used interchangeably to describe the same thing, a method is a function used within the context of a class or object.&lt;/p&gt;
&lt;p&gt;In JavaScript, &lt;code&gt;Math.random()&lt;/code&gt; is a method, as it is a function of the Math class.&lt;/p&gt;
</content:encoded></item></channel></rss>