<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:series="http://unfoldingneurons.com/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en" xml:base="http://davidwalsh.name/wp-atom.php"><title type="text">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</title> <subtitle type="text">Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</subtitle><updated>2012-02-04T19:28:58Z</updated><link rel="alternate" type="text/html" href="http://davidwalsh.name" /> <id>http://davidwalsh.name/feed/atom</id><generator uri="http://wordpress.org/" version="3.3">WordPress</generator> <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/Bludice" /><feedburner:info uri="bludice" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>43.072994</geo:lat><geo:long>-89.519924</geo:long><feedburner:emailServiceId>Bludice</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><entry> <author> <name>David Walsh</name> <uri>http://davidwalsh.name</uri> </author><title type="html"><![CDATA[Custom Getters and Setters with&#160;MooTools]]></title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Bludice/~3/sABQ57DNv1o/get-set" /> <id>http://davidwalsh.name/?p=5379</id> <updated>2012-02-01T15:27:08Z</updated> <published>2012-02-01T15:27:08Z</published> <category scheme="http://davidwalsh.name" term="MooTools" /> <summary type="html"><![CDATA[Working with Dojo all day and scoping out MooTools at night gives me a unique perspective; I get to constantly evaluate the two frameworks and mentally move functionalities from framework to framework. One small but handy feature within the Dojo Toolkit&#8217;s Dijit UI Framework is its set/get system. Dijit allows developers to add custom methods [...]<p><a
href="http://davidwalsh.name/get-set">Custom Getters and Setters with&nbsp;MooTools</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></summary> <content type="html" xml:base="http://davidwalsh.name/get-set">&lt;p&gt;Working with Dojo all day and scoping out MooTools at night gives me a unique perspective;  I get to constantly evaluate the two frameworks and mentally move functionalities from framework to framework.  One small but handy feature within the Dojo Toolkit&amp;#8217;s Dijit UI Framework is its set/get system.  Dijit allows developers to add custom methods tied into simple &lt;code&gt;get&lt;/code&gt; and &lt;code&gt;set&lt;/code&gt; methods to allow manipulation properties into and on the way out of a class.  I took a few moments to implement this system in MooTools.&lt;/p&gt;&lt;p&gt;The idea is that a Class instance has properties:&lt;/p&gt;&lt;pre class="js"&gt;
var MyClass = new Class({
	value: 10/*, more... */
});
&lt;/pre&gt;&lt;p&gt;Instead of simply setting and getting object properties directly, sometimes they need to be treated before coming in or going out.  For setting, it can be a sort of internal formatting or validation.  For getting, it&amp;#8217;s mostly formatting.  The method formats are &lt;code&gt;_get[SomeAttrName]Attr&lt;/code&gt; and &lt;code&gt;_set[SomeAttrName]Attr&lt;/code&gt;.  With that in mind, it&amp;#8217;s time to create the mixin class.&lt;/p&gt;&lt;h2&gt;JavaScript GetSet for&amp;nbsp;MooTools&lt;/h2&gt;&lt;p&gt;This new functionality will be independently coded as a class meant as a &lt;code&gt;Class&lt;/code&gt; mixin using the Implements property:&lt;/p&gt;&lt;pre class="js"&gt;
(function() {
	
	// Turns "thisPropertyName" into "ThisPropertyName"
	function getFunctionName(key, getSet) {
		return "_" + getSet + key.charAt(0).toUpperCase() + key.slice(1) + "Attr";
	}
	
	// Implement the getter / setter
	this.GetSet = new Class({
		// A custom getter that looks for _get
		get: function(key) {
			var fn = this[getFunctionName(key, "get")];
			return (fn &amp;#038;&amp;#038; fn.call(this, key)) || this[key];
		},
		set: function(key, value) {
			var fn = this[getFunctionName(key, "set")];
			if(fn) {
				fn.call(this, value);
			}
			else {
				this[key] = value;
			}
			// Returning "this" to allow chaining
			return this;
		}
	});
	
})();
&lt;/pre&gt;&lt;p&gt;The GetSet will feature two method, get and set, and will check for the presence of custom &lt;code&gt;set&lt;/code&gt; and &lt;code&gt;get&lt;/code&gt; methods;  if so, those methods are called, and if not, the property is simply set or returned.  Now let&amp;#8217;s look at a sample usage:&lt;/p&gt;&lt;pre class="js"&gt;
// Create a test class
var TestClass = new Class({
	// Implement the new class
	Implements: [GetSet],
	// The custom getter
	_getValueAttr: function() {
		return this.value / 10;
	},
	// The custom setter
	_setValueAttr: function(value) {
		this.value = value * 10;
	}
});

// Create a test class instance
var inst = new TestClass({
	value: 8
});

/*
	inst.set("value", 20);  // inst.value = 200
	inst.get("value");  // inst.value = 20
*/
&lt;/pre&gt;&lt;p&gt;In this case, we&amp;#8217;ve set custom get and set methods which will handle the class&amp;#8217; value property.  On the way in, the value is multiple by 10 and then set on the object.  On the way out, the value is divided by 10.  Of course, not the most realistic of scenarios, but this example provides a very simple illustration of how these methods can be used.&lt;/p&gt;&lt;p&gt;So what would be a more realistic scenario?  As I said above, custom setters can be very useful as an internal validator.  Both the getters and setters are valuable, however, because they also provide a way to &amp;#8220;spy&amp;#8221; on object properties and have multiple reactions to their changes.&lt;/p&gt;&lt;p&gt;&lt;a
href="http://davidwalsh.name/get-set"&gt;Custom Getters and Setters with&amp;nbsp;MooTools&lt;/a&gt; is a post from: &lt;a
href="http://davidwalsh.name"&gt;David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.&lt;/a&gt;&lt;/p&gt; &lt;img src="http://feeds.feedburner.com/~r/Bludice/~4/sABQ57DNv1o" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://davidwalsh.name/get-set#comments" thr:count="5" /><link rel="replies" type="application/atom+xml" href="http://davidwalsh.name/get-set/feed/atom" thr:count="5" /> <thr:total>5</thr:total> <feedburner:origLink>http://davidwalsh.name/get-set</feedburner:origLink></entry> <entry> <author> <name>David Walsh</name> <uri>http://davidwalsh.name</uri> </author><title type="html"><![CDATA[Upload Photos to Flickr with&#160;PHP]]></title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Bludice/~3/kgaNxIResSA/flickr-php" /> <id>http://davidwalsh.name/?p=5380</id> <updated>2012-01-31T15:20:44Z</updated> <published>2012-01-31T15:20:44Z</published> <category scheme="http://davidwalsh.name" term="PHP" /> <summary type="html"><![CDATA[I have a bit of an obsession with uploading photos to different services thanks to Instagram. Instagram&#8217;s iPhone app allows me to take photos and quickly filter them; once photo tinkering is complete, I can upload the photo to Instagram, Twitter, Facebook, and Flickr. This process made me wonder what it would take to upload [...]<p><a
href="http://davidwalsh.name/flickr-php">Upload Photos to Flickr with&nbsp;PHP</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></summary> <content type="html" xml:base="http://davidwalsh.name/flickr-php">&lt;a
href="http://davidwalsh.name/dw-content/flickr.php"&gt;&lt;img
src="http://davidwalsh.name/dw-content/flickr-logo.png" alt="Flickr PHP API" class="image" /&gt;&lt;/a&gt;&lt;p&gt;I have a bit of an obsession with uploading photos to different services thanks to Instagram.  Instagram&amp;#8217;s iPhone app allows me to take photos and quickly filter them;  once photo tinkering is complete, I can upload the photo to Instagram, Twitter, Facebook, and Flickr.  This process made me wonder what it would take to upload photos to Flickr using PHP.  This post details how you can authenticate and upload photos to Flickr using PHP with &lt;a
href="http://phpflickr.com/"&gt;phpFlickr&lt;/a&gt;.&lt;/p&gt;&lt;div
class="actions"&gt;&lt;a
href="http://davidwalsh.name/dw-content/flickr.php" class="demo"&gt;View Demo&lt;/a&gt;&lt;div
class="clear"&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2&gt;Step 1:  Flickr Application Key&amp;nbsp;Creation&lt;/h2&gt;&lt;p&gt;Just as with every other API usage, you need to go to Flickr to &lt;a
href="http://www.flickr.com/services/"&gt;sign up for an API key&lt;/a&gt;.  Put together a good description and title, but one key is that you set the callback/redirect URL to the example page (or at least I did).&lt;/p&gt;&lt;h2&gt;Step 2:  Grab&amp;nbsp;phpFlickr&lt;/h2&gt;&lt;p&gt;&lt;a
href="http://phpflickr.com/"&gt;phpFlickr&lt;/a&gt; is a suggested PHP library by Flickr.  The library is not perfect (there seems to be a few long-standing redirect issues) but it does well as an all-purpose Flickr API interface.&lt;/p&gt;&lt;h2&gt;Step 3:  Configuring and&amp;nbsp;Authentication&lt;/h2&gt;&lt;p&gt;It&amp;#8217;s easiest to understand the process by looking at the code:&lt;/p&gt;&lt;pre class="php"&gt;
// Start the session since phpFlickr uses it but does not start it itself
session_start();

// Require the phpFlickr API
require_once('phpFlickr-3.1/phpFlickr.php');

// Create new phpFlickr object: new phpFlickr('[API Key]','[API Secret]')
$flickr = new phpFlickr('[API KEY]','[API SECRET]', true);

// Authenticate;  need the "IF" statement or an infinite redirect will occur
if(empty($_GET['frob'])) {
	$flickr-&gt;auth('write'); // redirects if none; write access to upload a photo
}
else {
	// Get the FROB token, refresh the page;  without a refresh, there will be "Invalid FROB" error
	$flickr-&gt;auth_getToken($_GET['frob']);
	header('Location: flickr.php');
	exit();
}
&lt;/pre&gt;&lt;p&gt;After starting the session and requiring the phpFlickr API library, an instance of &lt;code&gt;phpFlickr&lt;/code&gt; needs to be created, providing it the API key and API secret.  With the instance created, an &lt;code&gt;if&lt;/code&gt; statement will be employed to react to a &lt;code&gt;frob&lt;/code&gt; parameter from Flickr.  If no &lt;code&gt;frob&lt;/code&gt; is provided, the &lt;code&gt;auth&lt;/code&gt; method should be called, which either confirms authentication or redirects the user to the Flickr site for sign in.  If a &lt;code&gt;frob&lt;/code&gt; &lt;em&gt;is&lt;/em&gt; provided, the authentication token is set and the page needs to be refreshed &lt;em&gt;(I&amp;#8217;m not sure why the redirect needs to take place, but it was the only way to ensure authentication worked gracefully)&lt;/em&gt;.&lt;/p&gt;&lt;h2&gt;Step 4:  Uploading a&amp;nbsp;File&lt;/h2&gt;&lt;p&gt;Uploading an image to Flickr is actually much easier with phpFlickr than authenticating.  Uploading a file is as easy as one function call:&lt;/p&gt;&lt;pre class="php"&gt;
// Send an image sync_upload(photo, title, desc, tags)
// The returned value is an ID which represents the photo
$result = $flickr-&gt;sync_upload('logo.png', $_POST['title'], $_POST['description'], 'david walsh, php, mootools, dojo, javascript, css');
&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;sync_upload&lt;/code&gt; method allows many parameters, but the image, title, description, and tags are the most prominent.  There is also an &lt;code&gt;async_upload&lt;/code&gt; with may also be used.&lt;/p&gt;&lt;p&gt;phpFlickr also allows simple read access so that you may create a slideshow of photos, tags, etc., so don&amp;#8217;t think that phpFlickr is just for uploading!&lt;/p&gt;&lt;div
class="actions"&gt;&lt;a
href="http://davidwalsh.name/dw-content/flickr.php" class="demo"&gt;View Demo&lt;/a&gt;&lt;div
class="clear"&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;My first attempt to create an independent PHP/Flickr script failed due to the need for OpenAuth.  phpFlickr does a great job in managing the entire process, and the documentation is decent for getting started.  I ran into a few problems with &amp;#8220;too much redirection&amp;#8221; (fixed by the &amp;#8220;if&amp;#8221; statement I added) and an &amp;#8220;invalid frob&amp;#8221; error (cured by the additional redirect) errors but beside those, phpFlickr is the right choice!&lt;/p&gt;&lt;p&gt;&lt;a
href="http://davidwalsh.name/flickr-php"&gt;Upload Photos to Flickr with&amp;nbsp;PHP&lt;/a&gt; is a post from: &lt;a
href="http://davidwalsh.name"&gt;David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.&lt;/a&gt;&lt;/p&gt; &lt;img src="http://feeds.feedburner.com/~r/Bludice/~4/kgaNxIResSA" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://davidwalsh.name/flickr-php#comments" thr:count="2" /><link rel="replies" type="application/atom+xml" href="http://davidwalsh.name/flickr-php/feed/atom" thr:count="2" /> <thr:total>2</thr:total> <feedburner:origLink>http://davidwalsh.name/flickr-php</feedburner:origLink></entry> <entry> <author> <name>David Walsh</name> <uri>http://davidwalsh.name</uri> </author><title type="html"><![CDATA[Image Data URIs with&#160;PHP]]></title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Bludice/~3/tf9F-YxLSas/data-uri-php" /> <id>http://davidwalsh.name/?p=5377</id> <updated>2012-01-30T16:42:40Z</updated> <published>2012-01-30T16:42:40Z</published> <category scheme="http://davidwalsh.name" term="Markup" /><category scheme="http://davidwalsh.name" term="PHP" /> <summary type="html"><![CDATA[If you troll page markup like me, you&#8217;ve no doubt seen the use of data URI&#8217;s within image src attributes. Instead of providing a traditional address to the image, the image file data is base64-encoded and stuffed within the src attribute. Doing so saves a network request for each image, and if you&#8217;re the paranoid [...]<p><a
href="http://davidwalsh.name/data-uri-php">Image Data URIs with&nbsp;PHP</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></summary> <content type="html" xml:base="http://davidwalsh.name/data-uri-php">&lt;p&gt;If you troll page markup like me, you&amp;#8217;ve no doubt seen the use of data URI&amp;#8217;s within image src attributes.  Instead of providing a traditional address to the image, the image file data is base64-encoded and stuffed within the src attribute.  Doing so saves a network request for each image, and if you&amp;#8217;re the paranoid type, can prevent exposure of directory paths.  Since creating data URIs is incredibly easy, let me show you how to do it with PHP.&lt;/p&gt;&lt;div
class="actions"&gt;&lt;a
href="http://davidwalsh.name/dw-content/data-uri-php.php" class="demo"&gt;View Demo&lt;/a&gt;&lt;div
class="clear"&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2&gt;The&amp;nbsp;PHP&lt;/h2&gt;&lt;p&gt;Start by reading in the image using file_get_contents (or any other PHP method you&amp;#8217;d like), then convert the image to base64 using base64_encode:&lt;/p&gt;&lt;pre class="php"&gt;
// A few settings
$image = 'cricci.jpg';

// Read image path, convert to base64 encoding
$imageData = base64_encode(file_get_contents($image));

// Format the image SRC:  data:{mime};base64,{data};
$src = 'data: '.mime_content_type($image).';base64,'.$imageData;

// Echo out a sample image
echo '&lt;img src="',$src,'" /&gt;';
&lt;/pre&gt;&lt;p&gt;With the image data in base64 format, the last step is placing that data within the data URI format, including the image&amp;#8217;s MIME type.  This would make for a good function:&lt;/p&gt;&lt;pre class="php"&gt;
function getDataURI($image, $mime = '') {
	return 'data: '.(function_exists('mime_content_type') ? mime_content_type($image) : $mime).';base64,'.base64_encode(file_get_contents($image));
}
&lt;/pre&gt;&lt;div
class="actions"&gt;&lt;a
href="http://davidwalsh.name/dw-content/data-uri-php.php" class="demo"&gt;View Demo&lt;/a&gt;&lt;div
class="clear"&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The thing to remember is that IE7 and lower don&amp;#8217;t support data URIs, so keep that in mind if you&amp;#8217;re considering switching from image paths to data URIs!&lt;/p&gt;&lt;p&gt;&lt;a
href="http://davidwalsh.name/data-uri-php"&gt;Image Data URIs with&amp;nbsp;PHP&lt;/a&gt; is a post from: &lt;a
href="http://davidwalsh.name"&gt;David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.&lt;/a&gt;&lt;/p&gt; &lt;img src="http://feeds.feedburner.com/~r/Bludice/~4/tf9F-YxLSas" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://davidwalsh.name/data-uri-php#comments" thr:count="14" /><link rel="replies" type="application/atom+xml" href="http://davidwalsh.name/data-uri-php/feed/atom" thr:count="14" /> <thr:total>14</thr:total> <feedburner:origLink>http://davidwalsh.name/data-uri-php</feedburner:origLink></entry> <entry> <author> <name>David Walsh</name> <uri>http://davidwalsh.name</uri> </author><title type="html"><![CDATA[Images, max-width, and&#160;Mobile]]></title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Bludice/~3/CiLex1n451o/image-max-width" /> <id>http://davidwalsh.name/?p=5375</id> <updated>2012-01-24T14:27:04Z</updated> <published>2012-01-24T14:27:04Z</published> <category scheme="http://davidwalsh.name" term="Mobile" /> <summary type="html"><![CDATA[Many web developers prefer to keep as much control over the applications, especially when it comes down to how the application displays on a mobile device. I&#8217;ll often see developers prevent zooming in mobile browsers, allowing them to manage display size: A useful snippet for any mobile developer. Another useful snippet, this one a small [...]<p><a
href="http://davidwalsh.name/image-max-width">Images, max-width, and&nbsp;Mobile</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></summary> <content type="html" xml:base="http://davidwalsh.name/image-max-width">&lt;p&gt;Many web developers prefer to keep as much control over the applications, especially when it comes down to how the application displays on a mobile device.  I&amp;#8217;ll often see developers &lt;a
href="http://davidwalsh.name/zoom-mobile-browsers"&gt;prevent zooming in mobile browsers&lt;/a&gt;, allowing them to manage display size:&lt;/p&gt;&lt;pre class="html"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/&gt;
&lt;/pre&gt;&lt;p&gt;A useful snippet for any mobile developer.  Another useful snippet, this one a small CSS helper, ensures that your images don&amp;#8217;t exceed the fixed width on mobile devices:&lt;/p&gt;&lt;pre class="css"&gt;
/* iphone */
@media only screen and (min-device-width : 320px) and (max-device-width : 480px) {
	img { max-width: 100%; }
}

/* ipad */
@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) {
	img { max-width: 100%; }
}
&lt;/pre&gt;&lt;p&gt;By setting the max-width property of the image, the image cannot bleed to the right of the page, regardless of its size.  You can add that same max-width property to images when it comes time for print too:&lt;/p&gt;&lt;pre class="css"&gt;
@media print {
	img { max-width: 100%; }
}
&lt;/pre&gt;&lt;p&gt;Keep this snippet handy for your current and future mobile web and print endeavors;  it&amp;#8217;s just another CSS directive to show your mobile and print users that you care!&lt;/p&gt;&lt;p&gt;&lt;a
href="http://davidwalsh.name/image-max-width"&gt;Images, max-width, and&amp;nbsp;Mobile&lt;/a&gt; is a post from: &lt;a
href="http://davidwalsh.name"&gt;David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.&lt;/a&gt;&lt;/p&gt; &lt;img src="http://feeds.feedburner.com/~r/Bludice/~4/CiLex1n451o" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://davidwalsh.name/image-max-width#comments" thr:count="9" /><link rel="replies" type="application/atom+xml" href="http://davidwalsh.name/image-max-width/feed/atom" thr:count="9" /> <thr:total>9</thr:total> <feedburner:origLink>http://davidwalsh.name/image-max-width</feedburner:origLink></entry> <entry> <author> <name>David Walsh</name> <uri>http://davidwalsh.name</uri> </author><title type="html"><![CDATA[Amazing 3D Animation with&#160;three.js]]></title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Bludice/~3/J81-7lts4Zk/threejs" /> <id>http://davidwalsh.name/?p=5373</id> <updated>2012-01-23T18:47:08Z</updated> <published>2012-01-23T15:49:14Z</published> <category scheme="http://davidwalsh.name" term="JavaScript" /> <summary type="html"><![CDATA[The hottest topic for client-side developers seems to be animation. Whether it be from CSS transformations, keyframe animations, or animations managed with JavaScript APIs, it seems like each day we come across another demo that shows us how can we&#8217;ve come outside of Flash. The latest shocker comes from the three.js project. The creators of [...]<p><a
href="http://davidwalsh.name/threejs">Amazing 3D Animation with&nbsp;three.js</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></summary> <content type="html" xml:base="http://davidwalsh.name/threejs">&lt;p&gt;The hottest topic for client-side developers seems to be animation. Whether it be from CSS transformations, keyframe animations, or animations managed with JavaScript APIs, it seems like each day we come across another demo that shows us how can we&amp;#8217;ve come outside of Flash. The latest shocker comes from the three.js project. The creators of three.js explains the project best:&lt;/p&gt;&lt;blockquote&gt;The aim of the project is to create a lightweight 3D engine with a very low level of complexity; in other words, for dummies. The engine can render using &amp;lt;canvas&amp;gt;, &amp;lt;svg&amp;gt; and WebGL.&lt;/blockquote&gt;&lt;p&gt;The three.js engine allows developers to create mindblowing 2D and 3D animations with Canvas and WebGL, from &lt;em
title="Since when were creating cubes basic?  Since three.js!"&gt;basic&lt;/em&gt; cubes to advanced animations so smooth you&amp;#8217;ll wet yourself.&lt;/p&gt;&lt;h2&gt;Favorite three.js&amp;nbsp;Demos&lt;/h2&gt;&lt;p&gt;The three.js repository comes with several dozens examples of the engine&amp;#8217;s capabilities. Here are a few of my favorites:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a
href="http://mrdoob.github.com/three.js/examples/webgl_trails.html" rel="nofollow"&gt;http://mrdoob.github.com/three.js/examples/webgl_trails.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a
href="http://mrdoob.github.com/three.js/examples/webgl_terrain_dynamic.html" rel="nofollow"&gt;http://mrdoob.github.com/three.js/examples/webgl_terrain_dynamic.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a
href="http://mrdoob.github.com/three.js/examples/webgl_shading_physical.html" rel="nofollow"&gt;http://mrdoob.github.com/three.js/examples/webgl_shading_physical.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a
href="http://mrdoob.github.com/three.js/examples/webgl_materials_cubemap_refraction.html" rel="nofollow"&gt;http://mrdoob.github.com/three.js/examples/webgl_materials_cubemap_refraction.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a
href="http://mrdoob.github.com/three.js/examples/webgl_animation_skinning.html" rel="nofollow"&gt;http://mrdoob.github.com/three.js/examples/webgl_animation_skinning.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a
href="http://mrdoob.github.com/three.js/examples/webgl_geometries.html" rel="nofollow"&gt;http://mrdoob.github.com/three.js/examples/webgl_geometries.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;You can see all of the examples here: &lt;a
href="http://mrdoob.github.com/three.js/"&gt;http://mrdoob.github.com/three.js/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Mind status: blown. three.js is an incredible project that allows developers to achieve amazing animations efficiently and without Flash. Mr.Doob: take a bow &amp;#8212; three.js is ahead of its time.&lt;/p&gt;&lt;p&gt;&lt;a
href="http://davidwalsh.name/threejs"&gt;Amazing 3D Animation with&amp;nbsp;three.js&lt;/a&gt; is a post from: &lt;a
href="http://davidwalsh.name"&gt;David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.&lt;/a&gt;&lt;/p&gt; &lt;img src="http://feeds.feedburner.com/~r/Bludice/~4/J81-7lts4Zk" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://davidwalsh.name/threejs#comments" thr:count="5" /><link rel="replies" type="application/atom+xml" href="http://davidwalsh.name/threejs/feed/atom" thr:count="5" /> <thr:total>5</thr:total> <feedburner:origLink>http://davidwalsh.name/threejs</feedburner:origLink></entry> <entry> <author> <name>David Walsh</name> <uri>http://davidwalsh.name</uri> </author><title type="html"><![CDATA[MooTools Mobile: It&#8217;s&#160;Touching!]]></title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Bludice/~3/hfekQSxaOcE/mootools-mobile-touching" /> <id>http://davidwalsh.name/?p=5372</id> <updated>2012-01-20T00:01:34Z</updated> <published>2012-01-19T15:33:42Z</published> <category scheme="http://davidwalsh.name" term="Mobile" /><category scheme="http://davidwalsh.name" term="MooTools" /> <summary type="html"><![CDATA[When the community asked the MooTools team to add basic mobile event listening to MooTools&#8217; Event class, we listened; today MooTools supports all touch and gesture events. What if we want more detailed mobile event listeners though, like swipe with direction, pinch, or touchhold events? That&#8217;s where Christoph Pojer&#8217;s excellent MooTools Mobile comes in. MooTools [...]<p><a
href="http://davidwalsh.name/mootools-mobile-touching">MooTools Mobile: It&#8217;s&nbsp;Touching!</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></summary> <content type="html" xml:base="http://davidwalsh.name/mootools-mobile-touching">&lt;a
href="https://github.com/cpojer/mootools-mobile"&gt;&lt;img
src="http://davidwalsh.name/dw-content/ipads.png" alt="iPad, iPhone, iOS " class="image" /&gt;&lt;/a&gt;&lt;p&gt;When the community asked the MooTools team to add basic mobile event listening to MooTools&amp;#8217; Event class, we listened;  today &lt;a
href="http://davidwalsh.name/mootools-touch"&gt;MooTools supports all touch and gesture events&lt;/a&gt;.  What if we want more detailed mobile event listeners though, like swipe with direction, pinch, or touchhold events?  That&amp;#8217;s where Christoph Pojer&amp;#8217;s excellent &lt;a
href="https://github.com/cpojer/mootools-mobile" rel="nofollow"&gt;MooTools Mobile&lt;/a&gt; comes in.  MooTools Mobile isn&amp;#8217;t a full mobile framework, but rather a set of utilities to make catering to mobile a bit more&amp;#8230;touching.  Let&amp;#8217;s have a look at the resources provided by MooTools Mobile!&lt;/p&gt;&lt;div
class="actions"&gt;&lt;a
href="https://github.com/cpojer/mootools-mobile" class="demo"&gt;View Demo&lt;/a&gt;&lt;div
class="clear"&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;As you&amp;#8217;ve come to expect from members of the MooTools team, Christoph&amp;#8217;s new Touch-based event classes are compact and modular.  Each class will be found within the Touch path.&lt;/p&gt;&lt;h2&gt;Swipe&lt;/h2&gt;&lt;p&gt;By using the &lt;code&gt;Touch/Swipe&lt;/code&gt; resource, you can attain the direction of the swipe, as well as the start and end coordinates:&lt;/p&gt;&lt;pre class="js"&gt;
// Add the swipe event listener
anyElement.addEvent("swipe", function(event){
    event.direction // "left" or "right"
    event.start // {x: Number, y: Number} Swipe start position
    event.end // {x: Number, y: Number} Swipe end position
});

// Configure minimal swipe distance and vertical swipe preferences
anyElement.store("swipe:distance", 30); // Default: 50
anyElement.store("swipe:cancelVertical", true); // Default: false
&lt;/pre&gt;&lt;p&gt;As you can see above, you may also configure minimum swipe distances and cancellation of vertical swipes.&lt;/p&gt;&lt;h2&gt;Pinch&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;Touch/Pinch&lt;/code&gt; resource allows you to listen for pinches, as well as configure the pinch threshold:&lt;/p&gt;&lt;pre class="js"&gt;
// Add a pinch event to anyElement
anyElement.addEvent("pinch", function(event){
    event.pinch // "in" or "out"
});

// Store a custom threshold
anyElement.store("pinch:threshold", 0.3); // Default: 0.5; Amount of scaling to be done to fire the pinch event
&lt;/pre&gt;&lt;p&gt;The pinch threshold is stored within elements themselves so you may customize to fit any element.&lt;/p&gt;&lt;h2&gt;Touchhold&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;touchhold&lt;/code&gt; event is used throughout all mobile operating systems, so why not implement touchhold within the browser?&lt;/p&gt;&lt;pre class="js"&gt;
//  Listen for touchhold on anyElement
anyElement.addEvent("touchhold", function(event){
    // Event fires
});
&lt;/pre&gt;&lt;p&gt;Any element may store an optional delay before the touchhold event fires:&lt;/p&gt;&lt;pre class="js"&gt;
anyElement.store("touchhold:delay", 1000); // Default: 750
&lt;/pre&gt;&lt;p&gt;Maximum versatility with minimal code!&lt;/p&gt;&lt;h2&gt;Browser&amp;nbsp;Enhancements!&lt;/h2&gt;&lt;p&gt;Besides providing these custom touch events, MooTools Mobile provides additional information within the &lt;code&gt;Browser&lt;/code&gt; object via a &lt;code&gt;Device&lt;/code&gt; property:&lt;/p&gt;&lt;pre class="js"&gt;
Browser.Device // Object added to Browser
	Browser.Device.name // ipad / iphone / ipod OR other
	Browser.Device.ipad // true if on ipad
	Browser.Device.iphone // true if on iphone
	Browser.Device.ipod // true if on ipod
	Browser.hasHighResolution // true on iPhone 4
	Browser.isMobile // True on any platform that is not Windows / Linux / Mac
&lt;/pre&gt;&lt;p&gt;These properties give you further insight as to the device capabilities!&lt;/p&gt;&lt;div
class="actions"&gt;&lt;a
href="https://github.com/cpojer/mootools-mobile" class="demo"&gt;View Demo&lt;/a&gt;&lt;div
class="clear"&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;With mobile development booming for the foreseeable future, it&amp;#8217;s important to make sure your site is as mobile-friendly as possible.  Christoph&amp;#8217;s mobile contribution is just the tiny helper developers may need to make their MooTools-powered web apps more mobile device-friendly. &lt;strong&gt;MooTools (Mobile) FTW&lt;/strong&gt;!&lt;/p&gt;&lt;p&gt;&lt;a
href="http://davidwalsh.name/mootools-mobile-touching"&gt;MooTools Mobile: It&amp;#8217;s&amp;nbsp;Touching!&lt;/a&gt; is a post from: &lt;a
href="http://davidwalsh.name"&gt;David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.&lt;/a&gt;&lt;/p&gt; &lt;img src="http://feeds.feedburner.com/~r/Bludice/~4/hfekQSxaOcE" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://davidwalsh.name/mootools-mobile-touching#comments" thr:count="4" /><link rel="replies" type="application/atom+xml" href="http://davidwalsh.name/mootools-mobile-touching/feed/atom" thr:count="4" /> <thr:total>4</thr:total> <feedburner:origLink>http://davidwalsh.name/mootools-mobile-touching</feedburner:origLink></entry> <entry> <author> <name>David Walsh</name> <uri>http://davidwalsh.name</uri> </author><title type="html"><![CDATA[Interesting -webkit CSS&#160;Properties]]></title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Bludice/~3/yEqw2Ybdnn8/webkit-css" /> <id>http://davidwalsh.name/?p=5364</id> <updated>2012-01-10T15:33:52Z</updated> <published>2012-01-10T15:33:52Z</published> <category scheme="http://davidwalsh.name" term="Browsers" /><category scheme="http://davidwalsh.name" term="CSS" /> <summary type="html"><![CDATA[A few weeks back I touched on a handful of Mozilla-specific CSS properties that I found to be interesting. This week I&#8217;d like to share a few WebKit-specific CSS properties that make me all tingly inside. -webkit-touch-callout The -webkit-touch-callout property allows you to dictate what does or doesn&#8217;t happen when a user taps and holds [...]<p><a
href="http://davidwalsh.name/webkit-css">Interesting -webkit CSS&nbsp;Properties</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></summary> <content type="html" xml:base="http://davidwalsh.name/webkit-css">&lt;a
href="http://davidwalsh.name/webkit-appearance"&gt;&lt;img
src="http://davidwalsh.name/dw-content/browsers-webnightly.png" alt="WebKit CSS" class="image" /&gt;&lt;/a&gt;&lt;p&gt;A few weeks back I touched on a handful of &lt;a
href="http://davidwalsh.name/moz-css"&gt;Mozilla-specific CSS properties&lt;/a&gt; that I found to be interesting.  This week I&amp;#8217;d like to share a few WebKit-specific CSS properties that make me all tingly inside.&lt;/p&gt;&lt;h2&gt;&lt;a
href="http://css-infos.net/property/-webkit-touch-callout"&amp;nbsp;rel="nofollow"&gt;-webkit-touch-callout&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;-webkit-touch-callout&lt;/code&gt; property allows you to dictate what does or doesn&amp;#8217;t happen when a user taps and holds on a link on iOS.  The default value is &lt;code&gt;default&lt;/code&gt; and tap-holding on a link brings up the link bubble dialog;  by using the value of &lt;code&gt;none&lt;/code&gt;, that bubble never comes up.&lt;/p&gt;&lt;pre class="css"&gt;
a.js-only {
	-webkit-touch-callout: none;
}
&lt;/pre&gt;&lt;p&gt;This would be very useful on apps that use A elements which aren&amp;#8217;t traditional links, but simply trigger AJAX / JavaScript functions.&lt;/p&gt;&lt;h2&gt;&lt;a
href="http://css-infos.net/property/-webkit-user-drag"&amp;nbsp;rel="nofollow"&gt;-webkit-user-drag&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;-webkit-user-drag&lt;/code&gt; property specifies that an entire element should be draggable instead of its contents:&lt;/p&gt;&lt;pre class="css"&gt;
/* no dragging at all */
.content p.noDrag {
	-webkit-user-drag: none;
}

/* drags entire element, not the text/selection */
.sidebar div.elDrag {
	-webkit-user-drag: element;
}
&lt;/pre&gt;&lt;h2&gt;&lt;a&amp;nbsp;href="http://davidwalsh.name/webkit-appearance"&gt;-webkit-appearance&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Using the &lt;code&gt;-webkit-appearance&lt;/code&gt; property, you can make a SPAN tag look like a radio button, or textarea, or SELECT dropdown, or any of the other 50 supported properties.&lt;/p&gt;&lt;pre class="css"&gt;
span.lookLikeRadio {
	-webkit-appearance: radio;
}

span.lookLikeTextarea {
	-webkit-appearance: textarea;
}

span.lookLikeScrollbar {
	-webkit-appearance: scrollbartrack-horizontal;
}
&lt;/pre&gt;&lt;p&gt;Wanna see this one in action?  Check out my post: &lt;a
href="http://davidwalsh.name/webkit-appearance"&gt;WebKit-Specific Style: -webkit-appearance&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;&lt;a
href="http://css-infos.net/property/-webkit-text-security"&amp;nbsp;rel="nofollow"&gt;-webkit-text-security&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Who knew you could customize the character which hides password characters?&lt;/p&gt;&lt;pre class="css"&gt;
input[type="password"] {
	-webkit-text-security: square;
}
&lt;/pre&gt;&lt;p&gt;Not necessarily useful but interesting that WebKit gives us this ability.&lt;/p&gt;&lt;h2&gt;&lt;a
href="http://css-infos.net/property/-webkit-user-select"&amp;nbsp;rel="nofollow"&gt;-webkit-user-select&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;-webkit-user-select&lt;/code&gt; property allows us to prevent users from selecting text within a given element:&lt;/p&gt;&lt;pre class="css"&gt;
div {
	-webkit-user-select: none;
}
&lt;/pre&gt;&lt;p&gt;Preventing selection within a node can be helpful when on nodes which you prefer only be clicked.&lt;/p&gt;&lt;p&gt;I disliked browser-specific functionality when I was younger because I had the wrong mentality;  you use them as &lt;em&gt;enhancers&lt;/em&gt;, not for core functionality.  Have a favorite WebKit-specific CSS property?  Share it!&lt;/p&gt;&lt;p&gt;&lt;a
href="http://davidwalsh.name/webkit-css"&gt;Interesting -webkit CSS&amp;nbsp;Properties&lt;/a&gt; is a post from: &lt;a
href="http://davidwalsh.name"&gt;David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.&lt;/a&gt;&lt;/p&gt; &lt;img src="http://feeds.feedburner.com/~r/Bludice/~4/yEqw2Ybdnn8" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://davidwalsh.name/webkit-css#comments" thr:count="2" /><link rel="replies" type="application/atom+xml" href="http://davidwalsh.name/webkit-css/feed/atom" thr:count="2" /> <thr:total>2</thr:total> <feedburner:origLink>http://davidwalsh.name/webkit-css</feedburner:origLink></entry> <entry> <author> <name>David Walsh</name> <uri>http://davidwalsh.name</uri> </author><title type="html"><![CDATA[JavaScript Enlightenment by Cody&#160;Lindley]]></title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Bludice/~3/fFAN-IemB-Y/javascript-enlightenment" /> <id>http://davidwalsh.name/?p=5366</id> <updated>2012-01-10T01:23:56Z</updated> <published>2012-01-09T16:02:35Z</published> <category scheme="http://davidwalsh.name" term="Books" /><category scheme="http://davidwalsh.name" term="JavaScript" /> <summary type="html"><![CDATA[JavaScript Guru Douglas Crockford famously said &#8220;JavaScript is the only language people feel like they don&#8217;t need to learn to use.&#8221; A quote that will surely provide a laugh, but it&#8217;s funny because it&#8217;s true. What furthers this sentiment is that JavaScript frameworks like jQuery have turned JavaScript into a language different than what it [...]<p><a
href="http://davidwalsh.name/javascript-enlightenment">JavaScript Enlightenment by Cody&nbsp;Lindley</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></summary> <content type="html" xml:base="http://davidwalsh.name/javascript-enlightenment">&lt;p&gt;JavaScript Guru Douglas Crockford famously said &amp;#8220;JavaScript is the only language people feel like they don&amp;#8217;t need to learn to use.&amp;#8221; A quote that will surely provide a laugh, but it&amp;#8217;s funny because it&amp;#8217;s true. What furthers this sentiment is that JavaScript frameworks like jQuery have turned JavaScript into a language different than what it truly is, and has made client-side coding so easy that there&amp;#8217;s sometimes no need to really &lt;em&gt;learn&lt;/em&gt; JavaScript. Anyone worth their salt, however, knows that in order to expertly and efficiently use any tool, you have to start with the basics.&lt;p&gt;&lt;p&gt;That&amp;#8217;s where &lt;a
href="http://jqueryenlightenment.com/" rel="nofollow"&gt;&lt;em&gt;JavaScript Enlightenment&lt;/em&gt;&lt;/a&gt; comes in. &lt;em&gt;JavaScript Enlightenment&lt;/em&gt; is an outstanding book by Cody Lindley, one of several members of the jQuery team. I&amp;#8217;ll let book&amp;#8217;s description speak for itself:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;This book is not about JavaScript design patterns or implementing an object-oriented paradigm with JavaScript code. It was not written to distinguish the good features of the JavaScript language from the bad. It is not meant to be a complete reference guide. It is not targeted at people new to programming or those completely new to JavaScript. Nor is this a cookbook of JavaScript recipes. Those books have been written. It was my intention to write a book to give the reader an accurate JavaScript worldview through an examination of native JavaScript objects and supporting nuances: complex values, primitive values, scope, inheritance, the head object, etc. I intend this book to be a short and digestible summary of the ECMA-262, Edition 3 specification, focused on the nature of objects in JavaScript.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;In short, &lt;em&gt;JavaScript Enlightment&lt;/em&gt; takes JavaScript back to its basics. The chapter summary is really drives that point home:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Constructing Objects&lt;/li&gt;&lt;li&gt;Working with Objects and Properties&lt;/li&gt;&lt;li&gt;Object()&lt;/li&gt;&lt;li&gt;Function()&lt;/li&gt;&lt;li&gt;The Head/Global Object&lt;/li&gt;&lt;li&gt;The this Keyword&lt;/li&gt;&lt;li&gt;Scope and Closures&lt;/li&gt;&lt;li&gt;Prototype Property&lt;/li&gt;&lt;li&gt;Array()&lt;/li&gt;&lt;li&gt;String()&lt;/li&gt;&lt;li&gt;Number()&lt;/li&gt;&lt;li&gt;Boolean()&lt;/li&gt;&lt;li&gt;Null&lt;/li&gt;&lt;li&gt;Undefined&lt;/li&gt;&lt;li&gt;Math Function&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;There are a couple of things I really enjoyed about Cody&amp;#8217;s writing style:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Many authors write in a way to reinforce that they&amp;#8217;re the smartest guy in the room. What people like them don&amp;#8217;t understand is that eager-to-learn developers have already bought the book: they trust that you&amp;#8217;re the expert, so you don&amp;#8217;t have to use advanced verbiage to look intelligent. Cody skips that ego-centric exercise, explain JavaScript concepts in Leyman&amp;#8217;s terms.&lt;/li&gt;&lt;li&gt;Each section covers one JavaScript object/concept, so the book is very focused. Too often development books bleed into and out of topics without true explanation.&lt;/li&gt;&lt;li&gt;Lindley&amp;#8217;s book is packed full of code examples; if you&amp;#8217;re anything like me, code examples tell you as much if not more than plan text. Every person has their own style of leaning, but there&amp;#8217;s nothing like a solid code example you can play around with.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The books itself, when it comes to topics covered, is great for beginners and intermediates a like; there&amp;#8217;s a lot of learning and reinforcing of core JavaScript concepts. Each code snippet provides a link to a working version of the code, which comes in handy if you want to quickly tinker with such code. Lastly, there&amp;#8217;s plenty of personality in Lindley&amp;#8217;s book; it&amp;#8217;s not simply a reference to flick through &amp;#8212; designers and developers will enjoy reading &lt;em&gt;JavaScript Enlightenment&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Cody Lindley&amp;#8217;s &lt;em&gt;JavaScript Enlightenment&lt;/em&gt; is an essential resource for any designer or developer looking to to understand JavaScript at its core, regardless of skill level or JavaScript framework. Lindley&amp;#8217;s ability to explain key JavaScript concepts with realistic, useful code examples is what really makes &lt;em&gt;JavaScript Enlightenment&lt;/em&gt; shine. Don&amp;#8217;t be a slave to your JavaScript framework, because copy&amp;#8217;n'paste is no way to go through a development life! Get enlightened by &lt;em&gt;JavaScript Enlightenment&lt;/em&gt;!&lt;/p&gt;&lt;p&gt;&lt;a
href="http://davidwalsh.name/javascript-enlightenment"&gt;JavaScript Enlightenment by Cody&amp;nbsp;Lindley&lt;/a&gt; is a post from: &lt;a
href="http://davidwalsh.name"&gt;David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.&lt;/a&gt;&lt;/p&gt; &lt;img src="http://feeds.feedburner.com/~r/Bludice/~4/fFAN-IemB-Y" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://davidwalsh.name/javascript-enlightenment#comments" thr:count="14" /><link rel="replies" type="application/atom+xml" href="http://davidwalsh.name/javascript-enlightenment/feed/atom" thr:count="14" /> <thr:total>14</thr:total> <feedburner:origLink>http://davidwalsh.name/javascript-enlightenment</feedburner:origLink></entry> <entry> <author> <name>David Walsh</name> <uri>http://davidwalsh.name</uri> </author><title type="html"><![CDATA[Using&#160;dojo/aspect]]></title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Bludice/~3/2imy-v--1ts/dojo-aspect" /> <id>http://davidwalsh.name/?p=5360</id> <updated>2012-01-05T18:34:47Z</updated> <published>2012-01-05T16:23:51Z</published> <category scheme="http://davidwalsh.name" term="Dojo" /> <summary type="html"><![CDATA[Simply put: the Dojo Toolkit has tools that other JavaScript toolkits don&#8217;t. One of those tools includes Dojo 1.7&#8242;s aspect, a module that allows developers to react to function calls by executing another function before or after that call. This aspect resource originates from Dojo&#8217;s awesome connect mechanism. Let&#8217;s check out how it works! aspect&#160;Basics [...]<p><a
href="http://davidwalsh.name/dojo-aspect">Using&nbsp;dojo/aspect</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></summary> <content type="html" xml:base="http://davidwalsh.name/dojo-aspect">&lt;p&gt;Simply put:  the Dojo Toolkit has tools that other JavaScript toolkits don&amp;#8217;t.  One of those tools includes Dojo 1.7&amp;#8242;s &lt;code&gt;aspect&lt;/code&gt;, a module that allows developers to react to function calls by executing another function before or after that call.  This aspect resource originates from &lt;a
href="http://davidwalsh.name/dojo-connect"&gt;Dojo&amp;#8217;s awesome connect mechanism&lt;/a&gt;. Let&amp;#8217;s check out how it works!&lt;/p&gt;&lt;h2&gt;aspect&amp;nbsp;Basics&lt;/h2&gt;&lt;p&gt;The idea and value of aspect is that it allows you to be notified of function calls without needing to modify the original function&amp;#8217;s contents.  You also don&amp;#8217;t need to implement pub/sub to know when methods are called.  The basic setup looks like:&lt;/p&gt;&lt;pre class="js"&gt;
// Load the dojo/aspect dependency
require(["dojo/aspect"], function(aspect) {
	
	// Create an object and method to spy on
	var original = {
		someMethod: function(arg1, arg2) {
			console.warn("original.someMethod called: ", arg1, arg2);
			return "Hello " + arg1 + " " + arg2;
		}
	};
	
	// Use aspect.after ("before" also available)
	aspect.after(original, "someMethod", function(arg1, arg2) {
		console.warn("After method called with arguments: ", arg1, arg2);
	}, true);
	
	// ...and a while later, call the original method
	original.someMethod("David", "Walsh");
	
});
&lt;/pre&gt;&lt;p&gt;The first argument is the origin object, the second argument is the method to listen in on, and the third is the function to fire before or after, depending on which aspect method you call.&lt;/p&gt;&lt;h2&gt;aspect.before&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;before&lt;/code&gt; method will fire before the originally called method fires:&lt;/p&gt;&lt;pre class="js"&gt;
// Fire a function before the original
aspect.before(original, "someMethod", function(arg1, arg2) {
	console.warn("aspect.before: ", arg1, arg2);
});

// "aspect.before: ", David, Walsh
// "original.someMethod called:", David, Walsh
&lt;/pre&gt;&lt;p&gt;Since this method is fired before the original function call, the arguments passed to the original method are automatically received by the aspect method.&lt;/p&gt;&lt;h2&gt;aspect.after&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;after&lt;/code&gt; method fires after the original method fires, and accepts an extra parameter called &lt;code&gt;receiveArguments&lt;/code&gt;, where you may direct the second method to receive the original method&amp;#8217;s arguments, or the return value of the original method.&lt;/p&gt;&lt;h3&gt;receiveArguments =&amp;nbsp;true&lt;/h3&gt;&lt;p&gt;Passing the receiveArguments as true will pass the two arguments from the original function call to the &lt;code&gt;aspect&lt;/code&gt; method:&lt;/p&gt;&lt;pre class="js"&gt;
// First scenario:  aspect.after that accepts the same arguments as the origin function
// because the fourth argument is passed as "true"
aspect.after(original, "someMethod", function(arg1, arg2) {
	console.warn("After method called with arguments: ", arg1, arg2);
}, true);

// Call the original method, see what happens!
original.someMethod("David", "Walsh");

// "original.someMethod called:", David, Walsh
// "aspect.after: ", David, Walsh
&lt;/pre&gt;&lt;p&gt;Removing the last argument instead allows the &lt;code&gt;aspect&lt;/code&gt; method to receive the return value of the original function call:&lt;/p&gt;&lt;pre class="js"&gt;
// Second scenario: aspect.after that accepts the result of the original function call
aspect.after(original, "someMethod", function(arg1, arg2) {
	console.warn("aspect.after: ", arg1, arg2);
	
	// "arg2" will be "undefined" since only the return value is provided 
	
}); // No "true"

// Call the original method, see what happens!
original.someMethod("David", "Walsh");

// "original someMethod: David Walsh"
// "aspect.after: ", David Walsh
&lt;/pre&gt;&lt;p&gt;In most cases, &lt;code&gt;aspect.after&lt;/code&gt; is what you will want to use.  An object with a remove method will be returned, allowing you to remove the connection whenever you&amp;#8217;d like.&lt;/p&gt;&lt;h2&gt;aspect.around&lt;/h2&gt;&lt;p&gt; What if you want to execute code both before and after the original method?  Simple:  use &lt;code&gt;aspect.around&lt;/code&gt;.  The &lt;code&gt;around&lt;/code&gt; method allows you to call the original function when you want, within your listener:&lt;/p&gt;&lt;pre class="js"&gt;
// Call the around method, which gets one argument, the original method
aspect.around(original, "someMethod", function(originalMethod) {
	// Return a new method, which receives the same arguments as the original, just like "aspect.after"
	return function(arg1, arg2) {
		// Execute "before" functionality
		console.warn("before!", arg1, arg2);
		
		// Execute the original method as desired
		originalMethod.apply(this, arguments);
		
		// Execute "after" functioanlity
		console.warn("after!");
	};
});

// Call the original method, see what happens!
original.someMethod("David", "Walsh");

// "before!", David, Walsh
// "original someMethod: David Walsh"
// "after! David Walsh"
&lt;/pre&gt;&lt;p&gt;The idea behind &lt;code&gt;aspect.around&lt;/code&gt; is very much like using &lt;code&gt;this.inherited(arguments)&lt;/code&gt; within Dojo classes;  you can make that call any time you&amp;#8217;d like, so other code may run before or after.&lt;/p&gt;&lt;h2&gt;Real Use of&amp;nbsp;aspect&lt;/h2&gt;&lt;p&gt;One realistic use of &lt;code&gt;aspect&lt;/code&gt; relates to extending Dijit widgets, or building a Dijit layout that uses multiple widgets.  Often you&amp;#8217;ll see something like:&lt;/p&gt;&lt;pre class="js"&gt;
// When the onChange event fires
aspect.after(this.dropdown, "onChange", function(value) {
	// ...fire an xhr request to get information about it
	dojo.xhrGet({
		url: "/data.php?value=" + value
	}).then(function(data) { 
		// Do something with it.
	});
}, true);
&lt;/pre&gt;&lt;p&gt;When the dropdown&amp;#8217;s value changes, an XHR request is fired to get information about that value.&lt;/p&gt;&lt;p&gt;Explaining aspect and the value of function-to-function connections can be difficult.  I usually try a parent-to-child analogy that just further confuses people. Think of it this way:  aspect allows you to know when other functions are called, without needing to modify the other function.  This happens all over the Dijit UI framework, Brilliant!&lt;/p&gt;&lt;p&gt;&lt;a
href="http://davidwalsh.name/dojo-aspect"&gt;Using&amp;nbsp;dojo/aspect&lt;/a&gt; is a post from: &lt;a
href="http://davidwalsh.name"&gt;David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.&lt;/a&gt;&lt;/p&gt; &lt;img src="http://feeds.feedburner.com/~r/Bludice/~4/2imy-v--1ts" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://davidwalsh.name/dojo-aspect#comments" thr:count="5" /><link rel="replies" type="application/atom+xml" href="http://davidwalsh.name/dojo-aspect/feed/atom" thr:count="5" /> <thr:total>5</thr:total> <feedburner:origLink>http://davidwalsh.name/dojo-aspect</feedburner:origLink></entry> <entry> <author> <name>David Walsh</name> <uri>http://davidwalsh.name</uri> </author><title type="html"><![CDATA[JavaScript Battery&#160;API]]></title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Bludice/~3/chFI3KItr_w/battery-api" /> <id>http://davidwalsh.name/?p=5362</id> <updated>2012-01-03T16:36:11Z</updated> <published>2012-01-03T15:12:56Z</published> <category scheme="http://davidwalsh.name" term="Browsers" /><category scheme="http://davidwalsh.name" term="JavaScript" /> <summary type="html"><![CDATA[Mozilla Aurora 11 was recently released with a bevy of new features. One of those great new features is their initial implementation of the Battery Status API. This simple API provides you information about the battery&#8217;s current charge level, its charging status, and allows you to be notified of changes via a few events. Let&#8217;s [...]<p><a
href="http://davidwalsh.name/battery-api">JavaScript Battery&nbsp;API</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></summary> <content type="html" xml:base="http://davidwalsh.name/battery-api">&lt;p&gt;Mozilla Aurora 11 was recently released with &lt;a
href="http://hacks.mozilla.org/2011/12/introducing-aurora-11-with-tons-of-new-features-and-improvements/" rel="nofollow"&gt;a bevy of new features&lt;/a&gt;.  One of those great new features is their initial implementation of the &lt;a
href="http://www.w3.org/TR/battery-status/" rel="nofollow"&gt;Battery Status API&lt;/a&gt;.  This simple API provides you information about the battery&amp;#8217;s current charge level, its charging status, and allows you to be notified of changes via a few events.  Let&amp;#8217;s check it out!&lt;/p&gt;&lt;div
class="actions"&gt;&lt;a
href="http://davidwalsh.name/dw-content/battery-api.php" class="demo"&gt;View Demo&lt;/a&gt;&lt;div
class="clear"&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The battery object is located at &lt;code&gt;window.navigator.battery&lt;/code&gt;, but since this is Mozilla&amp;#8217;s initial offering and the API is not yet cemented, you&amp;#8217;ll need to use &lt;code&gt;window.navigator.mozBattery&lt;/code&gt;.  The helpful &lt;code&gt;mozBattery&lt;/code&gt; properties include:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;charging: &lt;/code&gt;Represents if the system&amp;#8217;s battery is charging. The attribute must be set to false if the battery is discharging, and set to true, if the battery is charging, full, the implementation is unable to report the state, or there is no battery attached to the system, or otherwise.&lt;/li&gt;&lt;li&gt;&lt;code&gt;chargingTime: &lt;/code&gt;Represents the time remaining in seconds until the system&amp;#8217;s battery is fully charged.&lt;/li&gt;&lt;li&gt;&lt;code&gt;dischargingTime: &lt;/code&gt;Represents the time remaining in seconds until the system&amp;#8217;s battery is completely discharged and the system is about to be suspended.&lt;/li&gt;&lt;li&gt;&lt;code&gt;level: &lt;/code&gt;Represents the current battery level scaled from 0 to 1.0. The attribute must be set to 0 if the system&amp;#8217;s battery is depleted and the system is about to be suspended, and to 1.0 if the battery is full, the implementation is unable to report the battery&amp;#8217;s level, or there is no battery attached to the system.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Events for each of these statuses are provided, including &lt;code&gt;onchargingchange&lt;/code&gt;, &lt;code&gt;onchargingtimechange&lt;/code&gt;, &lt;code&gt;ondischargingtimechange&lt;/code&gt;, and &lt;code&gt;onlevelchange&lt;/code&gt;.  Basic usage is simple:&lt;/p&gt;&lt;pre class="js"&gt;
// Get the battery!
var battery = navigator.battery || navigator.webkitBattery || navigator.mozBattery;

// A few useful battery properties
console.warn("Battery charging: ", battery.charging); // true
console.warn("Battery level: ", battery.level); // 0.58
console.warn("Battery discharging time: ", battery.dischargingTime);

// Add a few event listeners
battery.addEventListener("chargingchange", function(e) {
	console.warn("Battery charge change: ", battery.charging);
}, false);
battery.addEventListener("chargingtimechange", function(e) {
	console.warn("Battery charge time change: ", battery.chargingTime);
}, false);
battery.addEventListener("dischargingtimechange", function(e) {
	console.warn("Battery discharging time change: ", battery.dischargingTime);
}, false);
battery.addEventListener("levelchange", function(e) {
	console.warn("Battery level change: ", battery.level);
}, false);
&lt;/pre&gt;&lt;p&gt;I promised a simple API, didn&amp;#8217;t I?  The battery API is the perfect API:  simple, effective, and focused!&lt;/p&gt;&lt;div
class="actions"&gt;&lt;a
href="http://davidwalsh.name/dw-content/battery-api.php" class="demo"&gt;View Demo&lt;/a&gt;&lt;div
class="clear"&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;So why use the battery API?  Since many mobile apps live inside a browser wrapper (aren&amp;#8217;t completely &amp;#8220;native&amp;#8221;), it&amp;#8217;s great to have access to system information.  Some processes are power-intensive and it may bear warning the user before starting the process that their device is low on battery.  Either way, this simple API&amp;#8217;s true usefulness should become apparent soon!&lt;/p&gt;&lt;p&gt;&lt;a
href="http://davidwalsh.name/battery-api"&gt;JavaScript Battery&amp;nbsp;API&lt;/a&gt; is a post from: &lt;a
href="http://davidwalsh.name"&gt;David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.&lt;/a&gt;&lt;/p&gt; &lt;img src="http://feeds.feedburner.com/~r/Bludice/~4/chFI3KItr_w" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://davidwalsh.name/battery-api#comments" thr:count="4" /><link rel="replies" type="application/atom+xml" href="http://davidwalsh.name/battery-api/feed/atom" thr:count="4" /> <thr:total>4</thr:total> <feedburner:origLink>http://davidwalsh.name/battery-api</feedburner:origLink></entry> </feed><!-- 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 1/37 queries in 0.018 seconds using disk: basic
Object Caching 1556/1607 objects using disk: basic

Served from: davidwalsh.name @ 2012-02-07 22:17:48 -->

