Hugoware

The product of a web developer with a little too much caffeine

Posts Tagged ‘Extensions

jsshell 3.0

with one comment

This weekend I finished up an upgrade for jsshell to version 3.0. I also put together a new jsshell landing page to help users get started.

New Stuff In 3.0

  1. jQuery and jLinq Upgrade: Both libraries have been upgraded to their newest versions. jQuery 1.4.4 and jQuery UI 1.8.7. jLinq has been upgraded to 3.0.2.
  2. Auto Complete: Previously, jsshell would show css classes, IDs and tags that were on the page as a ‘auto-suggest” popup but you couldn’t select anything on the list. Now, jsshell allows you use TAB to select the currently highlighted item. You can use up and down to change the highlighted item.
  3. More Auto Complete Sources: jsshell now shows suggestions for jQuery and jLinq commands, current IDs, tag names and css classes on the page and now some Javascript keywords and common CSS properties.
  4. Remember Last Command: jsshell now remembers the last successfully executed command. If you browse to a new page or refresh the view, the last command you ran will still be waiting for you.
  5. Access ‘file:///’ URL: Previously, Google denied the app from being released because it had access to the file URL. It seems they have changed the way this rule is handled so this version now includes the local file url.
  6. A ‘Run’ Button – Finally…: The only way to run commands before was to press CTRL+Enter. Now there is a button that does the same thing.

Special thanks to @stevehebert for his great suggestions on improvements for jsshell.

Please feel free to let me know if anything isn’t behaving as expected.

Advertisements

Written by hugoware

December 20, 2010 at 1:01 am

Campfire, Google Chrome and Extensions

with one comment

If you’ve never heard of them before, there is this little company called ’37 Signals’… they made a couple mildly popular products one of which is called Campfire.

Campfire has a really neat chat client you can use to collaborate with other team members. It even comes with some pretty handy features such as uploading files or tracking (and searching) chat history… and it all works even when you aren’t online.

That said, as neat as Campfire is – it is still a website so some of its functionality is a bit limited. For example, desktop notifications. Of course there could be stuff out there but I haven’t checked.

So with a bit of tinkering I came up with a handy little Chrome Extension to do the job.

You can click the image above or this link to install the Extension.

Chrome is especially useful with the Application Shortcuts feature. I use it in a variety of places like Grooveshark or Toggl so naturally Campfire chat fits in perfectly.

Anyways, if you use Campfire and Chrome then this might be a handy extension for you!

Written by hugoware

October 19, 2010 at 11:50 pm

Waiter, There Is Some jQuery In My jLinq…

leave a comment »

jLinq occasionally gets confused as a plug-in for jQuery. Unfortunately, jLinq doesn’t do much to help performing queries in jLinq. I’ve written some extension methods before to help link the two together but they were packaged with other projects (and not really ever released)

So this weekend I put together a few helpful extension methods and released them on GitHub.

Naturally, you’ll need the core jLinq library and the jLinq.jQuery library along with jQuery. Since a lot of jQuery uses chained methods you’ll need to use the special invoke syntax for jLinq queries (just an array).

Here are some of the commands you can use.

  • jlinq.$([selector]) : Starts a new query from document.body with the starting selector (if any).
  • $(selector).query([selector]) : Starts a new query from the current jQuery object. Allows an optional selector.
  • .include(selector, [jQuery Object]) : Includes the matches of the provided selector into the current query. You can use a different jQuery object as the source (otherwise it defaults to the object that started the query).
  • .get([selector]) : Converts the current matches in the query to a jQuery object. Allows an optional selector to further filter the results.

Just as a reminder, in order to invoke methods within a query you need to use an array where the first value is the name of the method and following values are the arguments. These arguments are all where the field name would normally be. Here are a few examples in case you need them.


//Example 1: Non-method query
jlinq.from(data).contains(
    "fieldName", //the field to pull the value from
    "check for this" //the argument for contains
    );

// Example 2 : No arguments
// function test() { ... }
jlinq.from(data).contains(
    ["test"], //no arguments, but still an invoke
    "check for this" //the argument for contains
    );

// Example 3 : With arguments
// function test(arg1, arg2) { ... }
jlinq.from(data).contains(
    ["test", 33, false], //the method with arguments
    "check for this" //the argument for contains
    );

So what do these new methods look like? Well here are a few examples to get you started!


