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:

$('<div>').html(titleString).text();

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.

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

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

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,
    youtubeIframe=document.getElementById('youtubeVideo').contentWindow;
 
//keep doing this until we get a response
interval = setInterval(function () {
    youtubeIframe.postMessage(
        '{"event":"listening","id":"apiID"}',
        '*');
}, 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:
JSFiddle

Javascript dump or print_r output or toSource() alternative output

You can use JSON.stringify to receive a JSON-style string, but sometimes you want an actual javascript notation, not just object notation. In that case, it’s tough to find a reasonable output. I’ve heard that firefox has a toSource method of objects that outputs something like I needed, but I wanted cross-browser compatibility. Here’s how I did it:

function dump(obj, pad)
{
	var output = "";
		if(!pad)
	{
		pad = "";
	}
		if(Array.isArray(obj))
	{
		output +="[\n ";
		for(var o in obj)
		{
			output += "\t"+pad+dump(obj[o], pad+"\t")+",\n";
		}
		output = output.slice(0,-2);
		output +="\n"+pad+"]";
	}
	else if(typeof(obj)==="object")
	{
		output +="{\n ";
		for(var o in obj)
		{
			output += "\t"+pad+o + ":" + dump(obj[o], pad+"\t") + ",\n";
		}
		output = output.slice(0,-2);
		output +="\n"+pad+"}";
	}
	else if(typeof(obj)==="string")
	{
		output += "\"" + obj.replace("\"", "\\\"") + "\"";
	}
	else if(typeof(obj)!=="function")
	{
		output += obj.toString();
	}
	else
	{
		output += "\"FUNCTION\"";
	}
	return output;
}

Determine Goal Width and Height in Image Resizing

I find myself doing image manipulation on a regular basis. One of the common things I have to do is to fit an image into a max width or height. I’ve distilled this as best I can, and I think this is as simple as it gets. It’s in PHP, but the logic should be applicable to any language.

$max_size=200;
$ratio = $image_width/$image_height;
if($ratio>1)
{
	$goal_width = $max_size;
	$goal_height = $max_size/$ratio;
}
else
{
	$goal_width = $max_size*$ratio;
	$goal_height = $max_size;
}

Dynamically Add Collapsible Elements in Jquery Mobile

I spent a long time trying to get this to work and finally success.
This code produces a div with content and then reminds the JQuery Mobile framework to actually wire it up with classes, functionality, etc.

$('<div data-role="collapsible"><h3>Title</h3><p>Content</p></div>').appendTo('[data-role="content"]');
$('div[data-role=collapsible]').collapsible({theme:'c',refresh:true});

Coding for Understandability

Often I have a number of options in how to code a particular piece of functionality. I’m constantly balancing between brevity, simplicity, speed, size, and readability. I often find that if I put a little more focus on simplicity and readability, I save myself time and headaches, in addition to making my code more readable, more object oriented, and more accessible to other coders.

I’m going to provide some examples in ECMAScript, but I know that similar problems exist in other languages, as well.

I recently ran across some code that was coded for brevity:

var userdefined:Object = (_model.partner || {}).userdefined || {},
bsb:BannerShownBeacon = new BannerShownBeacon(
	userdefined.dims 
		? userdefined.dims
		: userdefined.width && userdefined.height
			? userdefined.width + 'x' + userdefined.height
			: 'fixed_bottom'
)
;

Now, this is fully valid, well-written code, and it’s also tabbed and line-broken for readability, but what exactly is it doing? What is the purpose of this code?

The difficulty I find is that when someone is trying to determine whether their particular implementation is going to be executed — lets say we have dims, width, and height in our userdefined param, and we’re looking at this the first time. Since coding standards aren’t set for how to structure ? : style if statements, it’s difficult to go through this by instinct and take a guess at what it’s doing. Every language has if/else statements and most coders are intimately familiar with them.

First, we look to see if _model.partner exists and if it doesn’t, we create it, then we check to see if _model.partner.userdefined exists and if not, we create it and assign that to a variable.
Then, we create a second variable called bsb that expects a BannerShownBeacon;
If userdefined has a dims param, we use it, otherwise, we check if it has width and height params, and if it does, we combine them with an x in between, otherwise, we just use the term “fixed_bottom” and make a BannerShownBeacon out of that.

The final option is to include large amounts of comments (which is excellent for non-compiled languages like JS), but in compiled languages, this often doesn’t save any time or lines of code.

I’ve rewritten this here using if/else statements

var bsbText:String = "fixed_bottom";
if(_model.hasOwnProperty("partner"))
{
	if(_model.partner.hasOwnProperty("userdefined"))
	{
		var userdefined:Object = _model.partner.userdefined;
		if(userdefined.hasOwnProperty("dims"))
		{
			bsbText = userdefined.dims;
		}
		else if(userdefined.hasOwnProperty("width") && userdefined.hasOwnProperty("height"))
		{
			bsbText = userdefined.width + "x" + userdefined.height;
		}
	}
}
var bsb:BannerShownBeacon = new BannerShownBeacon(bsbText);

Preloading SWF in Firefox using SWFobject doesn’t support overflow = null

I was using the following code to pre-load my SWFs so I could instantiate them later.

swfDiv.style.width = '1px';
swfDiv.style.height = '1px';
swfDiv.style.overflow = 'hidden';
swfDiv.style.position='fixed';
swfDiv.style.top = '0px';
swfDiv.style.left = '0px';

And then, when I wanted to show my SWF, I would call

swfDiv.width = '100%';
swfDiv.height = '100%';
swfDiv.zIndex = 1000;
swfDiv.overflow = null;

This works great in Chrome, but in Firefox, things go really bad and REALLY strange things start happening. Turns out that Firefox doesn’t like null as an overflow attribute.
Setting this to “” instead works fine.

swfDiv.width = '100%';
swfDiv.height = '100%';
swfDiv.zIndex = 1000;
swfDiv.overflow = "";

Flash-Injected Javascript does not Minify Properly in Ant

We’re using Flash to inject javascript onto our page, and to save space, we’re using a minifier to produce smaller javascript code. The issue is that we’re using a string replacement on our code and the minifier produces an odd result.

Consider the following code:

var id = myobj['ID_PLACEHOLDER'];

When we inject the code, we do a replace on ID_PLACEHOLDER and replace it with the appropriate ID. This is great, except that our minifier sees this as a waste of chars and minifies the system to:

var id = myobj.ID_PLACEHOLDER;

This would be well and good except that our IDs can begin with numbers and Javascript variables cannot. To solve this, I had to modify our placeholder to be:

var id = myobj['1_ID_PLACEHOLDER'];

This does not minify and produces correct code on the injected end.

ExternalInterface Callbacks not Firing in Firefox when Using SWFObject

Your externalinterface call works fine in chrome, safari, maybe even IE. That’s because it takes a second for Firefox to get with the program and actually shove your object into the element.

here’s a happy little hack to make things work again:
Flash:

import flash.external.ExternalInterface;
ExternalInterface.addCallback("myFunction", myFunction);
function myFunction():void
{
	trace("JS Callback Successful");
}

Javascript:

//the swf id is the object into which SWFobject has loaded your SWF file
var swf= document.getElementById("my_swf_id");
try {
	swf.myFunction();
}
catch (e) { 
	//swf is not loaded yet, wait a bit and try again
	setTimeout(function(){
		swf.myFunction();
	}, 10);
}