<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>console.blog()</title>
	
	<link>http://patik.com/blog</link>
	<description>Web development with a little bit of travel &amp; futbol</description>
	<lastBuildDate>Mon, 07 Nov 2011 17:11:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/craig-patik-blog" /><feedburner:info uri="craig-patik-blog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Matching UI Behavior with User Behavior</title>
		<link>http://feedproxy.google.com/~r/craig-patik-blog/~3/OPGY9BH2QpY/</link>
		<comments>http://patik.com/blog/matching-ui-behavior-with-user-behavior/#comments</comments>
		<pubDate>Mon, 07 Nov 2011 12:36:00 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[User Interface]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[ui]]></category>
		<category><![CDATA[user interface]]></category>

		<guid isPermaLink="false">http://patik.com/blog/?p=194</guid>
		<description><![CDATA[The viewport is a direct window into what the user sees, and a lot can be learned by watching it. In my previous post I introduced Within Viewport and I want to discuss how, particularly through my Twitter app signal:noise, I&#8217;ve found it useful in making interfaces respond sensibly to user behavior. Dynamic content loading [...]]]></description>
			<content:encoded><![CDATA[<p>The viewport is a direct window into what the user sees, and a lot can be learned by watching it. In my previous post I introduced <a href="http://patik.com/code/within-viewport/">Within Viewport</a> and I want to discuss how, particularly through my Twitter app <a href="http://signaltonoi.se">signal:noise</a>, I&#8217;ve found it useful in making interfaces respond sensibly to user behavior.</p>
<h4>Dynamic content loading</h4>
<p>A common solution for developers looking to increase their site&#8217;s performance is to load data on demand, for example using <a href="http://www.infinite-scroll.com/">Infinite Scroll</a>. But sometimes the scroll position isn&#8217;t enough &mdash; you need to know about <em>the content</em> on screen.</p>
<p>In signal:noise I want to control how heavier content is loaded. Since a tweet is a paltry 140 characters, and dynamically adding more of them to the top of a page causes it to scroll, it&#8217;s reasonable to start out by loading fifty or so at the initial page load. But when you factor in images and video previews linked within those tweets (which signal:noise presents inline) the page can take longer to load. I use Within Viewport to make sure I&#8217;m only loading media for tweets that are on screen or just about to be shown.</p>
<h4>Responding to user behavior</h4>
<p>The obvious thing to do when a user reaches the boundary of their timeline is to load more tweets. But it takes time to call the Twitter API (possibly more than once), process that response, and send the new content back to the client. By comparing the number of tweets in the user&#8217;s field of view to the number that are out of sight, and tracking the speed with which those tweets move in and out view, the app can get a sense of the user&#8217;s momentum. With this knowledge the app can avoid calling the API too late (not having tweets ready to go) or too soon (unnecessarily hitting the API rate limit).</p>
<h4>Making appropriate measurements</h4>
<p>The app also tracks each user&#8217;s reading position so the can resume reading at the same place in future sessions. When determining which tweets have been read, it only makes sense to consider ones that are fully in view. The app has a fixed header that shrinks the viewport by about 60 pixels, so I need to make sure a tweet is not covered by that.</p>
<figure>
<object data="http://patik.com/code/within-viewport/example_diagram_sm.svg" type="image/svg+xml" id="svg" width="617" height="626"><br />
<img src="http://patik.com/code/within-viewport/example_diagram_sm.png" alt="Diagram showing elements of a Twitter feed being in and out of view"/><br />
</object></p>
<figcaption><a href="http://patik.com/code/within-viewport/example_diagram.svg" target="_blank">Larger version</a></figcaption>
</figure>
<h4>Live updates</h4>
<p>My app also allows keyboard navigation from tweet to tweet, similar to <a href="http://www.google.com/support/reader/bin/answer.py?answer=69973">Google Reader</a>. When the user jumps to a tweet that is not completely visible, the app needs to know so it can scroll the page.</p>
<h4>Tracking usage</h4>
<p>While not directly applicable to a Twitter app, you may want to find out what areas of your site a visitor actually sees. By firing events when sections move into and out of the viewport, you can use Google Analytics&#8217; <a href="http://code.google.com/apis/analytics/docs/tracking/eventTrackerGuide.html">Event Tracking</a> to find out how often users actually see parts of your page. Wondering why a particular widget doesn&#8217;t result in many click throughs? Perhaps the answer is as simple as not many people even get to see it.</p>
<h3>And more?</h3>
<p>All that from just a viewport? I initially wrote Within Viewport to solve only one of the problems above, but I soon found many other uses for it. It wasn&#8217;t until I began using it that I realized, as obvious as this may seem, how pertinent the viewport is as an insight to the user&#8217;s experience.</p>
<p>If you have any other ideas, or suggested additions to the script, I&#8217;d love to hear it in the comments.</p>
<img src="http://feeds.feedburner.com/~r/craig-patik-blog/~4/OPGY9BH2QpY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://patik.com/blog/matching-ui-behavior-with-user-behavior/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://patik.com/blog/matching-ui-behavior-with-user-behavior/</feedburner:origLink></item>
		<item>
		<title>Within Viewport: JavaScript and jQuery Plugin</title>
		<link>http://feedproxy.google.com/~r/craig-patik-blog/~3/IrkvbOlTgG8/</link>
		<comments>http://patik.com/blog/within-viewport-javascript-and-jquery-plugin/#comments</comments>
		<pubDate>Mon, 07 Nov 2011 12:29:07 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[ui]]></category>
		<category><![CDATA[viewport]]></category>

		<guid isPermaLink="false">http://patik.com/blog/?p=192</guid>
		<description><![CDATA[Within Viewport indicates whether an element is <em>entirely</em> within the viewport. It also allows you to specify your site's effective viewport, and includes an optional jQuery plugin.]]></description>
			<content:encoded><![CDATA[<p>Within Viewport indicates whether an element is <em>entirely</em> within the viewport. It also allows you to specify your site&#8217;s effective viewport (eg, to account for fixed header and navigation bars) and provides a few handy shortcut notations.</p>
<p>It&#8217;s quite simply to use:</p>
<pre class="brush: jscript; title: ; notranslate">
var elem = document.getElementById(&quot;myElem&quot;);

// Returns true if it's completely visible
withinViewport(elem);

// Same as above, but using the jQuery plugin
$(elem).is(&quot;:within-viewport&quot;);

// Run some function on all visible divs
$(&quot;div&quot;).withinViewport().myFunction();
</pre>
<ul class="demo-button-list">
<li><a href="http://patik.com/code/within-viewport/">Live Demo</a></li>
<li><a href="https://github.com/cpatik/within-viewport">Source Code at Github</a></li>
</ul>
<p>There are a few &#8220;in view&#8221; scripts out there &mdash; namely, Mika Tuupola&#8217;s <a href="http://www.appelsiini.net/projects/viewport">Viewport Selectors for jQuery</a> provides some convenient selectors that can be tested against elements, and Remy Sharp&#8217;s <a href="http://remysharp.com/2009/01/26/element-in-view-event-plugin/">Element &#8216;in view&#8217; Event Plugin</a> fires events when elements pass in and out of the viewport.</p>
<p>While useful, these utilities only detect whether elements are partially in view. The aim of Within Viewport is to determine <strong>what content the user can see and interact with</strong>.</p>
<h3>Use Cases</h3>
<p>A lot can be learned from monitoring the viewport, especially on a site with content that spans well outside of the user&#8217;s view. I will discuss how I use Within Viewport in much more detail in my <a href="http://patik.com/blog/matching-ui-behavior-with-user-behavior/">next post</a>. But here&#8217;s a quick overview of what you can do.</p>
<ul>
<li>
<h4>Dynamic content loading</h4>
<p>A site&#8217;s performance can be increased effectively by loading data on demand, for example when the user scrolls near the bottom of the page. But perhaps <em>the content</em> on screen is more pertinent than the scroll position. For example, you may want to load the entire structure of your site during the initial page load, but then populate that structure with heavier media as it nears the user&#8217;s field of view.</p>
</li>
<li>
<h4>Responding to user behavior</h4>
<p>You may also want to tailor when that content is loaded based on how rapidly the user moves about the page. If you are relying on a third party API for content, you may want to start the process sooner than you would begin requested content from your own server.</p>
<p>For example, the script below would find and load items with local content that is merely just beyond the viewport, but also load third-party content that appears much further down the page.</p>
<pre class="brush: jscript; title: ; notranslate">
// Image placeholders at most 100px below the fold
$('img:not([data-src^=&quot;http://&quot;]')
    .withinViewport({bottom:-100})
        .loadTheseImages();

// Image placeholders as far as 500px below the fold
$('img[data-src^=&quot;http://&quot;]')
    .withinViewport({bottom:-500})
        .loadTheseImages();
</pre>
</li>
<li>
<h4>Making appropriate measurements</h4>
<p>If you want to know what your user has seen, for example to remember their reading position in a feed, you can only consider ones that are fully in view. You also need to take into account the actual viewport, avoiding things like fixed header bars that cover parts of the page.</p>
<figure style="margin-left:-1em;">
<object data="http://patik.com/code/within-viewport/example_diagram_sm.svg" type="image/svg+xml" id="svg" width="617" height="626"><br />
<img src="http://patik.com/code/within-viewport/example_diagram_sm.png" alt="Diagram showing elements of a Twitter feed being in and out of view"/><br />
</object></p>
<figcaption><a href="http://patik.com/code/within-viewport/example_diagram.svg" target="_blank">Larger version</a></figcaption>
</figure>
</li>
<li>
<h4>Live updates</h4>
<p>If you implement keyboard navigation between items, similar to <a href="http://www.google.com/support/reader/bin/answer.py?answer=69973">Google Reader</a>, you need to make sure a newly-selected item is actually visible.</p>
</li>
<li>
<h4>Tracking how your app is used</h4>
<p>You can tap into Google Analytics&#8217; <a href="http://code.google.com/apis/analytics/docs/tracking/eventTrackerGuide.html">Event Tracking</a> to find out how often items enter your visitor&#8217;s field of view.</p>
</li>
</ul>
<p>I built Within Viewport to accomodate those needs, but I made it generic enough that any site or web app could benefit from it. There are configurable defaults and several shorthand notations described with examples in the <a href="https://github.com/cpatik/within-viewport/blob/master/README.md">documentation</a>.</p>
<h3>No jQuery? No problem</h3>
<p>I wanted to write a tool that was independent of jQuery so it could be dropped into any project. Of course jQuery does offer some useful mechanisms such as filtering and custom selectors, so I added an optional plugin to provide that functionality.</p>
<ul class="demo-button-list">
<li><a href="http://patik.com/code/within-viewport/">Live Demo</a></li>
<li><a href="https://github.com/cpatik/within-viewport">Source Code at Github</a></li>
</ul>
<img src="http://feeds.feedburner.com/~r/craig-patik-blog/~4/IrkvbOlTgG8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://patik.com/blog/within-viewport-javascript-and-jquery-plugin/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://patik.com/blog/within-viewport-javascript-and-jquery-plugin/</feedburner:origLink></item>
		<item>
		<title>Complete cross-browser console.log()</title>
		<link>http://feedproxy.google.com/~r/craig-patik-blog/~3/5ONAaZZjpAE/</link>
		<comments>http://patik.com/blog/complete-cross-browser-console-log/#comments</comments>
		<pubDate>Tue, 12 Apr 2011 16:55:28 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://patik.com/blog/?p=153</guid>
		<description><![CDATA[Many front-end web developers make use of the wonderful browser consoles that have matured in the past few years. While the tried-and-true console.log() often does the trick, its lack of support (particularly in IE) has led to the use of proxy functions, such as Paul Irish&#8217;s console.log wrapper and Ben Alman&#8217;s Debug() which prevent unsupportive [...]]]></description>
			<content:encoded><![CDATA[<p>Many front-end web developers make use of the wonderful browser consoles that have matured in the past few years. While the tried-and-true <code>console.log()</code> often does the trick, its lack of support (particularly in IE) has led to the use of proxy functions, such as <a href="http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/">Paul Irish&#8217;s console.log wrapper</a> and <a href="http://benalman.com/code/projects/javascript-debug/docs/files/ba-debug-js.html">Ben Alman&#8217;s Debug()</a> which prevent unsupportive browsers from throwing errors.</p>
<p>I had a need for logging data in <em>every</em> browser, not just ones that natively support <code>console.log()</code>. So I forked Paul&#8217;s function and expanded it to work with every browser I could test — IE6+, Firefox 3.6-4, Chrome 10-11, Safari 5, and Opera 11.</p>
<p>This will be exhaustive, so you may want to jump directly to:</p>
<ul class="demo-button-list">
<li><a href="http://patik.com/demos/consolelog/consolelog.js">Source Code</a></li>
<li><a href="http://patik.com/demos/consolelog/consolelog.min.js">Minified Source Code</a></li>
<li><a href="http://patik.com/demos/consolelog">Live Demo</a></li>
<li><a href="https://github.com/cpatik/console.log-wrapper">Github Repo</a></li>
</ul>
<h2>Current state of the console</h2>
<p>Like Paul&#8217;s implementation, we&#8217;re simply going to create a function called <code>log()</code> and pass along any arguments it receives to <code>console.log()</code>. But before that we need to do a little setup to ensure that, when possible, console.log() is properly defined as a function in every browser.</p>
<p>First, let&#8217;s review console support in today&#8217;s browsers:</p>
<ul>
<li>Chrome, Safari, Opera: native <code>console.log()</code></li>
<li>Firefox: native <code>console.log()</code> with Firebug</li>
<li>IE9: native <code>console.log()</code>, but it needs a little nudge to turn on</li>
<li>IE8: While <code>console.log()</code> exists, it&#8217;s an object rather than a function — But we can still write to the console with a clever trick.</li>
<li>Others: We can inject <a href="http://getfirebug.com/firebuglite">Firebug Lite</a> which will define <code>console.log()</code> as a function</li>
</ul>
<p>Note that when I talk about IE I&#8217;m referring to the native versions — &#8220;IE8&#8243; means IE8, <em>not</em> IE9 switched to IE8 mode with the <abbr title="No, I'm not going to prefix that with 'F12'">Developer Tools</abbr>.</p>
<p style="text-align: center;"><a href="http://patik.com/blog/wp-content/uploads/2011/04/ie7mode.png"><img class="aligncenter size-full wp-image-191" title="ie7mode" src="http://patik.com/blog/wp-content/uploads/2011/04/ie7mode.png" alt="IE's developer toolbar tricking you into thinking that it's running as a different version" width="640" height="208" /></a></p>
<h3>IE9</h3>
<p>Before we build <code>log()</code> we need to tell IE9 to use its own console and to consider <code>console.log()</code> to be a function. Many thanks to <a href="http://whattheheadsaid.com/2011/04/internet-explorer-9s-problematic-console-object">Andy E</a> for this piece.</p>
<pre class="brush: jscript; title: ; notranslate">if (typeof console.log == &quot;object&quot; &amp;&amp; Function.prototype.bind &amp;&amp; console) {
	[&quot;log&quot;,&quot;info&quot;,&quot;warn&quot;,&quot;error&quot;,&quot;assert&quot;,&quot;dir&quot;,&quot;clear&quot;,&quot;profile&quot;,&quot;profileEnd&quot;]
		.forEach(function (method) {
			console[method] = this.call(console[method], console);
		}, Function.prototype.bind);
}</pre>
<p>For this particular case we really only need to define the <code>log</code> method, but it can&#8217;t hurt to flip the switch on the others as well.</p>
<h2>Modern browsers</h2>
<p>Now we can define <code>log()</code>. There&#8217;s no sense in re-inventing a very round wheel, so I&#8217;m just going to fork <a href="http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/">Paul Irish&#8217;s original console.log wrapper</a>.</p>
<pre class="brush: jscript; highlight: [7]; title: ; notranslate">if (!window.log) {
	window.log = function () {
    log.history = log.history || [];  // store logs to an array for reference
    log.history.push(arguments);
	if (typeof console.log == 'function') {
		// Modern browsers
		if ((Array.prototype.slice.call(arguments)).length == 1 &amp;&amp; typeof Array.prototype.slice.call(arguments)[0] == 'string') {
			console.log( (Array.prototype.slice.call(arguments)).toString() );
		}
		else {
			console.log( Array.prototype.slice.call(arguments) );
		}
	}
	// to be continued...
</pre>
<p>Notice that <code>if()</code> condition. Paul&#8217;s use of <code>Array.prototype.slice.call()</code> is great because you can pass along any amount and variety of objects, strings, functions, etc directly to the console. However, there&#8217;s one unfortunate side effect: in Firebug and Chrome (and possibly others), if the argument array&#8217;s sole content is a single string greater than 50 characters, it will be truncated faster than you can say <a href="http://en.wikipedia.org/wiki/Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch">Llanfairpwllgwyngyllgoger&#8230;wllllantysiliogogogoch</a>.</p>
<p>So we&#8217;ll check the array length, and if it&#8217;s 1, and that 1 thing is a string, then we&#8217;ll convert the entire argument array to a string before passing it along. You could use <code>console.error()</code> to avoid truncation, but then it will look like an error when it&#8217;s not.</p>
<h3>Opera</h3>
<p>So that takes care of the modern browsers&#8230; except Opera. Opera seems to display the arguments as a whole <code>Array()</code> rather than splitting them apart. So if you passed several arguments you&#8217;d just see this:</p>
<p><a href="http://patik.com/blog/wp-content/uploads/2011/04/opera1.png"><img class="size-full wp-image-188 aligncenter" title="opera1" src="http://patik.com/blog/wp-content/uploads/2011/04/opera1.png" alt="Opera console showing &quot;Array()&quot; rather than the actual arguments" width="615" height="192" /></a></p>
<p>And that&#8217;s not too helpful. We can get around this with a rather boring <code>while()</code> loop to log each argument one by one.</p>
<pre class="brush: jscript; highlight: [4,5,6,7,8,9,10,11]; title: ; notranslate">var log = function () {
			// Modern browsers
			if (typeof console != 'undefined' &amp;&amp; typeof console.log == 'function') {
				// Opera 11
				if (window.opera) {
					var i = 0;
					while (i &lt; arguments.length) {
						console.log(&quot;Item &quot; + (i+1) + &quot;: &quot; + arguments[i]);
						i++;
					}
				}
				// All other modern browsers
				else if ((Array.prototype.slice.call(arguments)).length == 1 &amp;&amp; typeof Array.prototype.slice.call(arguments)[0] == 'string') {
					console.log( (Array.prototype.slice.call(arguments)).toString() );
				}
				else {
					console.log( Array.prototype.slice.call(arguments) );
				}
			}
			// to be continued...
</pre>
<p>Which results in:</p>
<p><a href="http://patik.com/blog/wp-content/uploads/2011/04/opera2.png"><img class="aligncenter size-full wp-image-189" title="opera2" src="http://patik.com/blog/wp-content/uploads/2011/04/opera2.png" alt="Opera's console listing each argument on a separate line" width="616" height="191" /></a></p>
<p>It&#8217;s a little messy and if you use <code>log()</code> a lot you&#8217;ll find that your console will fill up fast, so you&#8217;ll have to decide how important Opera support is  to you.</p>
<h2>IE8</h2>
<p>As we discussed earlier, IE8 has a console but your scripts can&#8217;t call <code>console.log()</code> directly, so we&#8217;re going to add a special condition for it. <a href="http://whattheheadsaid.com/2011/04/internet-explorer-9s-problematic-console-object">Andy&#8217;s aforementioned post</a> included a similar bit of code for writing to IE8&#8242;s console, however in actual IE8 (as opposed to IE9 switched to IE8 mode) <code>Function.prototype.bind</code> is not defined. Instead, I&#8217;m using <a href="http://twitter.com/#!/kangax/status/56059642433900544">@kangax</a>&#8216;s alternative, <code>Function.prototype.call.call()</code>.</p>
<pre class="brush: jscript; first-line: 21; title: ; notranslate">
			else if (!Function.prototype.bind &amp;&amp; typeof console != 'undefined' &amp;&amp; typeof console.log == 'object') {
				Function.prototype.call.call(console.log, console, Array.prototype.slice.call(arguments));
			}
</pre>
<p>One slight alteration: I changed the second part of the condition from <code>console</code> to <code>typeof console != 'undefined')</code>. It seems a little silly, but IE7 actually throws an error without the <code>typeof</code> check.</p>
<h2>Older browsers</h2>
<p>Now we&#8217;re going to inject <a href="http://getfirebug.com/firebuglite">Firebug Lite</a> (&#8220;FBL&#8221;) for all the other browsers — namely, IE7 and older — by adding a <code>&lt;script&gt;</code> tag to the DOM. (Personally, I like FBL better than IE&#8217;s and Opera&#8217;s consoles anyway, so you may want to use this for any browser where <code>(typeof console.log != 'function' || window.opera)</code> is true.) Doing this will expose <code>console.log()</code> as a function, which means your calls to <code>log()</code> will end up being handled by the &#8220;Modern browsers&#8221; section in the beginning of the function.</p>
<p>You can pull it directly from getfirebug.com, or use a local copy (point to the <code>/path/to/firebug-lite/<strong>build</strong>/firebug-lite.js</code> file).</p>
<p>In my experience FBL takes a few moments to load and begin accepting console logs, even locally. To compensate for this delay, this piece of code is split into two conditions. The first one loads FBL and will only run the first time you call <code>log()</code>:</p>
<pre class="brush: jscript; first-line: 24; title: ; notranslate">
		else {
			// Inject Firebug lite
			if (!document.getElementById('firebug-lite')) {
				// Include the script
				var script = document.createElement('script');
				script.type = &quot;text/javascript&quot;;
				script.id = 'firebug-lite';
				script.src = '/lib/js/firebug-lite/build/firebug-lite.js';
				// If you want to expand the console by default, uncomment this line
				//document.getElementsByTagName('HTML')[0].setAttribute('debug','true');
				document.getElementsByTagName('HEAD')[0].appendChild(script);
				setTimeout(function(){log(Array.prototype.slice.call(arguments));}, 1500);
			}
			else {
				// Script was included but hasn't finished loading yet
				setTimeout(function(){log(Array.prototype.slice.call(arguments));}, 500);
			}
		}
	} // &lt;= that's the end of log(), btw
}
</pre>
<p>The second condition is caught when your script calls <code>log()</code> before FBL has finished loading. Notice the id that I added to the <code>&lt;script&gt;</code> tag in the first condition — that tells us that FBL has begun loading. But since <code>console.log</code> is still not defined (otherwise we wouldn&#8217;t have gotten to this point in the code) we know that the script hasn&#8217;t fully loaded yet. Therefore we can simply use a <code>setTimeout</code> to try our call again every half second until it succeeds.</p>
<h2><abbr title="'Oh my god. Becky, look at her butt.'">&#8220;It is so big&#8221;</abbr></h2>
<p>Yeah, it is. Compared to Paul&#8217;s 6 lines, this version is a beast. But consider this: you log to the console during <em>development</em>. You&#8217;re not going to leave this in your production code (I hope!). So this function — and let&#8217;s face it, it&#8217;s not <em>that</em> long, especially when minified — is likely to be used only via localhost or over a LAN connection. I think the ability to log data in every browser is well worth a couple dozen lines of code tucked out of sight down at the bottom of <code>dev.js</code>.</p>
<p>I look forward to any suggestions or improvements you may have.</p>
<ul class="demo-button-list">
<li><a href="http://patik.com/demos/consolelog/consolelog.js">Source Code</a></li>
<li><a href="http://patik.com/demos/consolelog/consolelog.min.js">Minified Source Code</a></li>
<li><a href="http://patik.com/demos/consolelog">Live Demo</a></li>
<li><a href="https://github.com/cpatik/console.log-wrapper">Github Repo</a></li>
</ul>
<img src="http://feeds.feedburner.com/~r/craig-patik-blog/~4/5ONAaZZjpAE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://patik.com/blog/complete-cross-browser-console-log/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		<feedburner:origLink>http://patik.com/blog/complete-cross-browser-console-log/</feedburner:origLink></item>
		<item>
		<title>My wish: that Google would preload its CDN libraries</title>
		<link>http://feedproxy.google.com/~r/craig-patik-blog/~3/ISw-uHMeWI4/</link>
		<comments>http://patik.com/blog/my-wish-that-google-would-preload-its-cdn-libraries/#comments</comments>
		<pubDate>Sat, 09 Apr 2011 16:46:24 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://patik.com/csyes/?p=144</guid>
		<description><![CDATA[What if your site's CSS and JS libraries were already cached for anyone who had previously been to Google's homepage or Facebook? Almost no one would need to download those files from scratch when they reached your site, improving load time dramatically.]]></description>
			<content:encoded><![CDATA[<p>The idea behind using a common CDN such as <a href="http://code.google.com/apis/libraries/">Google&#8217;s</a>, as opposed to your own CDN (or none at all), is that by the time a person reaches your site there&#8217;s a chance they already have your JavaScript libraries cached. While it&#8217;s likely that an übergeek with fifty opened tabs will have jQuery cached before hitting one of your pages, the same isn&#8217;t so true for every Joe Facebook.</p>
<p>But what if a very popular site, one that nearly everyone would hit before reaching your site, loaded those libraries? I imagine the number of users running cached libraries would increase dramatically.</p>
<p>So which site? How about the most popular default home page — Google Search. (Sure, Facebook is popular, but we all know that even <a href="http://www.readwriteweb.com/archives/how_google_failed_internet_meme.php">Facebook user&#8217;s hit up Google first</a>.)</p>
<p>Think about it: a typical user begins their browsing session by loading Google&#8217;s search page, searches for something or other, and moves on with their task. But in the mean time, Google has silently loaded — not used, just loaded — jQuery, some popular web fonts, etc in the background. Perhaps the libraries are even chosen as the most likely ones the user will encounter based on his or her search terms. Those libraries are now cached in the user&#8217;s browser and your page will load that much faster with zero effort.</p>
<p>Of course there are some glaring drawbacks that would need to be addressed, but the solutions are pretty straightforward:</p>
<ul>
<li><strong>Page load speed.</strong> Among other things, one could use a <code>setTimeout()</code> to lazy-load the library after, say, 8 seconds. (If you&#8217;ve been on the page for 8 seconds, chances are you&#8217;re hanging around for another 0.5 seconds to allow the download to finish.)</li>
<li><strong>Bandwidth.</strong> Obviously mobile devices are out, at least until there&#8217;s some way to detect whether the user is on wifi and running a buff enough browser not to blink at the <code>&lt;script&gt;</code> parsing. Even so, there are ISP bandwidth caps to consider, but is a one-time 20KB download going to push anyone over their limit?</li>
<li><strong>Privacy.</strong> People will kick and scream at the thought of something loading without their explicit request. Surely there should be an option to turn this off; but really, if you&#8217;re paranoid enough not to want MooTools in your cache than you&#8217;ve surely installed NoScript anyway.</li>
</ul>
<p>Naturally this is all just a wish. It&#8217;s something I think Google could certainly pull off smartly, but I&#8217;d love to see it in practice even in a limited test (Chrome beta channel users, perhaps?) to see what effect it has on a typical person&#8217;s web experience.</p>
<img src="http://feeds.feedburner.com/~r/craig-patik-blog/~4/ISw-uHMeWI4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://patik.com/blog/my-wish-that-google-would-preload-its-cdn-libraries/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://patik.com/blog/my-wish-that-google-would-preload-its-cdn-libraries/</feedburner:origLink></item>
		<item>
		<title>How to Use Your iPhone Overseas</title>
		<link>http://feedproxy.google.com/~r/craig-patik-blog/~3/G11W1n6i8W0/</link>
		<comments>http://patik.com/blog/how-to-use-your-iphone-overseas/#comments</comments>
		<pubDate>Thu, 29 Jul 2010 22:22:35 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Travel]]></category>
		<category><![CDATA[europe]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://patik.com/blog/?p=136</guid>
		<description><![CDATA[If you&#8217;re preparing to travel overseas and you&#8217;ve had an iPhone for any amount of time you&#8217;re probably excited about its usefulness as a travel aid. In particular, you&#8217;ll be keen to make use of its always-on Internet connection. But you&#8217;ve probably heard the horror stories of arriving home to a thousand-dollar cell phone bill [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re preparing to travel overseas and you&#8217;ve had an iPhone for any amount of time you&#8217;re probably excited about its usefulness as a travel aid. In particular, you&#8217;ll be keen to make use of its always-on Internet connection.</p>
<p>But you&#8217;ve probably heard the horror stories of arriving home to a thousand-dollar cell phone bill littered with roaming charges. Fortunately, you have some options to make use of your iPhone&#8217;s capabilities outside of the United States.</p>
<p>While this topic has been <a title="http://www.eurocheapo.com/blog/using-an-american-iphone-in-europe%E2%80%A6-without-going-broke.html" href="http://www.eurocheapo.com/blog/using-an-american-iphone-in-europe%E2%80%A6-without-going-broke.html">covered</a> <a title="http://www.wired.com/gadgetlab/2009/02/how-to-take-you/" href="http://www.wired.com/gadgetlab/2009/02/how-to-take-you/">before</a>, most approaches are far too conservative. You don&#8217;t want to spend your entire vacation with your iPhone locked down in airplane mode, or constantly toggling Data Roaming on and off &#8212; nor do you need to. That defeats the entire purpose of a smartphone and prevents you from enhancing your trip with the iPhone&#8217;s many tools.<em> </em></p>
<p><em>Note that this post is specific to American AT&amp;T users, but the fundamental principles still apply to other smartphones on other carriers. It is also a bit Europe-centric &#8212; I&#8217;m just sticking to what I have experience with.</em></p>
<p><em>I also assume that you&#8217;re familiar with what a SIM card is, as well as the difference between voice and data where cellular networks are concerned.</em></p>
<h2>An Offline Frame of Mind</h2>
<p>When your iPhone is in its most helpful state, it&#8217;s probably consuming a lot of data, which unfortunately is your primary concern when it comes to roaming charges. So the first order of business is to concentrate on orienting yourself to being less network-reliant. This isn&#8217;t as daunting as it may seem.<a href="http://patik.com/blog/wp-content/uploads/2010/07/google_search_mobile.png"><img class="alignright  size-medium wp-image-139" title="Google search mobile links" src="http://patik.com/blog/wp-content/uploads/2010/07/google_search_mobile-199x300.png" alt="Google provides Mobilized links for web pages in its search  results" width="199" height="300" /></a></p>
<p>An important note to consider is that <strong>native apps</strong> tend to consume far less data than web browsing. For example, it uses a trivial amount of data (tens of kilobytes) to complete a simple FourSquare check in, so have a ball boasting about all the exotic locations you&#8217;re visiting. (Just be safe and <a title="http://www.gadling.com/2010/04/21/social-networking-and-travel-dos-and-donts/" href="http://www.gadling.com/2010/04/21/social-networking-and-travel-dos-and-donts/">don&#8217;t overshare</a>.) And while <a title="http://translate.google.com/" href="http://translate.google.com/">Google Translate</a>&#8216;s mobile interface is slim, consider an app such as <a title="http://www.itranslate.cc/" href="http://www.itranslate.cc/">iTranslate</a> which will only transfer the actual text you&#8217;re translating.</p>
<p>If you must perform a simple Google search away from wifi, hit the mobile link for a stripped down (read: image-lite and less data gobbling) version of the site.</p>
<h3>A Few &#8216;Offline&#8217; Tips</h3>
<ul>
<li><strong>Wifi</strong><br />
This seems a bit obvious, but try to book hotels with free wifi. Assuming your travel is for leisure, you&#8217;ll probably want to enjoy your day and save the web browsing, RSS feeds, and Facebook for when you&#8217;re unwinding in your room at the end of a long day.</p>
<p>Save your cellular data for the situations that are truly helpful while on foot &#8212; finding out where you are, checking for nearby points of interest, and verifying other time sensitive information.You can also use a service such as <a title="http://www.jiwire.com/" href="http://www.jiwire.com/">JiWire</a> and their <a title="http://www.jiwire.com/iphone" href="http://www.jiwire.com/iphone">Wi-Fi Finder</a> app to find and download a map of wifi locations in your city.</li>
<li><strong>Maps<br />
</strong>Perhaps the killer app of the iPhone when it comes to travel is its mapping capabilities and location awareness. Maps, however, are extremely data-intensive, so you&#8217;ll want to have them preloaded on your device.</p>
<ul>
<li><strong>OffMaps</strong> (99 cents) is an excellent app which allows you to freely download maps. On the ground, it will utilize the phone&#8217;s (free, non-data-consuming) GPS abilities to display your position on the map. (It can, of course, stream maps on-the-fly if you have a generous data plan.) It typically locates you within a second or two; it&#8217;s much faster than the GPS devices of the past.Before you leave home, use the maps to download the maps at several zoom levels for the destinations you will be at. A typical city may take a couple hundred megabytes at the most detailed zoom level, so be sure to use Wifi. You might also consider their useful but less-than-polished city guides which highlight sights, hotels, restaurants, and other travel-related points of interest collated from WikiTravel.org and other free sources (in-app purchase; first one&#8217;s free, then 99 cents for three or $9 for unlimited).</li>
<li><strong>Navigation apps</strong> (various products and prices, usually $40-$100) are available for many worldwide locations if you intend to do some driving. Just make sure you choose the right region, and that the maps are included in the download for offline access.</li>
</ul>
</li>
<li><strong>Guides</strong><br />
Search the App Store for the name of your destination city or country and you&#8217;ll find a range of guides, from basic &#8220;WikiTravel in a nice package&#8221; apps to sleek but more costly Lonely Planet guides. Also consider using a service like <a title="http://www.instapaper.com/" href="http://www.instapaper.com/">Instapaper</a> to collect articles and download them to your phone using the Instapaper app. As a last resort, paste the text into an email or the Notes app.Or you could just lug around a dead-tree guidebook, which has its benefits.</li>
<li><strong>Toggle Cellular Data</strong><a href="http://patik.com/blog/wp-content/uploads/2010/07/cellular_data_off.png"><img class="alignright size-medium wp-image-140" title="Cellular data turned off" src="http://patik.com/blog/wp-content/uploads/2010/07/cellular_data_off-200x300.png" alt="Cellular Data switched to &quot;Off&quot; in Settings" width="200" height="300" /><br />
</a></p>
<p>An easy way to ensure no data will be sent over your cellular connection, while still maintaining the ability to make and receive phone calls and use the phone&#8217;s location awareness, is to turn off cellular data in Settings.</p>
<p>That&#8217;s it. <em><strong>There is no need to turn on airplane mode</strong></em> to avoid data usage. Note that you do not need to explicitly turn off data roaming when toggling this setting.</p>
<p>If you&#8217;re confident that you&#8217;ve turned off all background processes (fetching mail, etc) then you can just leave cellular data flipped on to avoid the hassle of constantly toggling it. I recommend testing this at least once: make note of your current data usage (e.g., dial #3282* if you&#8217;re on AT&amp;T&#8217;s plan described below), leave the phone idle for an hour or two, then check your data usage again and make sure it hasn&#8217;t gone up. If it has, you&#8217;ve still got something running in the background.</li>
</ul>
<h2>Getting Connected</h2>
<p>You have three basic choices when it comes to connecting to a cellular network abroad. The first is the cheapest but requires a bit of research and a little leg work at your destination, while the other two are more expensive but just plain work with no hassle.</p>
<ol>
<li><strong>Foreign SIM Card</strong><br />
This is the cheapest option which gives you the most flexibility, and depending on the country, even the possibility of having so much data at your disposal you won&#8217;t even need to monitor your usage. Unfortunately, it requires <a title="http://en.wikipedia.org/wiki/IOS_jailbreaking" href="http://en.wikipedia.org/wiki/IOS_jailbreaking">jailbreaking</a> and unlocking your device. This has its own implications; I&#8217;ll leave it up to the reader to decide whether this is a path worth taking, and to figure out how to do it (the process and ability depends on your <a title="http://www.jailbreakmatrix.com/" href="http://www.jailbreakmatrix.com/">device and OS version</a>, not to mention your tech savviness).If you do unlock your phone, you will be free to use any SIM you can find. You will quite likely want to use a contract-free prepaid SIM which will allow you to just pay for what you use and can usually be found all over, from airports to convenience stores to specialty phone shops. These options are country-specific, so if you&#8217;re traveling to three or more countries you&#8217;ll want to look into &#8220;global SIM&#8221; cards such as <a title="http://www.telestial.com/view_product.php?ID=MSIM-EX01" href="http://www.telestial.com/view_product.php?ID=MSIM-EX01">Telestial</a> or <a title="http://www.gosim.com/?gosimusa" href="http://www.gosim.com/?gosimusa">GO-SIM</a>.</p>
<p>Start by perusing the <a title="http://paygsimwithdata.wikia.com/wiki/Pay_as_you_go_sim_with_data_Wiki" href="http://paygsimwithdata.wikia.com/wiki/Pay_as_you_go_sim_with_data_Wiki">Pay As You Go SIM Wiki</a> and <a href="http://prepaidgsm.net">PrepaidGSM.net</a> which includes a roundup of the options for each country, listing the data and voice rates. It may seem a little daunting at first, so concentrate on the data rate and assume you&#8217;ll use Skype for voice calls. Note that the main legacy carriers, such as Vodafone, O2, Orange, and T-Com — the rough European equivalents to AT&amp;T, Verizon, et al — are ubiquitous and feel &#8216;safe&#8217;, but there also exists a culture of &#8220;virtual operators&#8221; who utilize the big companies&#8217; networks but offer lower rates. Often these VOs (or sometimes MVNOs) will specialize in some &#8216;angle&#8217; that may not work for everyone, such as cheap data subsidized by more expensive voice calls — which is actually just what you want. (Think of low cost airlines like RyanAir which offer cutthroat prices based on limited services and alternate airports &#8212; it&#8217;s not entirely mainstream-friendly but it may just suit your needs.)</p>
<p>Take a moment to peruse the site&#8217;s forums for tips on your country and read about people&#8217;s experiences, taking into consideration how recent the posts are.Once you&#8217;ve narrowed your options down to three or four networks, head over to other travel forums such as <a title="http://www.flyertalk.com/forum/index.php" href="http://www.flyertalk.com/forum/index.php">FlyerTalk</a> or Lonely Planet&#8217;s <a title="http://www.lonelyplanet.com/thorntree/" href="http://www.lonelyplanet.com/thorntree/">Thorn Tree</a> and search for the network&#8217;s name to see what people have to say.</p>
<p>Finally, <strong>write down three or four operators</strong> (on paper or digitally), as well as how/where to buy them, to bring with you on your trip. You can&#8217;t be sure exactly which SIMs you&#8217;ll actually be able to find, so it&#8217;s good to have a backup. You may get a different story from the shop clerk who says you can&#8217;t actually use the SIM as you&#8217;d expect, or they may be difficult to find in stock. A piece of paper also provides a convenient tool to hand to a non-English speaking clerk (unless you know the Dutch/Hungarian/Romanian/Turkish phrase for &#8220;I need a prepaid SIM card for my unlocked phone with a good data rate&#8221; and can interpret his or her possibly jargon-laden response).</p>
<p>Note that the <em>availability</em> of SIMs can vary in both senses of that word. For example, in the UK, SIM cards are practically given away &#8212; you can throw a stone in any direction and, after bouncing off a kebab joint, it will land in front of a shop selling £10 SIMs that come with £10 of credit (meaning the SIM is free assuming you use all the credit). Often these can be bought anonymously with cash. In the middle are countries like Spain and Germany which may require a passport and/or in-country address (the standard practice is to use your hotel&#8217;s address) to purchase a card. Then there are countries like Turkey, where the security theatre had ascended to the point where the SIM card vendor must verify your national tax ID (similar to an American social security number in both function and sensitivity) and register it with your SIM before it&#8217;s activated, meaning a foreigner is basically out of luck unless they have a good friend or family member willing to buy one for them.</li>
<li><strong>AT&amp;T&#8217;s International Data Package<br />
</strong>This option is as simple as it gets — just log in to your account on AT&amp;T&#8217;s website and add an international data package to your account. Once you&#8217;re overseas, you&#8217;ll just use your iPhone like you would at home and it will work seamlessly.The catch? It&#8217;s not exactly cheap. You can choose from a paltry 20MB for $25, 50MB for $60, or even 100MB for a whopping $120. That&#8217;s not much data for a pretty hefty chunk of change. Figure that you&#8217;ll use about 50MB a month, or 12-15MB per week, if you&#8217;re careful about your usage and stick with the tips discussed above. You don&#8217;t want to go over &#8212; overage fees are an almost comical $5 per megabyte (though mercifully charged by the kilobyte should you go just a hair over).</p>
<p>There&#8217;s one other point to consider which may or may not work out in your favor. The international data package takes affect immediately and is prorated, which may or may not align with your billing cycle and trip. Consider how the 50MB plan would pan out over the following example:<a href="http://patik.com/blog/wp-content/uploads/2010/07/data_plan_schedule1.png"><img class="aligncenter size-full wp-image-138" title="Data plan timeline" src="http://patik.com/blog/wp-content/uploads/2010/07/data_plan_schedule1.png" alt="Time line showing a trip from July 7 to July 27, with only 33MB available from July 7 to July 22 when the billing cycle restarts, but then 50MB for the last 5 days of the trip" width="600" height="120" /></a>In this example, notice how inconveniently the amount of data aligns with the actual trip. The first fifteen days, representing a sizable bulk of the trip, only gets 25MB, while the last 5 days have 50MB at their disposal. (True, you will still end up paying for the amount of data you actually use, but remember the overage fees compared to the normal price per MB, not to mention the convenience of having a lot of data available should you unexpectedly encounter a day or two of unavoidable high usage.)</p>
<p>Here&#8217;s how it works, and why part of the trip only has 25MB available. The billing date here is the 22nd of the month, and the data plan began on the same day as the trip, the 7th. Since that&#8217;s only half of the billing cycle, you only get half of the data. When your next billing cycle begins, you&#8217;ll be reset back to the full 50MB. In this case, you&#8217;d be better off signing up on the 22nd of the previous month (June, in the above example) so that you have the whole 50MB available during your two-week trip. I&#8217;ve read that you can have this adjusted (so that the data charge aligns with the date of your trip instead of your billing cycle) by calling AT&amp;T; I recommend talking to them first if your dates aren&#8217;t aligning in your favor.</li>
<li><strong>Legit iPhone SIM providers</strong><br />
These aren&#8217;t any cheaper per megabyte than AT&amp;T&#8217;s plan, and they&#8217;re not as dead simple, but they give you a few more options: <a title="http://www.mobilitypass.com/iphone_voice_and_data_sim_card.html" href="http://www.mobilitypass.com/iphone_voice_and_data_sim_card.html">Mobility Pass</a>,</li>
</ol>
<h2>Conclusion</h2>
<p>If you&#8217;re comfortable with jailbreaking and unlocking your phone, and the country to which you&#8217;re traveling has SIMs available, then a 3rd party SIM is easily the cheapest and most flexible option.</p>
<p>If you don&#8217;t want to (or can&#8217;t) jailbreak or your country is on SIM lockdown, AT&amp;T provides an easy-as-pie option at a cost.</p>
<p>Either way, you&#8217;ll need to follow good data usage practices to keep your usage at more of a minimum than you&#8217;re used to. Also be sure you&#8217;ve got all the apps you need and prepare them before leaving home.</p>
<p>Above all else, don&#8217;t forget to leave the iPhone in your pocket most of the time and enjoy your vacation!</p>
<img src="http://feeds.feedburner.com/~r/craig-patik-blog/~4/G11W1n6i8W0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://patik.com/blog/how-to-use-your-iphone-overseas/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		<feedburner:origLink>http://patik.com/blog/how-to-use-your-iphone-overseas/</feedburner:origLink></item>
		<item>
		<title>Why the Germany-Spain Semi-Final Isn’t a Foregone Conclusion</title>
		<link>http://feedproxy.google.com/~r/craig-patik-blog/~3/WVZk5mtzseQ/</link>
		<comments>http://patik.com/blog/why-the-germany-spain-semi-final-isnt-a-foregone-conclusion/#comments</comments>
		<pubDate>Mon, 05 Jul 2010 16:03:59 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[Soccer]]></category>

		<guid isPermaLink="false">http://patik.com/blog/?p=131</guid>
		<description><![CDATA[Disclaimer: I’m a fan of both teams, but I have a bit at stake (no, not gambling-related) with regards to Spain winning the Cup. Nevertheless, I hope to make an objective case for Spain&#8217;s chances of victory. With 4-0 and 4-1 (or was it 4-2) thrashings over Argentina and England (and Frank Lampard), respectively, Germany [...]]]></description>
			<content:encoded><![CDATA[<p><em>Disclaimer: I’m a fan of both teams, but I have a bit at stake (no, not gambling-related) with regards to Spain winning the Cup. Nevertheless, I hope to make an objective case for Spain&#8217;s chances of victory.</em></p>
<p>With 4-0 and 4-1 (or was it 4-2) thrashings over <a href="http://www.fifa.com/worldcup/matches/round=249718/match=300061505/index.html">Argentina</a> and England (and <a href="http://soccer.fanhouse.com/2010/06/27/frank-lampard-goal-not-given-in-germany-vs-england-world-cup-ma/">Frank Lampard</a>), respectively, Germany go into their semi-final with Spain as the likely favorites. It&#8217;s hard to deny that a team with such excellent players, a gelling of individual talents, and a strong history should be able to beat a Spain side who has looked shaky in their attempt not to repeat their usual early exit from the Cup.</p>
<p><a href="http://www.guardian.co.uk/football/gallery/2010/jul/04/world-cup-2010-argentina#/?picture=364543099&amp;index=9"><img class="alignright size-medium wp-image-133" title="Klose" src="http://patik.com/blog/wp-content/uploads/2010/07/Klose-makes-it-2-0-to-Ger-0051-300x197.jpg" alt="" width="300" height="197" /></a></p>
<p>That said, I can see Spain pulling off a surprise win in this one, even while disregarding the difficult-to-ignore fact that Müller being out on suspension for Germany.</p>
<h3>Team play</h3>
<p>In this tournament, Germany  have not demolished teams that play well as a team. Argentina and  England, in particular, were merely a collection of stars just riding  along on a combination of individual performances and luck (more so luck  in England’s case) until they were found out by a solid team. While  Spain is star-studded, they gel as a team in a way that Argentina and England don’t  (admittedly, Germany are even better in this respect).</p>
<h3>Possession</h3>
<p>Spain dominate possession and if they score first they are  very solid for the rest of the game. Germany will have a tough time  pulling off their counterattacks (despite Spain’s not-quite-world-class  defense) with the way Spain move the ball around. Germany will score,  I’m sure, but not with the ease that they have in the last two games.</p>
<h3>Pressure</h3>
<p>Spain have also been hampered by being favorites, and suddenly they  are not favorites, almost underdogs in fact. I think this will lift a  lot of the pressure that has hampered Spain’s usual groove. And Villa’s  confidence is soaring compared to that of any individual German’s.</p>
<p>Germany, on the other hand, were not widely favored to win the tournament, and the sudden mounting enthusiasm of the media, fans, and the players themselves must be reaching a critical point.</p>
<h3>Those thrashings I mentioned&#8230;</h3>
<p>While I would never say Germany&#8217;s results against Argentina, England, and Australia were flukes, look at their other results. They narrowly defeated Ghana 1-0, a team who only just missed out on the semis themselves. They even lost to Serbia, a squad with solid team play who were pre-tournament favorites to reach the quarterfinals. Germany has tripped during these finals, and it&#8217;s unlikely they won&#8217;t trip again.</p>
<h3>Resilience</h3>
<p>It won’t be a blowout in either direction; 2-1 or 3-2 is my guess, if  it doesn&#8217;t go to penalties. And with the resilience and composure that Spain showed  in Euro 2008 (penalties against Italy, and of course the final against  Germany, holding on to a narrow lead for an hour) as well as in this tournament (defeating Paraguay despite being <a href="http://www.guardian.co.uk/football/2010/jul/03/david-villa-spain-paraguay">frustrated by their defense</a> and flustered by the <a href="http://www.smh.com.au/world-cup-2010/world-cup-news/villa-saves-spain-again-after-penalty-drama-20100704-zvcz.html">penalty debacle</a>), I’d give the edge to  Spain. <a href="http://patik.com/blog/wp-content/uploads/2010/07/sp9-420x01.jpg"><img class="alignright size-medium wp-image-132" title="Penalties" src="http://patik.com/blog/wp-content/uploads/2010/07/sp9-420x01-300x140.jpg" alt="" width="300" height="140" /></a></p>
<p>I certainly won’t be too sore if Germany prevail — they’re a  fantastic team playing the sport the way I like to see it be played: no  BS, just solid playmaking, composure, and clinical finishing.</p>
<img src="http://feeds.feedburner.com/~r/craig-patik-blog/~4/WVZk5mtzseQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://patik.com/blog/why-the-germany-spain-semi-final-isnt-a-foregone-conclusion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://patik.com/blog/why-the-germany-spain-semi-final-isnt-a-foregone-conclusion/</feedburner:origLink></item>
		<item>
		<title>How to Keep Sites from Spying on Your Copy and Paste</title>
		<link>http://feedproxy.google.com/~r/craig-patik-blog/~3/r5B4dreM_14/</link>
		<comments>http://patik.com/blog/how-to-keep-sites-from-spying-on-your-copy-and-paste/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 12:23:43 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
		
		<guid isPermaLink="false">http://patik.com/blog/?p=122</guid>
		<description><![CDATA[?Many news sites, from Wired to my local newspaper, have taken to adding a &#8216;feature&#8217; to their articles &#8212; any text you copy and paste is silently broadcast to another site. That other site, Tynt, keeps track of what you copy and paste to your friends in an effort to track demographics. While some find [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://patik.com/csyes/wp-content/uploads/2010/01/copypasta-adblock2.png"></a>?Many news sites, from <a href="http://www.wired.com/">Wired</a> to my <a href="http://www.timesunion.com/">local newspaper</a>, have taken to adding a &#8216;feature&#8217; to their articles &#8212; any text you copy and paste is <a href="http://yro.slashdot.org/story/10/01/14/1818222/Tynt-Insight-Is-Watching-You-Cut-and-Paste">silently broadcast to another site</a>. That other site, <a href="http://www1.tynt.com/see-whats-copied">Tynt</a>, keeps track of what you copy and paste to your friends in an effort to track demographics.</p>
<p style="text-align: center;"><a href="http://patik.com/csyes/wp-content/uploads/2010/01/copypasta.png"><img class="size-full wp-image-123 aligncenter" style="margin-top: 10px; margin-bottom: 10px; border: 1px solid black;" title="Copying and pasting, sort of" src="http://patik.com/csyes/wp-content/uploads/2010/01/copypasta.png" alt="Text copied and pasted from a news article into an IM window" width="463" height="142" /></a></p>
<p style="text-align: left;">While some find it useful that Tynt also appends the URL of the article you&#8217;re viewing, many find the behavior obtrusive and a violation of their privacy. Want to share a snippet of a story with a friend? Go ahead, Tynt (and presumably the news site) are watching.</p>
<p><strong>Here&#8217;s how to get rid of it</strong>, depending on your browser of choice.</p>
<h3><img class="size-thumbnail wp-image-126 alignright" style="margin: 5px;" title="Firefox" src="http://patik.com/blog/wp-content/uploads/2010/01/ff-icon1-150x150.png" alt="Firefox icon" width="81" height="81" />Firefox</h3>
<p>With AdBlock installed (and why wouldn&#8217;t you have it?), open the AdBlock preferences &#8212; either through the Tools menu or with the shortcut Ctrl-Shift-E. Click Filters &gt; Add new, then paste in this line:</p>
<pre style="text-align: center;"><tt style="background-color: #f9ffb7; border: 1px solid orange; padding: 5px 10px;">http://tcr.tynt.com/javascripts/Tracer.js</tt></pre>
<p style="text-align: center;"><a href="http://patik.com/csyes/wp-content/uploads/2010/01/copypasta-adblock2.png"><img class="aligncenter" style="margin-top: 10px; margin-bottom: 10px;" title="Click for full size" src="http://patik.com/csyes/wp-content/uploads/2010/01/copypasta-adblock2.png" alt="AdBlock preferences window" width="480" height="360" /></a></p>
<h3><img class="size-thumbnail wp-image-125 alignright" style="margin: 12px;" title="Chrome" src="http://patik.com/blog/wp-content/uploads/2010/01/Big+500x500+Chrome+Icon1-150x150.jpg" alt="Google Chrome icon" width="72" height="72" /></h3>
<h3>Chrome</h3>
<p>Chrome as a few ad-blocking extensions, such as <a href="https://chrome.google.com/extensions/detail/gighmmpiobklfepjocnamgkkbiglidom">AdBlock</a> and <a href="https://chrome.google.com/extensions/detail/cfhdojbkjhnklbpkdaibdccddilifddb">AdThwart</a>. Once one is installed, go to your extensions page by clicking the wrench icon in the upper right corner of Chrome, then choose Extensions. Open your extension&#8217;s options and add the same line shown above for Firefox.</p>
<h3>Internet Explorer, and everyone else</h3>
<p>First, ask yourself why you&#8217;re not using a safer, <a href="http://www.google.com/chrome">faster</a>, <a href="http://www.mozilla.com/firefox/">better</a> browser. Safari lacks add-ons (and therefore ad-blocking). And nobody uses Opera. (Kidding, sort of.) Surprisingly, Internet Explorer version 8 does offer ad-blocking. Follow <a href="http://www.ghacks.net/2009/04/08/internet-explorer-8-ad-blocking/">these easy steps from ghacks.net</a> to block this script.</p>
<img src="http://feeds.feedburner.com/~r/craig-patik-blog/~4/r5B4dreM_14" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://patik.com/blog/how-to-keep-sites-from-spying-on-your-copy-and-paste/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://patik.com/blog/how-to-keep-sites-from-spying-on-your-copy-and-paste/</feedburner:origLink></item>
		<item>
		<title>The Apple Tablet Will Be Exactly What We Think It Will Be</title>
		<link>http://feedproxy.google.com/~r/craig-patik-blog/~3/qiykli-t-Y8/</link>
		<comments>http://patik.com/blog/the-apple-tablet-will-be-exactly-what-we-think-it-will-be/#comments</comments>
		<pubDate>Tue, 29 Dec 2009 02:04:33 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
		
		<guid isPermaLink="false">http://patik.com/blog/?p=116</guid>
		<description><![CDATA[With the rumors around the Apple tablet reaching a fever pitch, a number of sites have taken to rounding up pre-iPhone speculation and using it to push the idea that we don&#8217;t know anything about the so-called iSlate. The thing is, we probably do. The iPhone came out of nowhere and surprised just about everyone. [...]]]></description>
			<content:encoded><![CDATA[<p>With the <a href="http://gizmodo.com/5434566/the-exhaustive-guide-to-apple-tablet-rumors">rumors around the Apple tablet</a> reaching a fever pitch, a number of sites have taken to <a href="http://gizmodo.com/5435723/the-iphone-wouldve-sucked-if-the-rumors-were-true">rounding up pre-iPhone speculation</a> and using it to push the idea that <a href="http://technologizer.com/2009/12/28/iphone-rumors/">we don&#8217;t know anything</a> about the so-called <a href="http://www.wired.com/gadgetlab/2009/12/apple-bought-islatecom-%E2%80%94-perhaps-for-a-tablet/?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+wired%2Findex+%28Wired%3A+Index+3+%28Top+Stories+2%29%29">iSlate</a>. The thing is, we probably do.</p>
<p>The iPhone came out of nowhere and surprised just about everyone. It made the various speculative mockups look laughable. But there are a couple reasons why we do know what the iSlate will be about.</p>
<h3>Apple has done touchscreens before</h3>
<div id="attachment_118" class="wp-caption alignright" style="width: 310px"><a href="http://nexus404.com/Blog/2009/12/26/apple%E2%80%99s-tablet-to-be-called-the-islate-islate-com-domain-registered-by-cupertino/"><img class="size-medium wp-image-118" title="iSlate" src="http://patik.com/blog/wp-content/uploads/2009/12/Apple-Touchscreen-Tablet-fictional-header1-e1262051920979-300x189.jpg" alt="" width="300" height="189" /></a><p class="wp-caption-text">It will probably look similar to this</p></div>
<p>By definition, a tablet PC is going to have a large touchscreen. Normally it&#8217;s hard to guess what a company might do with such an interface, however the iPhone has been around for 3 years (and 3 iterations), so we know have an idea of how Apple likes to use touchscreens.</p>
<h3>Apps</h3>
<p>Not even Apple saw how big apps would become, although it&#8217;s now obvious that they must be a focal point of the tablet &#8212; they just make too much money to ignore. It&#8217;s unfeasible that the Apple tablet would not feature apps front and center.</p>
<h3>We&#8217;re expecting a computer this time</h3>
<div id="attachment_117" class="wp-caption alignleft" style="width: 186px"><a href="http://www.baekdal.com/articles/Fun/ipod-phone-iphone/"><img class="size-medium wp-image-117" title="Not the iPhone" src="http://patik.com/blog/wp-content/uploads/2009/12/iphone1-e1262051973917-176x300.jpg" alt="" width="176" height="300" /></a><p class="wp-caption-text">But it won&#39;t look like this</p></div>
<p>In the build up to the iPhone, all anyone could think about was the iPod, which led most of the rumors to involve an iPod with phone capabilities tacked on. Finding out that the iPhone was actually a computer in your pocket was a pleasant surprise. But a tablet is supposed to be a mini computer. No surprise there.</p>
<p>Basically, as long as Apple does indeed release a tablet PC, there is little room for the speculation to be too far off base. It has to be an app-centric, touchscreen-based PC (not a glorified media player or e-book reader). Other than the keyboard implementation and the size, not much else can be a huge surprise.</p>
<p>But of course, I still can&#8217;t wait for it.</p>
<img src="http://feeds.feedburner.com/~r/craig-patik-blog/~4/qiykli-t-Y8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://patik.com/blog/the-apple-tablet-will-be-exactly-what-we-think-it-will-be/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://patik.com/blog/the-apple-tablet-will-be-exactly-what-we-think-it-will-be/</feedburner:origLink></item>
		<item>
		<title>Gaping Hole in Penalty-Taking Rules?</title>
		<link>http://feedproxy.google.com/~r/craig-patik-blog/~3/Dp7Lqfglcbk/</link>
		<comments>http://patik.com/blog/gaping-hole-in-penalty-taking-rules/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 00:44:58 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[Soccer]]></category>

		<guid isPermaLink="false">http://patik.com/blog/?p=112</guid>
		<description><![CDATA[During Chelsea&#8217;s draw with West Ham, an incorrect penalty decision led to Frank Lampard placing the ball on the spot. Immediately after his successful first attempt, the referee blew his whistle and ordered a retake of the penalty, citing encroachment from several West Ham players. Lampard retook the shot, then retook it once more, following [...]]]></description>
			<content:encoded><![CDATA[<p>During <a href="http://www.google.com/hostednews/afp/article/ALeqM5gWq0WyjcI8DteK9rsHif4VWCrf6Q">Chelsea&#8217;s draw with West Ham</a>, an incorrect penalty decision led to Frank Lampard placing the ball on the spot. Immediately after his successful  first attempt, the referee blew his whistle and ordered a retake of the penalty, citing encroachment from several West Ham players.</p>
<p><a href="http://www.france24.com/en/node/4952762"><img class="alignright size-full wp-image-113" title="West Ham's Mark Noble (C) and Chelsea's Frank Lampard (L) run for the ball as Chelsea's Michael Ballack (R) looks on during their Premiership match at Upton Park football Boleyn Grounds stadium, in east London. The match ended in a 1-1 draw." src="http://patik.com/blog/wp-content/uploads/2009/12/chelsea-west-ham-penalty.jpg" alt="" width="245" height="148" /></a></p>
<p>Lampard retook the shot, then retook it once more, following another encroachment. He made all three shots, but each time, keeper Robert Green looked closer and closer to saving the shot. Meanwhile, there was no specific punishment doled out to the West Ham players.</p>
<p>This raises the possibility of an interesting strategy, but one that would be detrimental to the sport. Keepers are given a slight advantage when a penalty is retaken &#8212; they have an idea of whether the taker is likely to fake, which side they like to aim for, etc. It can also unsettle the taker, who doesn&#8217;t expect to have to retake each attempt.</p>
<p>Based on this, it would seem a good strategy for a team who has just given up a penalty to purposely encroach two or three times. Assuming they agree on the number of times in advance with the keeper, it could give he keeper a much needed opportunity to <a href="http://en.wikipedia.org/wiki/Penalty_kick#Strategy_to_save_a_penalty">analyze the situation</a> while the penalty taker becomes increasingly frustrated.</p>
<p>We know that watching a player&#8217;s previous penalty attempts is helpful &#8212; just ask <a href="http://www.guardian.co.uk/football/2009/mar/01/carling-cup-final-manchester-united-foster">Ben Foster</a> and <a href="http://www.footballshirtculture.com/20061218132/collecting/lehmann-world-cup-penalty-note-fetches-one-million-euros.html">Jens Lehmann</a>.</p>
<p>Obviously this is not how the game should be played and it would be aggravating for fans and players alike to watch. I&#8217;d liken it to the strategy in American football or basketball of the defensive team calling a timeout to ruin the flow of the game in the final crucial moments.</p>
<p>Surely the rules need to be changed, or referees need to hand out yellow cards more liberally when a several players disrupt the game. Thoughts?</p>
<img src="http://feeds.feedburner.com/~r/craig-patik-blog/~4/Dp7Lqfglcbk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://patik.com/blog/gaping-hole-in-penalty-taking-rules/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://patik.com/blog/gaping-hole-in-penalty-taking-rules/</feedburner:origLink></item>
		<item>
		<title>Mobile Twitter bookmarklet displays the new, updated Twitter on your smartphone</title>
		<link>http://feedproxy.google.com/~r/craig-patik-blog/~3/rCksJ8yen-k/</link>
		<comments>http://patik.com/blog/mobile-twitter-bookmarklet-displays-the-new-updated-twitter-on-your-smartphone/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 17:44:26 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
		
		<guid isPermaLink="false">http://patik.com/blog/?p=108</guid>
		<description><![CDATA[Twitter recently unveiled a new interface for their mobile site located at mobile.twitter.com loaded with the features you&#8217;re accustomed to having on the desktop version of the site. However, when you browse to Twitter or follow a link from an email on your mobile phone you&#8217;re still shown the older, far less useful interface by [...]]]></description>
			<content:encoded><![CDATA[<p>Twitter recently unveiled a <a href="http://mashable.com/2009/12/03/twitter-mobile-3/">new interface for their mobile site</a> located at <a href="http://mobile.twitter.com">mobile.twitter.com</a> loaded with the features you&#8217;re accustomed to having on the desktop version of the site. However, when you browse to Twitter or follow a link from an email on your mobile phone you&#8217;re still shown the older, far less useful interface by default.</p>
<p>To automatically view any page in the new interface, just use the <a href="http://en.wikipedia.org/wiki/Bookmarklet">bookmarklet</a> below. If you&#8217;re currently on a Twitter page you&#8217;ll be redirected to the same page on mobile.twitter.com; or, if you&#8217;re anywhere else at all, you&#8217;ll simply go to the mobile home page.</p>
<p>The bookmarklet: <span style="background-color: #dddddd; color: #0000ff; text-decoration: underline; padding: 2px;"><a href="javascript:if(window.location.href.indexOf('twitter.com')&lt;0){window.location.href='http://mobile.twitter.com/'} else if(window.location.href.indexOf('mobile.twitter.com')&lt;0){window.location.href=window.location.href.replace(/(\w+\.)?twitter\.com/,'mobile.twitter.com');}"><strong>Mobile Twitter</strong></a></span></p>
<p>Or, to install it on an iPhone, follow these steps.</p>
<ol>
<li><a href="http://patik.com/csyes/mobile-twitter-bookmarklet-displays-the-new-updated-twitter-on-your-smartphone/#___javascript:if(window.location.href.indexOf('twitter.com')&lt;0){window.location.href='http://mobile.twitter.com/'} else if(window.location.href.indexOf('mobile.twitter.com')&lt;0){window.location.href=window.location.href.replace(/(\w+\.)?twitter\.com/,'mobile.twitter.com');}">Click here</a>, and bookmark the resulting page once it loads by clicking the + icon at the bottom of Mobile Safari. (It will look just like the page you&#8217;re on.) Call it something like &#8220;Mobile Safari&#8221;.</li>
<li>Tap the bookmarks icon to open your bookmarks, then click Edit</li>
<li>Tap on the bookmark you just made. Then tap on the second line, containing the URL, to edit it.</li>
<li>Hold your finger down on the URL until the magnifying glass appears. Slide your finger to the left until you see &#8220;#__javascript&#8221;. Put the cursor just before &#8220;javascript&#8221;, then hit Backspace to clear out everything that comes before it.</li>
<li>Click Done. The URL should now be a bunch of code beginning with &#8220;javascript&#8221;<img class="aligncenter size-full wp-image-109" title="Edit bookmark dialog, complete" src="http://patik.com/csyes/wp-content/uploads/2009/12/image_2.png" alt="Edit bookmark dialog, complete" width="160" height="240" /></li>
</ol>
<p>And that&#8217;s it. To use it, just open your bookmarks and tap on your new Mobile Twitter bookmarklet while you&#8217;re viewing any page.</p>
<img src="http://feeds.feedburner.com/~r/craig-patik-blog/~4/rCksJ8yen-k" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://patik.com/blog/mobile-twitter-bookmarklet-displays-the-new-updated-twitter-on-your-smartphone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://patik.com/blog/mobile-twitter-bookmarklet-displays-the-new-updated-twitter-on-your-smartphone/</feedburner:origLink></item>
	</channel>
</rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 11/14 queries in 0.004 seconds using disk: basic

Served from: patik.com @ 2012-05-29 21:42:28 -->