//finds all .result elements containing red or green
//and is also case-insensitive
jlinq.$("div.results")
    .contains(["text"], "red")
    .or("green")
    .get()
    .appendTo(document.body);

//finds all links pointing to MP3 files then sorts and styles them
var mp3Links = jlinq.$("a")
    .endsWith(["attr","href"], ".mp3")
    .sort(["text"])
    .get()
    .css({
        color:"#f00",
        fontWeight:"bold"
    });

//highlights all of the matching markup with 'Joe Smith'
$("div.result").query()
    .contains(["html"], "Joe Smith")
    .each(function(rec) { 
        var markup = rec.html()
            .replace(/Joe Smith/g, 
                "<span class='highlight'>Joe Smith</span>");
        rec.html(markup); 
        });

Now you can enjoy the awesomeness of jQuery along with the semi-usefulness of jLinq! You have access to ‘or’-ing, case insensitivity, sorting — It is all there!

This code is all brand new so I don’t recommend using it anywhere important just yet, but it is fun to see how jLinq can make queries a little bit easier.

Written by hugoware

September 26, 2010 at 10:18 pm

Null Instance Extension Methods

with 4 comments

Checking for null can be time consuming and add a lot of extra noise to the code you write. In some ways it can reduce the readability of your code and obscure the purpose of your functions.

For example, check out all of the null checks required for this bit of code.

public static int GetVersion() {
	
	//check if this exists
	if (!File.Exists(PATH_APP_DETAILS)) { return DEFAULT_VERSION; }

	//try and load the document
	XDocument document = null;
	try {
		document = XDocument.Load(PATH_APP_DETAILS);
	}
	catch {
		return DEFAULT_VERSION;
	}
	if (document == null) { return DEFAULT_VERSION; }
	
	//find the element
	XElement release = document.XPathSelectElement("app/release");
	if (release == null) { return DEFAULT_VERSION; }
	
	//get the value
	XAttribute version = release.Attribute("version");
	if (version == null) { return DEFAULT_VERSION; }
	
	//convert the version
	int current = int.TryParse(version.Value, out current) ? current : DEFAULT_VERSION;
	return current;
	
}

Yikes… that is a lot of code for such a small task but what else can you do? You can’t just call methods on something that is null or your app is going to blow up… or can you?

Null Instance Extension Methods

Extension methods feel magical the first time you see them in action but ultimately they are just static methods that can be invoked from anywhere in your project.

But here is the neat thing — Since an extension method isn’t tied to the instance of a class then they can be invoked without an instance of the class.

Sound confusing? Here is an example of what I mean…

//create an extension method
public static class StringExtensions {
	public static void Test(this string value) {
		Console.WriteLine("Hello from a null test!");
	}
}

//and then call it
string nothing = null;
nothing.Test(); //ok!
nothing.ToUpper(); //crash

You’ll notice that the call to Test worked fine – If you put a break point in the method and check the value argument then you’ll notice it is actually null! We were able to call the method Test even though there wasn’t an instance of a string.

So how can this help us? Well let’s take the same XML problem from earlier in the post and create some extension methods that don’t care if the instance being invoked is null or not.

//helper extension methods for XML documents
public static class XmlExtensions {
	
	//loads an xml document to use
	public static XDocument LoadDocument(this XDocument document, string path) {
		if (!File.Exists(path)) { return null; }
		try { return XDocument.Load(path); }
		catch { return null; }
	}
	
	//uses an XPath to find an element
	public static XElement GetElement(this XDocument document, string path) {
		return document is XDocument ? document.XPathSelectElement(path) : null;
	}
	
	//returns the value of an attribute
	public static string GetAttribute(this XElement element, string name) {
		XAttribute attribute = element is XElement ? element.Attribute(name) : null;
		return attribute is XAttribute ? attribute.Value : string.Empty;
	}
}

Now let’s take a look at how we can solve the same problem as before but with these new extension methods…

public static int GetVersion() {
	
	//open the document (Mono)
	XDocument document = document.LoadDocument(PATH_APP_DETAILS);

	//It appears you have to do it like this in Visual Studio
	//XDocument document = ((XDocument)null).LoadDocument(PATH_APP_DETAILS);
	
	//find the element
	XElement release = document.GetElement("app/release");
	
	//get the version
	string version = release.GetAttribute("version");
	
	//convert and return the value
	int current = int.TryParse(version, out current) ? current : DEFAULT_VERSION;
	return current;
}

