to-do lists for big problems => small pieces

one of the most useful skills i’m learning this summer is the ability to take seemingly seamless big problems and chisel them into smaller chunks.

the most recent example of this was adding support for min-vid from google’s main page. as i’m writing about in more depth shortly, min-vid uses the urlcontext and selectorcontext to parse a link to an mp4 to send to the min-vid player. but google LIES about its hrefs! for shame! this means that if you “inspect element” on a google search result, you’ll see a bunch of crap that is not a direct link to the resource you want. so i had to spend some time looking through all the gunk to find the link i wanted.

Screen Shot 2016-08-15 at 9.31.20 PM

when i looked at the actual href in its entirety, i noticed something interesting:


do you see it? the youtube link is in there, surrounded by a bunch of %2F‘s and %3D‘s. initially, i thought this was some kind of weird google cipher and that i needed to write a bunch of vars to convert these strange strings to the punctuation marks my link-parsing function expected. i wrote a regular expression to get rid of everything before https, then started the converting. it looked something like this:

at this point, i made myself a little to-do list. to-do lists make my life easier because i have a short attention span and am highly prone to rabbit holes, but am also really impatient and like to feel like i’m actually accomplishing things. the ability to cross tiny things off my list keeps me engaged and makes it much more likely that i’ll actually finish a thing i start. so. the list:

Screen Shot 2016-08-15 at 9.50.13 PM

thankfully, after cursing my fate at having to deconstruct and reconstruct such a ridiculous string, i found out about a thing called URI encoding. those weird symbols are not google-specific, and there are special functions to deal with them. decodeURIComponent took care of my first two to-do items. indexOf took care of my third. adding forward slashes to all my other selectorcontexts, to distinguish between the encoded hrefs on google and the un-encoded hrefs on other sites, took care of my last to-do.


i am 1000% positive i would not have completed this task without a to-do list. thanks to mentor jared for teaching me how!

all the links that’s fit to save for later

jared has ~a million links for me to review in response to every 1 question i ask. i ask a lot of questions.

needless to say, we have been filing links away on an imaginary “to read later” list for several weeks now.

i’m starting an actual “to read later” list here, with the hope that i’ll make it back around to some of these:

to be continued…

draggable min-vid, part 1

since merging john and i’s css PR, i’ve been digging into min-vid again. lots has changed! dave rewrote min-vid in react.js to make it easier for contributors to plug in.

why react.js? because we won’t have to write a thousand different platform checks anymore. for example, we’d have to trigger one set of behaviors if the platform was and another set of behaviors if the platform was this wasn’t scalable and it wasn’t very contributor-friendly. now, to add support for additional video-streaming platforms, contributors will just have to construct the URL to access the platform’s video files (hopefully via a well-documented API) and add the new URL constructing code to min-vid’s /lib folder in file called get-[platform]-url.js.

so that’s awesome!

right now, i’m working on how to make the video panel draggable within the browser window so you’re not just limited to watching yr vids in the lower left-hand corner:

Screen Shot 2016-07-20 at 12.23.26 PM

john came up with a hacky idea for draggability where, on mouseDown, we’ll:

  1. create an invisible container the size of the entire browser window
  2. as long as mouseDown is true, drag the panel wherever we want within the invisible container
  3. onMouseUp, snap the container to be the size of the panel again.

the idea is to make dragging less glitchy by changing our dragging process so we’re no longer sending data back and forth between react, the add-on, and the window.

how to get started? jared broke down the task into smaller pieces for me. here’s the first piece:

Screen Shot 2016-07-20 at 12.25.41 PM

the function for setting up the panel size is in the index.js file. we determine how and when to and panel.hide() based on the block of code below. the code tells the panel to listen for

  1. a message being emitted and
  2. for the content of that message, in this case from the controls.js file:

then, do different stuff based on what the message said.

i added another little chunk in there which says: if the title is drag, hide the panel and then show it again with these new dimensions. the whole new block of code looks like this:

