<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Matthew Spencer</title>
    <description></description>
    <link>https://transitory.technology/</link>
    <atom:link href="https://transitory.technology/feed/" rel="self" type="application/rss+xml"/>
    <pubDate>Tue, 14 Apr 2020 14:50:49 +0000</pubDate>
    <lastBuildDate>Tue, 14 Apr 2020 14:50:49 +0000</lastBuildDate>
    <generator>Jekyll v3.8.5</generator>
    
      <item>
        <title>More or less how I setup an iTunes alternative</title>
        <description>&lt;p&gt;In 2020 my resolution was not to use music streaming services and spend money in a way that goes more directly to artists through Bandcamp, &lt;a href=&quot;https://resonate.is/&quot;&gt;Resonate&lt;/a&gt;, or iTunes. One problem I ran into tho is that iTunes is pretty buggy these days — asking me to log in over and over and randomly quitting while I’m listing to music.&lt;/p&gt;

&lt;p&gt;Since most of my time spent listening to music is at my desk at work I was looking for desktop options primarily. I couldn’t really find many and felt so-so about the options until someone mentioned MPD (&lt;a href=&quot;https://www.musicpd.org/&quot;&gt;Music Player Daemon&lt;/a&gt;). Since I didn’t really find it easy to setup at first I wanted to share my experience setting up &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mpd&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ncmpcpp&lt;/code&gt; (&lt;a href=&quot;https://rybczak.net/ncmpcpp/&quot;&gt;NCurses Music Player Client (Plus Plus)&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;First here’s my best explanations for what these are:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mpd&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It plays audio files, keeps a database of music, and can be used to make playlists. It can run off a networked server or locally on a laptop. &lt;strong&gt;It has no visual interface.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ncmcpp&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is a text-based interface for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mpd&lt;/code&gt; that runs in a terminal.&lt;/p&gt;

&lt;h2 id=&quot;installation&quot;&gt;Installation&lt;/h2&gt;

&lt;p&gt;I used &lt;a href=&quot;https://brew.sh/&quot;&gt;Homebrew&lt;/a&gt; to install them although I’m sure there are other ways:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;brew install mpd
brew install ncmp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you want to use last.fm with MPD you will also want to:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;brew install mpdscribble
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;setup&quot;&gt;Setup&lt;/h2&gt;

&lt;h3 id=&quot;mpdmpdconf&quot;&gt;&lt;a href=&quot;https://github.com/matthewspencer/dotfiles/blob/master/.mpd/mpd.conf&quot;&gt;~/.mpd/mpd.conf&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;MPD needs to know a few things when it starts like where your music files are and where it should save state, playlists, etc.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;music_directory    &quot;~/Music&quot;
playlist_directory &quot;~/.mpd/playlists&quot;
db_file            &quot;~/.mpd/mpd.db&quot;
log_file           &quot;~/.mpd/mpd.log&quot;
pid_file           &quot;~/.mpd/mpd.pid&quot;
state_file         &quot;~/.mpd/mpdstate&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Which I believe you’ll need to create:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir -p ~/.mpd/playlists
touch ~/.mpd/{mpd.db,mpd.log,mpd.pid,mpdstate}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next I struggled with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audio_output&lt;/code&gt; configuration a bit, especially with bluetooth headphones, but the following works great for MacOS:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;audio_output {
    name       &quot;default&quot;
    type       &quot;ao&quot;
    mixer_type &quot;software&quot;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There’s a &lt;a href=&quot;https://linux.die.net/man/5/mpd.conf&quot;&gt;bunch more options&lt;/a&gt; but these are the most important.&lt;/p&gt;

&lt;h3 id=&quot;ncmpcppconfig&quot;&gt;&lt;a href=&quot;https://github.com/matthewspencer/dotfiles/blob/master/.ncmpcpp/config&quot;&gt;~/.ncmpcpp/config&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Most of my config is personal preference, but I wanted to talk about a few parts:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Ignore &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;the&lt;/code&gt; from artist names (put The Raincoats under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;r&lt;/code&gt; not &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t&lt;/code&gt;) using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ignore_leading_the = yes&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;I use 25% left pane &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;locked_screen_width_part = 25&lt;/code&gt; with the visualizer &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;startup_screen = visualizer&lt;/code&gt; and 75% right pane with the playlist viewer &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;startup_slave_screen = playlist&lt;/code&gt; focused by default &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;startup_slave_screen_focus = yes&lt;/code&gt; (ugh I know master/slave nomenclature)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also as above there’s a bunch more &lt;a href=&quot;https://github.com/arybczak/ncmpcpp/blob/master/doc/config&quot;&gt;config options&lt;/a&gt; I don’t talk about.&lt;/p&gt;

&lt;h3 id=&quot;the-visualizer&quot;&gt;The Visualizer&lt;/h3&gt;

&lt;p&gt;I really like the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ncmpcpp&lt;/code&gt; visualizer — it is cute and feels futuristic. To set it up you’ll need to tell &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mpd&lt;/code&gt; to output the visualizer bits and configure some preferences in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ncmpcpp&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In &lt;a href=&quot;https://github.com/matthewspencer/dotfiles/blob/master/.mpd/mpd.conf&quot;&gt;~/.mpd/mpd.conf&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;audio_output {
    name   &quot;visualizer&quot;
    type   &quot;fifo&quot;
    path   &quot;/tmp/mpd.fifo&quot;
    format &quot;44100:16:1&quot;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;(I assume &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fifo&lt;/code&gt; refers to “first in first out” but I’ve never specifically looked into it.)&lt;/p&gt;

&lt;p&gt;And in &lt;a href=&quot;https://github.com/matthewspencer/dotfiles/blob/master/.ncmpcpp/config&quot;&gt;~/.ncmpcpp/config&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# I think this has to match the name above,
# but I never really looked into it
visualizer_output_name = visualizer

## defaults to 30
visualizer_sync_interval = 30

## no  - 44100:16:1
## yes - 44100:16:2
visualizer_in_stereo = no

## spectrum, wave, wave_filled, ellipse
visualizer_type = ellipse
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Definitely check out the different types, but &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ellipse&lt;/code&gt; is my fave.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/uploads/2020/01/15/ncmpcpp-visualizer.png&quot; alt=&quot;ncmpcpp player with visualizer&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;starting&quot;&gt;Starting&lt;/h2&gt;

&lt;p&gt;To start &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mpd&lt;/code&gt; it is best to use Homebrew:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;brew services start mpd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You can &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo brew service start mpd&lt;/code&gt; if you want to run it at boot, but since I rarely reboot I opted not to since it makes configuration paths more of a pain.&lt;/p&gt;

&lt;p&gt;To start &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ncmpcpp&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ncmpcpp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;keyboard-shortcuts&quot;&gt;Keyboard shortcuts&lt;/h2&gt;

&lt;h3 id=&quot;ncmpcpp-shortcuts-i-use-most&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ncmpcpp&lt;/code&gt; shortcuts I use most&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p&lt;/code&gt; play/pause&lt;/li&gt;
  &lt;li&gt;` (backtick) in playlist edit to open random then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s&lt;/code&gt; for songs and 50 or whatever amount&lt;/li&gt;
  &lt;li&gt;1-8 for different screens, especially &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt; for the current playlist and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;4&lt;/code&gt; for the normal 3 column artist/album/song view&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;q&lt;/code&gt; quit&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;u&lt;/code&gt; update the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mpd&lt;/code&gt; database&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also setup &lt;a href=&quot;https://github.com/matthewspencer/dotfiles/blob/master/.ncmpcpp/bindings&quot;&gt;vim-like bindings&lt;/a&gt; since I expected them to work and they didn’t.&lt;/p&gt;

&lt;h3 id=&quot;setting-up-media-keys&quot;&gt;Setting up media keys&lt;/h3&gt;

&lt;p&gt;This part was a real pain. Basically to use the play/pause, next, and previous keys you have to do the following.&lt;/p&gt;

&lt;p&gt;Install &lt;a href=&quot;https://pqrs.org/osx/karabiner/&quot;&gt;Karabiner&lt;/a&gt; to edit MacOS key bindings:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;brew cask install karabiner-elements
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Install &lt;a href=&quot;https://musicpd.org/clients/mpc/&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mpc&lt;/code&gt;&lt;/a&gt; for a simple interface to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mpd&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;brew install mpc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Configuring Karabiner:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Open Karabiner-Elemnents.app (you’ll want to have this open with the &lt;strong&gt;Login items&lt;/strong&gt;)&lt;/li&gt;
  &lt;li&gt;Bind the media keys for the following in complex modifications:
    &lt;ul&gt;
      &lt;li&gt;play/pause &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/local/bin/mpc toggle&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;prev &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/local/bin/mpc prev&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;next &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/local/bin/mpc next&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;I found it easiest to edit &lt;a href=&quot;https://github.com/matthewspencer/dotfiles/blob/master/.config/karabiner/karabiner.json&quot;&gt;~/.config/karabiner/karabiner.json&lt;/a&gt; directly instead of the editor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You can either use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fn&lt;/code&gt; key or not, but whatever you put in the config will work that way disregarding the setting in System Preferences.&lt;/p&gt;

&lt;h2 id=&quot;adding-new-music&quot;&gt;Adding new music&lt;/h2&gt;

&lt;p&gt;One day I intend to setup &lt;a href=&quot;https://beets.readthedocs.io/en/stable/&quot;&gt;beets&lt;/a&gt; for organizing files, but today I still use iTunes to import new music and hit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;u&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ncmpcpp&lt;/code&gt; to update the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mpd&lt;/code&gt; database.&lt;/p&gt;
</description>
        <pubDate>Wed, 15 Jan 2020 00:00:00 +0000</pubDate>
        <link>https://transitory.technology/mpd-and-ncmpcpp/</link>
        <guid isPermaLink="true">https://transitory.technology/mpd-and-ncmpcpp/</guid>
        
        <category>mpd,</category>
        
        <category>ncmpcpp</category>
        
        
      </item>
    
      <item>
        <title>Becoming a web developer!</title>
        <description>&lt;p&gt;A friend asked me recently for a rundown of things to learn to get an entry-level web developer position. The following is the email I sent, which ended up being longer than I initially anticipated! All of this I based on my experience. I’m curious to hear of any resources I may have omitted due to ignorance. This could likely be improved!&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;So a few things in general:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;I’ve learned way more from trying stuff out than reading about it. Like we might be different kinds of learners, but I think side / example projects are invaluable. Even if they are just like for personal uses.&lt;/li&gt;
  &lt;li&gt;I Google everything all the time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;HTML&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://html5forwebdesigners.com/&quot;&gt;HTML5 For Web Designers&lt;/a&gt;: A book about newer stuff happening with the HTML spec. Also has a good history. (The full text of the book is available online).&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.w3.org/MarkUp/Guide/&quot;&gt;Dave Raggett’s Introduction to HTML&lt;/a&gt;: A very mellow guide to how HTML documents are structured. I suspect you know a lot of this already.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;CSS&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_started&quot;&gt;Getting started with CSS&lt;/a&gt;: Goes a bit into the history of CSS, how it works, some tutorials and examples. It’s a little dry, but it is the best I can think of.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.smashingmagazine.com/2009/10/mastering-css-coding-getting-started/&quot;&gt;Mastering CSS coding&lt;/a&gt;: A little dated, but gets into the box model, which is important.&lt;/li&gt;
  &lt;li&gt;Responsive Web Design: I turned this into a whole section (below) because it is super important.&lt;/li&gt;
  &lt;li&gt;CSS Preprocessors: Writing CSS can be repetitive and tedious, so people write in languages that get compiled to CSS like &lt;a href=&quot;http://sass-lang.com/&quot;&gt;Sass&lt;/a&gt; and &lt;a href=&quot;http://lesscss.org/&quot;&gt;Less&lt;/a&gt;. It’s better to learn CSS first, but this is something you’ll likely run into down the line.&lt;/li&gt;
  &lt;li&gt;CSS Frameworks: Again, writing CSS can be really fun and rewarding, but also a drag. There are tons of CSS frameworks that try to offer common patterns, especially for things like layout. A good example is &lt;a href=&quot;http://getbootstrap.com/&quot;&gt;Bootstrap&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://jsforcats.com/&quot;&gt;JavaScript For Cats&lt;/a&gt;: A pretty good introduction to JavaScript and interacting with the browser console. Actually pretty good introduction to programming concepts in general (loops, arrays, objects…).&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript&quot;&gt;A re-introduction to JavaScript&lt;/a&gt;: Goes in deeper on JavaScript as a programming language.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://bdcampbell.net/javascript/book/javascript_the_good_parts.pdf&quot;&gt;JavaScript: The Good Parts&lt;/a&gt;: Another book (PDF), gets &lt;em&gt;way&lt;/em&gt; more technical.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Blogs / Resources&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://css-tricks.com/&quot;&gt;CSS-Tricks&lt;/a&gt;: Definitely more than CSS. Lots of good examples/tutorials. Probably end up here Googling for help.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.html5rocks.com/en/&quot;&gt;HTML5 Rocks&lt;/a&gt;: Sponsored by Google. Goes pretty in depth to new stuff coming to browsers.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://dropshado.ws/&quot;&gt;dropshado.ws&lt;/a&gt;: Gets into edge cases and minutiae of web development. Tends to be more advanced stuff.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/&quot;&gt;MDN&lt;/a&gt;: Wiki for web development. Very good. Always opt for this over w3 schools in search results. (That site used to be good, but now it is shitty, full of ads, and kind of spammy).&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/&quot;&gt;Stack Overflow&lt;/a&gt;: Question and answer site for programmers. Often I Google something and end up here because someone has already asked and answered the question.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://howdns.works/&quot;&gt;How DNS Works&lt;/a&gt;: A really good series on DNS, basically how like google.com gets resolved to a server somewhere.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Courses&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://css-tricks.com/lodge/&quot;&gt;The Lodge&lt;/a&gt;: From CSS-Tricks. Free.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.codecademy.com/&quot;&gt;Code Academy&lt;/a&gt;: Also free, some additional stuff not covered on The Lodge.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://teamtreehouse.com/&quot;&gt;Treehouse&lt;/a&gt;: Cost money, more support (I assume!).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tools&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Text editors: They are all pretty good. Super teched out folks use &lt;a href=&quot;http://www.vim.org/&quot;&gt;vim&lt;/a&gt; or &lt;a href=&quot;https://www.gnu.org/software/emacs/&quot;&gt;emacs&lt;/a&gt; (don’t use these). I use &lt;a href=&quot;https://www.sublimetext.com/&quot;&gt;Sublime Text&lt;/a&gt;. &lt;a href=&quot;https://panic.com/coda/&quot;&gt;Coda&lt;/a&gt; is nice because it has a built in browser for testing. &lt;a href=&quot;https://atom.io/&quot;&gt;Atom&lt;/a&gt; is like Sublime Text but free.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://codepen.io/&quot;&gt;CodePen&lt;/a&gt;: Text editor in the browser. Nice feedback loop of edit =&amp;gt; preview =&amp;gt; edit =&amp;gt; preview… Associated with the CSS-Tricks folks. Good place to get started.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.chrome.com/devtools&quot;&gt;Chrome Developer Tools&lt;/a&gt;: The cool thing about the web is you can always view the source of websites and see how they are made.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Git / Version Control&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.atlassian.com/git/&quot;&gt;Atlassian’s Getting Git Right&lt;/a&gt;: The whole series of tutorials is pretty good, I refer back to it often. Good place to get started: &lt;a href=&quot;https://www.atlassian.com/git/tutorials/what-is-version-control&quot;&gt;What is version control&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/&quot;&gt;GitHub&lt;/a&gt;: A git repository hosting service. Important, monolithic. &lt;a href=&quot;https://github.com/matthewspencer/&quot;&gt;This is me&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.git-tower.com/&quot;&gt;Tower&lt;/a&gt;: A good GUI for git. Cost money. (Graphical User Interface… as apposed to a Command Line Interface or CLI…) GitHub has a &lt;a href=&quot;https://desktop.github.com/&quot;&gt;free GUI&lt;/a&gt;. It’s okay.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Responsive Web Design&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is perhaps more of a conceptual point, but is mega-important to writing CSS. So, briefly… websites used to be designed for a specific screen size (a long time ago 640px or 800px wide, in more recent eras 960px). After the iPhone (this is somewhat of a simplification, but you get the idea), the idea is to build websites that are flexible to any screen size (within reason), often considering the mobile screen first and expanding to the larger tablet and desktop views. This was an important conceptual change in the early 2010s, but now is 100% integrated with like everything. So mega-important. Anyhow, here’s some articles and books:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://alistapart.com/article/responsive-web-design&quot;&gt;Responsive Web Design&lt;/a&gt;: Early article coining the terminology and discussing the benefits of the approach.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.smashingmagazine.com/2011/01/guidelines-for-responsive-web-design/&quot;&gt;Responsive Web Design: What It Is and How To Use It&lt;/a&gt;: Kind of rehashes the previous link but gets more into media queries.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://abookapart.com/products/responsive-web-design&quot;&gt;Responsive Web Design&lt;/a&gt;: Book by the guy who wrote the first article.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developers.google.com/web/fundamentals/design-and-ui/responsive/fundamentals/?hl=en&quot;&gt;Responsive web design basics&lt;/a&gt;: Documentation of the technical details of responsive web design, made by Google.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://abookapart.com/products/mobile-first&quot;&gt;Mobile First&lt;/a&gt;: Another book on the concept of developing for mobile first which I briefly mentioned above.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Web Standards&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Oh god, this should also be mentioned. There used to be a time when each browser supported different things. Writing cross browser code was a nightmare. There was a big push for web standards. Things have gotten better, but there is still not 100% parity between all browsers, especially mobile. W3C &amp;amp; WHATWG both kind of manage the HTML spec, W3C for CSS too, and ECMA for JavaScript.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vocabulary&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;CSS: Cascading Stylesheets&lt;/li&gt;
  &lt;li&gt;HTML: HyperText Markup Language&lt;/li&gt;
  &lt;li&gt;DNS: Domain Name System&lt;/li&gt;
  &lt;li&gt;API: application programming interface&lt;/li&gt;
  &lt;li&gt;GUI: graphic user interface&lt;/li&gt;
  &lt;li&gt;CLI: command line interface&lt;/li&gt;
  &lt;li&gt;Front-end: Things that happen in the browser—HTML, CSS, JavaScript.&lt;/li&gt;
  &lt;li&gt;Back-end: Things that happen on the server. Lots more programming languages, some common PHP, Ruby, Python, MySQL (databases), Node.js (JavaScript again, this is confusing I know)…&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 08 Apr 2016 00:00:00 +0000</pubDate>
        <link>https://transitory.technology/becoming-a-web-developer/</link>
        <guid isPermaLink="true">https://transitory.technology/becoming-a-web-developer/</guid>
        
        <category>Resources</category>
        
        
      </item>
    
      <item>
        <title>Browser extensions and restrictive CSP headers</title>
        <description>&lt;p&gt;Recently I’ve been working on browser extensions for Chrome and Safari. One of the major hurdles was dealing with sites that have restrictive &lt;a href=&quot;http://www.html5rocks.com/en/tutorials/security/content-security-policy/&quot;&gt;Content Security Policy&lt;/a&gt; (CSP) headers. CSP headers are used to prevent XSS attacks or code injection from unauthorized sources. Some sites (e.g. &lt;a href=&quot;/uploads/2016/04/07/twitter-content-security-policy.png&quot;&gt;twitter.com&lt;/a&gt;) make full use of them. And, the thing is, when you boil it down, browser extensions are just that, code injection.&lt;/p&gt;

&lt;p&gt;Let’s say you wanted to load a stylesheet from your server, you’re likely to get &lt;a href=&quot;/uploads/2016/04/07/csp-error.png&quot;&gt;this gnarly console error&lt;/a&gt;. This is the browser telling you that they honoring this site’s CSP. This is good and important, but is frustrating for our purposes.&lt;/p&gt;

&lt;p&gt;One approach that I’ve been using for Chrome is using the browser extension to rewrite CSP headers. I’m going to show how this is possible here for posterity, but, spoiler, this is a bad idea and you shouldn’t do this and there are crazy caveats and I’m going to give you a better workaround!&lt;/p&gt;

&lt;p&gt;Chrome has an API (&lt;a href=&quot;https://developer.chrome.com/extensions/webRequest&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;chrome.webRequest&lt;/code&gt;&lt;/a&gt;) which gives you, the browser extension developer, access to every request the browser makes. To enable access to this API add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;webRequest&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;webRequestBlocking&lt;/code&gt; to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;permissions&lt;/code&gt; array in manifest.json:&lt;/p&gt;

&lt;div data-gist=&quot;a48f17eb2db3a1c5c0b1dcf625e6a312&quot; data-file=&quot;1-manifest-webrequest.json&quot;&gt;&lt;/div&gt;

&lt;p&gt;Additionally, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;webRequest&lt;/code&gt; API is only available for the older (deprecated?) &lt;a href=&quot;https://developer.chrome.com/extensions/background_pages&quot;&gt;Background Pages&lt;/a&gt;. To switch from the newer, more performant &lt;a href=&quot;https://developer.chrome.com/extensions/event_pages&quot;&gt;Event Pages&lt;/a&gt; set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;persistent&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;background&lt;/code&gt; object in manifest.json:&lt;/p&gt;

&lt;div data-gist=&quot;a48f17eb2db3a1c5c0b1dcf625e6a312&quot; data-file=&quot;2-manifest-persistent.json&quot;&gt;&lt;/div&gt;

&lt;p&gt;Okay, now let’s hook into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;chrome.webRequest.onHeadersReceived&lt;/code&gt; event and rewrite some CSP headers!&lt;/p&gt;

&lt;div data-gist=&quot;a48f17eb2db3a1c5c0b1dcf625e6a312&quot; data-file=&quot;3-on-headers-received.js&quot;&gt;&lt;/div&gt;

&lt;p&gt;Pretty wild right? Well this &lt;em&gt;works&lt;/em&gt;, but there are said caveats. The major drawback to this approach is that &lt;strong&gt;only one installed extension can rewrite headers&lt;/strong&gt;&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. This would only work for the most recently installed extension, so there are no assurances that doing something gross like this would even work 100% of the time. And this only works for Chrome, there are no parallels for Safari.&lt;/p&gt;

&lt;p&gt;Now I said there was a better workaround. It is somewhat less gross and works for both extensions! Reading through Apple’s (somewhat inscrutable) documentation I discovered Safari extension code is sandboxed. This means the browser considers it safe and doesn’t consider CSP headers for code loaded from the extension. This mean an extension file could be used as a proxy to load files off of our server.&lt;/p&gt;

&lt;p&gt;The idea is to use a content (or injected content) script to load an “unsafe” iframe inside of a “safe” iframe.&lt;sup id=&quot;fnref:2&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; Below is the basic idea, but it can be accomplished in different ways:&lt;/p&gt;

&lt;p&gt;The safe iframe looks like this and gets appended to the current page:&lt;/p&gt;

&lt;div data-gist=&quot;a48f17eb2db3a1c5c0b1dcf625e6a312&quot; data-file=&quot;4-iframe.html&quot;&gt;&lt;/div&gt;

&lt;p&gt;The linked script looks like this and is used to load the unsafe iframe&lt;sup id=&quot;fnref:3&quot;&gt;&lt;a href=&quot;#fn:3&quot; class=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;

&lt;div data-gist=&quot;a48f17eb2db3a1c5c0b1dcf625e6a312&quot; data-file=&quot;5-iframe.js&quot;&gt;&lt;/div&gt;

&lt;p&gt;Then inside the extension’s background (or global) script:&lt;/p&gt;

&lt;div data-gist=&quot;a48f17eb2db3a1c5c0b1dcf625e6a312&quot; data-file=&quot;6-iframe-usage.js&quot;&gt;&lt;/div&gt;

&lt;p&gt;Side note: Chrome needs these files to be whitelisted in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;web_accessible_resources&lt;/code&gt; array in manifest.json:&lt;/p&gt;

&lt;div data-gist=&quot;a48f17eb2db3a1c5c0b1dcf625e6a312&quot; data-file=&quot;7-manifest-accessible-resources.json&quot;&gt;&lt;/div&gt;

&lt;p&gt;So the essence of this approach: a safe iframe is loaded directly from the extension’s directory, its contents are deemed safe by the browser, magic. Hopefully this helps you in your future extension explorations.&lt;/p&gt;

&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;The &lt;a href=&quot;/uploads/2016/04/07/only-one.png&quot;&gt;Chrome extension error&lt;/a&gt; indicating as much. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot;&gt;
      &lt;p&gt;This idea was definitely inspired by advertisers and their “safe” iframes. &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:3&quot;&gt;
      &lt;p&gt;Chrome doesn’t think inline JavaScript is safe so it is loaded from an external file. &lt;a href=&quot;#fnref:3&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Thu, 07 Apr 2016 00:00:00 +0000</pubDate>
        <link>https://transitory.technology/browser-extensions-and-csp-headers/</link>
        <guid isPermaLink="true">https://transitory.technology/browser-extensions-and-csp-headers/</guid>
        
        <category>JavaScript,</category>
        
        <category>Chrome,</category>
        
        <category>Safari,</category>
        
        <category>Extensions,</category>
        
        <category>CSP,</category>
        
        <category>Security</category>
        
        
      </item>
    
      <item>
        <title>setDragImage Edge Cases</title>
        <description>&lt;h3 id=&quot;what-this-is&quot;&gt;What this is&lt;/h3&gt;

&lt;p&gt;The &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API&quot;&gt;HTML Drag and Drop API&lt;/a&gt; is an important tool for building dynamic interfaces, but it is inconsistently implemented across browsers (which can be &lt;a href=&quot;http://www.quirksmode.org/blog/archives/2009/09/the_html5_drag.html&quot;&gt;&lt;em&gt;quite frustrating&lt;/em&gt;&lt;/a&gt;). The goal of this post is to enumerate some of these rough edges, specifically with regards to the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setDragImage&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setDragImage&lt;/code&gt;&lt;/a&gt; method on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dataTransfer&lt;/code&gt; object&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;h3 id=&quot;firefox-and-the-dom&quot;&gt;Firefox and the DOM&lt;/h3&gt;

&lt;p&gt;When using a custom element for the drag image, Firefox prefers it to be in the DOM. In fact, it won’t display it otherwise. Safari and Chrome permit this, but they don’t like it. They’ll often pick up weird artifacts in the drag image from nearby elements.&lt;/p&gt;

&lt;p&gt;Unfortunately, there isn’t a good way to test for this other than looking at the browser’s user agent&lt;sup id=&quot;fnref:2&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;

&lt;div data-gist=&quot;77ca95e1c67ee877df9f&quot; data-file=&quot;1-is-firefox.js&quot;&gt;&lt;/div&gt;

&lt;p&gt;It works like this, on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dragstart&lt;/code&gt; add the element to the DOM for Firefox:&lt;/p&gt;

&lt;div data-gist=&quot;77ca95e1c67ee877df9f&quot; data-file=&quot;2-dragstart.js&quot;&gt;&lt;/div&gt;

&lt;p&gt;And on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dragend&lt;/code&gt; clean-up the drag image:&lt;/p&gt;

&lt;div data-gist=&quot;77ca95e1c67ee877df9f&quot; data-file=&quot;3-dragend.js&quot;&gt;&lt;/div&gt;

&lt;h3 id=&quot;using-an-image&quot;&gt;Using an image&lt;/h3&gt;

&lt;p&gt;To use an image (or background image) for the drag image, it must first be downloaded. Otherwise the drag image appears blank on drag. Images can be prefetched using an image element:&lt;/p&gt;

&lt;div data-gist=&quot;77ca95e1c67ee877df9f&quot; data-file=&quot;4-prefetch.js&quot;&gt;&lt;/div&gt;

&lt;p&gt;Also worth noting, animated gifs do not animate when set as the drag image.&lt;/p&gt;

&lt;h3 id=&quot;positioning-the-drag-image&quot;&gt;Positioning the drag image&lt;/h3&gt;

&lt;p&gt;The latter two arguments for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setDragImage&lt;/code&gt; are the x and y offset of the drag image relative to the cursor. Often examples set these to a specific number like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;, but this differs from the normal &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;img&lt;/code&gt; drag behavior which sets the drag image relative to the cursor position on mousedown.&lt;/p&gt;

&lt;p&gt;To recreate this behavior, use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getBoundingClientRect()&lt;/code&gt; to calculate the offset position:&lt;/p&gt;

&lt;div data-gist=&quot;77ca95e1c67ee877df9f&quot; data-file=&quot;5-offset.js&quot;&gt;&lt;/div&gt;

&lt;h3 id=&quot;maximum-drag-image-dimensions&quot;&gt;Maximum drag image dimensions&lt;/h3&gt;

&lt;p&gt;Anecdotally these are the largest pixel dimensions for a drag image before cropping occurs:&lt;/p&gt;

&lt;p&gt;400×400 - Safari/Chrome &lt;br /&gt;
700×450 - Firefox&lt;/p&gt;

&lt;p&gt;Noting this, it is important to scale the dimension of the drag image as well as its offset position. The following scales the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clientRect&lt;/code&gt; to the smallest maximum:&lt;/p&gt;

&lt;div data-gist=&quot;77ca95e1c67ee877df9f&quot; data-file=&quot;6-scaled-clientrect.js&quot;&gt;&lt;/div&gt;

&lt;h3 id=&quot;firefox-and-windowdevicepixelratio&quot;&gt;Firefox and window.devicePixelRatio&lt;/h3&gt;

&lt;p&gt;Unlike Safari and Chrome, Firefox sees the actual dimensions not the retina-scaled dimensions. Multiply the offsets by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;devicePixelRatio&lt;/code&gt;, otherwise Firefox’s offset is always off on retina screens&lt;sup id=&quot;fnref:3&quot;&gt;&lt;a href=&quot;#fn:3&quot; class=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;

&lt;div data-gist=&quot;77ca95e1c67ee877df9f&quot; data-file=&quot;7-retina.js&quot;&gt;&lt;/div&gt;

&lt;h3 id=&quot;firefox-and-the-drag-event&quot;&gt;Firefox and the drag event&lt;/h3&gt;

&lt;p&gt;Safari and Chrome provide dynamic mouse position on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;drag&lt;/code&gt; event. Firefox does not (&lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=505521&quot;&gt;wontfix&lt;/a&gt;). To get around this just use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dragover&lt;/code&gt; event which provides the mouse position in all browsers.&lt;/p&gt;

&lt;h3 id=&quot;other-notes&quot;&gt;Other notes&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Firefox will not allow you to drag an element without the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;draggable&lt;/code&gt; attribute.&lt;/li&gt;
  &lt;li&gt;The drag image element accepts limited styling.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setDragImage&lt;/code&gt; is used to set a custom ghosted image that appears while a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;draggable&lt;/code&gt; element is being dragged. This post glosses over the basics of its usage, which is covered quite thoroughly in &lt;a href=&quot;http://www.kryogenix.org/code/browser/custom-drag-image.html&quot;&gt;&lt;em&gt;Setting a custom ghost image when using HTML5 drag and drop&lt;/em&gt;&lt;/a&gt;. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot;&gt;
      &lt;p&gt;It would better to have a feature test for this. I’m open to suggestions. &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:3&quot;&gt;
      &lt;p&gt;Again, open to suggestions for feature detection in lieu of user agent detection. &lt;a href=&quot;#fnref:3&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Tue, 09 Feb 2016 00:00:00 +0000</pubDate>
        <link>https://transitory.technology/set-drag-image/</link>
        <guid isPermaLink="true">https://transitory.technology/set-drag-image/</guid>
        
        <category>JavaScript,</category>
        
        <category>Dragging</category>
        
        
      </item>
    
      <item>
        <title>Bass: A Fish Wrapper for Bash Utilities</title>
        <description>&lt;p&gt;I use &lt;a href=&quot;/fish-shell/&quot;&gt;Fish&lt;/a&gt; for my shell and up until recently I’ve just dealt with its slow startup time. I treated it as my penance for being fussy about such things. But today I reached the limit of my patience and decided to track down the cause of this delay. I discovered was this was a &lt;a href=&quot;https://github.com/passcod/nvm-fish-wrapper/issues/13#issuecomment-108113067&quot;&gt;commmon issue&lt;/a&gt; with the &lt;a href=&quot;https://github.com/passcod/nvm-fish-wrapper/&quot;&gt;Fish wrapper&lt;/a&gt; for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nvm&lt;/code&gt; bash utility. The author of the tool has deprecated it in lieu of a general Bash-Fish bridge called &lt;a href=&quot;https://github.com/edc/bass&quot;&gt;Bass&lt;/a&gt;. After installing Bass, I was able to quickly setup the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nvm&lt;/code&gt; command for Fish using the following function:&lt;/p&gt;

&lt;div data-gist=&quot;21a8b97f34cdb9b99e3a&quot;&gt;&lt;/div&gt;
</description>
        <pubDate>Tue, 09 Feb 2016 00:00:00 +0000</pubDate>
        <link>https://transitory.technology/bass/</link>
        <guid isPermaLink="true">https://transitory.technology/bass/</guid>
        
        <category>fish,</category>
        
        <category>shell,</category>
        
        <category>nvm,</category>
        
        <category>bash,</category>
        
        <category>bass</category>
        
        
      </item>
    
      <item>
        <title>Safari’s weird mousemove</title>
        <description>&lt;p&gt;The implementation of Safari’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mousemove&lt;/code&gt; event differs in a notable way from Chrome and Firefox. After first mouse movement, Safari fires the event on key press of the modifier keys &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ctrlKey&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;shiftKey&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;altKey&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;metaKey&lt;/code&gt;. For example, the following logs the event name in Safari without mouse movement.&lt;/p&gt;

&lt;div data-gist=&quot;1844cb88925eef8c75c5&quot; data-file=&quot;1-log-mousemove.js&quot;&gt;&lt;/div&gt;

&lt;p&gt;Additionally Safari’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MouseEvent&lt;/code&gt; object uses the last known position values (i.e. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clientX&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clientY&lt;/code&gt;), which can create issues. To get around this behavior and ensure the mouse has actually moved, check against the last known position:&lt;/p&gt;

&lt;div data-gist=&quot;1844cb88925eef8c75c5&quot; data-file=&quot;2-check-for-position-change.js&quot;&gt;&lt;/div&gt;
</description>
        <pubDate>Fri, 11 Dec 2015 00:00:00 +0000</pubDate>
        <link>https://transitory.technology/mouse-move-in-safari/</link>
        <guid isPermaLink="true">https://transitory.technology/mouse-move-in-safari/</guid>
        
        <category>JavaScript,</category>
        
        <category>keydown,</category>
        
        <category>mousemove,</category>
        
        <category>browser</category>
        
        <category>bugs</category>
        
        
      </item>
    
      <item>
        <title>document.scrollingElement</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Update October 2017&lt;/strong&gt;&lt;/p&gt;

  &lt;p&gt;Chrome now uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;document.documentElement&lt;/code&gt; for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scrollTop&lt;/code&gt;. Chrome, Safari, and Firefox support &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;document.scrollingElement&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When discussing animating document scroll with jQuery, there are often examples given like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$('html, body').animate({scrollTop: 200});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You’ll notice both the document and body elements are selected. This is due to inconsistencies between browsers. The standards mode approach is to use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;document.documentElement&lt;/code&gt;, but quirks mode uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;document.body&lt;/code&gt;.&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;While the approach to target both works, it can be potentially problematic. For example, if you have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;complete&lt;/code&gt; callback on the animate, it will get called twice, once for each element:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$('html, body').animate({
  scrollTop: 200
}, {
  complete: function () {
    // I’m doing cool stuff after the animation.
    // Whoops! I’m doing it again.
  }
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This can prevented using something like Underscore’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_.once()&lt;/code&gt;, but ideally we could solve for the root issue.&lt;/p&gt;

&lt;p&gt;To that end, there’s &lt;a href=&quot;http://dev.w3.org/csswg/cssom-view/#dom-document-scrollingelement&quot;&gt;a working draft&lt;/a&gt; for a new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;document&lt;/code&gt; attribute called &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/document/scrollingElement&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scrollingElement&lt;/code&gt;&lt;/a&gt;. It would be used in lieu of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;documentElement&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;body&lt;/code&gt; as a consistent approach across browsers.&lt;/p&gt;

&lt;p&gt;Unfortunately, there currently isn’t much support for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scrollingElement&lt;/code&gt;&lt;sup id=&quot;fnref:2&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;. If you want to start using it today you could use &lt;a href=&quot;https://gist.github.com/dperini/ac3d921d6a08f10fd10e&quot;&gt;this function&lt;/a&gt; or &lt;a href=&quot;https://github.com/mathiasbynens/document.scrollingElement&quot;&gt;the polyfill&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For now, I’m continuing target both elements.&lt;/p&gt;

&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;Firefox and Internet Explorer use the former, Safari and Chrome (and probably Opera) use the latter. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot;&gt;
      &lt;p&gt;At the time of writing, the next version of Chrome will support it (Chrome 44). &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Fri, 10 Jul 2015 00:00:00 +0000</pubDate>
        <link>https://transitory.technology/scrollingelement/</link>
        <guid isPermaLink="true">https://transitory.technology/scrollingelement/</guid>
        
        <category>JavaScript,</category>
        
        <category>jQuery,</category>
        
        <category>scrollingElement</category>
        
        
      </item>
    
      <item>
        <title>Asynchronous gist embeds</title>
        <description>&lt;p&gt;I discovered recently that gist embeds use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;document.write()&lt;/code&gt;. This is &lt;em&gt;fine&lt;/em&gt; in some cases, but it doesn’t work at all with asynchronously-loaded content. This is because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;document.write()&lt;/code&gt; can’t be used once the document has completed loading. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;document.write()&lt;/code&gt; is also blocking meaning that the document cannot proceed to load until the write is complete. If gist.github.com is slow to respond, your site will load slowly.&lt;/p&gt;

&lt;p&gt;The good news is that we can get around this. Each gist has a JSON endpoint, which we can use to load the gist asynchronously. The following is a simple example using jQuery:&lt;/p&gt;

&lt;div data-gist=&quot;5968c0064b1ea73c4f42&quot;&gt;&lt;/div&gt;

&lt;p&gt;For a more flexible approach, please check out this &lt;a href=&quot;https://github.com/matthewspencer/gist&quot;&gt;jQuery plugin&lt;/a&gt; that I wrote. This site you are reading now uses it. That gist right there.&lt;/p&gt;
</description>
        <pubDate>Sat, 27 Jun 2015 00:00:00 +0000</pubDate>
        <link>https://transitory.technology/asynchronous-gists/</link>
        <guid isPermaLink="true">https://transitory.technology/asynchronous-gists/</guid>
        
        <category>gist,</category>
        
        <category>GitHub,</category>
        
        <category>JavaScript,</category>
        
        <category>AJAX,</category>
        
        <category>jQuery</category>
        
        
      </item>
    
      <item>
        <title>Get the current URL in WordPress</title>
        <description>&lt;p&gt;Sometimes you need to get the current URL (or path) in WordPress outside the loop (e.g. when a post ID is unavailable like on archive pages). There are different ways of handling this — constructing the URL using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$_SERVER&lt;/code&gt; or the global &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$wp&lt;/code&gt; object — but I prefer the following approach for its brevity.&lt;/p&gt;

&lt;p&gt;The idea is to use &lt;a href=&quot;https://developer.wordpress.org/reference/functions/add_query_arg/&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add_query_arg()&lt;/code&gt;&lt;/a&gt; with a bogus / empty query variable. This works because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add_query_arg()&lt;/code&gt; has a fallback when no URI is passed. The falsey value removes the query variable from the path (this is how &lt;a href=&quot;https://developer.wordpress.org/reference/functions/remove_query_arg/&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;remove_query_arg()&lt;/code&gt;&lt;/a&gt; works).&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;// This will return the current path including query_vars
add_query_arg( '_', false );

// This will return the absolute URL
home_url( add_query_arg( '_', false ) );
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Fri, 26 Jun 2015 00:00:00 +0000</pubDate>
        <link>https://transitory.technology/current-url-in-wordpress/</link>
        <guid isPermaLink="true">https://transitory.technology/current-url-in-wordpress/</guid>
        
        <category>wordpress,</category>
        
        <category>path,</category>
        
        <category>url</category>
        
        
      </item>
    
      <item>
        <title>Debug: a simple console.log wrapper with line numbers</title>
        <description>&lt;p&gt;Not all browsers support the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;console&lt;/code&gt; object in the same way or at all. While it is best to avoid running debugging code on a production site, there are times when you may need to (or think you do 😜). To get around these cross browser issues, the following helper function calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;console.log()&lt;/code&gt; for you, first checking if the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;console&lt;/code&gt; object exits:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;function debug(args) {
  if (!window.console || !console.log) {
    return;
  }
  console.log(args);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The issue with this function is that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;console&lt;/code&gt; shows the line and column numbers for this function definition instead of showing the line and column numbers of the caller. Not very helpful!&lt;/p&gt;

&lt;p&gt;The following method resolves this by using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bind&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;call&lt;/code&gt;, to act as if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;console.log()&lt;/code&gt; is getting called from the caller:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;var debug = function () {
  if (!window.console || !console.log) {
    return;
  }
  return Function.prototype.bind.call(console.log, console);
} ();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Fri, 26 Jun 2015 00:00:00 +0000</pubDate>
        <link>https://transitory.technology/console-log/</link>
        <guid isPermaLink="true">https://transitory.technology/console-log/</guid>
        
        <category>console,</category>
        
        <category>debug,</category>
        
        <category>JavaScript</category>
        
        
      </item>
    
  </channel>
</rss>

