-
Blog Future
09 March 2012I decided that instead of attempting to revitalise this old blog that it was best to put it to sleep and start fresh when I'm in more of a position to start blogging again. In the meantime, I have removed any posts which I felt were no longer of any use and closed commenting on all the remaining posts.
I also decided to deprecate my two existing jQuery plugins as there is a good chance that they don’t work with the latest release as well as just requiring a general overhaul anyway. They will remain online until the new blog is put online and then all future code will be hosted by BitBucket.
I have some big interesting ideas for my new blog, which will involve me building my own blog engine to support some of the functionality I plan to use. I’ll also be making all the source code open source so that anyone can contribute or do what the hell they like with it!
Finally, I will also be blogging about one of my other big projects that’s in the pipeline, although this won’t be open source. Until then please subscribe so that you’ll be notified when the new blog goes live.
I look forward to seeing you on the other side!
Filed under | 0 comments » -
ASP.NET MVC 3 Razor C# View Engine
10 January 2011I'm currently developing a personal project using ASP.NET MVC 3 RC2 and the Razor view engine, one of the things that most developers spend a lot of time doing is tweaking code to gain the best performance out of an application and this is something that I've recently spent some time on within the confines of MVC. One of the greatest improvements in MVC 3 is from an extensibility perspective, especially with the recent implementation of dependency injection through the new IDependencyResolver interface.
I hit an exception the other day when requesting a view that I'd misspelled and when looking at the stack trace found the many search locations that by default are searched:-
- ~/Views/Controller/View.aspx
- ~/Views/Controller/View.ascx
- ~/Views/Shared/View.aspx
- ~/Views/Shared/View.ascx
- ~/Views/Controller/View.cshtml
- ~/Views/Controller/View.vbhtml
- ~/Views/Shared/View.cshtml
- ~/Views/Shared/View.vbhtml
RazorCSharpViewEngine.cs
using System.Web.Mvc; public class RazorCSharpViewEngine : RazorViewEngine { public RazorCSharpViewEngine() { AreaViewLocationFormats = new[] { "~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.cshtml" }; AreaMasterLocationFormats = new[] { "~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.cshtml" }; AreaPartialViewLocationFormats = new[] { "~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.cshtml" }; ViewLocationFormats = new[] { "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml" }; MasterLocationFormats = new[] { "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml" }; PartialViewLocationFormats = new[] { "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml" }; } }Below is a simple example that clears all existing view engines and registers the RazorCSharpViewEngine without the use of dependency injection.
Global.asax.cs
public class Global : HttpApplication { public void Application_Start() { // Clears all previously registered view engines. ViewEngines.Engines.Clear(); // Registers our Razor C# specific view engine. // This can also be registered using dependency injection through the new IDependencyResolver interface. ViewEngines.Engines.Add(new RazorCSharpViewEngine()); } }The code isn't much but hopefully demonstrates just a tiny snippet of power that MVC 3 brings to the table. I'd be interested to hear any feedback on this especially as the whole MVC 3 and Razor view engine stuff is relatively new.
Filed under | 4 comments » -
PHP Deep Object Cloning
23 July 2010I spent many hours yesterday trying to create an exact deep clone of a complex object structure, so that i could make changes to the clone without any affect to the original. I started by using the PHP 5 Object Clone functionality, which creates a shallow copy of all the object's properties, however any properties that are references to other variables, will remain references. This is great, but i needed a deep copy of the object including all references to child objects, however deeply nested. The PHP manual states that when cloning an object, the magic __clone() method is called if possible, which can be used to manually create a deep clone of the object.
Using the magic clone method was a step forwards, i could traverse through the object's properties and any that were references i could create clones of, however this meant that any of the object's properties that were object's that had references were still not cloned. I started implementing an interface and abstract base class, that when derived could clone an object's properties and any that also derived from the same abstract base class could also be cloned, creating a recursive cloning process. This worked perfectly until i hit object properties that were arrays of objects, at which point i decided it was time to take a step back and look for an alternative approach.
It then hit me that if i use the PHP Serialisation functionality to create a byte-stream string representation of the entire object structure and then de-serialise the byte-stream back into the object structure again, that the entire new object would be re-created and therefore be a clone of the original. It worked like a dream, so i've encapsulated it into a static class for re-usablility and have made it open-source. Hopefully the following code will save someone the time that it took me to finally achieve simple deep cloning of an object however complex its structure.
ObjectCloner.php
<?php final class ObjectCloner { private function __construct() {} public static function cloneObject($source) { if ($source === null) { return null; } return unserialize(serialize($source)); } } ?>You can use the above class as in the example class below.
Example.php
<?php class Example { public function someMethod() { // We create an instance of some complex object. $original = new ComplexObject(); // We create an exact clone of the complex object, using the ObjectCloner class. $clone = ObjectCloner::cloneObject($original); // Changing some deeply nested property on the clone will have no affect on the original. $clone->someObjectProperty->someOtherObject->someString = 'NewValue'; echo $original->someObjectProperty->someOtherObject->someString; // Would produce 'OriginalValue' echo $clone->someObjectProperty->someOtherObject->someString; // Would produce 'NewValue' } } ?>I'd appreciate any feedback or comments.
Filed under | 10 comments » -
PHP Domain Name Resolver
07 May 2010I recently needed to extract a domain name from any given URL string and found that it was a lot harder than i had first anticipated. The extraction process was simple if you literally wanted the second-level domain name that only contained a single TLD (e.g. .com, .net), however given a double TLD (e.g. .co.uk, .com.tw), you would get back the first part of the TLD and not the domain name. To make matters worse i wanted the extraction process to handle both localhost and IP addresses correctly, which of cause are all valid URLs.
After a lot of messing around i eventually came up with the class below, which handles all the above scenarios perfectly. The only thing I'm not happy about is the static array of double TLDs and I'm pretty sure i haven't got all of the possible combinations either. If you find I've missed one or have a better solution to the double TLDs problem, please leave a comment.
DomainNameResolver.php
<?php final class DomainNameResolver { private function __construct() {} public static function resolve($url = '') { static $urlCache = array(); static $doubleTlds = array( 'co.uk', 'me.uk', 'net.uk', 'org.uk', 'sch.uk', 'ac.uk', 'gov.uk', 'nhs.uk', 'police.uk', 'mod.uk', 'asn.au', 'com.au', 'net.au', 'id.au', 'org.au', 'edu.au', 'gov.au', 'csiro.au', 'br.com', 'com.cn', 'com.tw', 'cn.com', 'de.com', 'eu.com', 'hu.com', 'idv.tw', 'net.cn', 'no.com', 'org.cn', 'org.tw', 'qc.com', 'ru.com', 'sa.com', 'se.com', 'se.net', 'uk.com', 'uk.net', 'us.com', 'uy.com', 'za.com' ); $url = trim($url); if (empty($url) || $url[0] == '/') { $url = $_SERVER['HTTP_HOST'] . $url; } if (strpos($url, '://') === false) { $url = 'http://' . $url; } if (isset($urlCache[$url])) { return $urlCache[$url]; } $host = parse_url($url, PHP_URL_HOST); if ($host !== null) { if (preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $host)) { $urlCache[$url] = $host; return $host; } $host = strtolower($host); $parts = explode('.', $host); if (!isset($parts[1])) { $urlCache[$url] = $parts[0]; return $parts[0]; } $tld = array_pop($parts); $host = array_pop($parts) . '.' . $tld; if (!empty($parts) && in_array($host, $doubleTlds)) { $host = array_pop($parts) . '.' . $host; } $urlCache[$url] = $host; return $host; } return false; } } ?>You can use the above class as in the example class below.
Example.php
<?php class Example { public function someMethod() { echo DomainNameResolver::resolve(); // Would display waynehaffenden.com echo DomainNameResolver::resolve('https://subdomain.subdomain.example.co.uk'); // Would display example.co.uk echo DomainNameResolver::resolve('http://localhost'); // Would display localhost echo DomainNameResolver::resolve('http://127.0.0.1'); // Would display 127.0.0.1 } } ?>I hope the above code proves to be useful to someone and saves the time and effort i had to put in to get it working. Would love to hear your feedback on this one.
Filed under | 2 comments » -
jQuery PNG Plugin
17 February 2010Please note: This plugin is now outdated and may not work correctly with the latest versions of jQuery and will only remain online for a limited time only. For more information please see this post: Blog Future.I had to work on a project recently where i was using 24-bit transparent PNG files, which aren't supported properly in Internet Explorer 6. Although there are other existing jQuery/JavaScript fixes out there, none of them achieved exactly what i wanted. I also found that while using the jQuery Cycle plugin to animate a slideshow of photos, Internet Explorer 7 & 8 don't support multiple filters, which results in a black border appearing around the transparent PNG image while it is tweening. As i always strive for pixel perfect design, this obviously wasn't acceptable and therefore came the birth of the jQuery PNG plugin.
The jQuery PNG Plugin applies a fix to the above problems by using the Microsoft DirectX AlphaImageLoader filter, which renders the image using the DirectX engine. This plugin fixes both images and CSS background images. When using the plugin, you can specify whether the fix is applied to parent elements or to elements and any appropriate child elements. The plugin only runs on Internet Explorer 6, unless forced to on Internet Explorer 7 & 8 to save the fix being unnecessarily applied.
Please note: To get the best performance from this plugin, it is highly recommended that it isn't applied until the appropriate images have fully loaded. This is because images take around double the time to load and render using the Microsoft DirectX engine.
Multiple Filter Issue in Internet Explorer 7 & 8
Although this plugin attempts to fix this issue, it can't directly because it adds a filter to the image. The way to overcome this is to wrap the images within a parent tag such as <div><img /></div> or more often <ul><li><img /></li></ul>. This way the fix is applied to the image tag and the tweening filter can occur on the parent tag.
Usage
The following settings are available:
- shimImage (String) - The path to where the transparent 1x1 shim image is located. This defaults to simply 'shim.gif', which can be found within the jQuery PNG Zip file.
- force (Boolean) - If set to true then the fix will be applied to all Microsoft Internet Explorer browsers. This defaults to false.
- children (Boolean) - If set to false then the fix will only be applied to parent elements. This defaults to true.
Default Settings
To save keep passing the above settings to each instance of this plugin, you can simply define them statically like so:
$.png.defaults.shimImage = '/path/to/image/shim.gif';
You can still pass the settings to an instance, which take precedence over the defaults.
Implementation
Minimal implementation:
$(function() { $('#element-id').png(); });Maximum implementation:
$(function() { $('#element-id').png({ shimImage: '/path/to/image/shim.gif', force: false, children: true }); });Run when images have loaded:
$('img').load(function() { $(this).png(); });jQuery Versions
This plugin has been tested and fully works in both jQuery 1.3 and 1.4.
Testing
This plugin has been successfully tested in:
- Internet Explorer 8/7/6
Licensing
This plugin is dual licensed under the MIT and GPL licenses.
Download
You can download the latest version of the plugin below.
- jQuery PNG Zip - Contains All Files
- jQuery PNG Minified - Recommend
- jQuery PNG Source - Uncompressed Source
Filed under | 13 comments » -
jQuery Textarea AutoResizable Plugin
30 December 2009Please note: This plugin is now outdated and may not work correctly with the latest versions of jQuery and will only remain online for a limited time only. For more information please see this post: Blog Future.I've been using jQuery for a while now but have only really started getting into it in a big way over the last few months. I've been using many different plugins to achieve various different effects and behaviours but only recently had the need to start developing my own plugins.
I was using the jQuery Auto-Resize Plugin on a project recently, to automatically grow/shrink textareas based on the text, to remove the need for traditional scroll bars. This plugin uses an alternate method to compute the height of the textarea, meaning that you don't have to use a fixed-width font or have to define the cols and rows attributes of the textarea. The problem was that although this plugin is great, it didn't quite do what I needed and had some minor bugs, especially within different browsers and when pre-filling it with text (This is at the time of writing this blog). Anyways, after hacking around with the plugin, I eventually felt the urge to completely re-write it and add additional features, which you can find below.
The jQuery AutoResizable plugin adds extended functionality to the standard HTML textarea control that will automatically grow or shrink the height of the control using animation to always fit the text contained, which gets rid of the classic need for scrollbars. However, once the control reaches a specified height it will stop growing and the scrollbar will be re-activated. Please see the demo below.
Demo
Usage
The following settings are available:
- animate (Boolean) - If set to false no animation will take place and the textarea height will immediately change. This defaults to true. (Please click here to read about the required CSS to make this work correctly.)
- animateDuration (Number|String) - The animation duration in milliseconds or one of the pre-defined jQuery duration constants (fast, normal, slow). This defaults to 200.
- maxHeight (Number) - The maximum height in pixels that the textarea should grow to, once this height is reached it will stop growing. This defaults to 500.
- onBeforeResize[currentHeight, newHeight] (Function) - The callback function that is triggered before an actual resize occurs. This function is passed the current height and the new height. If you return false within the callback function the actual resizing doesn't occur. When in the context of the callback function 'this' refers to the textarea control.
- onAfterResize (Function) - The callback function that is triggered after an actual resize completes. When in the context of the callback function 'this' refers to the textarea control.
- padding (Number) - The number of extra pixels which is appended to the textarea height, this is used to reassure the user there is more space to type in and it seems to give a smoother animation. This defaults to 20.
- paste (Boolean) - If set to false then most browsers won't respond to text being pasted via the context menu until another event is triggered. This defaults to true. (Please click here to read more information on this.)
- pasteInterval (Number) - The paste listener interval in milliseconds. This defaults to 100.
Animation CSS Requirement
Below is the CSS you must use for the animation to work correctly.
textarea { display: block; overflow: auto; }Paste Functionality
This is the main new feature that I have added that the previous plugin lacked. It means that the textarea will respond when a user uses the context menu to paste text. This feature is implemented using the JavaScript window.setInterval() function and therefore maybe seen as a disadvantage cause of the constant polling. However, the paste listener only listens when the textarea has focus.
Implementation
Minimal implementation:
$(function() { $('textarea').autoResizable(); });Maximum implementation:
$(function() { $('textarea').autoResizable({ animate: true, animateDuration: 300, maxHeight: 1000, onBeforeResize: function(currentHeight, newHeight) { alert('Before resize!'); // Uncomment the line below to stop the resizing to occur. //return false; }, onAfterResize: function() { alert('Resized!'); }, padding: 30, paste: true, pasteInterval: 100 }); });jQuery Versions
This plugin has been tested and fully works in both jQuery 1.3 and 1.4.
Testing
This plugin has been successfully tested in:
- Internet Explorer 8/7/6
- Firefox 3.5/3/2
- Chrome
- Opera 9/8
- Safari 4/3
Licensing
This plugin is dual licensed under the MIT and GPL licenses.
Download
You can download the latest version of the plugin below.
- jQuery AutoResizable Zip - Contains All Files
- jQuery AutoResizable Minified - Recommend
- jQuery AutoResizable Source - Uncompressed Source
Filed under | 0 comments »