<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
   <title>Tom Mollerus&apos; Weblog</title>
   <link rel="alternate" type="text/html" href="http://www.mollerus.net/tom/blog/" />
   <link rel="self" type="application/atom+xml" href="http://www.mollerus.net/tom/blog/atom.xml" />
   <id>tag:www.mollerus.net,2010:/tom/blog/1</id>
   <updated>2010-01-28T16:15:36Z</updated>
   <subtitle>Web Security, Usability, CSS/XHTML, ColdFusion, and PHP</subtitle>
   <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.25</generator>


<entry>
   <title>Want to learn about HTML5?</title>
   <link rel="alternate" type="text/html" href="http://www.mollerus.net/tom/blog/2010/01/want_to_learn_about_html5.html" />
   <id>tag:www.mollerus.net,2010:/tom/blog//1.222</id>
   
   <published>2010-01-28T15:27:39Z</published>
   <updated>2010-01-28T16:15:36Z</updated>
   
   <summary>I stumbled across Mark Pilgrim&apos;s Dive Into HTML5 last night, and what a great read it is. Not only is it informative, teaching you about new tags and their uses, but you also get to read the history of HTML,...</summary>
   <author>
      <name>Tom Mollerus</name>
      <uri>http://www.mollerus.net/tom/blog/</uri>
   </author>
   
      <category term="XHTML/CSS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="http://www.mollerus.net/tom/blog/">
      <![CDATA[<p>I stumbled across <a href="http://diveintohtml5.org">Mark Pilgrim's <em>Dive Into HTML5</em></a> last night, and what a great read it is. Not only is it informative, teaching you about new tags and their uses, but you also get to read the history of HTML, written in Mark's entertaining style.<br />
<img alt="160x120_happy-2010.jpg" src="http://c.wearehugh.com/dih5/openclipart.org_johnny_automatic_monkey_reading.png" class="mt-image-none" style="" />
</p>]]>
      
   </content>
</entry>

<entry>
   <title>How long could I survive on the surface of the sun?</title>
   <link rel="alternate" type="text/html" href="http://www.mollerus.net/tom/blog/2010/01/how_long_could_i_survive_on_the_surface_of_the_sun.html" />
   <id>tag:www.mollerus.net,2010:/tom/blog//1.221</id>
   
   <published>2010-01-28T02:17:37Z</published>
   <updated>2010-01-28T02:19:27Z</updated>
   
   <summary>Just in case you were wondering. Created by Oatmeal. Check out their posters....</summary>
   <author>
      <name>Tom Mollerus</name>
      <uri>http://www.mollerus.net/tom/blog/</uri>
   </author>
   
      <category term="Humor" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="http://www.mollerus.net/tom/blog/">
      <![CDATA[<p>Just in case you were wondering.</p>

<p style="text-align: center;"><a href="http://theoatmeal.com/quiz/sun_surface"><img src="http://theoatmeal.com/img/quizzes/generated/10_1_second.jpg" alt="How long could you survive on the surface of the sun?" /></a><br />
Created by <a href="http://theoatmeal.com">Oatmeal</a>. Check out their posters.</p>]]>
      
   </content>
</entry>