so we have some new instructions for the panel. but how do we trigger them?  we trigger the instructions by creating the drag function within the PlayerView component and then rendering it. this code says: on whatever new custom event, send a message. the content of the message is an object with the format {detail: obj}—in this case, {action: 'drag'}. then, render the trigger in a <div> in an <a> tag.

and we style the class in our css file:

so we get something like this, before clicking the red square:

Screen Shot 2016-07-20 at 1.19.37 PM

and after clicking the red square:

Screen Shot 2016-07-20 at 1.19.45 PM

next, i have to see if i can make the panel fill the page, then only drag the video element inside the panel, then snap the panel its position on the window and put it back to its original size, 320 x 180.

playing with react.js

i taught an intro to p5.js workshop earlier this summer, and a big part of what made it possible was jess klein and atul varma’s widget, which lets people play with p5.js sketches and see their changes in the browser without having to refresh the page.

i think it’s an amazing teaching tool, but it currently doesn’t support p5 libraries like p5.dom. this means we can’t incorporate video capture into widget views. ultimately, i’d love to contribute to the widget project and use p5.dom support to create some interactive documentation for kyle mcdonald’s computer vision examples. it’d also be great for making computer vision a little more accessible to beginners.

to contribute to the widget, i need to know some react so i’m playing around with atul’s react tutorial for p5 programmers. react seems really powerful in ways that i don’t totally understand yet. at this point, i’m trying to figure out how everything is wired up in a react program—syntax, which APIs are being referenced where and how, etc.

this code & video is just a slight change from the tutorial. from what i can tell, SVG has?/is? an API, which defines certain shapes like circle and rect. the function within the SVG tag, onClick, is a global event listener. i changed it from what was in the example, onMouseMove. things like clientY and clientX are part of another API; they’re built in (to what? idk) and have specific parameters/syntax rules that you have to follow. none of this is required for react programs, but this exercise is helpful for starting to learn structure and what references i might look to when i get stuck.

and here’s the example from the tutorial. the index.html file is the same, but there are some slight differences in the react-sketch.js file.

day whoscountinganymore: the “good-first-bug” tag

let’s talk about this tag for a minute. it looks like this:Screen Shot 2016-06-30 at 7.46.06 PM

it appears on github. it signals to baby contributors that the issue it is attached to may be a safe one to start with.

while i still imagine myself as a baby contributor, the truth is that i’m really not anymore. it’s been almost a year since i wrote my first line of code in dan shiffman’s “intro to computational media” class, and i’ve been inching my way into open source projects ever since. so that’s where i’m at. one year in. this good-first-bug bug should be a piece of cake. here’s the bug/issue:

Screen Shot 2016-06-30 at 10.35.26 AM

add a link? nbd. i followed all the instructions on the test pilot readme for setting up a development environment, but i hit a 404 page when i tried to navigate to the development server. and then there were npm errors related to gulp. and development permissions issues. and that was setting up the dev environment before editing any files. which, by the way, which file is this url supposed to live in anyway?

it turns out test pilot uses ampersand.js for data binding. which, as far as i can tell, basically means that we’re not directly editing html, but templates for html files. “models” or something. yes, something about scalability. so dave clarified:

Screen Shot 2016-06-30 at 10.35.26 AM copy

to load the dummy data, per step 6, you need the super secret docker command:

docker exec testpilot_server_1 ./ loaddata fixtures/demo_data.json

which lives in this 3-month-old issue here.

i thought i was in the clear, but i hit another error after that:

Screen Shot 2016-06-30 at 8.01.01 PM

how can you say “discourse_url does not exist” when it totally DOES exist BECAUSE I JUST WROTE IT?

sweet salvation finally came in the form of a previous test pilot bug fix for an issue that was basically exactly the same as the one i was working on: “add link to experiment model

after reviewing that commit, i saw that what i was missing, what was producing the “does not exist” error for me, was that i hadn’t yet created a particular python script in the experiments/migrations/ folder.