As far as I can tell, no matter what you throw at this code, you will either get the default version or the value in the XML document. This definitely reduces the lines of code count… but the clarity gains might be debatable.

  1. A developer modifying this code might not realize the value could be null or could be a real object. If they call an instance method and the value ends up being null then the application is going to crash.
  2. Some developers are going to scratch their heads when they read the line XDocument document = document.LoadDocument(...). Invoking a method on a value you’re declaring and should be null and returning the result it to itself? Huh?
  3. The more forgiving your code is then the more prone to external errors it will be, which in turn will introduce subtle runtime errors in your applications. Sometimes it’s a better idea just to throw an exception and keep the program from running.

So, while this approach has benefits it also has pitfalls. Make sure to evaluate the risks before using something like this in your code. If implemented carefully this could reduce complexity in your application…

…or at least make for a neat parlor trick the next time you’re with your dev team.

Written by hugoware

August 22, 2010 at 9:14 pm

jsshell – Reputable Software??

with 2 comments

Yes, it seems impossible so I took a screenshot. My little jsshell project has made it onto a pretty ‘notable’ list of Google extensions.

If you don’t know what jsshell then you might watch the introduction screencast.

Well… yeah, it isn’t spelled correctly… but I promise it is the same one.

In any case, you can check out the list on the Google site for yourself and possibly pick up some of the other awesome plugins while you’re at it. Don’t wait too long since it is only a matter of time before they realize their mistake 🙂

So, what better way to celebrate than to go ahead and open-source the code?

As usual, you’ll find my code out on git-hub, since its, ya’know, awesome… GitHub that is…

[Source Code]
http://github.com/hugoware/jsshell

Written by hugoware

June 28, 2010 at 10:56 pm

Enumeration Extensions 2.0

with 8 comments

A while back I had posted some code about making it easier to work with enumerated types — Especially with the Flags attribute. An experienced programmer won’t have a hard time understanding all the voodoo magic behind the the bitwise operators but for the rest of us then something a little easier to read is always welcome.

The problem with the previous code is that it was created to work with the project I was currently working on so I didn’t put a lot of effort into making it work with multiple types. That said, below is the official version 2.0 of the EnumerationExtensions class.

using System;

namespace Extensions {

    /// <summary>
    /// Extension methods to make working with Enum values easier
    /// </summary>
    public static class EnumerationExtensions {

        #region Extension Methods

        /// <summary>
        /// Includes an enumerated type and returns the new value
        /// </summary>
        public static T Include<T>(this Enum value, T append) {
            Type type = value.GetType();

            //determine the values
            object result = value;
            _Value parsed = new _Value(append, type);
            if (parsed.Signed is long) {
                result = Convert.ToInt64(value) | (long)parsed.Signed;
            }
            else if (parsed.Unsigned is ulong) {
                result = Convert.ToUInt64(value) | (ulong)parsed.Unsigned;
            }

            //return the final value
            return (T)Enum.Parse(type, result.ToString());
        }

        /// <summary>
        /// Removes an enumerated type and returns the new value
        /// </summary>
        public static T Remove<T>(this Enum value, T remove) {
            Type type = value.GetType();

            //determine the values
            object result = value;
            _Value parsed = new _Value(remove, type);
            if (parsed.Signed is long) {
                result = Convert.ToInt64(value) & ~(long)parsed.Signed;
            }
            else if (parsed.Unsigned is ulong) {
                result = Convert.ToUInt64(value) & ~(ulong)parsed.Unsigned;
            }

            //return the final value
            return (T)Enum.Parse(type, result.ToString());
        }

        /// <summary>
        /// Checks if an enumerated type contains a value
        /// </summary>
        public static bool Has<T>(this Enum value, T check) {
            Type type = value.GetType();

            //determine the values
            object result = value;
            _Value parsed = new _Value(check, type);
            if (parsed.Signed is long) {
                return (Convert.ToInt64(value)& (long)parsed.Signed) == (long)parsed.Signed;
            }
            else if (parsed.Unsigned is ulong) {
                return (Convert.ToUInt64(value) & (ulong)parsed.Unsigned) == (ulong)parsed.Unsigned;
            }
            else {
                return false;
            }
        }

        /// <summary>
        /// Checks if an enumerated type is missing a value
        /// </summary>
        public static bool Missing<T>(this Enum obj, T value) {
            return !EnumerationExtensions.Has<T>(obj, value);
        }

