<?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>Hacking at 0300 &#187; Danny</title>
	<atom:link href="http://bililite.nfshost.com/blog/author/danny/feed/" rel="self" type="application/rss+xml" />
	<link>http://bililite.nfshost.com/blog</link>
	<description>Thoughts on web design and programming from a very occasional volunteer webmaster</description>
	<lastBuildDate>Fri, 03 Feb 2012 10:05:17 +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>Nearly Free Speech</title>
		<link>http://bililite.nfshost.com/blog/2012/02/03/nearly-free-speech/</link>
		<comments>http://bililite.nfshost.com/blog/2012/02/03/nearly-free-speech/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 10:05:17 +0000</pubDate>
		<dc:creator>Danny</dc:creator>
				<category><![CDATA[Web Design]]></category>

		<guid isPermaLink="false">http://bililite.nfshost.com/blog/?p=2228</guid>
		<description><![CDATA[I've used 1&#038;1 since I started mucking about on the web; they had a cheap plan for $3/month with one domain name and a simple LAMP stack. But the price has been going up (now $5/month; still comparatively cheap!), and I'm starting to chafe at the limitations (no SSH shell access, proprietary 404 pages, no [...]]]></description>
			<content:encoded><![CDATA[<p>I've used <a href="http://1and1.com">1&#038;1</a> since I started mucking about on the web; they had a cheap plan for $3/month with one domain name and a simple <a href="http://en.wikipedia.org/wiki/LAMP_(software_bundle)">LAMP stack</a>. But the price has been going up (now $5/month; still comparatively cheap!), and I'm starting to chafe at the limitations (no SSH shell access, proprietary 404 pages, no languages beside PHP) and I didn't want to shell out for my own virtual server (<a href="http://www.rackspace.com/cloud/cloud_hosting_products/servers/pricing/">Rackspace</a> goes as low as $11/month but I'm really cheap). So I was overjoyed when I found <a href="http://nearlyfreespeech.net">Nearly Free Speech</a>.<p>
<span id="more-2228"></span>
<p>It has several advantages:</p>
<ol>
<li>SSH into a real Linux shell. It's been a while since I used Unix, but the old habits come back fast and I like having all those tools available.</li>
<li><a href="http://en.wikipedia.org/wiki/SSH_File_Transfer_Protocol">SFTP</a> support. More secure and faster (at least it seems that way) than FTP, especially with <a href="http://notepad-plus-plus.org/">Notepad++</a>.</li>
<li>It sure seems cheap (only $0.01/day for the site, $0.02/day for as many mySQL databases as you want).</li>
<li><a href="http://example72.nfshost.com/versions.php">Lots of languages</a> besides PHP. Maybe I will learn <a href="http://xkcd.com/353/">Python</a> someday.</li>
<li>Up-to-date versions of the tools, like PHP 5.3 (<a href="http://us.php.net/manual/en/functions.anonymous.php">anonymous functions</a>!) and Apache 2.2 (<a href="http://httpd.apache.org/docs/2.3/mod/mod_dir.html#fallbackresource">FallbackResource</a>!). 1and1 was still stuck on the old versions.</li>
<li>They enable <a href="http://us.php.net/manual/en/features.remote-files.php">file URL wrappers</a>, so I can use get_file_contents('http://example.com') and the like, rather than cURL.</li>
<li>A general feel that these guys are <a href="http://faq.nearlyfreespeech.net/full/easy#easy">more hacker-oriented rather than simple, one-click-install-package oriented</a>.</li>
</ol>
<p>But there are disadvantages as well.</p>
<ol>
<li>It's not nearly as cheap as it seems. A simple site as above is $0.03/day = $10.95/year, but it's all pay for what you use. They charge for server usage based on storage, $0.01 per megabyte-month, so my 100 megabytes of fonts and images is another $12/year. Domain name registration is $9.49/year, plus $0.41/year for DNS. Bandwidth is $0.20 to $1.00/gigabyte, depending on usage. For my relatively popular blog (about 300-600 visits/day) I'm sending about 100 MB/day or $0.07/day or $25.55/year. That adds up to $58.40/year, basically the same price as 1and1. And I feel like I have to watch every byte stored or transferred. I know it's not really much money, but it's an avocation rather than a vocation so I need to justify the cost to myself. The bandwidth I'm going to have to explore to find out what's going on and possibly stop hotlinking and the like. The storage costs I can hack around by putting the big stuff on <a href="http://aws.amazon.com/s3/pricing/">Amazon S3</a> at only $0.14/gigabyte.</li>
<li>They don't automatically take the money from a credit card. You have to deposit funds in your account, and if it runs dry, the site goes down. They'll send out low-balance warnings but I'd like an automated method. Alos, every payment comes with a $1.00 deposit fee, so making monthly payments is another $12/year.</li>
<li>PHP runs in <a href="http://us.php.net/manual/en/features.safe-mode.php">safe mode</a>, so a lot of file and system functions are disabled. This is deprecated in the latest PHP, so I don't know what NearlyFreeSpeech will do, but right now it makes life much more difficult. There are workarounds, notably using <a href="/blog/2012/01/12/writing-cgi-scripts/" title="Writing CGI scripts">CGI scripts</a> rather than straight PHP, but this is the biggest downside.</li>
<li><a href="https://www.nearlyfreespeech.net/about/faq?&#038;keywords=cron&#038;form=1#WontGo">No cron jobs</a>. You can't run any processes on their servers besides the webserver, mySQL and whatever you're doing when SSH'ing in. <a href="http://faq.nearlyfreespeech.net/section/programming/cron#cron">They promise they're working on a solution</a>, but no update since 2008. You can use hacks like <a href="http://codex.wordpress.org/Category:WP-Cron_Functions">WP-cron</a> but that is exactly that, a hack.</li>
</ol>
<p>But overall, it looks like a good thing and I'm looking forward to (slowly, as I have the time) moving all of bililite.com over to the new host (then transferring the domain when I'm sure it works).</p>]]></content:encoded>
			<wfw:commentRss>http://bililite.nfshost.com/blog/2012/02/03/nearly-free-speech/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New Amazon Advertising API</title>
		<link>http://bililite.nfshost.com/blog/2012/02/01/newamzonapi/</link>
		<comments>http://bililite.nfshost.com/blog/2012/02/01/newamzonapi/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 14:48:06 +0000</pubDate>
		<dc:creator>Danny</dc:creator>
				<category><![CDATA[Web Design]]></category>

		<guid isPermaLink="false">http://bililite.nfshost.com/blog/?p=2225</guid>
		<description><![CDATA[Just got an email from Amazon reminding me that "As part of our continued effort to ensure that the Product Advertising API is an efficient and effective advertising tool, we’ve identified opportunities to streamline the API", which is their way of saying that the API exists to make them money. Anything that doesn't serve that [...]]]></description>
			<content:encoded><![CDATA[<p>Just got an email from Amazon reminding me that "As part of our continued effort to ensure that the Product Advertising API is an efficient and effective advertising tool, we’ve identified opportunities to streamline the API", which is their way of saying that the API exists to make <em>them</em> money. Anything that doesn't serve that purpose is eliminated, however nice it might be for me. Their right, even if they're <em>not</em> right. I've already taken into account <a href="/blog/2011/11/01/the-new-amazon-advertising-api/" title="The New Amazon Advertising API">the major changes</a>. The only thing is to change the API version to the most recent; in the <a href="http://mierendo.com/software/aws_signed_query/">aws_signed_request</a> routine, change the <code class="language-html">$params["Version"]</code> line to read <code class="language-html">$params["Version"] = "2011-08-01";</code> and that should be it.</p> ]]></content:encoded>
			<wfw:commentRss>http://bililite.nfshost.com/blog/2012/02/01/newamzonapi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing CGI scripts</title>
		<link>http://bililite.nfshost.com/blog/2012/01/12/writing-cgi-scripts/</link>
		<comments>http://bililite.nfshost.com/blog/2012/01/12/writing-cgi-scripts/#comments</comments>
		<pubDate>Thu, 12 Jan 2012 18:28:41 +0000</pubDate>
		<dc:creator>Danny</dc:creator>
				<category><![CDATA[Web Design]]></category>

		<guid isPermaLink="false">http://bililite.nfshost.com/blog/?p=2206</guid>
		<description><![CDATA[nearlyfreespeech runs with safe mode and safe_mode_gid on, so you can't run shell scripts or other cool things. Usually that's not an issue, but if you do, they let you run CGI scripts, in any of a number of languages. You just have to treat it as a shell script, with a shebang notation of [...]]]></description>
			<content:encoded><![CDATA[<p>nearlyfreespeech runs with <a href="http://www.php.net/manual/en/features.safe-mode.php">safe mode</a> and <a href="http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.safe-mode-gid">safe_mode_gid</a> on, so you can't run shell scripts or other cool things. Usually that's not an issue, but if you do, they let you run <a href="http://en.wikipedia.org/wiki/Common_Gateway_Interface">CGI</a> scripts, in any of a <a href="http://example72.nfshost.com/versions.php">number of languages</a>. You just have to treat it as a shell script, with a <a href="http://en.wikipedia.org/wiki/Shebang_(Unix)">shebang</a> notation of the proper language. There are a few caveats that took me a day to find out:</p>
<ol><li>The correct program is <code>/usr/local/bin/php-cgi</code> (or whereever your server puts PHP), not <code>/usr/local/bin/php</code>. That is the command-line interpreter, which does not output the headers. You can manually do <code class="language-php">echo "Content-type: text/html\n"</code> etc., followed by a blank line, but who wants to try to debug that?</li>
<li>The script has to be executable. You get a 500 Server Error otherwise. Do a <code>chmod +x scriptname.cgi</code>.</li>
<li>Scripts need the appropriate file and directory permissions to write to the server.  Changing the permissions of the server directory is probably too insecure (though for safe mode it's the only way); it's better to set-uid the script, but then keep it under wraps. </li>
</ol>
<p>So a sample CGI script would be:</p>
<pre><code class="language-html">#!/usr/local/bin/php-cgi
&lt;?php echo "Hello, world"; ?&gt;</code></pre>
<p>in an executable file with a <code>.cgi</code> extension.</p>
<p>Note that FTP and SFTP can't set the setuid bit, so that if you upload the file (or edit it with an FTP-aware editor like <a href="http://notepad-plus-plus.org/">Notepad++</a>), you need to <code>chmod 477 scriptname.cgi</code> again.]]></content:encoded>
			<wfw:commentRss>http://bililite.nfshost.com/blog/2012/01/12/writing-cgi-scripts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Things I Learned About .htaccess, part 2</title>
		<link>http://bililite.nfshost.com/blog/2012/01/12/things-i-learned-about-htaccess-part-2/</link>
		<comments>http://bililite.nfshost.com/blog/2012/01/12/things-i-learned-about-htaccess-part-2/#comments</comments>
		<pubDate>Thu, 12 Jan 2012 16:29:48 +0000</pubDate>
		<dc:creator>Danny</dc:creator>
				<category><![CDATA[Web Design]]></category>

		<guid isPermaLink="false">http://bililite.nfshost.com/blog/?p=2200</guid>
		<description><![CDATA[I've learned some things about .htaccess, but mostly I've learned that programming it is deep black magic. The most important thing is "Don't use mod-rewrite unless you absolutely need to". All the fancy stuff is better off done by the PHP (or whatever language you're using) code. Don't do: RewriteEngine On RewriteBase / RewriteRule ^([^/\.]+)/$ [...]]]></description>
			<content:encoded><![CDATA[<p>I've <a href="/blog/2009/07/27/things-i-learned-about-htaccess/">learned some things about .htaccess</a>, but mostly I've learned that programming it is deep black magic. The most important thing is "Don't use mod-rewrite unless you absolutely need to". All the fancy stuff is better off done by the PHP (or whatever language you're using) code.</p>
<p>Don't do:</p>
<pre><code>RewriteEngine On
RewriteBase /
RewriteRule ^([^/\.]+)/$ /index.php?main=$1&#038;part=$1 [QSA,L]
RewriteRule ^([^/\.]+)/([^/\.]+)$ /index.php?main=$1&#038;part=$2 [QSA,L]</code></pre>
<p>to map your site to your index page; do:</p>
<pre><code><a href="https://httpd.apache.org/docs/2.3/mod/mod_dir.html#fallbackresource">FallbackResource</a> /index.php</code></pre>
<p>And in <code>index.php</code> parse the <code class="language-php">$_SERVER['REQUEST_URI']</code> to get your page/subpage arguments. Much easier to debug!</p>
<p>And to use <code>FallbackResource</code> you need to be running Apache 2.2, so get a good web host.</p>]]></content:encoded>
			<wfw:commentRss>http://bililite.nfshost.com/blog/2012/01/12/things-i-learned-about-htaccess-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Moving the Blog Again</title>
		<link>http://bililite.nfshost.com/blog/2012/01/08/moving-the-blog-again/</link>
		<comments>http://bililite.nfshost.com/blog/2012/01/08/moving-the-blog-again/#comments</comments>
		<pubDate>Mon, 09 Jan 2012 04:38:37 +0000</pubDate>
		<dc:creator>Danny</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://bililite.nfshost.com/blog/?p=2196</guid>
		<description><![CDATA[I'm working on moving bililite.com to nearlyfreespeech.net; it's cheaper, more reliable and more hacker-friendly than 1&#38;1. I'll write a post with my experiences and reasons later. But for now just the blog has moved to bililite.nfshost.com/blog, with the plan to move the domain registration for bililite.com to nearlyfreespeech when everything is working and then return [...]]]></description>
			<content:encoded><![CDATA[<p>I'm working on moving <a href="http://bililite.com">bililite.com</a> to <a href="http://nearlyfreespeech.net">nearlyfreespeech.net</a>; it's cheaper, more reliable and more hacker-friendly than <a href="http://1and1.com">1&amp;1</a>. I'll write a post with my experiences and reasons later. But for now just the blog has moved to bililite.nfshost.com/blog, with the plan to move the domain registration for bililite.com to nearlyfreespeech when everything is working and then return the blog to bililite.com/blog. Moving it was straightforward, as <a href="/blog/2009/06/05/moving-the-blog/" title="Moving the Blog">I've done it before</a>, but there are some subtleties: nearlyfreespeech runs with <a href="http://www.php.net/manual/en/features.safe-mode.php">safe mode</a> and <a href="http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.safe-mode-gid">safe_mode_gid</a> on, so you have to watch file and directory permissions; SaraPin <a href="http://snarp.dreamwidth.org/124165.html">explains exactly how</a>. WordPress loads with the group <code>me</code> and nearlyfreespeech's webserver runs with the group <code>web</code>, so you need to SSH into the account and change the WordPress directory with <code>chgrp -R * web</code>. The file permisssions should be 664 (writeable to self and group, readable to all) and the directory permissions should be 775 (writeable and executable to self and group, executable to all; under UNIX, getting a file from a directory is "executing" it), but the default WordPress installation does that.</p>
<p>If you don't know what that means, you probably shouldn't be using a d.i.y. host like nearlyfreespeech.</p>
<p>And now it works!</p>
<p>Almost. <a href="http://sexybookmarks.shareaholic.com/">SexyBookmarks</a>'s images aren't loading when I use the new code, so I went back to the old version. It slows the page load down anyway, so I may take it off entirely.</p>
<p>And the rest of the bililite site is still at the old host, and some of the sample code (in /blog/blogfiles) uses that, so for now I have a line in my <code>.htaccess</code> to refer it back: <code>RedirectMatch /blog/blogfiles(.*) http://bililite.com/blog/blogfiles$1</code>.</p>]]></content:encoded>
			<wfw:commentRss>http://bililite.nfshost.com/blog/2012/01/08/moving-the-blog-again/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Awesome</title>
		<link>http://bililite.nfshost.com/blog/2011/12/21/awesome/</link>
		<comments>http://bililite.nfshost.com/blog/2011/12/21/awesome/#comments</comments>
		<pubDate>Thu, 22 Dec 2011 01:49:15 +0000</pubDate>
		<dc:creator>Danny</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://bililite.nfshost.com/blog/?p=2192</guid>
		<description><![CDATA[My office manager gave me this as a Christmas present. I have a great job.]]></description>
			<content:encoded><![CDATA[My office manager gave me <a href="http://www.hasbro.com/starwars/en_US/shop/details.cfm?R=A2A5597F-5056-900B-104C-AFD6347F1E11:en_US">this</a> as a Christmas present. I have a great job.]]></content:encoded>
			<wfw:commentRss>http://bililite.nfshost.com/blog/2011/12/21/awesome/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nice Javascript library: underscore.js</title>
		<link>http://bililite.nfshost.com/blog/2011/12/20/nice-javascript-library-underscore-js/</link>
		<comments>http://bililite.nfshost.com/blog/2011/12/20/nice-javascript-library-underscore-js/#comments</comments>
		<pubDate>Tue, 20 Dec 2011 16:27:48 +0000</pubDate>
		<dc:creator>Danny</dc:creator>
				<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://bililite.nfshost.com/blog/?p=2187</guid>
		<description><![CDATA[Modern javascript provides a host of cool functional-programming toys like forEach and reduce, but I'm stuck with IE* at work, which does not. jQuery fills some of those gaps (it has $.each and $.map) but not everything one would want. Enter underscore.js, which bills itself as "the tie to go along with jQuery's tux." It [...]]]></description>
			<content:encoded><![CDATA[<p>Modern javascript provides a host of cool functional-programming toys like <code>forEach</code> and <code>reduce</code>, but I'm stuck with IE* at work, which does not. jQuery fills some of those gaps (it has <code class="language-javascript">$.each</code> and <code class="language-javascript">$.map</code>) but not everything one would want.</p>
<p>Enter <a href="http://documentcloud.github.com/underscore/">underscore.js</a>, which bills itself as "the tie to go along with jQuery's tux."</p>
<p>It doesn't modify any native objects, requiring you to wrap them as <code class="language-javascript">_([1,2,3]).map(function(x) {return 2*x;})</code>, which returns <code class="language-javascript">[2,4,6]</code>. Chaining has to be explicitly enabled, <code class="language-javascript">_([1,2,3]).chain().map(function(x) {return 2*x;}).reduce(function(memo, num){ return memo + num; }, 0)</code> returns <code class="language-javascript">12</code>.</p>
<p>Looks useful.</p>]]></content:encoded>
			<wfw:commentRss>http://bililite.nfshost.com/blog/2011/12/20/nice-javascript-library-underscore-js/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New jQuery Plugin: showPassword</title>
		<link>http://bililite.nfshost.com/blog/2011/12/13/new-jquery-plugin-showpassword/</link>
		<comments>http://bililite.nfshost.com/blog/2011/12/13/new-jquery-plugin-showpassword/#comments</comments>
		<pubDate>Tue, 13 Dec 2011 20:10:36 +0000</pubDate>
		<dc:creator>Danny</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://bililite.nfshost.com/blog/?p=2179</guid>
		<description><![CDATA[I put yesterday's unmask password plugin together with the code to automatically create a checkbox to control it, and removed the dependency on jQuery UI. Download the code. Example &#60;input type=&#34;password&#34; id=&#34;password&#34;/&#62; $('#password').showPassword('Show Characters as I Type'); Use $('[type=password]').showPassword(string) creates a checkbox as above with string as the label. If the checkbox is checked then [...]]]></description>
			<content:encoded><![CDATA[<p>I put yesterday's <a href="/blog/2011/12/12/unmask-password-plugin/" title="Unmask Password Plugin">unmask password plugin</a> together with the code to automatically create a checkbox to control it, and removed the dependency on jQuery UI.</p>
<p><a href="/inc/jquery.showPassword.js">Download the code</a>.</p>
<script src="/inc/jquery.showPassword.js"></script>
<h4>Example</h4>
<pre><code class="demo language-html">&lt;input type=&quot;password&quot; id=&quot;password&quot;/&gt;</code></pre>
<pre><code class="demo language-javascript">$('#password').showPassword('Show Characters as I Type');</code></pre>
<h4>Use</h4>
<p><code class="language-javascript">$('[type=password]').showPassword(string)</code> creates a checkbox as above with <code>string</code> as the label. If the checkbox is checked then the password field is unmasked. <code class="language-javascript">$('type=password').showPassword(true)</code> unmasks the field directly, and <code class="language-javascript">$('type=password').showPassword(false)</code> restores masking.</p>]]></content:encoded>
			<wfw:commentRss>http://bililite.nfshost.com/blog/2011/12/13/new-jquery-plugin-showpassword/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unmask Password Plugin</title>
		<link>http://bililite.nfshost.com/blog/2011/12/12/unmask-password-plugin/</link>
		<comments>http://bililite.nfshost.com/blog/2011/12/12/unmask-password-plugin/#comments</comments>
		<pubDate>Mon, 12 Dec 2011 23:40:43 +0000</pubDate>
		<dc:creator>Danny</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://bililite.nfshost.com/blog/?p=2151</guid>
		<description><![CDATA[I hate password masking&#8212;hiding what I'm typing to prevent someone from looking over my shoulder at my passwords. I know when I'm in public and when I'm alone in the house, and it should be my choice to actually see what I'm typing, since it has to have some nonsense combination of characters. Even Jakob [...]]]></description>
			<content:encoded><![CDATA[<p>I hate password masking&mdash;hiding what I'm typing to prevent someone from looking over my shoulder at my passwords. I know when I'm in public and when I'm alone in the house, and it should be my choice to actually see what I'm typing, since it has to have <a href="http://xkcd.com/936/">some nonsense combination of characters</a>. Even <a href="http://www.useit.com/alertbox/passwords.html">Jakob Nielsen agrees with me</a>.</p>
<p>The logical thing to do is to have a <a href="http://lea.verou.me/2009/06/on-password-masking-and-usability/">checkbox that would show the characters</a>, and the easiest way to do that is to change the <code>type</code> of the <code>input</code> element from <code>password</code> to <code>text</code>.</p>
<p>For most browsers, this is <a href="http://stackoverflow.com/questions/540851/jquery-change-element-type-from-hidden-to-input#answer-3057767">nontrivial but doable</a>. You have to <code><a href="http://api.jquery.com/detach/">detach</a></code> the element first in order to change its <code>type</code>. But in Internet Explorer, there's no way to change it. One solution is to create a new <code>input</code> element with <code>type</code> <code>text</code> and copy all the other attributes into it, but that seems like overkill. All we need is a way for the user to see what he is typing, so a tooltip-like overlay would work.</p>
<p>This is what I came up with (note that it requires <a href="http://jqueryui.com/demos/position/">jQuery UI <code>position</code></a>:</p>
<pre><code class="demo language-html">&lt;input type=&quot;password&quot; id=&quot;password&quot;/&gt;
&lt;label&gt;&lt;input type=&quot;checkbox&quot; id=&quot;check&quot;/&gt; Show characters as I type&lt;/label&gt;</code></pre>
<pre><code class="demo language-javascript">try{
  $('&lt;input type=&quot;password&quot;&gt;').detach().attr('type', 'text');
  $.fn.showPassword = function(shouldShow){
    var type =  shouldShow ? 'text' : 'password';
    return this.each(function(){
      /* from http://stackoverflow.com/questions/540851/jquery-change-element-type-from-hidden-to-input */
      marker = $('&lt;span /&gt;').insertBefore(this);
      $(this).detach().attr('type', type).insertAfter(marker);
      marker.remove(); 
    });
  };
}catch(e){
  $.fn.showPassword = function(shouldShow){
    return this.each(function(){
      if (shouldShow){
        var span = $(this).siblings('.showPassword');
        if (span.length &gt; 0){
          span.show();
        }else{
          span = $('&lt;span&gt;').addClass('showPassword').css({
            opacity: 0.9,
            background: 'white',
            position: 'absolute',
            fontFamily: 'sans-serif',
            paddingLeft: '2px'
          }).position({
            at: 'left bottom',
            of: this,
            my: 'left top'
          }).text(this.value).insertBefore(this);
          $(this).keyup(function(){ span.text(this.value); });
        }
      }else{
        $(this).siblings('.showPassword').hide();
      }
    });
  };
}
$('#check').change(function(){
  $('#password').showPassword($(this).is(':checked'));
});</code></pre>
<p>Try this in Internet Explorer as well as a standards browser. The details are different, but the functionality is the same.</p>]]></content:encoded>
			<wfw:commentRss>http://bililite.nfshost.com/blog/2011/12/12/unmask-password-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5 validator plugin</title>
		<link>http://bililite.nfshost.com/blog/2011/12/06/html5-validator-plugin/</link>
		<comments>http://bililite.nfshost.com/blog/2011/12/06/html5-validator-plugin/#comments</comments>
		<pubDate>Tue, 06 Dec 2011 19:47:00 +0000</pubDate>
		<dc:creator>Danny</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://bililite.nfshost.com/blog/?p=2105</guid>
		<description><![CDATA[tl;dr Download the code. Use $.validateHTML5(callback), where callback (result, data) is a function that is called with the result, a string that can be "valid" if the page validated, "invalid" if it did not, "warning" if it validated but is "in some way questionable", or "not validated" if some error occurred. data is the actual [...]]]></description>
			<content:encoded><![CDATA[<script type="text/javascript" src="/inc/jquery.validateHTML5.js"></script>
<h3>tl;dr</h3>
<p><a href="/inc/jquery.validateHTML5.js">Download the code</a>. Use <code class="language-javascript">$.validateHTML5(callback)</code>, where <code class="language-javascript">callback (result, data)</code> is a function that is called with the <code>result</code>, a string that can be <code class="language-javascript">"valid"</code> if the page validated, <code class="language-javascript">"invalid"</code> if it did not, <code class="language-javascript">"warning"</code> if it validated but is "in some way questionable", or <code class="language-javascript">"not validated"</code> if some error occurred. <code>data</code> is the actual <a href="http://wiki.whatwg.org/wiki/Validator.nu_JSON_Output"><code>JSON</code> output</a> from the validator.</p>
<span id="more-2105"></span>
<h3>Discussion</h3>
<p>Lots of sites have links like <code class="language-html">&lt;a href="http://validator.w3.org/check/referer"&gt;Valid HTML&lt;/a&gt;</code>, which <em>claims</em> that the site is valid and allows you to click the link and check it, but it would be nice to have some way of actually validating the page that is being shown. Nice for me as the author, at least. I'm not sure anyone else cares.</p>
<p>Luckily, I've been doing everything recently in <a href="http://html5.org/">HTML5</a>, and <a href="http://html5.validator.nu/">Validator.nu</a> has a <a href="http://wiki.whatwg.org/wiki/Validator.nu_JSON_Output">web service API with JSON output</a> that we can use programmatically. We don't want to do this on the server side, since that takes time that our users don't need to waste. Also (I did this when playing around with it) you can end up in an infinite loop, where my server GETs the validator output, which GETs the page from the server, which GETs the validator output, which GETs the page from the server, <i>ad infinitum</i>.</p>
<p>So we want to send the page without validating it and then use <a href="http://en.wikipedia.org/wiki/Ajax_(programming)">AJAX</a> to validate it. Fortunately, the validator allows <a href="http://en.wikipedia.org/wiki/JSONP">JSONP</a>, so we don't have to worry about same-origin security. Unfortunately, the <a href="http://wiki.whatwg.org/wiki/Validator.nu_JSON_Output">documentation wiki</a> is wrong about exactly what is returned, so it took some experimentation to get it to work.</p>
<p><a href="/blog/blogfiles/validatortest.php">See the example</a>.</p>
<p>The <a href="http://validator.w3.org/">W3C validator</a> has a validator and does have a <a href="http://validator.w3.org/docs/api.html">web service</a>, but the only documented output format is SOAP. <code>output=json</code> works to produce JSON, but I can't find a way to get JSONP.</p>
]]></content:encoded>
			<wfw:commentRss>http://bililite.nfshost.com/blog/2011/12/06/html5-validator-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

