Category: Programming

  • HTML: IE file submission

    I’ve been bumping up against an interesting bug in Internet Explorer recently, and, having just found the solution, thought I’d share it with you.

    The problem is that in Internet Explorer (tested 7 & 8), when your document is in quirks mode, uploading a file sometimes just sends through the file name, without the actual body of the request. Put the document into standards mode, and it all works. It should be noted that this is when you’re dynamically setting up the elements used with JavaScript.

    The cause? In quirks mode, the enctype attribute isn’t supported. So whilst setting “encType” on the form element to the correct “multipart/form-data” will indeed set this attribute, it won’t actually cause the upload to include the file. Instead, you need to set the encoding attribute to this value, too. It certainly doesn’t help that the MSDN article on the <input type=”file”> element tells you to set “enctype”, but makes no mention of “encoding”.

    I couldn’t find any reference to this problem on the intertubes (although maybe I just didn’t look hard enough), so hopefully this will help someone.

  • Javascript: Print a single element

    Sometimes, you’ll want to allow users the ability to print only a part of your page; for example, a table but not the various links around the page. It’s possible to use a printing stylesheet, but this can cause severe headaches when you need different parts printed at different times. Really, we want to be able to just say element.printElement(), and have it just work. That’s what the MooTools function below does. It’s loosely based around the concepts outlined at this website.

    [sourcecode language=”javascript”]Element.implement({
    printElement: function(docTitle) {
    var strName = ‘printer-‘ + (new Date()).getTime();
    var styles = [];
    $$(‘link[type=text/css]’).each(function(style) {
    styles.push(‘‘);
    });
    var title = docTitle || document.title;
    var that = this.getParent();
    var iframe = new IFrame({
    name: strName,
    styles: {
    width: 1,
    height: 1,
    position: ‘absolute’,
    left: -9999
    },
    events: {
    load: function() {
    var doc = window.frames[strName].document,
    win = window.frames[strName];
    var f = function() {
    if (!doc.head) {
    f.delay(10);
    return;
    }
    // We need to delay printing so that styles are applied.
    (function() {
    doc.title = title;
    // IE7 won’t let us adopt() here for some reason, and we can’t do anything to the head.
    doc.body.innerHTML = styles.join(”) + that.innerHTML;
    (function() {
    win.focus(); // IE needs the window to be focused.
    win.print();
    }).delay(100);
    }).delay(200);
    };
    f();
    }
    }
    }).inject($(document.body));
    (function() {
    iframe.dispose();
    }).delay(30000);
    }
    });[/sourcecode]

  • Input elements that fill their container

    Previously, this post advocated the use of “text-indent” on a padding-less, border-less, 100% width input. This works, but it’s quite clunky, and old versions of IE don’t support text-indent, so it just looks bad. A much better solution is to

    Just use box-sizing.

    As pointed out in the comments, the simplest solution is to simply change the box-sizing model of the input element to “border-box”, rather than the default “content-box”. In the example below, I’ve given the containing div a 4px whiteborder.

    [sourcecode language=”xhtml”]

    [/sourcecode]

    Note that for Firefox, you still need to use the -moz- prefix; it’s supported unprefixed in all the other major browsers, though.

    Updated 2012-08-03.

  • Limiting the contents of a string via RegEx

    Often, you will need to prevent users from entering data that doesn’t conform to a specific pattern. For example, you may want to allow users to enter only numbers or only valid email addresses. To this end, I’ve written a little utility function that returns the “standardised” version of a string, according to the regex you supply.

    [sourcecode language=”javascript”]String.implement({
    limitContent: function(allowedRegex) {
    return $splat(this.match(allowedRegex)).join(”);
    }
    });[/sourcecode]

    Basically, the function takes the result of evaluating the regular expression on the string, converts it into an array if it isn’t one, and then joins the array’s elements together with an empty string.

    Examples:

    [sourcecode language=”javascript”]console.log(“12345”.limitContent(/.{4}/)); // Only allow four characters
    console.log(“joe@mail.com”.limitContent(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}/)); // Only allow email addresses
    [/sourcecode]

  • Google Wave & iPhone

    I just tried out Google Wave on the iPhone. Interestingly, despite an initial “your browser is not supported” message, the actual system sports a rather snazzy app-like interface on the iPhone.

    I’ll be interested to see what kind of support Wave will ‘officially’ have on mobile platforms, and perhaps even more interested in what ‘unofficial’ support there’ll be.

  • CSS Columns

    In this post, I will walk through the new columns specification that arrived in CSS 3. I will show you the current implementation state of columns in the four major rendering engines: Gecko (Firefox), Webkit (Safari & Chrome), Trident (Internet Explorer), and Presto (Opera).

    Before we get on to platform-specific issues and workarounds, though, we’ll look at the various CSS properties available for working with columns.

    For more in-depth information on columns, you should check out the W3C working draft and Mozilla’s MDC page on columns. The Webkit blog also has an article, but it’s not particularly informative.

    Contents

    I will add more to this entry as I discover more about columns — the goal is to make it an easy-to-understand reference.

    Browser capabilities

    PropertyGeckoWebkitTridentPresto
    column-count-moz-column-count-webkit-column-count
    column-width-moz-column-width-webkit-column-width
    columns-webkit-columns
    column-gap-moz-column-gap-webkit-column-gap
    column-rule-color-moz-column-rule-color-webkit-column-rule-color
    column-rule-style-moz-column-rule-style-webkit-column-rule-style
    column-rule-width-moz-column-rule-width-webkit-column-rule-width
    column-rule-moz-column-rulecolumn-rule
    column-span
    column-fill
    break-before
    break-inside

    Browsers used for testing: Firefox 3.5.4 (Windows), Safari 4.0.2 (Windows), Internet Explorer 8.0.6001, Opera 10.00 (Windows)

    Please let me know if this table is inaccurate, and I will update it.

    Browser bugs

    These are the bugs that I have encountered using CSS columns — if you know of more, please let me know, and I’ll add them to these lists.

    Gecko bugs

    • Specifying an “overflow” (or “overflow-x” or “overflow-y”) property on an element with columns prevents the column rule from being rendered at all.
    • Column rules occasionally don’t render, regardless of the “overflow” property.
    • There is no way to break columns.

    Webkit bugs

    • Pixel creep: Pixels from a later column can creep back to the bottom of the previous column. This can happen with plain text, but it is much more noticeable when you use a non-layout altering effect like text-shadow or box-shadow.
    • Text that overflows the column horizontally is chopped off
    • There is no way to break columns.

    Properties

    column-count

    Value: | auto
    Initial value: auto

    If you don’t set the column-width property, column-count specifies the number of columns into which the content should be flowed.

    If you specify column-width, column-count imposes a limit on the maximum number of columns to be rendered if you supply a numeric value.

    column-width

    Value: | auto
    Initial value: auto

    This property indicates the optimal column width — columns may be rendered narrower or wider by the UA, according to the available space.

    If column-width has the value “auto”, then the width of the columns is determined by other means (for example, column-count).

    columns

    Value: column-width && column-count

    The columns property is a short-hand property, used to set both column-width and column-count simultaneously.

    column-gap

    Value: | normal
    Initial value: normal

    Use column-gap to specify the size of the gutter that lies between columns. Most UAs will render “normal” as 1em.

    column-rule-color

    Value:

    When a column-rule is specified, you may use column-rule-color to set the colour for the line drawn between columns. This property is approximately equivalent to the various border-(?)-color properties.

    column-rule-style

    Value:

    By using column-rule-style, you may determine how the line between columns is to be rendered, if at all. Similar to border-(?)-style.

    column-rule-width

    Value:
    Initial value: medium

    column-rule-width sets the width of the line rendered in the gutter between columns. Basically, it’s the same as the border-(?)-width properties.

    column-rule

    Value: column-rule-width && column-rule-style & & column-rule-color

    Shorthand for setting all three column-rule properties.

    column-span

    Value: 1 | all
    Initial value: 1

    By using column-span, you can allow an element to span either the entire set of columns, or none at all.

    Note that you cannot set an arbitrary number of columns to span — this property essentially ‘interrupts’ the column flow and restarts it below the spanned element.

    column-fill

    Value: auto | balance
    Initial value: balance

    If you have set a height for your columnified element, setting column-fill to ‘auto’ will cause the columns to be ‘filled’ in turn, rather than have the content balanced equally between them.

  • MooTools object messaging

    Events

    In JavaScript, we often tend to use events all over the place. In MooTools, the custom ‘domready’ event is particularly prevalent. However, events suffer from a few drawbacks:

    You can’t attach events to non-existent objects.

    Pretty self-explanatory, really. What this means in practice, though, is that you can’t easily let object A know when object B exists.

    If an object starts to listen for an event after it’s already fired, it’ll never hear it.

    Because content on the web isn’t always delivered in perfect order (especially when you’re loading scripts synchronously), it’s possible for an object to try to listen for an event after it’s already been fired. Obviously, this means that your listener object will never run the code that’s dependent on that event, which could be Bad Thing™.

    It’s not particularly easy to know which object is listening for which events.

    There are ways around this, but you can’t just dir() the listeners in Firebug.

    A messaging system

    For all of these reasons (and probably a few more that I’ve forgotten about), a messaging system can be an invaluable addition to your arsenal when writing JavaScript. How does a messaging system work? Well, interested objects ‘register’ themselves as listeners for particular message ‘handles’, and other objects can send messages using those ‘handles’. Below is a very simple MooTools messaging system that I knocked up, which has a few cool features, including:

    • When you register() a listener, you can have its callback immediately fire if that message has ever been sent before.
    • You can very easily see which callbacks are associated with which messages by simply dir()-ing the ‘listeners’ member.
    • You can unregister() a listener at any time (provided you’ve got a reference to the function and the handle).
    • Handles can be any valid JavaScript type — Strings, Numbers, even Objects.

    Feel free to use and extend this system — as I mentioned, this is a very simple system. If you do extend it, let me know in the comments!

    Let me know what you think about this system in the comments.

    [sourcecode language=”javascript”]
    barryvan.base.Messaging = new Class({
    listeners: $H(),
    sentMessages: [],

    initialize: function() {

    },

    /**
    * Register a listener for a particular handle.
    * handle [String]: The message ‘handle’ to listen for.
    * callback [Function]: The function to be called when the handle is sent a message. The contents of the messages will be included in the function call.
    * dontCheck [Boolean]: If falsey and the handle has had a message sent to it, immediately call the callback function (without contents), and continue to add the listener as normal.
    */
    register: function(handle, callback, dontCheck) {
    if ($type(callback) !== ‘function’) return;

    if (!dontCheck && this.sentMessages[handle]) {
    callback();
    }

    if (!this.listeners.has(handle)) this.listeners[handle] = [];
    this.listeners[handle].push(callback);
    },

    /**
    * Unregister a listener for a particular handle.
    * handle [String]: The message ‘handle’ to cease listening for.
    * callback [Function]: The function which was earlier assigned as the callback for the messages.
    */
    unregister: function(handle, callback) {
    if (this.listeners.has(handle)) {
    this.listeners[handle].erase(callback);
    }
    },

    /**
    * Send a message to the given handle with the given contents — send the contents to all the registered listeners for that handle.
    * handle [String]: The message ‘handle’ to transmit to.
    * contents [Mixed]: The contents to be sent to the listeners.
    */
    send: function(handle, contents) {
    this.sentMessages.include(handle);
    if (this.listeners.has(handle)) {
    this.listeners[handle].each(function(callback) {
    callback(contents);
    });
    }
    }
    });
    [/sourcecode]

  • CSS minifier and alphabetiser

    Update: This project is now hosted on GitHub: https://github.com/barryvan/CSSMin/

    There are quite a few CSS minifiers out there, which can bring the raw size of your CSS files down substantially. There are, however, significant gains to be made if the CSS is minified so that it gzips better. To that end, I’ve written a small Java application that will read in a CSS file and output its contents to stdout or another file in a format that’s optimised for gzipping.

    The problem

    A gzipped file will be stored most efficiently when there are many recurring strings in the file. This means that when writing CSS files, this code:
    [sourcecode language=”css”].pony {
    border: solid red 1px;
    font-weight: bold;
    }
    .lemur {
    border: solid red 1px;
    font-weight: normal;
    }[/sourcecode]
    will be better-compressed than this:
    [sourcecode language=”css”].pony {
    border: solid red 1px;
    font-weight: bold;
    }
    .lemur {
    font-weight: normal;
    border: red solid 1px;
    }[/sourcecode]
    In the first sample, notice that we have a very long string that occurs twice:

     {
    border-style: solid red 1px;
    font-weight: 

    In the second sample, there are strings that occur more than once, but they’re much shorter. The gzip algorithm can, in the first case, replace that entire long string with a much shorter placeholder.

    What it does

    So, how can we optimise CSS for gzipping, then? A file that’s minified using this CSS Minifier will have these operations applied:

    • All comments removed.
    • The properties within all selectors ordered alphabetically.
    • The values for all properties ordered alphabetically.
    • All unnecessary whitespace removed.
    • Font weights replaced by their numeric counterparts (which are shorter).
    • Quotes stripped wherever possible.
    • As much text as possible transformed to lowercase.
    • Prefixed properties (for example, -moz-box-sizing) placed before the unprefixed variant (box-sizing).
    • Colours simplified from rgb() to six- or three-digit hex values, or simple names.
    • Units on values of 0 stripped.
    • Multi-parameter items simplified to as few parameters as possible.
    • Various other small tweaks and adjustments made.

    By way of example, the following CSS snippet:
    [sourcecode language=”css”]body {
    padding: 8px;
    margin: 0;
    background-color: blue;
    color: white;
    font-family: “Trebuchet MS”, sans-serif;
    }

    h1 {
    margin: 0;
    padding: 0;
    font-size: 200%;
    color: #0F0;
    font-weight: bold;
    }

    p {
    margin: 0 0 2em;
    line-height: 2em;
    }[/sourcecode]
    would be formatted to the following (note that line breaks have been added for legibility — no line breaks appear in the final output):

    body{background-color:blue;color:#fff;font-family:"trebuchet ms",sans-serif;
    margin:0;padding:8px}h1{color:#0f0;font-size:200%;font-weight:700;margin:0;
    padding:0}p{line-height:2em;margin:0 0 2em}

    Compression results

    These are the results of compressing the main CSS file for one of the webapps I develop at work.

     Original size (bytes)Gzipped size (bytes)
    Plain8193812291
    YUI6443410198
    LotteryPost6360910165
    CSS Drive6927510795
    CSSMin637919896

    Download

    Head over to GitHub to download the source.

    Usage

    First, if you haven’t done so yet, compile the code:
    [sourcecode]# javac CSSMin.java[/sourcecode]
    Then, you can call the minifier by running
    [sourcecode]# java CSSMin in.css [out.css][/sourcecode]
    If you do not specify an output file, the resultant CSS will be printed to stdout (and can then be redirected as you wish).

    Contact

    If you have any questions or comments about this app, or if you find a bug or some weird behaviour, just comment on this post, and I’ll see what I can do.

    You can also raise issues on GitHub, fork the project, commit changes, and more.

    If you find this utility useful, let me know!

  • Quicksort an array of objects

    Often, you will need to sort an array of objects in Javascript. The inbuilt sort() function can’t do this, but here is a Quicksort implementation for doing just this.

    Parameters

    array The array to be sorted. (See below for an implementation on the Array Native itself, which makes this variable unnecessary).

    key The key to sort by. Make sure every object in your array has this key.

    Examples

    [sourcecode language=’javascript’]
    var objs = [
    {fruit:”cherry”},
    {fruit:”apple”},
    {fruit:”banana”}
    ];

    console.log(objs.sortObjects(‘fruit’));
    // Logs [{fruit:”apple”},{fruit:”banana”},{fruit:”cherry”}] to the console
    [/sourcecode]

    The code

    [sourcecode language=’javascript’]
    sortObjects: function(array, key) {
    for (var i = 0; i < array.length; i++) { var currVal = array[i][key]; var currElem = array[i]; var j = i - 1; while ((j >= 0) && (array[j][key] > currVal)) {
    array[j + 1] = array[j];
    j–;
    }
    array[j + 1] = currElem;
    }
    }
    [/sourcecode]

    Implemented on the Array native:

    [sourcecode language=’javascript’]
    Array.implement({
    sortObjects: function(key) {
    for (var i = 0; i < this.length; i++) { var currVal = this[i][key]; var currElem = this[i]; var j = i - 1; while ((j >= 0) && (this[j][key] > currVal)) {
    this[j + 1] = this[j];
    j–;
    }
    this[j + 1] = currElem;
    }
    }
    });
    [/sourcecode]

  • Javascript string ellipsising

    Putting ellipses into strings that are too long has been around for a very long time. Unfortunately, Javascript doesn’t offer a native method of doing this, so below is a little function that’ll do it for you.

    This function returns a copy of the string it’s called on, ellipsised, and takes three parameters:

    toLength (required) The number of characters to truncate the string to (or 0 to disable ellipsising)

    where (optional, default ‘end’) A string representing where the ellipsis should be placed — ‘front’, ‘middle’, or ‘end’

    ellipsis (option, default ‘\u2026’) A string to be used as the ellipsis.

    Examples

    [sourcecode language=’javascript’]
    // Our clichéd string
    var s = ‘Jackdaws love my great big sphinx of quartz’;

    alert(s.ellipsise(10));
    // Alerts “Jackdaws l…”

    alert(s.ellipsise(10, ‘front’));
    // Alerts “… of quartz”

    alert(s.ellipsise(10, ‘middle’, ‘pony’));
    // Alerts “Jackdponyuartz”[/sourcecode]

    The code

    [sourcecode language=’javascript’]String.implement({
    ellipsise: function(toLength, where, ellipsis) { // Where is one of [‘front’,’middle’,’end’] — default is ‘end’
    if (toLength < 1) return this; ellipsis = ellipsis || '\u2026'; if (this.length < toLength) return this; switch (where) { case 'front': return ellipsis + this.substr(this.length - toLength); break; case 'middle': return this.substr(0, toLength / 2) + ellipsis + this.substr(this.length - toLength / 2) break; case 'end': default: return this.substr(0, toLength) + ellipsis; break; } } });[/sourcecode]If you're not using MooTools, you can use this variant instead:[sourcecode language='javascript']String.prototype.ellipsise = function(toLength, where, ellipsis) { // Where is one of ['front','middle','end'] -- default is 'end' if (toLength < 1) return this; ellipsis = ellipsis || '\u2026'; if (this.length < toLength) return this; switch (where) { case 'front': return ellipsis + this.substr(this.length - toLength); break; case 'middle': return this.substr(0, toLength / 2) + ellipsis + this.substr(this.length - toLength / 2) break; case 'end': default: return this.substr(0, toLength) + ellipsis; break; } }[/sourcecode]

  • Avoid Javascript’s ‘with’ keyword

    Javascript is a fantastic language — in fact, it’s become the language that I do most of my programming in nowadays. It’s flexible, fast, and powerful. Unfortunately, though, it suffers from a few flaws, which, although not critical, can be frustrating. One of the potentially most confusing features is the with keyword, which promises a lot, but can really just make life difficult.

    The with keyword might appear to be harmless enough: it allows you to avoid typing long references; instead of
    [sourcecode language=’javascript’]ah.woom.ba.weh.lyric = ‘In the jungle’;[/sourcecode]
    we can type
    [sourcecode language=’javascript’]with (ah.woom.ba.weh) {
    lyric = ‘In the jungle’;
    }[/sourcecode]

    But what happens if we happen to have a variable in scope named lyric? In the example below, which lyric should be modified?
    [sourcecode language=’javascript’]var lyric = ‘In the jungle’;
    with (ah.woom.ba.weh) {
    lyric = ‘The mighty jungle’;
    }[/sourcecode]
    The simplest way to deal with this issue is to use a variable:
    [sourcecode language=’javascript’]var a = ah.woom.ba.weh;
    a.lyric = ‘The mighty jungle’;[/sourcecode]
    Now there is no ambiguity.

    Based on a post by Douglas Crockford at the YUI Blog.

  • Internet Explorer DOMDocument & XPath

    I discovered a couple of interesting things about Internet Explorer’s MSXML2.DOMDocument object. It turns out that there are essentially two “production-quality” versions of it available: 3.0 and 6.0. Version 6.0 is much the better version, but it’s quite new, and not available on all systems. This means that in IE7 and IE8, instantiating a new MSXML2.DOMDocument object gives you version 3.0.

    Now most of the time, this isn’t a problem. Today, though, I was constructing an XPath expression that used the substring() function; something like this:

    [sourcecode language=’xml’]//Element[substring(Child, 1, 3)=’abc’][/sourcecode]

    This will pull all Elements with a Child element whose value’s first three characters are “abc”. Not particularly complex. It turns out, though, that version 3.0 or the DOMDocument doesn’t actually use XPath as its default language: it uses a bastardised version of XPath called “XSLPatterns”, which just so happens to not support the substring() function at all.

    So how do we deal with this situation? One way is to always instantiate version 6.0 of the DOMDocument:

    [sourcecode language=’javascript’]xd = new ActiveXObject(‘msxml2.DOMDocument.6.0′)[/sourcecode]

    The problem with this approach is that, like I mentioned earlier, you can’t always be guaranteed that your users will have version 6.0 installed (even though it’s a free download). The safer way to deal with this problem is to switch the expression language to XPath in your 3.0 object:

    [sourcecode language=’javascript’]xd = new ActiveXObject(‘msxml2.DOMDocument’);
    xd.setProperty(“SelectionLanguage”, “XPath”);[/sourcecode]

    The advantage of this approach is that you’re not specifying a version, so when MS eventually changes the default to 7.0 (or whatever), your code will work without a problem.

    For more information on this, check out  this blog post from Microsoft’s XML team, which goes into a little bit more detail.