i’m not totally clear on what that script does—i copy/pasted dave’s script and adjusted it for the changes i was making—but my guess, judging by the folder name “migrations” and the python code that says something like “add a field to the experiment model” is that it tells some part of the add-on that a new thing has been added and that the add-on should incorporate it instead of ignoring it.

okay. the point of this has not been to be boring for boring’s sake. it has been to say: “good-first-bug” is relative. sometimes things that are named hard are easy. sometimes, things that are named intro-level are not. ask for help. iz okay.

intro to programming at the allied media conference

went really well! AMC is dreamy and has such a special place in my heart and my development as a human. highlights were:

i enjoyed teaching the workshop, but wish i’d provided a way to get feedback from folks. what worked? what didn’t? what else would be useful to know? but hopefully there will be a next time and i’ll think to collect that stuff.

materials are here:

day 18: the case of the missing vine api and the add-on sdk

i’m trying to add vine support to min-vid and realizing that i’m still having a hard time wrapping my head around the min-vid program structure.

what does adding vine support even mean? it means that when you’re on, i want you to be able to right click on any video on the website, send it to the corner of your browser, and watch vines in the corner while you continue your browsing.

i’m running into a few obstacles. one obstacle is that i can’t find an official vine api. what’s an api? it stands for “application programming interface” (maybe? i think? no, i’m not googling) and i don’t know the official definition, but my unofficial definition is that the api is documentation i need from vine about how to access and manipulate content they have on their website. i need to be able to know the pattern for structuring video URLs. i need to know what functions to call in order to autoplay, loop, pause, and mute their videos. since this doesn’t exist in an official, well-documented way, i made a gist of their embed.js file, which i think/hope maybe controls their embedded videos, and which i want to eventually make sense of by adding inline comments.

another obstacle is that mozilla’s add-on sdk is really weirdly structured. i wrote about this earlier and am still sketching it out. here’s what i’ve gathered so far:

  • the page you navigate to in your browser is a page. with its own DOM. this is the page DOM.
  • the firefox add-on is made of content scripts (CS) and page scripts (PS).
  • the CS talks to the page DOM and the PS talks to the page DOM, but the CS and the PS don’t talk to each other.
  • with min-vid, the CS is index.js. this controls the context menu that comes up when you right click, and it’s the thing that tells the panel to show itself in the corner.
  • the two PS’s in min-vid are default.html and controls.js. the default.html PS loads the stuff inside the panel. the controls.js PS lets you control the stuff that’s in the panel.

so far, i can get the vine video to show up in the panel, but only after i’ve sent a youtube video to the panel. i can’t the vine video to show up on its own, and i’m not sure why. this makes me sad. here is a sketch:


day 16: helpful git things

it’s been important for me to get comfortable-ish with git. i’m slowly learning about best practices on a big open source project that’s managed through github.

one example: creating a separate branch for each feature i work on. in the case of min-vid, this means i created one branch to add support, a different branch to add to the project’s README, a different branch to work on vine support, etc. that way, if my changes aren’t merged into the main project’s master, i don’t have to re-clone the project. i just keep working on the branch or delete it or whatever. this also lets me bounce between different features if i get stuck on one and need to take a break by working on another one. i keep the workflow on a post-it on my desktop so i don’t have to think about it (a la atul gawande’s so good checklist manifesto):

git checkout master

git pull upstream master
(to get new changes from the main project’s master branch)

git push origin master
(to push new changes up to my own master branch)

git checkout -b [new branch]
(to work on a feature)

npm run package
(to package the add-on before submitting the PR)

git add .

git commit -m '[commit message]

git push origin [new branch]
(to push my changes to my feature branch; from here, i can submit a PR)

git checkout master

another important git practice: squashing commits so my pull request doesn’t include 1000 commits that muddy the project history with my teensy changes. this is the most annoying thing ever and i always mess it up and i can’t even bear to explain it because this person has done a pretty good job already. just don’t ever ever forget to REBASE ON TOP OF MASTER, people!