        #endregion

        #region Helper Classes

        //class to simplfy narrowing values between 
        //a ulong and long since either value should
        //cover any lesser value
        private class _Value {

            //cached comparisons for tye to use
            private static Type _UInt64 = typeof(ulong);
            private static Type _UInt32 = typeof(long);

            public long? Signed;
            public ulong? Unsigned;

            public _Value(object value, Type type) {

                //make sure it is even an enum to work with
                if (!type.IsEnum) {
                    throw new ArgumentException("Value provided is not an enumerated type!");
                }

                //then check for the enumerated value
                Type compare = Enum.GetUnderlyingType(type);

                //if this is an unsigned long then the only
                //value that can hold it would be a ulong
                if (compare.Equals(_Value._UInt32) || compare.Equals(_Value._UInt64)) {
                    this.Unsigned = Convert.ToUInt64(value);
                }
                //otherwise, a long should cover anything else
                else {
                    this.Signed = Convert.ToInt64(value);
                }

            }

        }

        #endregion

    }

}

This code results in a much easier to read syntax and is mildly better at avoiding type casting issues. Instead of defaulting to int as the other version did, this version attempts to decide between Int64 or UInt64 since either could meet the requirements for any of their lesser counterparts.

Now we can use syntax similar like you see below…

//create the typical object
RegexOptions options = RegexOptions.None;

//Assign a value
options = options.Include(RegexOptions.IgnoreCase); //IgnoreCase

//Or assign multiple values
options = options.Include(RegexOptions.Multiline | RegexOptions.Singleline); //IgnoreCase, Multiline, Singleline

//Remove values from the list
options = options.Remove(RegexOptions.IgnoreCase); //Multiline, Singleline

//Check if a value even exists
bool multiline = options.Has(RegexOptions.Multiline); //true
bool ignoreCase = options.Missing(RegexOptions.IgnoreCase); //true

Anyways, a whole lot easier to read in my opinion. Enjoy!

Written by hugoware

February 23, 2010 at 10:26 pm

Simple External Templates With jQuery

with 4 comments

New code available: I’ve written a follow up post about this topic with new code and new features.

If you’ve ever tried building a jQuery object from scratch then you’ve probably found that it is a little time consuming and probably a little ugly by the time you’re finished. You could put additional HTML templates as hidden elements on the page but maybe you’d rather keep that extra mark up out of your page.

One option would be load a template from a website address and then make your changes once it arrives. The code would probably look something like this.

//create the container
var element = null;

//make the request for the HTML
$.ajax({
    url:"template.html",
    success:function(html) {
        element = $(html);
        //make changes here
    }
});

There isn’t anything wrong with this code but it does put a bit of separation of your declaration of an element and the actual usage of the element. The problem is that you can’t do the whole process at once since the AJAX call takes a little time and you have to rely on a call back before you have access to the object.

It would be nice if we could have immediate access to our jQuery object on an AJAX call, but not block anything else on the page.

Time For Some Javascript Magic ™

I’m not really sure what you would call the example below, but the general idea is to capture (and queue up) any actions that would be invoked on our jQuery object and then release them once the AJAX call has been finished.

Let’s look at some code and see what it would look like (extra comments to try and explain the process)

/*
 * Arguments
 * $.template(url) - Pass in a string to a url to load 
 * $.template(params) - An object with parameters found below
 *   url: Path to the template resource (required)
 *   data: Same as the 'data' argument in the $.ajax call
 *   error: Same as the 'error' argument in the $.ajax call
 *   complete: Same as the 'complete' argument in the $.ajax call
 *   beforeUpdate: delegate(html) called just before the actual object is created
 *   afterUpdate: delegate(html, actual) called just after the actual object is created
 */

