<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ForestMist &#187; Web</title>
	<atom:link href="http://forestmist.org/category/web/feed/" rel="self" type="application/rss+xml" />
	<link>http://forestmist.org</link>
	<description></description>
	<lastBuildDate>Tue, 11 Oct 2011 03:17:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>WordPress Cookieless Domains</title>
		<link>http://forestmist.org/2011/10/wordpress-cookieless-domains/</link>
		<comments>http://forestmist.org/2011/10/wordpress-cookieless-domains/#comments</comments>
		<pubDate>Mon, 10 Oct 2011 21:41:25 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Cookieless]]></category>
		<category><![CDATA[htaccess]]></category>
		<category><![CDATA[Performance Optimization]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://forestmist.org/?p=1450</guid>
		<description><![CDATA[First off, cookieless domains are your friends for content distribution. Why? Because every time a web browser talks to a server it sends a copy of all its cookies for that domain. As you can imagine this is quite ridiculous if your client is requesting an image, CSS, JS or other static resource which can [...]]]></description>
			<content:encoded><![CDATA[<div class="story-image" style="background-image: url(http://forestmisty.org/wp-content/uploads/2011/10/wordpress-cookieless-domain.jpg);"><a href="http://forestmisty.org/wp-content/uploads/2011/10/wordpress-cookieless-domain.jpg"></a></div>
<p>First off, cookieless domains are your friends for content distribution. Why? Because every time a web browser talks to a server it sends a copy of all its cookies for that domain. As you can imagine this is quite ridiculous if your client is requesting an image, CSS, JS or other static resource which can never use that cookie information. These wasted upload bits are totally unnecessary so lets get rid of them with the help of a cookieless domain.</p>
<h2>Sub or New Domain?</h2>
<p>You might think there is a magical &#8216;no cookies&#8217; option on your server but there isn&#8217;t. A cookieless domain is simply one that has never set a cookie. This means two options; create a sub domain (like s.forstmist.org) or create a new domain name.</p>
<p>At first glance a sub domain seems nice and simple but there is a caveat. If you redirect your visitors from a sub domain (www.forestmist.org) to your root domain (forestmist.org) you&#8217;ll end up with cookies on your root domain. These root cookies are automatically sent along with any requests to <em>all</em> sub domains. That&#8217;s right, having cookies on your root domain taints <em>all</em> your sub domains from becoming cookieless domains. This is not a concern if you channel all your visitors to a www sub domain since any cookies there will not be available to the root domain and therefore won&#8217;t taint other sub domains.</p>
<p>For short domain name lovers, registering a new domain for serving static content is a no brainer. I definitely fall into this category so I registered forestmisty.org which I shall use as an example in the rest of this guide.</p>
<p><span class="Apple-style-span" style="font-size: 20px;"><strong>.htaccess Redirect</strong></span></p>
<p>With the new misty domain setup and pointing to my web server everything was working great. Requests to static images weren&#8217;t passing cookie information but what if someone went to the root of forestmisty.org? What if a broken link sent them to a 404? WordPress would handle the request and that means potential cookies from it or Google Analytics. Yikes!</p>
<p>What would be nice is if we can allow any requests for forestmisty.org/wp-content/ but redirect anything else back to forestmist.org. We can do exactly that with the following .htaccess commands.</p>
<pre>RewriteEngine on
RewriteCond %{HTTP_HOST} ^forestmisty.org$ [NC]
RewriteCond %{REQUEST_URI} !^/wp-content/?(.*)$ [NC]
RewriteRule ^(.*)?$ http://forestmist.org/$1 [R=301,L]</pre>
<p>The first line enables the Apache rewrite engine.<br />
The second line says anytime a request comes in for &#8216;forestmisty.org&#8217; continue to the next line.<br />
The third line says if the request is NOT for &#8216;/wp-content/&#8230;&#8217; continue to the next line.<br />
The forth line says if we made it this far redirect the original request to forestmist.org including any extra query information like /favicon.ico, /creative-resume, etc&#8230;</p>
<p>By the way&#8230;<br />
^ means the start of a string.<br />
$ means the end of a string.<br />
? means the preceding character or collection in parenthesis is optional.<br />
. means any one character.<br />
* means the preceding character can occur 0 or more times.<br />
$1 means insert whatever was inside the first set of parenthesis to the left.<br />
[NC] means not case sensitive.<br />
[R=301] means do a 301 redirect.<br />
[L] means the last rule so don&#8217;t bother processing the rest of the .htaccess file.</p>
<p>Now we can rest assured that requests to our new cookieless domain will stay cookie free by only servering up what are almost always static file requests from the /wp-content folder.</p>
<h2>Configure WordPress</h2>
<p>Our new domain is setup and protected pretty well thanks to our .htaccess file so now it&#8217;s time for WordPress to join the fray. Specially, WordPress needs to have any /wp-content  links rewritten to point to the same location on our cookie free domain.</p>
<ul>
<li>Download, install and activate the excellent <a href="https://github.com/wmark/CDN-Linker/downloads">CDN Linker</a> by <a href="http://mark.ossdl.de/">W-Mark Kubacki</a>.</li>
<li>Login to WordPress</li>
<ul>
<li>Settings » CDN Linker</li>
<ul>
<li>Enter your new cookieless domain for CDN URL.</li>
<li>Change your &#8216;Include Dirs&#8217; line to read &#8216;wp-content&#8217; if you setup your .htaccess file like mine.</li>
<li>Save Changes</li>
</ul>
</ul>
</ul>
<p>Load your home page and view source. You should see your new cookieless domain being referenced quite often. Yay!</p>
<h2>Success</h2>
<p>With a little bit of effort our server is less stressed, our clients are loading faster and hopefully you&#8217;ve got a silly grin on your face.</p>
]]></content:encoded>
			<wfw:commentRss>http://forestmist.org/2011/10/wordpress-cookieless-domains/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>PHP 5 &#8211; Sort by Folder</title>
		<link>http://forestmist.org/2011/06/php-5-sort-by-folder/</link>
		<comments>http://forestmist.org/2011/06/php-5-sort-by-folder/#comments</comments>
		<pubDate>Sun, 26 Jun 2011 23:01:50 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHP 5]]></category>

		<guid isPermaLink="false">http://forestmist.org/?p=1295</guid>
		<description><![CDATA[Recently, I needed to display a list of files with PHP. My only caveat was that I wanted to do so using newer methods of PHP 5 where possible. I was delighted to find scandir. Problem was, scandir returns files mixed with folders and that would upset my flock of easily frightened Windows users. So a quick&#8230; er [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I needed to display a list of files with PHP. My only caveat was that I wanted to do so using newer methods of PHP 5 where possible.</p>
<p>I was delighted to find <a href="http://php.net/manual/en/function.scandir.php">scandir</a>. Problem was, scandir returns files mixed with folders and that would upset my flock of easily frightened Windows users.</p>
<p>So a quick&#8230; er medium&#8230; ok fine,  an exasperating search on Google and only outdated, complex and inefficient samples were to be found. <a href="http://www.youtube.com/watch?v=1Lr_TVZnuxs">PUFF</a>!</p>
<p>So, here is the version I came up with.</p>
<div style="text-align: center"><a class="css3-button" href="http://forestmist.org/share/code/php-sort-by-folder/demo/">Demo<span></span></a></div>
<h2>Downloads</h2>
<ul>
<li><a href="/share/code/php-sort-by-folder/Sort%20by%20Folder.zip"><strong>Sort by Folder</strong></a> is optimized for easier PHP comprehension.</li>
<li><a href="http://forestmist.org/share/code/php-sort-by-folder/Sort%20by%20Folder%20(with%20HTML).zip"><strong>Sort by Folder (with HTML)</strong></a> contains extra code which adds more information and cleaner formatting to the generated HTML.</li>
</ul>
<h2>How it works</h2>
<p>The most crucial part of all the code you will see inside the demo is the PHP getObjects() function. Without this everything else would be moot so lets go over it in a bit more detail.</p>
<pre class="brush: php; title: ; notranslate">
function getObjects($path) {
    $path .= '/';
    $array = scandir($path); // returns an array of files and folders sorted alphabetically
    $array = array_diff($array, array('.', '..', '.DS_Store', 'Thumbs.db')); // filter out things we don't want

    $return_array = array();

    foreach($array as $item) {
        if(is_dir($path . $item)) {
            $return_array[$item] = getObjects($path . '/' . $item);
        }
    }

    $count = 0;
    foreach($array as $item) {
        if(!is_dir($path . $item)) {
            $return_array[$item] = $item;
            $count++;
        }
    }
    if($count == 0) {
        $return_array[''] = '';
    }

    return $return_array;
}
</pre>
<p><strong>Line 3</strong><br />
Scandir returns an array of mixed folders and files for the path requested. This does not include sub directories.</p>
<p><strong>Line 4</strong><br />
Filter out any undesirables. That means the current &#8216;.&#8217; and parent directory &#8216;..&#8217; although we don&#8217;t want any Mac &#8216;.DS_Store&#8217; or WIndows &#8216;Thumbs.db&#8217; files either.</p>
<p><strong>Line 6</strong><br />
We create a new array called $return_array which will be built up with all the folders and files in the order we want them. Folders first, then files. Both alphabetically.</p>
<p><strong>Line 8-12</strong><br />
Here we loop through each item in our filtered results from scandir. If the item is a directory we set the results of $return_array[$item] to a recursive call of the very same function we are already in. Traveling deeper each recursive call, that means we can handle seemingly infinite directory structures. Neat.</p>
<p>This first loop through <em>only</em> cares about directories which is exactly what puts them first in our $return_array. Files will come next.</p>
<p><strong>Line 14</strong><br />
We set a variable $count to 0 to keep track of how many files we find in the next foreach loop.</p>
<p><strong>Line 15-19</strong><br />
In this second loop we check to make sure the items are not directories and if so return those items while incrementing the $count variable.</p>
<p><strong>Line 21-23</strong><br />
Now that we are finished looping for files we can check our $count variable. If 0 then set $return_array to &#8221;. This can useful later in case we want to do something special for directories without files.</p>
<p><strong>Line 25</strong><br />
Finally, we return whatever we have found. In most cases this means returning an $array to another instance of the function although ultimately the original one will return a completed array to the PHP call outside our function that started it all.</p>
<p>In the demo we can now loop through this nicely ordered array and write out some HTML and CSS, add a sprinkle of JavaScript and we have a real working web app.</p>
<div style="position: absolute; margin-left: -96px;"><a href="http://www.flickr.com/search/?q=elephpant&#038;s=rec"><img src="http://forestmisty.org/wp-content/uploads/2011/06/php-elephant.png" width="65" height="88" style="border-width: 0px; moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none;"><img src="http://forestmisty.org/wp-content/uploads/2011/06/php-elephant-nose.png" width="95" height="89" style="border-width: 0px; moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; position: absolute; margin-left: -66px;"></a></div>
<h2>Epilogue</h2>
<p>Once you get your head around recursive loops things become much simpler. Plus you get to worry more about optimizing your code since each loop can be run so many times. It&#8217;s a good problem to have, really.</p>
<p>Anyway, I certainly hope this helps you in your next endeavor. I know I certainly would be lost without all the wonderful code and tutorials shared by others.</p>
<p>Cheers!</p>
]]></content:encoded>
			<wfw:commentRss>http://forestmist.org/2011/06/php-5-sort-by-folder/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ForestMist Regeneration</title>
		<link>http://forestmist.org/2011/02/forestmist-regeneration/</link>
		<comments>http://forestmist.org/2011/02/forestmist-regeneration/#comments</comments>
		<pubDate>Mon, 14 Feb 2011 07:17:41 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Redesign]]></category>

		<guid isPermaLink="false">http://forestmist.org/?p=1201</guid>
		<description><![CDATA[I&#8217;ve been making some big changes in my personal life so I felt my website needed to reflect that. Something new, clean and more optimized. It&#8217;s no Muramasa but it&#8217;s definitely a stepping stone towards something even more fantastical. Plans within plans my friend. I think it came out pretty nice. Works perfect in nice browsers like Chrome, FireFox, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been making some big changes in my personal life so I felt my website needed to reflect that. Something new, clean and more optimized. It&#8217;s no <a href="http://en.wikipedia.org/wiki/Muramasa">Muramasa</a> but it&#8217;s definitely a stepping stone towards something even more fantastical. Plans within plans my friend.</p>
<p><a href="http://forestmisty.org/wp-content/uploads/2011/02/ForestMist-Regeneration-2011-02.png"><img class="alignnone size-large wp-image-1202" title="ForestMist-Regeneration-2011-02" src="http://forestmisty.org/wp-content/uploads/2011/02/ForestMist-Regeneration-2011-02-700x414.png" alt="" width="567" height="336" /></a></p>
<p>I think it came out pretty nice. Works perfect in nice browsers like Chrome, FireFox, Safari, Opera and even works well in IE 6, 7 and 8. The nicer browsers will have subtle shadows, rounded corners, bit cleaner lines between items but really that could be considered progressive enhancement. The site is perfectly readable in old busted browsers too. Good job if I do say so myself.</p>
<p>I learned a lot on this project, more so than I had imagined but then again&#8230; good projects always prepare you for the next challenge. I&#8217;m proud to have stuck with it over the course of many days it took.</p>
<p>xoxo</p>
<p>-Daniel</p>
]]></content:encoded>
			<wfw:commentRss>http://forestmist.org/2011/02/forestmist-regeneration/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Add a password reset feature to Halogen eAppraisal</title>
		<link>http://forestmist.org/2010/04/add-a-password-reset-feature-to-halogen-eappraisal/</link>
		<comments>http://forestmist.org/2010/04/add-a-password-reset-feature-to-halogen-eappraisal/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 05:45:19 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[ASP]]></category>
		<category><![CDATA[Encryption]]></category>

		<guid isPermaLink="false">http://forestmist.org/?p=1058</guid>
		<description><![CDATA[One really important feature missing from Halogen eAppraisal is the ability for users to reset their own passwords. Seems like such a basic feature but even their friendly support folks confirmed that there was no addon or plan to release the feature in a future version. Weird! No matter though, let&#8217;s make our own. Investigation I spent [...]]]></description>
			<content:encoded><![CDATA[<p>One really important feature missing from Halogen eAppraisal is the ability for users to reset their own passwords.</p>
<p>Seems like such a basic feature but even their friendly support folks confirmed that there was no addon or plan to release the feature in a future version. Weird!</p>
<p>No matter though, let&#8217;s make our own.</p>
<h2>Investigation</h2>
<p>I spent untold amounts of time clawing through unfamiliar Java code. A occasional scrap was enough to forge my determination but nothing really made sense yet. Too many files, too many directories but maybe if I just kept trying&#8230;</p>
<p><a href="http://www.youtube.com/watch?v=8HE9OQ4FnkQ">A-ha</a>!</p>
<p>Hidden deep within the lair of &lt;Tomcat&gt;\webapps\Halogen\WEB-INF\classes\com\halogensoftware\common\security\ is a file called &#8216;Utility.class&#8217;. Inside, a string that resembles the worst regular expression ever created.</p>
<p style="padding-left: 30px;">^a`Z{b1Y}c2X[d3W]e4V|f5U\g6T:h7S;i8R&#8221;j9Q&#8217;k0P&lt;l-O&gt;m=N?n~M,o!L.p@K/q#Jr$Is%Ht^Gu&amp;Fv*Ew(Dx)Cy_Bz+A</p>
<p>I was sure this string was used to encrypt the passwords stored in the database but I needed a way to confirm that so&#8230;</p>
<p>Using a test account I set the password to the number 1 which was encrypted as the letter Y. Password 11 became Y}. Password 111 became Y}c.</p>
<p>Ah, so simple!</p>
<p>If your password was the ^ symbol it would find it in the string above and then move right one space and choose the letter &#8220;a&#8221; as your encrypted password. If your password was ^^ then the the first encrypted character would be &#8220;a&#8221; again but the second one would shift two places to the right and store the ` symbol</p>
<p>Here are a few more example conversions.</p>
<ul>
<li>^^^ becomes a`Z</li>
<li>wT7w becomes (hi)</li>
<li>A+z becomes ^^^</li>
</ul>
<p>Notice that in the last example we&#8217;ve simply looped around once we hit the right side of the hash string.</p>
<p>Now that we know how it works let&#8217;s build our own utility in ASP that we can use to reset anyone&#8217;s password.</p>
<h2>The Solution</h2>
<p>Besides the obvious DSN string, you&#8217;ll want to carefully consider how you validate your users.</p>
<p>The setup I used at work talked to a Human Resources database and would validate no less than three pieces of information before even attempting a reset. I urge you dear reader to do the same.</p>
<pre class="brush: vb; title: ; notranslate">
sID = Request.Form(&quot;id&quot;)
sPassword = Request.Form(&quot;password&quot;)

Set oConn = Server.CreateObject(&quot;ADODB.Connection&quot;)
oConn.Open &quot;DSN String for the Halogen eAppraisal Database&quot;

Set oRS = Server.CreateObject(&quot;ADODB.Recordset&quot;)
oRS.Open &quot;SELECT TOP 1 * FROM [view-user_info] WHERE username = '&quot; &amp; sID &amp; &quot;'&quot;, oConn, 0, 3 'adOpenForwardOnly, adLockOptimistic

If not oRS.EOF then
	sKeyCode = &quot;a`Z{b1Y}c2X[d3W]e4V|f5U\g6T:h7S;i8R&quot;&quot;j9Q'k0P&lt;l-O&gt;m=N?n~M,o!L.p@K/q#Jr$Is%Ht^Gu&amp;Fv*Ew(Dx)Cy_Bz+A&quot;
	sKeyCodeLength = Len(sKeyCode)
	x = 1
	sBadChar = 0
	Do until x &gt; Len(sPassword)
		sChar = Mid(sPassword, x, 1)

		If InStr(sKeyCode, sChar) then
			sKeyCodePos = InStr(sKeyCode, sChar) + x
			If sKeyCodePos &gt; sKeyCodeLength then
				'Need to loop around the beginning
				Do until sKeyCodePos &lt;= sKeyCodeLength
					sKeyCodePos = sKeyCodePos - sKeyCodeLength
				loop
			End If
			sEncodeChar = Mid(sKeyCode, sKeyCodePos, 1)
			sEncodePassword = sEncodePassword + sEncodeChar
		Else
			'Could not find a character in sKeyCode
			sBadChar = sBadChar + 1
		End If
		x = x + 1
	loop

	If sBadChar &gt; 0 then
		Response.Write &quot;&lt;p&gt;&lt;strong&gt;Unsupported characters were used to try to set the encrypted password. New password was not saved.&lt;/strong&gt;&lt;/p&gt;&quot;
	Else
		oRS(&quot;password&quot;) = sEncodePassword
		oRS(&quot;password_change_date&quot;) = NULL
		oRS.Update
		Response.Write &quot;&lt;p&gt;The password for your account &quot; &amp; sID &amp; &quot; has been reset.&lt;/p&gt;&quot;
	End If
Else
	Response.Write &quot;&lt;p&gt;&lt;strong&gt;A corresponding account for the user &quot; &amp; sID &amp; &quot; does not exist. Please contact support.&lt;/strong&gt;&lt;/p&gt;&quot;
End If

oRS.Close
oConn.Close
Set oRS = nothing
Set oConn = nothing
</pre>
<p>Questions welcome so feel free to comment below.</p>
<p>See ya later, space cowboy.</p>
]]></content:encoded>
			<wfw:commentRss>http://forestmist.org/2010/04/add-a-password-reset-feature-to-halogen-eappraisal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5 Audio Loops</title>
		<link>http://forestmist.org/2010/04/html5-audio-loops/</link>
		<comments>http://forestmist.org/2010/04/html5-audio-loops/#comments</comments>
		<pubDate>Mon, 12 Apr 2010 00:02:01 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web Browser]]></category>

		<guid isPermaLink="false">http://forestmist.org/?p=1102</guid>
		<description><![CDATA[One of the neatest things about HTML5 is support for the new &#60;audio&#62; tag. Like &#60;video&#62; it allows you to natively support media in good browsers like Chrome, FireFox, Opera and Safari. Add a touch of JavaScript and a new era of  media applications become possible. Synthesizers, music trackers and games require seamless audio loops though [...]]]></description>
			<content:encoded><![CDATA[<p>One of the neatest things about HTML5 is support for the new &lt;audio&gt; tag. Like &lt;video&gt; it allows you to natively support media in good browsers like Chrome, FireFox, Opera and Safari. Add a touch of JavaScript and a new era of  media applications become possible.</p>
<p>Synthesizers, music trackers and games require seamless audio loops though so we need something a bit simpler for our first foray into HTML5 audio.</p>
<p>Oooh, how about a retro beatbox with individual track adjustments (start/stop/loop/volume) that could be used to build a unique soundscape from many separate instruments. Perfect!</p>
<p>Fantasy can only become reality through hard work so let&#8217;s get started with some tests first.</p>
<h2>Loop Method 1</h2>
<pre><audio id="audio_1" controls preload loop>
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.ogg">
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.wav">
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.mp3">
</audio></pre>
<p>Uses the &#8216;loop&#8217; property.</p>
<pre class="brush: xml; title: ; notranslate">&lt;audio id=&quot;audio_1&quot; controls preload loop&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.ogg&quot;&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.wav&quot;&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.mp3&quot;&gt;
&lt;/audio&gt;</pre>
<h2>Loop Method 2</h2>
<pre><audio id="audio_2" controls preload>
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.ogg">
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.wav">
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.mp3">
</audio></pre>
<p>Uses a JavaScript function to loop when an &#8216;ended&#8217; event is called.</p>
<pre class="brush: xml; title: ; notranslate">&lt;audio id=&quot;audio_2&quot; controls preload&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.ogg&quot;&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.wav&quot;&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.mp3&quot;&gt;
&lt;/audio&gt;</pre>
<pre class="brush: jscript; title: ; notranslate">
document.getElementById('audio_2').addEventListener('ended', function(){
this.currentTime = 0;
}, false);
</pre>
<h2>Loop Method 3</h2>
<pre><audio id="audio_3" controls preload>
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.ogg">
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.wav">
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.mp3">
</audio>
<audio id="audio_4" controls preload>
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.ogg">
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.wav">
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.mp3">
</audio></pre>
<p>Uses two JavaScript functions and two audio elements with the same source to alternate playback duties.</p>
<pre class="brush: xml; title: ; notranslate">&lt;audio id=&quot;audio_3&quot; controls preload&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.ogg&quot;&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.wav&quot;&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.mp3&quot;&gt;
&lt;/audio&gt;
&lt;audio id=&quot;audio_4&quot; controls preload&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.ogg&quot;&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.wav&quot;&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.mp3&quot;&gt;
&lt;/audio&gt;</pre>
<pre class="brush: jscript; title: ; notranslate">document.getElementById('audio_3').addEventListener('ended', function(){
this.currentTime = 0;
this.pause();
document.getElementById('audio_4').play();
}, false);

document.getElementById('audio_4').addEventListener('ended', function(){
this.currentTime = 0;
this.pause();
document.getElementById('audio_3').play();
}, false);</pre>
<pre><script type="text/javascript">		document.getElementById('audio_2').addEventListener('ended', function(){
this.currentTime = 0;
}, false);

document.getElementById('audio_3').addEventListener('ended', function(){
this.currentTime = 0;
this.pause();
document.getElementById('audio_4').play();
}, false);

document.getElementById('audio_4').addEventListener('ended', function(){
this.currentTime = 0;
this.pause();
document.getElementById('audio_3').play();
}, false);
</script></pre>
<h2>Browser Support</h2>
<p>Tests were done on Windows 7 with Chrome 5.0.342.9 beta, FireFox 3.6.3, Internet Explorer 9.0 Preview, Opera 10.51 and Safari 4.0.5. </p>
<p><strong>Chrome</strong> seems to trigger loops before the current sound is completely finished leading to some odd jumpiness. All loop methods are affected.</p>
<p><strong>FireFox</strong> doesn&#8217;t seem to like the &#8216;loop&#8217; property of method 1, odd. Method 2 has the slightest of delays between loops and method 3 was actually perfect! I didn&#8217;t believe it until verification at the millisecond level with <a href="http://audacity.sourceforge.net/">Audacity</a>. Hooray Mozilla!</p>
<p><strong>Internet Explorer 9</strong> doesn&#8217;t support the audio tag yet. Hopefully it will before an official release.</p>
<p><strong>Opera</strong> performs almost as well as FireFox although there is still a small delay even when using method 3.</p>
<p><strong>Safari</strong> seems slow to start playback which is very easy to detect once you hear a loop. All loop methods affected.</p>
<p>Feedback on other browsers/OS compatibility would be very interesting so please feel free to discuss any findings in the comments below.</p>
<h2>Final Thoughts</h2>
<p>As of right now (April 11, 2010) only FireFox can do a perfect loop by cheating a bit and using two &lt;audio&gt; elements with JavaScript.</p>
<p>So yeah, it&#8217;s a bit too early for HTML5 audio loops but don&#8217;t let that stop you from creating sound boards, media players and other fun things.</p>
<p>Hopefully with some more optimizations audio support will continue to improve and a HTML5 beatbox fantasy can become reality.</p>
<p>Until then there are plenty of other fun things to play with.</p>
<p>Cheers!</p>
]]></content:encoded>
			<wfw:commentRss>http://forestmist.org/2010/04/html5-audio-loops/feed/</wfw:commentRss>
		<slash:comments>33</slash:comments>
		</item>
		<item>
		<title>Disable right clicking on images only</title>
		<link>http://forestmist.org/2010/03/disable-right-clicking-on-images-only/</link>
		<comments>http://forestmist.org/2010/03/disable-right-clicking-on-images-only/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 03:53:04 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[MooTools]]></category>
		<category><![CDATA[Web Browser]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://forestmist.org/?p=161</guid>
		<description><![CDATA[There are few instances where disabling someone&#8217;s context menu is appropriate. In most cases it&#8217;s unnecessary and can even lead to infuriating your visitors. Here are some ways to target all the image elements on a page while leaving the rest of the hypertext in peace. JavaScript Lightweight, no framework required and works well in [...]]]></description>
			<content:encoded><![CDATA[<p>There are few instances where disabling someone&#8217;s context menu is appropriate. In most cases it&#8217;s unnecessary and can even lead to infuriating your visitors.</p>
<p>Here are some ways to target all the image elements on a page while leaving the rest of the hypertext in peace.</p>
<h2>JavaScript</h2>
<p>Lightweight, no framework required and works well in IE 6, 7, 8, Chrome, FireFox and Safari. <a href="/wp-content/uploads/2010/03/Protect-Images-with-JavaScript.html">Demo »</a></p>
<pre class="brush: jscript; title: ; notranslate">
document.oncontextmenu = context_menu;

function context_menu(e) {
if (!e) var e = window.event;
	var eTarget = (window.event) ? e.srcElement : e.target;

	if (eTarget.nodeName == &quot;IMG&quot;) {
		//context menu attempt on top of an image element
		return false;
	}
}
</pre>
<hr />
<h2>jQuery</h2>
<p>Perhaps the prettiest code of the three. <a href="/wp-content/uploads/2010/03/Protect-Images-with-jQuery.html">Demo »</a></p>
<pre class="brush: jscript; title: ; notranslate">
$(document).ready(function(){
	$(document).bind(&quot;contextmenu&quot;,function(e){
		if(e.target.nodeName == 'IMG'){
			//context menu attempt on top of an image element
			return false;
		}
	});
});
</pre>
<hr />
<h2>MooTools</h2>
<p>Moo&#8230; <a href="/wp-content/uploads/2010/03/Protect-Images-with-MooTools.html">Demo »</a></p>
<pre class="brush: jscript; title: ; notranslate">
window.addEvent('domready', function() {
	$(document.body).addEvent('contextmenu', function(e) {
		if(e.target.nodeName == 'IMG') {
			//context menu attempt on top of an image element
			return false;
		}
	});
});
</pre>
<hr />
<h2>Final Thoughts</h2>
<p>With a bit more code you can target specific IDs, class names or any number of elemental combinations. Doing so will limit your context menu friendly fire and keep both you and your users in a happy balance.</p>
<p>Cheers!</p>
]]></content:encoded>
			<wfw:commentRss>http://forestmist.org/2010/03/disable-right-clicking-on-images-only/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A home for the experimentally insane</title>
		<link>http://forestmist.org/2009/10/a-home-for-the-experimentally-insane/</link>
		<comments>http://forestmist.org/2009/10/a-home-for-the-experimentally-insane/#comments</comments>
		<pubDate>Sat, 24 Oct 2009 23:06:30 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Experimental]]></category>
		<category><![CDATA[Web Browser]]></category>

		<guid isPermaLink="false">http://forestmist.org/?p=354</guid>
		<description><![CDATA[I&#8217;ve added a new experimental section to the site which I hope will contain many a mad thing for you dear visitor. On on first journey we find out if its possible to create strange shapes using only CSS. So come one and come all to see the gross disregard for copyright law as we [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_358" class="wp-caption alignright" style="width: 180px"><a href="http://forestmisty.org/wp-content/uploads/2009/10/Daniel-the-Monster-2003.png"><img class="size-medium wp-image-358 " title="Daniel the Monster" src="http://forestmisty.org/wp-content/uploads/2009/10/Daniel-the-Monster-2003-300x300.png" alt="Let me show you something..." width="150" height="150" /></a><p class="wp-caption-text">Founder of the home for the experimentally insane.</p></div>
<p>I&#8217;ve added a new experimental section to the site which I hope will contain many a mad thing for you dear visitor.</p>
<p>On on first journey we find out if its possible to create strange shapes using only CSS.</p>
<p>So come one and come all to see the gross disregard for copyright law as we make your very own <a href="/experimental/bahamas-logo-using-css3/"><strong>Bahamas logo using CSS</strong></a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://forestmist.org/2009/10/a-home-for-the-experimentally-insane/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automatically backup FireFox 3 bookmarks</title>
		<link>http://forestmist.org/2009/08/automatically-backup-firefox-3-bookmarks/</link>
		<comments>http://forestmist.org/2009/08/automatically-backup-firefox-3-bookmarks/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 05:45:51 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[FireFox 3]]></category>
		<category><![CDATA[Web Browser]]></category>

		<guid isPermaLink="false">http://forestmist.org/?p=131</guid>
		<description><![CDATA[I like to format my computer fairly often which means having all my data in one easy to find location. Not only does this make backing up easy but it also removes that dreadful feeling you get when you realize your new OS install overwrote your irreplacable bookmarks, precious emails and/or accumulated works of Bettie Page. [...]]]></description>
			<content:encoded><![CDATA[<p>I like to format my computer fairly often which means having all my data in one easy to find location. Not only does this make backing up easy but it also removes that dreadful feeling you get when you realize your new OS install overwrote your irreplacable bookmarks, precious emails and/or accumulated works of <a href="http://en.wikipedia.org/wiki/Bettie_Page">Bettie Page</a>.</p>
<p>Bookmarks are easily forgotten but with a few tweaks <a href="http://www.mozilla.com/en-US/firefox/firefox.html">FireFox 3</a> can back them up for you.</p>
<h2>Customize your bookmark backup settings</h2>
<p>Open FireFox 3.</p>
<p>Go to <strong>about:config</strong> in your location bar.</p>
<p>Specify <strong>browser.bookmarks</strong> as your filter.</p>
<p>Set <strong>browser.bookmarks.autoExportHTML</strong> to <strong>true</strong>.</p>
<p>Create a new string titled <strong>browser.bookmarks.file</strong> and set its value to the location you want to backup all your bookmarks to.</p>
<p style="padding-left: 30px;"><em>In my case I entered &#8220;D:\ForestMist\Personal\bookmarks.html&#8221;.</em></p>
<p style="padding-left: 30px;"><a href="http://forestmisty.org/wp-content/uploads/2009/08/firefox-3-about-config.png"><img class="size-medium wp-image-138 alignnone" title="firefox 3 about:config example" src="http://forestmisty.org/wp-content/uploads/2009/08/firefox-3-about-config-300x94.png" alt="firefox 3 about:config example" width="300" height="94" /></a></p>
<p>Restart FireFox.</p>
<h2>Epilogue</h2>
<p>Everytime you close FireFox it will export a fresh copy of all your bookmarks to the file you specified. There may a slight performance hit for doing this but I think the benefits far outweigh the cost.</p>
<p>Now you can mirror your bookmarks with services like <a href="https://www.sugarsync.com/">SugarSync</a>, share them easily with friends or just have peace of mind in case the new JSON database FireFox 3 uses behind the scenes explodes in a spectacular example of <a href="http://en.wikipedia.org/wiki/Murphy%27s_law">Murphy&#8217;s Law</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://forestmist.org/2009/08/automatically-backup-firefox-3-bookmarks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Media Consumption</title>
		<link>http://forestmist.org/2009/08/media-consumption/</link>
		<comments>http://forestmist.org/2009/08/media-consumption/#comments</comments>
		<pubDate>Tue, 11 Aug 2009 04:16:52 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Music]]></category>
		<category><![CDATA[Video]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://forestmist.org/?p=109</guid>
		<description><![CDATA[My tastes in media, like food, seem to change with time. I thought it would be fun to document what currently tickles my fancy. This will prove useful for future versions of my self but hopefully you&#8217;ll get a few links out of it too. Audio Boagworld Good all around podcast for those in the [...]]]></description>
			<content:encoded><![CDATA[<p>My tastes in media, like food, seem to change with time. I thought it would be fun to document what currently tickles my fancy. This will prove useful for future versions of my self but hopefully you&#8217;ll get a few links out of it too. <img src='http://forestmist.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><img class="alignright size-full wp-image-124" title="Me like media." src="http://forestmisty.org/wp-content/uploads/2009/08/Cookie-Monster-eating-iPhone.jpg" alt="Cookie-Monster-eating-iPhone" width="194" height="301" /></p>
<h3>Audio</h3>
<p style="padding-left: 30px;"><a href="http://boagworld.com/">Boagworld</a><br />
Good all around podcast for those in the web industry.</p>
<h3>Games</h3>
<p style="padding-left: 30px;"><a href="http://www.worldofwarcraft.com">World of Warcarft</a><br />
For more hours than I care to admit.</p>
<p style="padding-left: 30px;"><strong><span style="font-weight: normal;">Looking forward to <a href="http://www.sega.com/platinumgames/bayonetta/index2.php">Bayoneta</a>, <a href="http://www.somethinginthesea.com">Bioshock 2</a> and <a href="http://www.brutallegend.com">Brutal Legend</a> on the PS3.</span></strong></p>
<h3>Music</h3>
<p style="padding-left: 30px;"><a href="http://www.youtube.com/watch?v=tlolAo5sEfI">Luxury</a> by Tiga</p>
<p style="padding-left: 30px;"><a href="http://www.youtube.com/watch?v=SfxKichbdTE">Memory Gospel</a> by Moby</p>
<p style="padding-left: 30px;"><a href="http://vimeo.com/3884738">She&#8217;s Got Me Dancing</a> by Tommy Sparks</p>
<h3>Video</h3>
<p style="padding-left: 30px;"><a href="http://www.hulu.com/">Hulu</a><br />
Great for keeping up with various shows on my timetable. Yes, 3am showings of Inspector Gadget is exactly how I roll. Currently hopeful that <a href="http://www.hulu.com/warehouse-13">Warehouse 13</a> and <a href="http://www.hulu.com/defying-gravity">Defying Gravity</a> will continue to be interesting.</p>
<p style="padding-left: 30px;"><a href="http://www.netflix.com/">Netflix</a><br />
Love the Blu-ray and wide selection. Sci-fi and Comedy dominate the rental lists.</p>
<p style="padding-left: 30px;"><a href="http://revision3.com/pixelperfect">Pixel Perfect</a><br />
Bert Monroy&#8217;s excellent show on Photoshop and related topics. Excellent for learning new techniques and reinforcing current skills.</p>
<p style="padding-left: 30px;"><a href="http://www.ted.com/">TED</a><br />
My late night sleep aid and all around mind stimulator. Love the fact that I can watch these on my iPhone from the comfort of bed.</p>
<p style="padding-left: 30px;"><a href="http://revision3.com/tekzilla">Tekzilla</a><br />
Patrick and Veronica do a great job of hosting this show about all things tech. The bloopers at the end of each episode are the perfect icing to an entertainly educational show.</p>
<h3>Websites</h3>
<p style="padding-left: 30px;"><a href="http://www.authenticjobs.com/">Authentic Jobs</a><br />
I visit a lot of job sites regularly but I really enjoy their layout and consistent quality of postings the best. Strong contenders include  <a href="http://www.krop.com/">Krop</a> and the <a href="http://jobs.37signals.com/jobs">37signals Job Board</a>.</p>
<p style="padding-left: 30px;"><a href="http://www.deviantart.com/">deviantART</a><br />
Wonderful site for sampling a wide range of art, photography and design. I don&#8217;t think my mom would approve of some of the material but perhaps that is why I like it so much.  ;)</p>
<p style="padding-left: 30px;"><a href="http://twitter.com/ForestMist">Twitter</a><br />
I really enjoy the exercise of distilling an idea down to it&#8217;s essentials so it will remain true despite the 140 character limit. It&#8217;s a really great way to improve your writing skills.</p>
]]></content:encoded>
			<wfw:commentRss>http://forestmist.org/2009/08/media-consumption/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Catching up with FOWA Dublin 2009</title>
		<link>http://forestmist.org/2009/06/catching-up-with-fowa-dublin-2009/</link>
		<comments>http://forestmist.org/2009/06/catching-up-with-fowa-dublin-2009/#comments</comments>
		<pubDate>Tue, 02 Jun 2009 12:00:27 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Video]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Self Improvement]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://forestmist.org/?p=58</guid>
		<description><![CDATA[Nice of Carsonified to post although their isn&#8217;t as much video content as I would like. The following presentations were the best by far. Doing a Start Up in the Real World by David Heinemeier Hansson Great talk filled with real advice. No fluff. Watch it then formulate your own plan to make the world a [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://events.carsonified.com/fowa/2009/dublin/content"><img class="alignnone size-full wp-image-65" title="20090602-fowa-dublin-2009" src="http://forestmisty.org/wp-content/uploads/2009/06/20090602-fowa-dublin-2009.jpg" alt="20090602-fowa-dublin-2009" width="569" height="73" /></a></p>
<p>Nice of Carsonified to post although their isn&#8217;t as much video content as I would like. <img src='http://forestmist.org/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p>The following presentations were the best by far.</p>
<ul>
<li><a href="http://events.carsonified.com/fowa/2009/dublin/videos/david-heinemeir-hanson-2">Doing a Start Up in the Real World</a> by David Heinemeier Hansson<br />
<em>Great talk filled with real advice. No fluff. Watch it then formulate your own plan to make the world a better place. </em> <img src='http://forestmist.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li><a href="http://events.carsonified.com/fowa/2009/dublin/videos/ryan-carson-3">14 Web App Survival Tips</a> by Ryan Carson<br />
<em>Lots of tips for the aspiring web app creator to help deal with promotion, finance and more.</em></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://forestmist.org/2009/06/catching-up-with-fowa-dublin-2009/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

