jQuery Executes Script Tags in SubNodes

I recently wanted to clean a string of all HTML in order to use it as a title. Our users occasionally paste things into the title they shouldn’t, and while they have that right, it’s easier to prevent breakage and just use text instead of allowing them to break things. Since we use jQuery, I figured the following code might work:


this does strip out all html from the string as expected, but with one unintended consequence—if the titleString contains the html for a script tag, that tag will be run.

$('<div>').html('<script>alert("Bad Idea!")</script>').text();
// Alerts 'Bad Idea!' then returns only the text.

The solution is to remove the initial div declaration.

$('<script>alert("Bad Idea!")</script>').text();
// just returns the text.

jQuery only executes script tags in children of tags, not the initial creation.

Parent-Scoped mixins Sass

I recently had a need to build a Sass mixin that didn’t produce its output inside of its heirarchy. It’s easy, but wasn’t obvious in the documentation:

Typically I do my mixins like this:

@mixin scale($val) {
	-webkit-transform: scale($val);
	-moz-transform: scale($val);
	-ms-transform: scale($val);
	-o-transform: scale($val);
	transform: scale($val);
.btn {
	@include scale(0.5);

Which, when you use it produces output like this:

.btn {
	-webkit-transform: scale(0.5);
	-moz-transform: scale(0.5);
	-ms-transform: scale(0.5);
	-o-transform: scale(0.5);
	transform: scale(0.5);

My need was a page-wide change. If the body tag had a specific selector, I needed particular children to have different styles. Here’s how it’s done:

@mixin foreign-button($val) {
	body.russian & {
	background-image: url('russian/'+$val);
	body.spanish &amp; {
		background-image: url('spanish/'+$val);
.btn {
	@include foreign-button('path/to/image.png');

The output of this method looks like this:

body.russian .btn {
	background-image: url('russian/path/to/image.png');
body.spanish .btn {
	background-image: url('spanish/path/to/image.png');

The key is the placement of the & character. It’s an indicator to sass of where you’d like to put your heirarchical selector, in this case, .btn

Jenkins, Forever, and Node.js

I’ve got a project that’s written in Node that uses forever to keep it running. I’ve always been a fan of Jenkins to process and handle the various tasks of building and releasing. Hooking Node to Jenkins was something that took a little time to get right. Here’s my code:

The Build Step is Execute Shell and here’s the code I’m running:

npm install
export PROJECT_CONFIG='production'
if forever list | grep 'project.js' ; then
	forever stop project.js
forever start project.js
forever list | grep 'project.js'
  • updates your node project’s requirements
  • Sets an environment variable of PROJECT_CONFIG to ‘production’
    I’ve opted to use a special config name as well as a special js file name so as to allow Jenkins to run multiple projects at once, if I need to.
  • Forever keeps a list of all node files currently active, we need to look through the list and see if our project is already running
  • If our project is running, we stop it.
    If we used restart, there’s a possibility that the config environment variable wouldn’t be set properly.
  • Finally, start the project
  • Ensure that the project is in the list of running projects (and get a location for the log file)

YouTube iframe API Without External Script

The YouTube API is fairly straightforward, but requires the inclusion of a separate script tag, which then loads another script tag, all so you can do whatever specific thing you need to do. It always bothers me when you have to include a whole library in order to do anything, and while it’s small and minified, I also like to have control over what I’m doing.

Recently I wanted to listen for the end of a YouTube video and run a function. Here’s how I did it:

  • The Iframe tag you receive from YouTube needs to have enablejsapi=1 appended to the url parameters.
  • The YouTube video will send status messages to the main window once it’s told to.
  • Tell the YouTube video that it needs to start sending messages, via postMessage.
    The problem is that this must be done after the YouTube iframe is listening, which is up to us to determine. Since the YouTube video doesn’t post ANY messages (not even a ready message) until it’s told, we have to keep sending postMessages to the iframe until the video starts sending them back.
var interval,
//keep doing this until we get a response
interval = setInterval(function () {
}, 250);
window.addEventListener('message', function (event) {
    //if the message is from the right location
    if(event.source == youtubeIframe){
        if (interval) {
            interval = clearInterval(interval);
        //get the data
        var json = JSON.parse(event.data);

Here’s a working example:

PayPal Treated Me Right

I recently tried integrating PayPal’s APIs with a site I work on and I jumped the gun before reading (I know, rookie mistake). I had integrated many other payment processing systems and I assumed wrongly that PayPal would accept test credit card numbers for testing. They flagged this as fraud, which I suppose is valid, and locked my account, limiting my ability to finalize my site.

They gave me a list of things to do to reinstate my account, and I did them, then they got more aggressive and asked for more validation, specifically the billing details that matched my credit card number—a test number that I obviously couldn’t provide. I explained this to them and they reinstated my account. I had little hope up to this point due to PayPal’s bad PR lately, but they solved my problem with a minimum of fuss, though it did take a while. Score one for the good guys.

Git back to where you used to be

I’m still not as versed in Git as I used to be. In various situations, I find myself looking at things and saying, well, I’ve backed up my own files, I know where I used to be. How do I just wipe everything clean and start over?

Obviously there’s always delete the dir and re-clone the files. With multi-gigabyte repos over a cell connection this isn’t the best option. Here’s a list of situations and their remedies as I’ve found them. All commands are run in the main directory of your project.

I’ve got changes, but I don’t want to commit them:

#just go ahead and delete everything you know about. 
git reset --hard

I’ve got changes and new files to add, but I just want to wipe everything out:

#hey git, there's all sorts of things in here to pay attention to
git add .
#just go ahead and delete everything you know about. 
git reset --hard

My commits have diverged, but I just wanna be where the origin is, not where I am:

#just go ahead and go back to where you were. 
git reset --hard @{upstream}

I’ve got commits staged, but I just want to wipe everything out:

#wipe out the last commit. Repeat as necessary
git reset --soft "HEAD^"

nginx 403 on osx

I’ve got nginx up and running (trying to replace my mamp stack with it) and I kept running into a 403 error regardless of configuration. Turns out this was due to a config error. In OSX, you need to specify a user:group in the nginx config file that match a user that has access to the files you want to serve.

For example, my computer’s user is mengel and my group is staff. My config file is as follows:

user mengel staff;
events {
    worker_connections 1024;
http {
    server {
        listen 80;
        server_name localhost;
        root    /Users/mengel/Documents/Workspace/localhost;
        location /{ 
           autoindex on;
           autoindex_exact_size off;

Multiple Email Addresses with a Default in Git

Someone pointed out to me that my commits to github were showing up using my work email address (and therefore my commits weren’t connected to the proper account). I do personal and professional work on the same laptop and I find myself wanting to commit one git repo via one email address and one repo to another.

The first idea I had was to set the global email address to the default and then set individual email addresses on a per-project basis. Git always uses the global email address if one’s set. Thanks, git. Anyway, I have a super-hacky workaround for this based partially on my PS1 code for my bash profile. The first thing you have to do is open your ~/.gitconfig file and remove the user.email line. This was originally set using git config --global user.email your@email.com, but we’ll be handling this more manually:

	gb=$(git branch 2> /dev/null | sed -e '/^[^*]/d' -e "s/* \(.*\)/\1/")
	if [[ -z $gb ]]
	then echo -e ""
		ge=$(git config user.email)
		if [[ -z $ge ]]
			git config user.email "morgan@gallerus.com"
			echo -e "morgan@gallerus.com:"$gb'\n\r'
		else echo -e $ge":"$gb'\n\r'

This first line takes the output from git branch and finds a line with a * in it indicating that branch is selected. If it finds one, it re-searches for the name specifically. If either of these is not found, an empty string is returned.

in bash, [[ -z ]] indicates empty. If we find that the output of the branch script is empty, we stop checking. Otherwise, we set the local email address to the default.

Finally, we output the various bits for use in our PS1 shell prompt, but you don’t have to do that if you don’t want to.

The final output looks something like this (only more colorful)


which is now how I like to set up my bash environment.

Selenium ChromeDriver used to work

I used to use this code:

from selenium import webdriver
desktop_browser_list = [webdriver.Chrome("./drivers/chromedriver")]

But then Chrome apparently got fancier and doesn’t work with the old chromedriver. So I downloaded the new version, but it threw various errors.
So, now I have to switch to

from selenium import webdriver
options = webdriver.ChromeOptions()
options.binary_location = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
desktop_browser_list = [webdriver.Chrome(executable_path="./drivers/chromedriver", chrome_options=options)]