last thing, which has been more important on my side project that i’m hosting on gh-pages: updating my gh-pages branch with changes from my master branch. this is crucial because the gh-pages branch, which displays my website, doesn’t automatically incorporate changes i make to my index.html file on my master branch. so here’s the workflow:

git checkout master
(work on stuff on the master branch)

git add .

git commit -m '[commit message]'

git push origin master
(the previous commands push your changes to your master branch. now, to update your gh-pages branch:)

git checkout gh-pages

git merge master

git push origin gh-pages

yes, that’s it, the end, congrats!

p.s. that all assumes that you already created a gh-pages branch to host your website. if you haven’t and want to, here’s how you do it:

git checkout master
(work on stuff on the master branch)

git add .

git commit -m '[message]'

git push origin master
(same as before. this is just normal, updating-your-master-branch stuff. so, next:)

git checkout -b gh-pages
(-b creates a new branch, gh-pages names the new branch “gh-pages”)

git push origin gh-pages
(this pushes changes from your origin/master branch to your new gh-pages branch)

yes, that’s it, the end, congrats!

day 6: brain to launch & a close reading

the project i’m working on, min-vid, is a firefox add-on that lets you minimize a video and keep it in the corner of the browser so you can watch while you’re reading/doing other stuff on the page behind it.

this is an idea straight out of dave’s brain.

getting this idea from dave’s brain to the firefox browser takes a lot of work and coordination. one of the first steps was for the dev team to decide on which features would add up to an ‘mvp,’ or ‘minimum viable product.’

a user experience designer looks at these mvp features and designs the human-readable interface around them. all the little x’s in the corners of browser windows, things that light up or expand or gray out when you mouse over them, windows that snap into place… they’re all designed by a person to work that way. in min-vid’s case, this person is named john. hey john.

so in addition to this set of mvp features, there are some basic logistical things that go into launching an open source product: a wiki page, a README that explains the thing and lets people know how to contribute, a name.

and then there are a thousand functionality issues to figure out. here’s a screen shot of partial issue list:

Screen Shot 2016-05-31 at 10.50.10 AM

one mvp feature of this product is vimeo support since lots of folks watch videos hosted by vimeo. dave is working on that, and it involves getting the vimeo api to talk to the firefox add-on api. looking at his code for the new vimeo support, i realized i didn’t understand the basic structure of the existing add-on.

so i spent a big chunk of today doing what basically amounted to a close reading of the core add-on code. i copy/pasted it into github gists, where i added comments, questions, and links to helpful resources. then, i sent my marked up index.js file to dave and he responded with additional comments, answers, and more resources.

to folks (but mostly, ahem, my own internal monologue) who say “THAT IS NOT REAL WORK OR A GOOD USE OF TIME,” i say, “wrong this is actually a great learning exercise bye!”

day 3: draw it out

i’m working on a patch for adding a button that lights up if there’s a playable URL in the page.

jared sent some links and explanations, but i also needed to draw it out.



“OK, so you’ve got a content script, that runs in each web page, and your addon code, which isn’t in the page and can’t see it

So you’ll want your content script to always load on every page, and do a querySelectorAll check for the youtube href*= selectors used by the context menu code

Once the content script (loaded by pageMod) finds a hit in the page, it should send a message back to the main addon script, telling it to light up the button

We’ll also need to detect when a new page loads and un-highlight the button (hopefully you can do this from the addon, without involving a content script, but I’m not sure)”


  1. get the script in the page to send over a message, and have the addon code just console.log something when it gets the message so you can convince yourself messaging is working. I think self.port is the addon SDK wrapper around postmessage.
  2. once you’re able to send messages over, then you can have your content script look for youtube links in the page, and send over a message that says if it found a match
  3. and then you can update the addon code to toggle the button state based on whether a matching link was found


sdk guide to content scripts

port object