Well, I just deleted over 56,000 comments from my database. I hope I didn’t delete any ACTUAL comments. Fucking spammers. I may have some new stuff to post soon. I have been working with AngularJS recently…Might be cooking up something fun.

Posted in AngularJS, javascript, programming, Uncategorized | Leave a comment

Checking for global scope leak

Last night I got a wild hair and wanted to write a bit of code for fun. Basically I wanted to see what variables were added to the global scope by different libs and bits of code. Basically you can run this and it will tell you if you have accidentally left off a var or added something to the global namspace in some other way. It is rather simple, it does add a var to the global, but I remove that at the end so you don’t see funny results.

To run it, simply replace the:

<script src="jquery-2.1.3.js" type="text/javascript"></script>

with whichever files you wish to check. The code is pretty simple:

	   <title>What's New</title>

	<script type="text/javascript">
		_cleanWindow = Object.getOwnPropertyNames(window);

	<script src="jquery-2.1.3.js" type="text/javascript"></script>

	<script type="text/javascript">
			var _modifiedWindow = Object.getOwnPropertyNames(window);
			var _newShit = {};
			var i = j = 0;
			var output = '<\/ br>';

			for(i = 0; i <= _modifiedWindow.length; i++) {
				for(j = 0; j <= _cleanWindow.length; j++) {
					if(_cleanWindow[j] === _modifiedWindow[i]) {

					if(j === _cleanWindow.length &amp;&amp; _modifiedWindow[i] !== '_cleanWindow') {
						_newShit[_modifiedWindow[i]] = _modifiedWindow[i];

			for(prop in _newShit) {
				output += prop + ': ' + window[prop] + '<br>';

			document.body.innerHTML += output;


Posted in javascript, programming | Leave a comment

I Don’t Like Being Told What I Can and Can’t Do

I was trying to update my Netflix autoplay bookmarklet since the autoplay feature that Netflix came out with is…not great. What I found was that Netflix tried to disable the console. Well, that became a more interesting problem to solve…and quite an easy one too. The code Netflix uses to disable the console is:

(function () {
    try {
        var $_console$$ = console;
        Object.defineProperty(window, "console", {
            get: function () {
                if ($_console$$._commandLineAPI) throw "Sorry, for security reasons, the script console is deactivated on";
                return $_console$$
            set: function ($val$$) {
                $_console$$ = $val$$
    } catch ($ignore$$) {}

To undo this is actually really simple, we just need to set the getter/setter back to ‘undefined’ and everything is happy:

Object.defineProperty(window, "console", {
	get: undefined,
	set: undefined

And of course this is easy to make into a bookmarklet like so:

Enable Console

Sorry Netflix =)

Posted in javascript, Netflix, programming | Tagged | Leave a comment

Netflix added autoplay!

Hey I don’t need to update my bookmarklet any more. Actually, I was going to update it again, but I had an interview with them and they told me it was about to happen, so that was why I didn’t bother! Didn’t know if I should post that before it happened though. It was fun though, thanks everybody for enjoying it!

Posted in javascript, Netflix | 7 Comments

Fixed Netflix Autoplay Bookmarklet!

As promised, here is the new fixed version of my bookmarklet:

Netflix Autoplay Bookmarklet

Please note I can no longer tell when the episode is almost over, so I am now just timing the entire length of play. You will now see a countdown telling you when it will change to the next episode. This means a few things:
* If you pause the show, or it takes a long time to buffer, or is has to buffer in the middle, the timer will be off and it will switch early. There are some things you can do about this, first, you will see ‘||’ next to the timer, clicking it will pause the countdown, clicking again will unpause it, so if you walk away, be sure to click this. Also, you can click the countdown and type a new time into it, you can either give a number of seconds, or enter time in the mm:ss format.

Also, next to the pause button you will see a ‘-’ most of you can ignore this, but if you have a lot of problems with buffering taking a really long time or something, you can also click the ‘-’ and enter a number of seconds there. This will be added to what the bookmarklet thinks is the length of each episode to allow for buffering and such. By default 10 seconds is added to allow the episodes to load properly.

I have not done extensive testing on this, so there could very will be some bugs. If you find any, let me know.


	//Takes our countdown timer and converts it to mm:ss and displays to user
	function updateTime() {
		var seconds = (countdownTimer % 60) + '';
		if(seconds.length === 0)
			seconds = '00';
		else if(seconds.length === 1)
			seconds = '0' + seconds;

		timerNode.innerHTML = Math.floor(countdownTimer / 60) + ':' + seconds;

	//Grabs the data for the episode matching the ID passed in
	function getCurrentEpisodeData(episodeId) {
		var episode, i = 0, j = 0;

		if(episodeData && && {
			for(i=0; i<; i++) {
				for(j=0; j<[i].episodes.length; j++) {
					if([i].episodes[j].id === episodeId) {
						episode =[i].episodes[j];

		return episode;

	//Grabs the data for the episode following the one with the ID passed in
	function getNextEpisodeData(episodeId) {
		var episode, i = 0, j = 0, found = false;

		if(episodeData && && {
			for(i=0; i<; i++) {
				for(j=0; j<[i].episodes.length; j++) {
					if([i].episodes[j].id === episodeId) {
						found = true;
					else if(found) {
						episode =[i].episodes[j];

		return episode;

	//base64 decoder
	function decode64(input) {
		var keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
		output = '',
		chr1, chr2, chr3 = '',
		enc1, enc2, enc3, enc4 = '',
		i = 0,
		base64test = /[^A-Za-z0-9\+\/\=]/g;

		input = input.replace(base64test, '');

		do {
			enc1 = keyStr.indexOf(input.charAt(i++));
			enc2 = keyStr.indexOf(input.charAt(i++));
			enc3 = keyStr.indexOf(input.charAt(i++));
			enc4 = keyStr.indexOf(input.charAt(i++));

			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;

			output = output + String.fromCharCode(chr1);

			if (enc3 != 64) {
				output = output + String.fromCharCode(chr2);
			if (enc4 != 64) {
				output = output + String.fromCharCode(chr3);

			chr1 = chr2 = chr3 = '';
			enc1 = enc2 = enc3 = enc4 = '';

		} while (i<input.length);

		return unescape(output);

	if(window.NetflixAutoplayLoaded) {
		alert('Autoplay already loaded.');
		//return false;
	} else {
		window.NetflixAutoplayLoaded = true;

	//resize the player so we can see the text we are about to insert under it
	document.getElementById('SLPlayer').style.height = (window.innerHeight - 35) + 'px';
	document.getElementById('SLPlayerWrapper').style.height = (window.innerHeight - 35) + 'px';
	document.getElementById('page-content').style.height = (window.innerHeight - 35) + 'px';

	//create the text and other shizzy we want
	var autoplayElement = document.body.appendChild(document.createElement('div')); = 'NetflixAutoplayContainer';
	autoplayElement.innerHTML = '<div id="NetflixAutoplay"></div> <div id="NetflixAutoplayTimerContainer">Time left until switch: <span id="NetflixAutoplayTimer">00:00</span> <span id="NetflixAutoPauser">||</span> <span id="NetflixAutoDelay" contentEditable="true">-</span></div>';
	var timerNode = document.getElementById('NetflixAutoplayTimer');
	var autoplayText = document.getElementById('NetflixAutoplay');
	var pauseButton = document.getElementById('NetflixAutoPauser');
	var delay = document.getElementById('NetflixAutoDelay');

	//the number of seconds to wait for the show to buffer on load
	var timerDelay = 10; 

	//Pull the current episode information and the full series data for us
	var episodeData = JSON.parse(decode64(netflix.Silverlight.MoviePlayer.getPlugin().settings.metadata));
	var currentEppId = (/,EpisodeMovieId=\d*/.exec(netflix.Silverlight.MoviePlayer.getPlugin().settings.initParams)[0]).split('=')[1];

	//gets data for current & next epps
	var currentEpp = getCurrentEpisodeData(currentEppId);
	var nextEpp = getNextEpisodeData(;

	var paused = false; //bool to see if paused
	var done = false; //bool to see if finished autoplay
	var editingTime = false; //bool to check if user is editing time

	//Javascript to execute to change episode
	var ini = document.getElementsByTagName('script');
	ini = ini[ini.length-1].innerHTML;

	//Set the countdown till next episode + the pause we need for buffer
	function updateCountdown() {
		countdownTimer = parseInt(currentEpp.runtime, 10) + timerDelay;

	var countdownTimer = 0; //episode length timer
	updateCountdown(); //Sets the count down timer for current episode

	//Prompt user for number of episodes
	var numToWatch = 3;
	function getNumberOfEpisodesToWatch() {
		var newNum;
		do {
			newNum = prompt('How many episodes would you like to play?', numToWatch);
		} while (isNaN(newNum));

		numToWatch = parseInt(newNum, 10);

		//set the text
		if(numToWatch > 0) {
			autoplayText.innerHTML = 'Netflix autoplay on, Episodes left: ' + numToWatch;

			if(done) { //if we have already finished, restart
				done = false;
		} else {
			autoplayText.innerHTML = 'Netflix autoplay off';

	//ask the user for the number of episodes they want

	//handler for pause button
	function pause() {
		if(pauseButton.innerHTML === '||') {
			paused = true;
			pauseButton.innerHTML = '>';
		} else {
			paused = false;
			pauseButton.innerHTML = '||';

	//handles editing the buffer delay
	function delayEdit(e) {
		if((!e.keyCode || e.keyCode === 13) && !isNaN(delay.innerHTML)) {
			timerDelay = parseInt(delay.innerHTML, 10);

			if (!e) var e = window.event;
			e.cancelBubble = true;
			if (e.stopPropagation) e.stopPropagation();
			return false;

	//handler for editing time left to play
	function editTime(e) {
		editingTime = true;

		if (!e) var e = window.event;
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
		return false;

	//handles updating time left to play after user edit
	function endEdit(e) {
		if(timerNode.contentEditable.toString() === 'true' && (e.type === 'blur' || e.keyCode === 13)) {
			timerNode.contentEditable = false;
			editingTime = false;

			var time = timerNode.innerHTML;
			if(time.indexOf(':') >0) { //converts minutes:seconds into time
				time = time.split(':');
				countdownTimer = parseInt(time[0], 10)*60 + parseInt(time[1], 10);
			} else {					//converts just seconds into time
				if(!isNaN(time)) {
					countdownTimer = parseInt(time, 10);

			if (!e) var e = window.event;
			e.cancelBubble = true;
			if (e.stopPropagation) e.stopPropagation();
			return false;

	//Does everything to change to the next episode
	function switchEpps() {
		//setup the script for the next epp
		ini = ini.replace(/,EpisodeMovieId=\d*/,',EpisodeMovieId=' +;

		//switch out data to the new epps
		currentEpp = nextEpp;
		nextEpp = getNextEpisodeData(;

		//Switch to next epp & update text
		if(currentEpp) {
			autoplayText.innerHTML = 'Netflix autoplay on, Episodes left: ' + numToWatch;
		} else {
			autoplayText.innerHTML = 'There does not seem to be a next episode.';

	//Main loop, updates our timer and stuff, switches to next epp when necessary, yadayda
	function nextEppTimer() {
		setTimeout(function() {
			if(isNaN(countdownTimer) || isNaN(numToWatch)) {
				autoplayText.innerHTML = 'NUMBERS DO NOT WORK THAT WAY!  GOOD NIGHT!';

			if(countdownTimer <= 0) {
				if(numToWatch-- > 0) {
				} else {
					done = true;
					autoplayText.innerHTML = 'Netflix autoplay completed.';
					numToWatch = 0;
			} else {
				if(!editingTime && !paused) {
		}, 1000);

	//attach the events we need
	autoplayText.addEventListener('click', getNumberOfEpisodesToWatch, false);
	pauseButton.addEventListener('click', pause, false);
	timerNode.addEventListener('click', editTime, false);
	timerNode.addEventListener('blur', endEdit, false);
	timerNode.addEventListener('keypress', endEdit, false);
	delay.addEventListener('blur', delayEdit, false);
	delay.addEventListener('keyup', delayEdit, false);

Posted in javascript, Netflix, programming | 24 Comments

I Know My Netflix Bookmarklet Broken!

Yes folks, I know. I am sorry, the new player they released last week broke it. I too was sad to discover this, I mean I didn’t really make it for you all, I made it because I wanted it! I really didn’t know if anybody was actually using it, but seeings as my site has maintained traffic at pretty much double by highest day ever EVERY DAY since Netflix broke it, I guess other people like it too. Netflix changed a lot of things, some of it easy to fix, some not as much. Shit happens; que sera sera.

YES, I HAVE A FIX! It is not done yet. I think it will be better in some ways, worse in others. I promise you all (baring catastrophe) it will be out this week.

Thanks to everybody leaving comments and sending me emails telling me that you love it, were upset that it broke, and really want me to fix it! It is amazing to have people actually getting enough enjoyment out of something I made to do those things!

TL;DR: Fix will be out this week.

Posted in Geeks, javascript, Netflix, programming | 2 Comments

Getting All jQuery Events for a DOM Node.

I have more than once found myself needing to know all of the events for a specific DOM node. In the past I have used which worked great for a time. The problem is that I am now working on projects so large that Visual Events takes forever to load and then fills the entire screen making it nigh impossible to find the events for the node I am interested in. Combine this with live events, delegated events, on/off, etc, Visual Events was no longer doing the job for me. So I made myself another bookmarklet.

jQuery Events
To use it:

Drag the link to your bookmark bar.

Open the page you wish to see the events on.

Open your javascript console.

Click the bookmarklet.

Click the little red “Click Me” it puts in the top left corner.

Click the element you wish to see the events for.

In your console you will see a list of all of the events for the node you clicked, what type they are, and their namespace. If the node you click has no events (perhaps you clicked an element inside of the one with the events) it will look up the DOM until it finds a node with events. It will also look all the way up the DOM for that node and show you all of the events that are delegated to that node. The code could use a lot of cleanup and stuff, but it works for me right now.

Here is the code for it:

javascript:(function() {
	$('#eventFinder, #eventTitle').remove();

	$(document.body).append('<div id="eventFinder" style="display: none; position: absolute; z-index: 999999; width: '+$(document).width()+'px; height: '+$(document).height()+'px; top: 0; left: 0 " ></div>');

	$(document.body).append('<div id="eventTitle" style="position: absolute; z-index: 999998; width: 50; px; height: 20px; top: 0; left: 0 ; background-color: red" >Click Me</div>');

	$('#eventTitle').click(function() {

	function findNodeEvents(e) {
		var ele;
		if(e.pageX) {
			ele = document.elementFromPoint(e.pageX, e.pageY);
		} else {
			ele = e[0];

		var tmpEvents;
		var $origEle = $(ele);
		var $ele = $origEle;
		var events = [];
		var eventsFound = false;

		console.log('Finding events for node:');
		while(true) {
			tmpEvents = $'events');
			if(tmpEvents) {
				for(type in tmpEvents) {
					for(var i = 0; i < tmpEvents[type].length; i++) {
						if(((!tmpEvents[type][i].selector &amp;&amp; $ele[0] === ele) || $[type][i].selector))) {
							eventsFound = true;
							if($ele[0] !== ele) {
								console.log('Delegated From:');

							console.log('Event: ' + type + (tmpEvents[type][i].namespace ? '.' + tmpEvents[type][i].namespace : '') + ': ' + tmpEvents[type][i].handler);

			$ele = $ele.parent();
			if($ele.length <= 0) {

		if(!eventsFound) {
			var $parent = $origEle.parent();
			if($parent.length > 0) {
				console.log('No events found - Trying parent');
			} else {
				console.log('No events found - Do you know what you are doing?');

Posted in jQuery, jQueryUI, Uncategorized | 1 Comment

I Githubed myself!

(Githubbed?) Well, I finally took the time to throw my bookmarklet up on Github, I have some more projects I may add soon, but for now, if you want to fork my bookmarklet, I have it here:

Also, getting on Github with windows was not as easy as they made it sound, I had to generate keys using puttygen, doing it through GIT bash did not work at all like Ghithub’s documentation lead me to believe.

Posted in GIT, Github, javascript, Netflix | 5 Comments

Well, my site is all messed up…

That is a bummer…Tried to get a new layout on it, but it was messed up, tried to restore it from a backup, but that was messed up…I will get it fixed at some point.

Posted in Uncategorized | 1 Comment

Fixing the Terrible: Turning an SVN Branch into a GIT Repository

Long ago, someone, for some reason, thought it was a good idea to use branches in SVN as if they were repositories, so one repository contained many different branches each branch being its own completely independent project. When we moved to GIT we agreed to not repeat this mistake. We converted the entire SVN repo to a GIT repo long ago using Svn2Git, this worked well, except we still had all of those crazy branches in there. I don’t remember how we got the other branches out originally, but I am sure it was not the best way…or even a good way. We have been using GIT for some time and understand it better, and we still have a few old branches that we never extracted, but the time has come for us to do so. It was much easier now that we have some clue what is going on, and I though I would explain how we did it because it is rather simple…if you know what you are doing.

For us we actually want these to be bare remote repositories can be pushed to. Basically all you need to do is push the single branch into a new GIT repository and create a “master” branch in it. If you are making a bare repository, you then just need to clone the new repository to a bare one. Really, that is it, so here is a breakdown.

So, working on the assumption that we have our entire SVN repo (or whatever is your poison) converted to a GIT repo, we start by creating a new empty repo. Create a new directory to hold the repo, then go into that directory and run:

git init

This creates a new empty repository.

Now, push the branch from the old repo into the new one by going into the directory of the old repo and running:

git push /path/to/new/repo branch-to-extract

At this point your new repo contains only the single branch you extracted!

Next we have to create a new “master” branch for this repository. To do so, first we have to checkout the old branch. Navigate to the directory for the new repo you just created and run:

git checkout branch-to-extract

You should now see the code that was in that branch. Now we create a new “master” branch with:

git branch master

At this point you have a GIT repo for you project that is good to go! If this is all you need, you are done! If you want to turn this into a bare remote repository that someone can use, simply clone it –bare as normal.

Simply clone this new repo to the new remote one:

git clone --bare /path/to/new/repo /path/to/bare/repo

You can now clone this repo to your local machine and use it normally, with all the great pushing, pulling, branching and everything else GIT has to offer. If you like you can delete the “/path/to/new/repo” repo that we setup to extract old branch from, or delete the branch that you imported from from your fantastic new repo.

It really is that easy. It all makes perfect sense now and took me only a few minutes to figure out. When we were first trying to move to GIT though, and didn’t really understand it, this was not easy and did not make perfect sense. Hopefully if someone else out there has done the same bad thing or something similar and is now trying to fix the problem this will help them out.

Posted in GIT, programming | 1 Comment