Blogger Bug - Corrupted Javascript for() loops

The Bug


Twice, when I have had call to write a javascript implementation for a blogspot page I have found that everything beneath the first line of a for() loop is chewed up, garbled, and spit back out upon saving it. Blogger doesn't throw an error of any kind, it just saves your code to the gadget, having silently mutated and destroyed what was written. This is observed by simply returning to the gadget via the edit button. There the code will be corrupt.


Example


<script type="text/javascript">

function addPlayers() {
var allmp3s = document.getElementsByName('mp3');
for (i=0;i<allmp3s.length;i++){
var mp3Player = buildEmbed(allmp3s[i]);
allmp3s[i].insertBefore(document.createElement('br'), allmp3s[i].firstChild);
allmp3s[i].insertBefore(mp3Player, allmp3s[i].firstChild);
}
}
</script>


Paste the code above into an HTML/Javascript gadget and save it. Now click edit to return to the code. Others have confirmed that as of this post's date blogspot corrupts it like so:

<script type="text/javascript">
function addPlayers() {
var allmp3s = document.getElementsByName('mp3');
for (i=0;i<allmp3s.length;i++){
}
}
mp3player="buildEmbed(allmp3s[i]);
" br var allmp3s[i].firstchild);
allmp3s[i].insertbefore(document.createelement( ),
allmp3s[i].insertbefore(mp3player,></script>


Workaround


Simply use another type of loop. A while() loop and a counter variable can be used to do accomplish the same results your for() loop might have. I haven't observed Blogger to corrupt while() loops.

A Good Reason to Kill Yourself

This summary is not available. Please click here to view the post.

Embed Flash MP3 Players w/ Javascript

What it Does:


The code provided here finds any <a> tags on the page that have been assigned the attribute, name="mp3". Then, using the URL from the <a> tag, it generates and places the proper code, embedding a flash mp3 player just above that <a> tag's link. Unaltered, this script uses the "Maxi" mp3 player hosted and available for download at http://flash-mp3-player.net/. (Though you need not download anything to run this script.)

Why?


First: Convenience. With this implementation I need only create a standard link and give it a name. From there, my mp3 player will appear on it's own, without all the ubiquitous <object><param><embed> malarky typically required to embed a flash file.

Secondly, to enable a reasonable level of dynamism to my Blogspot hosted site. If and when someone designs a slicker or more efficient mp3 player or... let's say the mp3 player I've been linking to disappears from its server someday - I'd like to be able to fix the broken links and integrate a new player into my site without having to edit every single post in which I'd ever embedded an audio file. This javascript standardizes the website's mp3 player, so that changing the embed code in the script effectively changes the embed code everywhere on the site.

How?


<script type="text/javascript">
/*
-----------------------------------------------
Dynamic Flash Embedder (for Linking MP3s)

Written by: Roy Tousignant
Date: 15 May 2009
URL: tvopiate.blogspot.com
----------------------------------------------- */

var playerloc = 'http://flash-mp3-player.net/medias/player_mp3_maxi.swf'

function buildObj(mp3) {
var flashtags = '<object data="'+playerloc+'" width="200" height="20" type="application/x-shockwave-flash">'
flashtags += '<param value="'+playerloc+'" name="movie">';
flashtags += '<param value="mp3='+mp3.href+'&amp;showstop=1&amp;showvolume=1" name="FlashVars">';
flashtags += '</object><br/>';

var obj = document.createElement('span');
obj.innerHTML = flashtags;
return obj;
}

function addPlayers() {
var mp3objs = document.getElementsByName('mp3');
var i = 0;
while (i < mp3objs.length) {
if(mp3objs[i].tagName == "A") {
mp3objs[i].parentNode.insertBefore(buildObj(mp3objs[i]), mp3objs[i]);
}
i++;
}
}

window.onload=addPlayers;
</script>


Usage


If you're using Blogger add a HTML/JavaScript gadget to your layout and paste in the code provided above. It doesn't matter where in your Blogspot layout you place the gadget. It will work just the same.

With the code in place you simply create links to the mp3 files you want to embed, making sure to include name="mp3" in the <a> tag. You can do this anywhere on your page: in posts; in the sidebars; in the header...

<a href="http://www.mymp3host.com/song.mp3" name="mp3">Download my Song</a>


That's it. Any links you make that carry the name "mp3" will magically receive an embedded mp3 player one line break above the link, allowing visitors to stream the file right there.

More Usage


Changing the flash player will probably require some basic understanding of simple coding. It's pretty straightforward to those who know, but for those who don't I'll provide an example. (Be it any help to you or not.)

To change the mp3 player that is being embedded you just need to edit the 'playerloc' and 'flashtags' variables near the top of the script to reflect the object/embed code for the new player.

For example, Google has a flash MP3 player that can be linked to. To embed Google's player manually onto a page you would use this object/embed code:

<object data="http://www.google.com/reader/ui/3247397568-audio-player.swf?audioUrl=http://www.mymp3host.com/song.mp3" width="400" height="27" type="application/x-shockwave-flash">
<param value="http://www.google.com/reader/ui/3247397568-audio-player.swf?audioUrl=http://www.mymp3host.com/song.mp3" name="movie">
<param name="flashVars" value="playerMode=embedded">
</object>


Therefore, to integrate Google's embed code into our script you would replace the playerloc and flashtags variables in our javascript code with:

var playerloc='http://www.google.com/reader/ui/3247397568-audio-player.swf?audioUrl=';

var flashtags = '<object data="' + playerloc + mp3.href + '" width="400" height="27" type="application/x-shockwave-flash">';
flashtags += '<param value="' + playerloc + mp3.href + '" name="movie">';
flashtags += '<param name="flashVars" value="playerMode=embedded">';
flashtags += '</object><br/>';


Note here that Google's player looks for the mp3 location to be included in-line with the link to the audio player itself, whereas the Maxi MP3 Player being used by default expects the mp3's url to be declared in the flashVar param.

And that's all the hints you get. ...ya' bunch of noobs.

Design Notes


"Why did you use a while loop instead of a for loop," you ask? To avoid a bug in blogger's code. In development whenever I saved the script to Blogger's HTML/Javascript gadget, use of the for loop caused everything thereafter to be scrambled.

End of Line


I suppose that's it. Wow, it might've taken as long documenting it as it did writing the damned thing. And I was trying to keep it brief! Actually it took me about 10 hours, start to finish, developing this script; forced to learn all sorts of javascript functions I'd never worked with before; fighting the Blogspot bugs to make it work in the gadget... Well.

Do leave me a comment if you're using it. I'd love to see my handiwork gracing other sites. And if you have any problems with it... 'the hell do I care?

Grand Re-Reopening

After much deliberation I have at last decided to let Blogger host this site. I feel more comfortable working within some boundaries, I think. The volume of possibilities I had while hosting the site through http://www.asmallorange.com/ became as much a burden as anything. And Blogger's limitations are proving themselves just imposing enough to provide a challenge, while flexible enough to allow for the most cunning solutions.

I also take heart in the notion that this freely provided medium will most probably outlive my interest in it; will possibly even outlive my ability (or willingness) to continue breathing. Whereas any payed hosting solution surely fails to outlive even my bank account.

I won't say much more. I'm getting sick of "opening" the site, honestly. It's all pomp and circumstance. Besides, I've got a pile of articles that need written and more that need transferred from the other blogspot site I mean to deprecate. So, then...

'Twas a Good Day for Disc Golf

Today I finally got out to Bay Court Park's subtly remade disc golf course, what's been closed until some time two weeks ago. At the end of last season the parks and recreations peoples pulled the pins out of the ground. Earlier this month they finally resunk them and, for whatever reason, they moved them all to slightly different locations.

It's nice to see such a familiar course change and become something new. Especially when you shoot the kind of first-out games I did today.

Okay, the scores are less than impressive: +1 on my first round and -1 on my second. But I tell you those are high marks for a day like today. The wind was gusting intensely throughout the whole back half of the course. So much so, more than once I watched my disc parachute in the wind, rolling and bouncing a hundred and fifty feet off target and onto some other hole's fairway.

Despite the wind I was happy with my game and the new course. Hole 2 has been lengthened by about thirty feet, which was nice. It really showed me how much more distance I'm getting out of my drives this year, in comparison with last. Hole 3, though drastically relocated. still sits on the edge of a steep hillside, daring you to throw for the chains, miss, and find yourself forty feet overshot or rolled away.

In fact, during my first round I threw a pretty chip shot right at three's pin. It bounced off the ground at the pole and slid out of site, just over the hill's crest. I thought I had placed within five feet of the pin. But from atop the hill I found no disc. A sweeping gaze revealed my errant disc, some thirty feet rolled away from where I watched it first touch down, lying at the bottom of a ditch. From the bottom of that ditch, slightly perturbed, I made my shot for birdy. I threw at an angled pitch; a diving shot that guaranteed, if I missed, I wouldn't go rolling down the hill again. The disc went up six feet to the right of the chains, held in the air briefly by the gusting winds, and dived straight into the bottom of the basket.

I'll remember that shot for some time. Aside from being the kind of long-distance putt I rarely ever make, I have never felt a disc - mine or anyone's - go in the basket like that. It was so gentle. It grazed the chains, but sounded dainty as a wind chime. And when it touched down it didn't ping or bong when it connected with the basket either. It was as though the disc had given itself over to me, abiding my desire, unresisting. I hadn't so much thrown it at the pins as placed it atop my open palm and blown it where I wanted it to go. I felt this strange touchdown in my arm's bicep when the disc met the basket. And it was odd.

Hole 4 has been lengthened as well. Last year I could never quite drive to the pin. I could get within twenty feet, but I never overshot it and I never got within a comfortable putting distance. This year, thanks some to my 'longer arm' and thanks more to the wind at my back, I crushed a drive all the way to within twelve feet of the goal. On a hole listed as a par 4, no less! Unfortunately I didn't eagle, for the wind - fickle, she is - turned against me, conspiring with my timid short game to concoct an unlikely miss.

The last five holes were throwing into or against the cut of the wind, suddenly making par a worthy goal. It took me three holes and as many bogeys to realize that my heavier, 170 gram Valkyrie disc, which I had figured - for it's weight - all the better to play into the wind, is more or less helpless in the wind. And, in fact, it was my light-weight driver, the 150 gram Valkyrie Star, (I'm a Valkyrie whore - love 'em) that I only tried out of frustration, that somehow managed to pierce the wind without parachuting off course.

On the second go-round I had a better idea of how to shoot into the wind, which probably won me those two extra strokes. The only hole I recall being especially noteworthy was the ninth. Hole 9 has always been an intimidating hole. It plays about 150 feet straight between two lines of trees and it's a tight corridor. That first one-fifty is no more than 15 feet wide the whole way down, and then it empties to the left. I've always had something of a knack for the hole. Last year, more often than not, I managed to consistently thread the needle of hole 9 and skip right up to the basket. But that was last year, and this year they've moved the basket.

The dog-leg left that hole 9 always featured is now a much sharper cut. The trick to nine's corridor used to be throwing a flat, well-aimed shot that broke very gently left at the end. Keeping the disc low - say eight feet off the ground - used to work out well for me. But now that the pin has been brought in, exiting the corridor has become more of a sudden 60 degree cut to the left.

On my first attempt at hole 9 the wind got under my disk, keeping it too flat, and I threaded the corridor, but without any break left at the end. The disc slammed into the tree line and I ended up taking my second shot from the forest's edge. And it cost me. I ended up bogeying the last hole, going positive on my otherwise even round. So on my second go I opted for a 30 degree release, with a lot of power behind it to keep it between the trees until the end. I hit it perfectly; didn't so much as graze a single branch on my way out of the corridor and put myself into a very nice birdie position. Again, the wind foiled my birdie but this time I was able to save par.

Yes, 'twas a good day for disc golf at the Andersonville Rd., Bay Court Park. A good day made even better when, between rounds, I put down a towel on the beach at the lake's edge and sunbathed while reading Kafka's 'Amerika.' 'Twas a good day for disc golf.

'Twas a good day for Roy.