//creates a function to access a web template
jQuery.template = function(params) {
	
	//format the passed in parameters
	//check if this was only the resource url
	if (typeof(params) === "string") {
		params = { url:params };
	}
	
	//prepare the arguments passed into the class
	if (!$.isFunction(params.beforeUpdate)) { params.beforeUpdate = function() {}; }
	if (!$.isFunction(params.afterUpdate)) { params.afterUpdate = function() {}; }
	

	//create the object that handles the work
	var self = {
	
	//Properties
	//---------------------------------------------------------
	
		//handles forwarding methods onto the actual object
		container:null,
		
		//the actual jQuery object being created
		actual:null,
		
		//method calls that are waiting to be called
		queue:[],
		
	//Methods
	//---------------------------------------------------------
		
		//prepares the container for use
		setup:function() {
			
			//apply each of the methods
			self.container = $("<div/>");
			for(var item in self.container) {
				if (!$.isFunction(self.container[item])) { continue; }
				self.register(item);
			}
			
		},
		
		//handles creating method forwarding on the returned object
		register:function(method) {
		
			//create a method that handles routing the original method calls
			self.container[method] = 
				function(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14) {
				
				//if the actual object has been called, just invoke
				if (self.container.actual) {
					return self.container.actual[method](
						p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14
						);
				}
				//otherwise, queue the request
				else {
					self.queue.push({
						action:method,
						params:[p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14]
					});
					
					//then return the temporary object
					return self.container;
				}
			
			};
		
		},
		
		//executes any queued commands and updates the jQuery object
		update:function(html) {
			
			//create the jQuery object
			self.container.actual = $(html);
			
			//then execute all of the waiting commands
			$.each(self.queue, function(i, arg) {
				self.container.actual[arg.action](
					arg.params[0], arg.params[1], arg.params[2], arg.params[3], arg.params[4],
					arg.params[5], arg.params[6], arg.params[7], arg.params[8], arg.params[9],
					arg.params[10], arg.params[11], arg.params[12], arg.params[13], arg.params[14]
					);
			});
		
		},
		
		//starts the ajax request to download the template HTML
		download:function() {
			
			//starts downloading content
			$.ajax({
			
				//parameters for the template request
				url:params.url,
				data:params.data,
				dataType:"html",
				
				//performs the catch up work for the ajax
				success:function(html) {
					//** Optional: Uncomment 'setTimeout' to simulate a delay 
					//setTimeout(function() {
					params.beforeUpdate(html);
					self.update(html);
					params.afterUpdate(html, self.container.actual);
					//}, 2000);
				},
				
				//additional handling of the request
				error:params.error,
				complete:params.complete
			});
		
		},
		
	//Initalization
	//---------------------------------------------------------
		
		//setup the object to work
		init:function() {
		
			//prepare the temporary container
			self.setup();
		
			//start downloading the content
			self.download();
		}
	
	};
	
	//prepare the the template code
	self.init();
	
	//return the custom container to forward method calls
	return self.container;
	
};

This code allows you to have direct access to a jQuery object even before it has finished loading the content from the server. So, instead of using a callback we can write our jQuery like we normally would.

//note: the first command is all one long chain with a comments
//between functions to explain a bit more

//create the object and immediately apply changes
var template = $.template("template.txt")
	.css({"color":"#f00", "width":"200", "background":"#333"})
	.animate({width:800, height:900}, 3000)

	//you can even append and appendTo the object in advance
	.appendTo($("#container"))

	//or search for and update child elements
	.find(".title").text("howdy")

	//and parent elements
	.parent().css({"background":"#00f"});
	
//you can also still access the template from the 
//assigned variable
template.find("div").click(function() {
	alert('clicked');
});

//even if if you call it much later, it still works
setTimeout(function() {
	template.css({"color":"#0f0"});
}, 10000);

What Is Going On Here?

As I mentioned before the real problem is that the jQuery object we create isn’t ready as soon as we want to assign to it. Because of that we have to use a callback to resume the work. However, the cool thing about dynamic languages is that we can override anything we want.

In this example we start by creating a container that has all the same functions as a typical jQuery object but has one slight modification — all the methods are overridden and placed into a queue (man, I love enclosures). Once our AJAX call has completed we run an update command that executes everything we have saved against our new jQuery object instead of the one that received the calls to begin with — madness!

After we’ve caught up and our actual object is created we can stop saving actions to the queue and instead just invoke them immediately. I nicknamed this method forwarding for the sake of having a cool, buzzword sounding sort of name but if anyone knows what this is really called, please tell me 🙂

It is worth noting that this is only going to work with functions that return the jQuery object (at least until the ‘real’ object is created). The reason is that since we’re just capturing methods and saving them for later then we don’t know what the actual return type is. Needless to say, using a property probably won’t be accurate either (since we can’t intercept the request for the property like we would with a method)

In any case, this might simplify the next time you need to download content in jQuery but you don’t want to break up your functionality.

Written by hugoware

January 14, 2010 at 10:59 pm