<entry>
   <title>The year changed. So what? [Humor]</title>
   <link rel="alternate" type="text/html" href="http://www.mollerus.net/tom/blog/2010/01/the_year_changed_so_what_humor.html" />
   <id>tag:www.mollerus.net,2010:/tom/blog//1.220</id>
   
   <published>2010-01-04T14:43:08Z</published>
   <updated>2010-01-04T14:49:55Z</updated>
   
   <summary>For those of you who aren&apos;t fans of the webcomic Nedroid Picture Diary, you should be. I never realized until I saw this strip how much sense it would make if more than just the year changed on January 1st....</summary>
   <author>
      <name>Tom Mollerus</name>
      <uri>http://www.mollerus.net/tom/blog/</uri>
   </author>
   
      <category term="Humor" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="http://www.mollerus.net/tom/blog/">
      <![CDATA[<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="160x120_happy-2010.jpg" src="http://www.mollerus.net/tom/blog/images/160x120_happy-2010.jpg" width="160" height="120" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></span>For those of you who aren't fans of the webcomic <em><a href="http://nedroidcomics.livejournal.com/">Nedroid Picture Diary</a></em>, you should be. I never realized until I saw <a href="http://nedroidcomics.livejournal.com/267656.html">this strip</a> how much sense it would make if <em>more</em> than just the year changed on January 1st.]]>
      
   </content>
</entry>

<entry>
   <title>Firefox 3.5 surpasses market share of IE7 and 8 (for now)</title>
   <link rel="alternate" type="text/html" href="http://www.mollerus.net/tom/blog/2009/12/firefox_35_surpasses_market_share_of_ie7_and_8_for.html" />
   <id>tag:www.mollerus.net,2009:/tom/blog//1.219</id>
   
   <published>2009-12-29T17:10:12Z</published>
   <updated>2009-12-29T17:31:31Z</updated>
   
   <summary>According to analytics provider StatCounter, FireFox 3.5 has surpassed the market share of IE7 and IE8 for the first time. That&apos;s good news if you like the idea of diversity in the browser &quot;ecosystem&quot;, and great news for Firefox fans...</summary>
   <author>
      <name>Tom Mollerus</name>
      <uri>http://www.mollerus.net/tom/blog/</uri>
   </author>
   
      <category term="Browsers" scheme="http://www.sixapart.com/ns/types#category" />
   
      <category term="World Events" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="http://www.mollerus.net/tom/blog/">
      <![CDATA[<p>According to analytics provider StatCounter, <a href="http://gs.statcounter.com/#browser_version-ww-weekly-200827-200951">FireFox 3.5 has surpassed the market share of IE7 and IE8 for the first time.</a> That's good news if you like the idea of diversity in the browser "ecosystem", and great news for Firefox fans and web standards devotees. But looking at the trends indicated in StatCounter's graph, I'm not sure whether Firefox's top position will continue.</p>]]>
      <![CDATA[<p>Here's the graph from StatCounter:</p>

<em><div id="browser_version-ww-weekly-200827-200951" width="600" height="400" style="width:600px; height: 400px;"></div></em><!-- You may change the values of width and height above to resize the chart --><p>Source: <a href="http://gs.statcounter.com/#browser_version-ww-weekly-200827-200951">StatCounter Global Stats - Browser Version Market Share</a></p><script type="text/javascript" src="http://www.statcounter.com/js/FusionCharts.js"></script><script type="text/javascript" src="http://gs.statcounter.com/chart.php?browser_version-ww-weekly-200827-200951"></script>

<p>First of all, note that <a href="http://gadgetwise.blogs.nytimes.com/2009/12/24/firefox-wins-a-round-with-an-asterisk/?ref=technology">as the New York Times reports, the total number of IE users still eclipses the total number of Firefox users</a>.  Also, note the trends for FF3.5, which is gaining users, for IE7, which is losing users, and for IE8, which is gaining users.  It's evident that the trends for IE7 and IE8 mirror each other pretty well, which leads to the fact that IE7 users are simply upgrading to IE8. It turns out that right now, the number of FF3.5 useres just happens to be at a higher point than both IE7 and IE8 while people are upgrading their version of IE. So, relatively soon, expect the number of IE8 users to climb back ahead of the number of FF3.5 users.</p>

<p>Still, it's reassuring to look at StatCounter's numbers across all browser versions. Note that total Firefox use is still gaining on total IE use:</p>

<em><div id="browser-ww-weekly-200827-200951" width="600" height="400" style="width:600px; height: 400px;"></div></em><!-- You may change the values of width and height above to resize the chart --><p>Source: <a href="http://gs.statcounter.com/#browser-ww-weekly-200827-200951">StatCounter Global Stats - Browser Market Share</a></p><script type="text/javascript" src="http://www.statcounter.com/js/FusionCharts.js"></script><script type="text/javascript" src="http://gs.statcounter.com/chart.php?browser-ww-weekly-200827-200951"></script>

<p>In the end, what it shouldn't matter to us web developers which browser has what market share, as long as we leave behind the days of the IE6 monoculture. I think we all prefer our browsers to evolve newer, faster features, and to support web standards.</p>]]>
   </content>
</entry>

<entry>
   <title>Job postings at Ping Identity: Waltham, MA, and Denver, CO</title>
   <link rel="alternate" type="text/html" href="http://www.mollerus.net/tom/blog/2009/09/job_postings_at_ping_identity_waltham_ma_and_denve.html" />
   <id>tag:www.mollerus.net,2009:/tom/blog//1.217</id>
   
   <published>2009-09-30T13:40:12Z</published>
   <updated>2009-09-30T13:50:04Z</updated>
   
   <summary>Two new job postings have come up at my company, Ping Identity. We&apos;re a strong, growing company with Fortune 500 clients and venture backing from both coasts. Contact me directly with your resume if you&apos;re interested in either of the...</summary>
   <author>
      <name>Tom Mollerus</name>
      <uri>http://www.mollerus.net/tom/blog/</uri>
   </author>
   
      <category term="Office Life" scheme="http://www.sixapart.com/ns/types#category" />
   
      <category term="Web Development" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="http://www.mollerus.net/tom/blog/">
      <![CDATA[<p>Two new job postings have come up at my company, <a href="http://www.pingidentity.com">Ping Identity</a>. We're a strong, growing company with Fortune 500 clients and venture backing from both coasts. <a href="http://www.mollerus.net/tom/contact/">Contact me</a> directly with your resume if you're interested in either of the positions below:</p>

<p><strong>System Administrator, PingConnect</strong><br />
<em>Summary:</em> As a SaaS Systems Administrator at Ping Identity you will provide in-depth technical support and effective complex problem solving for a wide variety of infrastructure and applications related to the PingConnect service offering. VM, VPN, security, and network design is a must. Must be expert with IPsec and SSL VPN technologies. This position entails network and system design, implementation and maintenance. This is an on-call position that requires support and flexibility at a variety of hours.<br />
<em>Reporting to:</em> Senior Director, Operations<br />
<em>Location:</em> Waltham, MA or Denver, CO</p>

<p><strong>Technical Product Manager</strong><br />
<em>Summary:</em> As a Technical Product Manager at Ping Identity, you will engage with customers to understand detailed use cases and drive requirements in to the Ping Identity product planning process for both PingFederate, Ping Identity's flagship on-premise software, and PingConnect, our expanding on-demand server. You will have the opportunity to interact with key stakeholders inside and outside of the company with a primary focus on the technical aspects of Ping Identity's product offering. You will also be one of the primary technical interfaces for third party technology and SaaS partners, understanding key integration points and combined value propositions.<br />
<em>Reporting to:</em> Director of Product Management<br />
<em>Location:</em> Denver, CO</p>]]>
      
   </content>
</entry>

<entry>
   <title>Where to stay in Denver</title>
   <link rel="alternate" type="text/html" href="http://www.mollerus.net/tom/blog/2009/09/where_to_stay_in_denver.html" />
   <id>tag:www.mollerus.net,2009:/tom/blog//1.216</id>
   
   <published>2009-09-30T12:50:20Z</published>
   <updated>2009-09-30T12:54:47Z</updated>
   
   <summary>The Magnolia Hotel is my favorite in Denver. It easily has more age, flair, and character than the other chain hotels I&apos;ve stayed in. The elevators don&apos;t always run so fast, but they handle it with humor-- a plaque in...</summary>
   <author>
      <name>Tom Mollerus</name>
      <uri>http://www.mollerus.net/tom/blog/</uri>
   </author>
   
      <category term="At Large" scheme="http://www.sixapart.com/ns/types#category" />
   
      <category term="Office Life" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="http://www.mollerus.net/tom/blog/">
      <![CDATA[<p>The Magnolia Hotel is my favorite in Denver. It easily has more age, flair, and character than the other chain hotels I've stayed in.  The elevators don't always run so fast, but they handle it with humor-- a plaque in each of them reads "Our elevators are old, sometimes slow, occasionally fast, and often creaky."</p>

<p>Oh, and the staff hold the doors open for you when you enter or leave. You won't find that behavior at the Residence Inn.</p>]]>
      
   </content>
</entry>

<entry>
   <title>Have you requested time for RIA Unleashed: Boston?</title>
   <link rel="alternate" type="text/html" href="http://www.mollerus.net/tom/blog/2009/09/have_you_requested_time_for_ria_unleashed_boston.html" />
   <id>tag:www.mollerus.net,2009:/tom/blog//1.215</id>
   
   <published>2009-09-21T18:59:12Z</published>
   <updated>2009-09-21T19:36:08Z</updated>
   
   <summary>I&apos;ve just gotten approval to go to RIA Unleashed: Boston on November 13th, and if you haven&apos;t made up your mind on whether or not to go, I&apos;d suggest you make up your mind to attend. Brian&apos;s previous Flex Camp...</summary>
   <author>
      <name>Tom Mollerus</name>
      <uri>http://www.mollerus.net/tom/blog/</uri>
   </author>
   
      <category term="ColdFusion" scheme="http://www.sixapart.com/ns/types#category" />
   
      <category term="Web Development" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="http://www.mollerus.net/tom/blog/">
      <![CDATA[<p>I've just gotten approval to go to <a href="http://www.riaunleashed.com/">RIA Unleashed: Boston</a> on November 13th, and if you haven't made up your mind on whether or not to go, I'd suggest you make up your mind to attend.  Brian's previous Flex Camp conferences showed off some amazing implementations and hosted some impressive speakers, and this year looks to have an even better agenda for web developers with <a href="http://www.riaunleashed.com/page.cfm/agenda">a track devoted exclusively to ColdFusion developers.</a>  The list of speakers include Tim Buntel, Adam Lehman, Jason Delmore, and Ray Camden.  I can't wait for this conference.</p>

<p>So make sure you come, too.  And by the way, feel free to use my name as the person who referred you. ;)</p>]]>
      
   </content>
</entry>

<entry>
   <title>Boston CFUG&apos;s September meeting: &quot;ColdFusion Application Security: The Next Step&quot;</title>
   <link rel="alternate" type="text/html" href="http://www.mollerus.net/tom/blog/2009/09/boston_cfugs_september_meeting_coldfusion_applicat.html" />
   <id>tag:www.mollerus.net,2009:/tom/blog//1.214</id>
   
   <published>2009-09-09T18:04:29Z</published>
   <updated>2009-09-09T18:14:29Z</updated>
   
   <summary>For those CF developers in the Boston area, please join us at our next CFUG meeting entitled &quot;ColdFusion Application Security: The Next Step&quot;, where Jason Dean, the ColdFusion blogosphere&apos;s resident security expert, will be presenting to us via Connect. Jason&apos;s...</summary>
   <author>
      <name>Tom Mollerus</name>
      <uri>http://www.mollerus.net/tom/blog/</uri>
   </author>
   
      <category term="ColdFusion" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="http://www.mollerus.net/tom/blog/">
      <![CDATA[<p>For those CF developers in the Boston area, please join us at our next CFUG meeting entitled "ColdFusion Application Security: The Next Step", where Jason Dean, the ColdFusion blogosphere's resident security expert, will be presenting to us via Connect. Jason's blog can be found at <a href="http://www.12robots.com/">http://www.12robots.com/</a>.</p>

<p>Jason says: "We've all parameterized our SQL queries to prevent SQL injection attacks, right? So what's next? Are our applications safe now? No, they are not. SQL injection is only the tip of the vulnerability iceberg. There are many other security topics that need to be addressed in our applications. Threats and vulnerabilities are everywhere, and it is likely that your applications contain some of them. In this presentation we will discuss what threatens web applications and how to create countermeasures to address these vulnerabilities."</p>

</p><strong>Please RSVP at:</strong> <a href="http://www.eventbrite.com/event/430485594">http://www.eventbrite.com/event/430485594</a><br />
<strong>Date and time:</strong> September 16, 2009 from 6:00pm - 8:00pm<br />
<strong>Address:</strong> Adobe Systems, 275 Grove St., Newton, MA 02466</p>
]]>
      
   </content>
</entry>

<entry>
   <title>Smart example values in form fields</title>
   <link rel="alternate" type="text/html" href="http://www.mollerus.net/tom/blog/2009/08/default_values_in_form_fields.html" />
   <id>tag:www.mollerus.net,2009:/tom/blog//1.213</id>
   
   <published>2009-08-17T13:11:35Z</published>
   <updated>2009-08-17T13:13:56Z</updated>
   
   <summary>If I asked you to fill out the following form to get information about an LDAP server that you were supposedly giving me access to, would you know what type of information to type in? The public IP address or...</summary>
   <author>
      <name>Tom Mollerus</name>
      <uri>http://www.mollerus.net/tom/blog/</uri>
   </author>
   
      <category term="Usability" scheme="http://www.sixapart.com/ns/types#category" />
   
      <category term="XHTML/CSS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="http://www.mollerus.net/tom/blog/">
      <![CDATA[<p>If I asked you to fill out the following form to get information about an LDAP server that you were supposedly giving me access to, would you know what type of information to type in?<br />
<br />
<form>
<label for="LDAPS_URI2">The public IP address or DNS for your LDAP server:</label> 
<input type="text" name="LDAPS_URI2" id="LDAPS_URI2" value="" />

<label for="LDAPS_ADDN2">AD Account DN</label> 
<input type="text" name="LDAPS_ADDN2" id="LDAPS_ADDN2" value="" />
</form>
</p>

<p>Chances are you could enter the first value, but the second is a little tougher to understand.  It would be useful to be able to give supply an example to show you what type of information is correct, right?  But how do you put in examples while keeping it clear to the user that they're <strong>just examples</strong> and need to be replaced with something else?</p>]]>
      <![CDATA[<p>It's not too difficult to put default values in your form's text fields, <a href="http://www.wittysparks.com/2008/08/24/create-beautiful-form-fields-using-css-and-images/">style them a little differently so that it's obvious they're just examples that should be overwritten</a>, and make then disappear when the user clicks on the field to write their own text. You can even <a href="http://cssglobe.com/post/2494/using-form-labels-as-text-field-values">use the fields' labels as the default text field values,</a> which saves space and can be semantically elegant.</p>

<p>But what if you <em>want</em> labels for your form-- say, if it's technical in nature (like my LDAP server example above) and needs some extra context, or so that people know what the fields are supposed to be even after they've entered their own values? Then you can't just grab the labels and put them into the fields. You want to 1) supply example values, 2) style them appropriately, 3) make them disappear when the user wants to type their own value, and 4) style what the user types in with a normal style.</p>

<p>Here's a script using the jQuery library that you can use to supply this form with the behaviors we just listed:</p>

<pre><code>&lt;style type="text/css"&gt;
.example { color: #666666; }
&lt;style&gt;

&lt;form&gt;
&lt;label for="LDAPS_URI"&gt;The public IP address or DNS for your LDAP server:&lt;/label&gt;
&lt;input type="text" name="LDAPS_URI" id="LDAPS_URI" value="" /&gt;

&lt;label for="LDAPS_ADDN"&gt;AD Account DN&lt;/label&gt;
&lt;input type="text" name="LDAPS_ADDN" id="LDAPS_ADDN" value="" /&gt;
&lt;/form&gt;

&lt;script type="text/javascript" src="http://jqueryui.com/latest/jquery-1.3.2.js"&gt;&lt;/script&gt;
&lt;script&gt;
function fieldExample(fieldID, example) {
	var field = document.getElementById(fieldID);
	var exampleClass = 'example';

	// If the field is empty or has the example value in it
	if(field.value == "" || field.value == example) {
		// Style the field with our example class
		$(field).addClass(exampleClass);
		// Set the field's value to the example text
		field.value = example;
	}

	// When the field receives focus
	$(field).focus( function() {
			// Remove the example class
			$(this).removeClass(exampleClass);
			// If the field contains the example text, remove it
			if($(this).val() == example) $(this).val('');
		}
	);

	// When the field is no longer has the focus
	$(field).blur( function() {
			// If the field is empty
			if($(this).val() == '') {
				// Add the example text back in with the example class
				$(this).addClass(exampleClass);
				$(this).val(example);
			} else {
				// Else if the field is not empty, make sure it doesn't have the example class
				$(this).removeClass(exampleClass);
			}
		}
	);
	
	// When the field's form is submitted
	$(field).parents('form:first').submit( function() {
			// Loop through each of the form elements
			for(input = 0; input < this.elements.length; input++) {
				// If the element is of type input and has the example class
				if($(this.elements[input]).hasClass(exampleClass))
					// It must have example text, so clear the field before it's submitted
					$(this.elements[input]).val('');
			}
		}
	);
}
&lt;/script&gt;</code></pre>

<p>To populate the fields with examples, just call the <code>fieldExample</code> function after the form:</p>

<pre><code>&lt;script&gt;
// Identifty each of the fields and example values you want
fieldExample('LDAPS_URI', 'ldap.mycompany.com, or 200.200.200.200');
fieldExample('LDAPS_ADDN', 'CN=user, OU=marketing, DN=mycompany, DN=com');
&lt;/script&gt;</code></pre>

<p>All of which would add up to behavior like this:<br />
<style type="text/css">
  .example {color: #666666;}
</style>

<form>
<label for="LDAPS_URI">The public IP address or DNS for your LDAP server:</label>
<input type="text" name="LDAPS_URI" id="LDAPS_URI" value="" />

<label for="LDAPS_ADDN">AD Account DN</label>
<input type="text" name="LDAPS_ADDN" id="LDAPS_ADDN" value="" />
</form>

<script type="text/javascript" src="http://jqueryui.com/latest/jquery-1.3.2.js"></script>
<script>
function fieldExample(fieldID, example) {
	var field = document.getElementById(fieldID);
	var exampleClass = 'example';
	
	if(field.value == "" || field.value == example) {
		$(field).addClass(exampleClass);
		field.value = example;
	}
	
	$(field).focus( function() {
			$(this).removeClass(exampleClass);
			if($(this).val() == example) $(this).val('');
		}
	);
	$(field).blur( function() {
			if($(this).val() == '') {
				$(this).addClass(exampleClass);
				$(this).val(example);
			} else {
				$(this).removeClass(exampleClass);
			}
		}
	);
	
	$(field).parents('form:first').submit( function() {
			for(input = 0; input < this.elements.length; input++) {
				if($(this.elements[input]).hasClass(exampleClass))
					$(this.elements[input]).val('');
			}
		}
	);
}

fieldExample('LDAPS_URI', 'ldap.mycompany.com, or 200.200.200.200');
fieldExample('LDAPS_ADDN', 'CN=user, OU=marketing, DN=mycompany, DN=com');
</script></p>
]]>
   </content>
</entry>

<entry>
   <title>The Whitney Complexity Scale</title>
   <link rel="alternate" type="text/html" href="http://www.mollerus.net/tom/blog/2009/08/the_whitney_complexity_scale.html" />
   <id>tag:www.mollerus.net,2009:/tom/blog//1.212</id>
   
   <published>2009-08-06T11:37:06Z</published>
   <updated>2009-08-07T14:26:41Z</updated>
   
   <summary>Admit it: one of the least favorite parts of our jobs as developers is coming up with time estimates for our work. Joel Spoelsky describes it this way: Why won&apos;t developers make schedules? Two reasons. One: it&apos;s a pain in...</summary>
   <author>
      <name>Tom Mollerus</name>
      <uri>http://www.mollerus.net/tom/blog/</uri>
   </author>
   
      <category term="Code Building\Versioning" scheme="http://www.sixapart.com/ns/types#category" />
   
      <category term="Humor" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="http://www.mollerus.net/tom/blog/">
      <![CDATA[<p>Admit it: one of the least favorite parts of our jobs as developers is coming up with time estimates for our work.  Joel Spoelsky describes it this way:</p>

<blockquote>Why won't developers make schedules? Two reasons. One: it's a pain in the butt. Two: nobody believes the schedule is realistic. Why go to all the trouble of working on a schedule if it's not going to be right?</blockquote>

<p>If you're like me, and don't have the data available to do <a href="http://www.joelonsoftware.com/items/2007/10/26.html">evidence-based scheduling</a>, to produce estimates you basically make a guess based on past experience.  And we all know how accurate those guesses are.  (Usually, not very accurate at all. I worked with a project manager once who confided to me that all of the PMs at the company would take the developers' estimates and then double them to come up with what they felt was a more realistic schedule.)  Sometimes I feel like it's like a serious job endeavour and more like a <a href="http://en.wikipedia.org/wiki/Name_That_Tune">game of <em>Name That Tune</em></a> for software ("I can code that feature in... 6 hours, George!").</p>

<p>So around here at Ping Identity, we don't have to rely on time estimates so much.  Instead, the engineering team has started using a metric called "Whitneys", measured on what we call the <strong>Whitney Complexity Scale</strong>. It's named after its creator, technical project director Brian Whitney.</p>]]>
      <![CDATA[<div style="text-align: center; font-size: 14px;"><p><strong>Whitney Complexity Scale</strong></p></div>

<p>Complexity = f(C#, CF, TE, K, S, U, F)<br />
<br />
C# = Components impacted<br />
C = Complexity of feature by self<br />
TE = Test environment and challenge of quality needs <br />
K = Knowledge level or not in dev team<br />
S = Scope/impact to Ping portfolio<br />
U = Consideration of upgrades<br />
F = Consider that it may be only a doc, SQE solution
</p>

<p>Now the labels of the actual scale are where it starts to get funny:

<table border="1">
<tr valign="bottom">
<th>Effort/Label</th>
<th>Complexity Rating</th>
<th>Description</th>
</tr>
<tr>
<td>Negative</td>
<td>-1</td>
<td>Although we haven't started on it yet, it will be done before you ask for it.</td>
</tr>
<tr>
<td>Zero</td>
<td>0</td>
<td>It's already done, you just don't know about it yet.</td>
</tr>
<tr>
<td>Minimal</td>
<td>1-2</td>
<td>Bill's cat JJ* could do it and it really wouldn't take him very long</td>
</tr>
<tr>
<td>Easy</td>
<td>3-4</td>
<td>This is an extension to an existing feature to implement new use cases or configuration options.  We can use existing test environments and add new test cases to accommodate new use cases.  Requires some changes to existing sections within existing documents to describe new use cases or configuration options.</td>
</tr>
<tr>
<td>Medium</td>
<td>5-6</td>
<td>It may be a complex feature that requires quite a bit of development effort, along with a number of different configuration and deployment options to test.  May use existing 3rd party environments as needed. It might be relatively simple to implement, but requires setting up a complex test environment and re-testing across multiple different options in the matrix.  </td>
</tr>
<tr>
<td>Challenging</td>
<td>7-8</td>
<td>This could be a large new feature with an extensive set of use cases involving a new technology that we don't know much about.</td>
</tr>
<tr>
<td>Whoa Nelly</td>
<td>9-10</td>
<td>This is a major effort.  It will affect multiple components in multiple products.  Extensive new set of use cases.  Must be extensively regression tested in multiple environments.  Requires testing of many different options.  Requires testing across multiple products or across multiple physical instances of a single product.  Requires integration with 3rd party environments, including many different configurations of same.</td>
</tr>
<tr>
<td>Impossible</td>
<td>11</td>
<td>Requires an act of {the deity of your choice} to implement.  It affects all Ping Identity software as well as competitor's software, as well as other 3rd party software.  This affects physical properties of materials.  This affects physical behavior of the universe.</td>
</tr>
</table>
</p>

<p style="font-size: 10px;"><em>* Bill refers to Bill Wood, VP of Engineering at Ping Identity</em></p>]]>
   </content>
</entry>

<entry>
   <title>Microsoft making Office available for free online?</title>
   <link rel="alternate" type="text/html" href="http://www.mollerus.net/tom/blog/2009/07/microsoft_making_office_available_for_free_online.html" />
   <id>tag:www.mollerus.net,2009:/tom/blog//1.210</id>
   
   <published>2009-07-13T21:38:20Z</published>
   <updated>2009-07-13T21:53:41Z</updated>
   
   <summary>Alright, so the news is that Microsoft is going to bring Office online-- for free. So you&apos;d think that Microsoft, with all of its experience in writing productivity software, would run the table on other online office apps like Google...</summary>
   <author>
      <name>Tom Mollerus</name>
      <uri>http://www.mollerus.net/tom/blog/</uri>
   </author>
   
      <category term="At Large" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="http://www.mollerus.net/tom/blog/">
      <![CDATA[<p>Alright, so the news is that <a href="http://bigtech.blogs.fortune.cnn.com/2009/07/13/microsoft-office-to-go-online-for-free/">Microsoft is going to bring Office online-- for free.</a> So you'd think that Microsoft, with all of its experience in writing productivity software, would run the table on other online office apps like Google Docs or Zoho, right?  I'd agree-- if Office were to be as easy to use and as accessible as these competitors. But read what John Fortt had to say about why he thinks that Office online will be a good thing for Microsoft instead of cannibalizing the existing sales of paid Office software:</p>

<p><blockquote>Office Web Applications will work better if you actually purchase Office 2010. Users with the latest Office software will be able to more easily share documents and keep each other's changes in sync. Add in the fact that the paid version of Office will come with a brilliant feature that lets Office buyers broadcast their PowerPoint presentations over the web (like Cisco's WebEx), and the Microsoft's online giveaway looks less like an oops, and more like an upsell.</blockquote></p>

<p>The factors he just listed seem to me to be <em>the exact reasons why Microsoft won't succeed in the online productivity app space.</em> Heck, I've got the latest version of Office on my laptop, but I still prefer to use Google Apps because it doesn't have any tie-ins to desktop software. I don't want my or my colleagues' editing capabilities to be crippled just because some of us don't have the latest version of Office or don't have Office at all.</p>

<p>And as for the certainly brilliant feature that lets paid Office users broadcast their Powerpoint presentations over the web... how long before some competitor (*cough* Google) manages to do the exact same thing, for free?</p>

<p>Microsoft is doing the right thing, here, certainly, of reading the writing on the wall that the days of expensive, installed productivity software are numbered.  But I don't feel that they're going to be preventing any loss of market share, here. They're just delaying the inevitable.</p>]]>
      
   </content>
</entry>

<entry>
   <title>Boston CFUG meeting this Thursday, July 16th</title>
   <link rel="alternate" type="text/html" href="http://www.mollerus.net/tom/blog/2009/07/boston_cfug_meeting_this_thursday_july_16th.html" />
   <id>tag:www.mollerus.net,2009:/tom/blog//1.209</id>
   
   <published>2009-07-13T19:07:37Z</published>
   <updated>2009-07-13T19:10:05Z</updated>
   
   <summary>Reminder-- the next Boston CFUG meeting is this Thursday! We&apos;re hosting Sean Schroeder and Matt Levine, the creators of the free and open-source Mura content management system, from Blue River Interactive. Some of you may have heard of Mura under...</summary>
   <author>
      <name>Tom Mollerus</name>
      <uri>http://www.mollerus.net/tom/blog/</uri>
   </author>
   
      <category term="ColdFusion" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="http://www.mollerus.net/tom/blog/">
      <![CDATA[<p>Reminder-- the next Boston CFUG meeting is this Thursday! We're hosting Sean Schroeder and Matt Levine, the creators of the free and open-source Mura content management system, from Blue River Interactive. Some of you may have heard of Mura under its former name, Sava CMS.</p>

<p>As I said in my email last week, I will be corralling as many people as I can to go out for beers after the meeting, so join us for a good time.</p>

<p>The meeting will be at 6:00pm this Thursday, July 16th, at the Sun Life Financial offices in Wellesley. Please RSVP if you plan on attending.</p>

<p>For more details about the event: <a href="http://groups.adobe.com/posts/ae47fb602a">http://groups.adobe.com/posts/ae47fb602a</a>
To RSVP: <a href="http://www.eventbrite.com/event/374175168">http://www.eventbrite.com/event/374175168</a></p>]]>
      
   </content>
</entry>

<entry>
   <title>Three methods for password reveal</title>
   <link rel="alternate" type="text/html" href="http://www.mollerus.net/tom/blog/2009/07/_username_password_function_revealpasswordreveal.html" />
   <id>tag:www.mollerus.net,2009:/tom/blog//1.208</id>
   
   <published>2009-07-06T18:05:04Z</published>
   <updated>2009-07-08T13:56:21Z</updated>
   
   <summary>In my last post, I wrote about whether password fields should be masked or revealed so that users can see the passwords as they type them. One method I mentioned in that post is adding a checkbox to turn password...</summary>
   <author>
      <name>Tom Mollerus</name>
      <uri>http://www.mollerus.net/tom/blog/</uri>
   </author>
   
      <category term="Security" scheme="http://www.sixapart.com/ns/types#category" />
   
      <category term="Usability" scheme="http://www.sixapart.com/ns/types#category" />
   
      <category term="Web Development" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="http://www.mollerus.net/tom/blog/">
      <![CDATA[<p>In my last post, I wrote about <a href="http://www.mollerus.net/tom/blog/2009/06/better_yet_make_password_masking_optional.html">whether password fields should be masked or revealed</a> so that users can see the passwords as they type them.  One method I mentioned in that post is <a href="http://www.codinghorror.com/blog/archives/001056.html">adding a checkbox to turn password masking on and off</a> depending on the user's preferences.</p>

<p>Since then, I've come across another technique that is worth looking in addition to the first.  Let's examine.

]]>
      <![CDATA[<p><strong>Technique 1: Users control password reveal with a checkbox</strong><br />
This option is able to give everyone (both your customers and Jakob Nielsen) what they want since customers can hide or show the password at their convenience. Better yet, you can always store the customer's preference in a cookie and show them the same behavior each time they enter their password.
<form name="login">
<table>
<tr>
<td>Username: </td>
<td><input type="text" name="username" value="Biff Henderson" size="25" /></td>
</tr>
<tr>
<td>Password: </td>
<td><input type="password" name="userpass" id="userpass" size="25" value="oh nose you can see this" onkeyup="copyTo(this, 'userpasstext');" />
<input type="text" name="userpasstext" id="userpasstext" size="25" value="oh nose you can see this"  onkeyup="copyTo(this, 'userpass');" style="display: none;" /></td>
</tr>
<tr>
<td></td>
<td><input type="checkbox" name="reveal" onclick="revealPassword(this.checked);" /> Show password</td>
</tr>
</table>
</form></p>

<script>
function revealPassword(reveal) {
    if(reveal) {
        document.getElementById('userpass').style.display = 'none';
        document.getElementById('userpasstext').style.display = 'inline';
    } else {
        document.getElementById('userpasstext').style.display = 'none';
        document.getElementById('userpass').style.display = 'inline';
    }
}

function copyTo(source, destination) {
    document.login[destination].value = source.value;
}
</script>

<p>To add this kind of control to your form, you add two new elements: first, a checkbox (that's kind of obvious); and second, a text input field with the exact same size, class and/or style as the password field, but a declaration of "<code>display: none;</code>" in the style:</p>

<pre><code>...&lt;tr&gt;
&lt;td&gt;Password: &lt;/td&gt;
&lt;td&gt;&lt;input type="password" name="userpass" id="userpass" size="25" value="oh nose you can see this" onkeyup="copyTo(this, 'userpasstext');" /&gt;
&lt;input type="text" name="userpasstext" id="userpasstext" size="25" value="oh nose you can see this"  onkeyup="copyTo(this, 'userpass');" style="display: none;" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;input type="checkbox" name="reveal" onclick="revealPassword(this.checked);" /&gt; Show password&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

</code></pre>

<p>Note that both the password field and the text field have an <code>onkeyup</code> event handler which calls a function named <code>copyTo()</code>.  The <code>copyTo().</code> function takes two arguments: a handler to the current form field, so that you can access the characters that have been typed into it, and the name of the other field, so that we can copy those characters to it to keep the contents of the two fields identical. Then the checkbox contains a call to <code>revealPassword()</code>, passing the checked status to handle whether the password is revealed or masked:

<pre><code>&lt;script&gt;
function revealPassword(reveal) {
    if(reveal) {
        document.getElementById('userpass').style.display = 'none';
        document.getElementById('userpasstext').style.display = 'inline';
    } else {
        document.getElementById('userpasstext').style.display = 'none';
        document.getElementById('userpass').style.display = 'inline';
    }
}

function copyTo(source, destination) {
    document.login[destination].value = source.value;
}
&lt;/script&gt;

</code></pre>

<p><br />
<strong>Technique 2: Automatically reveal the password during focus</strong><br />
I observed this while setting a password on the Sprint site.  This option is fast and easy-- you save the user from having to check off the checkbox as in the first technique-- but it's not as flexible for users who want to see their password in cleartext all the time. Here's what it looks like:
<form name="login2">
<table>
<tr>
<td>Username: </td>
<td><input type="text" name="username2" value="Biff Henderson" size="25" /></td>
</tr>
<tr>
<td>Password: </td>
<td><input type="password" name="userpass2" id="userpass2" size="25" value="oh nose you can see this" onkeyup="copyTo2(this, 'userpasstext2');" onfocus="revealPassword2(true);" />
<input type="text" name="userpasstext2" id="userpasstext2" size="25" value="oh nose you can see this"  onkeyup="copyTo2(this, 'userpass2');" onblur="revealPassword2(false);" style="display: none;" /></td>
</tr>
</table>
</form></p>

<script>
function revealPassword2(reveal) {
    if(reveal) {
        document.getElementById('userpass2').style.display = 'none';
        document.getElementById('userpasstext2').style.display = 'inline';
    } else {
        document.getElementById('userpasstext2').style.display = 'none';
        document.getElementById('userpass2').style.display = 'inline';
    }
}

function copyTo2(source, destination) {
    document.login2[destination].value = source.value;
}
</script>

<p>The code in this technique is very similar to that of the first (and the JavaScript code remains the same), but instead of controlling the reveal in the event handler of a checkbox, you add an <code>onfocus()</code> handler to the password field, and an <code>onblur()</code> handler to the text field. Each calls the <code>revealPassword()</code> function, passing the appropriate value:</p>

<pre><code>...&lt;tr&gt;
&lt;td&gt;Password: &lt;/td&gt;
&lt;td&gt;&lt;input type="password" name="userpass" id="userpass" size="25" value="oh nose you can see this" onkeyup="copyTo(this, 'userpasstext');" onfocus="revealPassword(true);" /&gt;
&lt;input type="text" name="userpasstext" id="userpasstext" size="25" value="oh nose you can see this"  onkeyup="copyTo(this, 'userpass');" onblur="revealPassword(false);" style="display: none;" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;input type="checkbox" name="reveal" onclick="revealPassword(this.checked);" /&gt; Show password&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

</code></pre>

<p>I mentioned <em>three</em> techniques in the title, didn't I?  The last is from the iPhone, though I have no idea how to accomplish it on the web.</p>

<p><br />
<strong>Technique 3: Reveal the last character, mask the rest</strong><br />
I noticed this option in the iPhone's interface, and I think it's a nice way to provide strong security while still giving the user the ability to see that they've typed accurately.  As you type, the last character you entered is displayed as cleartext, and the rest are obscured. After 2 or 3 seconds, even the last character converts to a bullet.</p>

<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="iphone-login.jpg" src="http://www.mollerus.net/tom/blog/images/iphone-login.jpg" width="314" height="200" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></span>

<p>If you do figure out how to recreate this interface on the web, definitely let me know. It might be easy to save text to a hidden field as it's typed, but how would you handle changes in the middle of the string? [Note: In the comments below, <a href="#comment-17405">Charlie Griefer points out a jQuery plugin</a> that will do exactly this.  Thanks, Charlie!]</p>]]>
   </content>
</entry>

<entry>
   <title>Better yet, make password masking optional</title>
   <link rel="alternate" type="text/html" href="http://www.mollerus.net/tom/blog/2009/06/better_yet_make_password_masking_optional.html" />
   <id>tag:www.mollerus.net,2009:/tom/blog//1.207</id>
   
   <published>2009-06-26T00:46:07Z</published>
   <updated>2009-06-26T01:02:04Z</updated>
   
   <summary>Jakob Nielsen just called for password masking to die: Usability suffers when users type in passwords and the only feedback they get is a row of bullets. Typically, masking passwords doesn&apos;t even increase security, but it does cost you business...</summary>
   <author>
      <name>Tom Mollerus</name>
      <uri>http://www.mollerus.net/tom/blog/</uri>
   </author>
   
      <category term="Security" scheme="http://www.sixapart.com/ns/types#category" />
   
      <category term="Usability" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="http://www.mollerus.net/tom/blog/">
      <![CDATA[<p>Jakob Nielsen just called for <a href="http://www.useit.com/alertbox/passwords.html">password masking to die:</a>

<blockquote>Usability suffers when users type in passwords and the only feedback they get is a row of bullets. Typically, masking passwords doesn't even increase security, but it does cost you business due to login failures. 

It's time to show most passwords in clear text as users type them. Providing feedback and visualizing the system's status have always been among the most basic usability principles. Showing undifferentiated bullets while users enter complex codes definitely fails to comply.</blockquote></p>

<p>He claims that miscreants can still steal your password just by watching the keyboard instead of the screen, and that mistyped passwords will reduce business because of user frustration. I don't agree that either of these are worthy arguments: first, it's a lot harder to watch someone's keystrokes than it is to read off letters accumulating in an on-screen field; and second, I would guess that the amount of lost business due to user frustration over password fields is very neglible. Plus I'm willing to bet you'd lose more users if you didn't obscure your passwords because they would think your site was <em>lacking</em> in good security.</p>

<p>I do agree with one of his suggestions later in the posting, which Jeff Atwood has proposed before: <a href="http://www.codinghorror.com/blog/archives/001056.html">adding a checkbox to the form (or dialog box) so the user can control whether the password field is masked or revealed</a>.  This setting could even be applied globally in application preferences, applied by web site, or even applied by network connection. If you're on the home network, don't mask; if you're at work, mask; if you're on an unrecognized network, and therefore probably in public, mask.</p>]]>
      
   </content>
</entry>

<entry>
   <title>Boston CFUG meeting tomorrow night at Adobe&apos;s offices</title>
   <link rel="alternate" type="text/html" href="http://www.mollerus.net/tom/blog/2009/06/boston_cfug_meeting_tomorrow_night_at_adobes_offic.html" />
   <id>tag:www.mollerus.net,2009:/tom/blog//1.206</id>
   
   <published>2009-06-22T17:53:40Z</published>
   <updated>2009-06-22T17:58:07Z</updated>
   
   <summary>For those of you in the Boston area: want to hear about the next version of ColdFusion and the new IDE, code-named Bolt? Then you&apos;ll want to make sure to attend tomorrow night&apos;s Boston CFUG meeting at Adobe&apos;s offices in...</summary>
   <author>
      <name>Tom Mollerus</name>
      <uri>http://www.mollerus.net/tom/blog/</uri>
   </author>
   
   
   <content type="html" xml:lang="en" xml:base="http://www.mollerus.net/tom/blog/">
      <![CDATA[<p>For those of you in the Boston area: want to hear about the next version of ColdFusion and the new IDE, code-named Bolt? Then you'll want to make sure to attend tomorrow night's Boston CFUG meeting at Adobe's offices in Newton, with speakers Adam Lehman and Tim Buntel.</p>

<p>Adam will be giving us the scoop on the upcoming version of ColdFusion as well as the new IDE codenamed Bolt. Tim Buntel will show us some of the features in Flex 4 and Flash Builder designed specifically with ColdFusion developers in mind.</p>

<p>Brian and I are planning for food and giveaways that are even better than usual, too!</p>

<p>RSVP Today! http://www.eventbrite.com/event/356084057</p>]]>
      
   </content>
</entry>

</feed>
