OLIVER WILKERSON

Oliver Wilkerson is not a designer.

Easy-reading CSS
May 14, 2012 - 4:14:42 pm

I've seen a few posts about how to write css for readability (e.g. http://coding.smashingmagazine.com/2008/05/02/improving-code-readability-with-css-styleguides/, http://woork.blogspot.com/2008/03/write-well-structured-css-file-without.html, http://woorkup.com/2009/10/18/5-rules-to-write-more-readable-css-files/) and a lot of them give good common-sense tips, but I'd like to challenge a couple things.

I like to order my CSS selectors based on the order they appear in the HTML. So if I've got this HTML:

<div id="container">
    <div id="logo">...</div>
    <nav id="main-nav">...</nav>
</div>

My css might look like:

#container {
    position: relative;
    top: -10px;

    max-width: 1024px;
    width: 90%;

    margin: 0 auto;

    color: #000;
    
    .box-shadow(0px 0px 4px 1px rgba(127, 127, 127, 0.6));
}

#logo {
    float: left;

    padding: 0.5em 1em;

    font-family: 'LogoFont';
    font-size: 24px;

    color: #c4bb00;
}

#main-nav {
    /* etc */
}

In cases where the content is dynamic and the elements are "reliably" in order, then order based on expected user experience. I do this because debugging that content often requires that order anyway.

Most importantly

I prefer to order my css attributes based on this order:

  • positioning
  • dimensions (width, height)
  • spacing
  • colors
  • effects

I do this because when I'm tweaking or debugging, I'm often not looking in alphabetical order like the blog posts above mention. I'm looking for layout fixes. Or color fixes. Ordering things like this to me makes logical sense as well as makes editing what I'm looking for easy to spot. See the #container css above.

This is just my way. Thought I'd share.

to comment, login using [ google, twitter, facebook ]

Jade instead of HTML: Why I naively think this should be the future.
Apr 26, 2012 - 6:54:45 pm

For some time I've complained that HTML, while a great concept, is just a cruel thing to make someone write out. HTML is too verbose and really, just annoying to write.

So Jade is currently catching my interest a lot. I've said a few times in discussions that I wish instead of writing:

<div id="container">
    <div id="content">
        <section class="talk-section">
            <header class="crazy-cool-text-styles">I type things.</header>
            <p>
                 I would type more things.
            </p>
        </section>
    </div>
</div>

I could write:

#container
    #content
        section.talk-section 
            header.crazy-cool-text-styles I type things.
            p I would type more things.

And that's basically what Jade is. Brilliant.
Let's talk about this. That's 12 lines, 300 characters for HTML and 5 lines, 149 characters for Jade. My fingers feel better just thinking about it.

I'm not going to do a huge post on this. I just wanted to list off some pros and cons. Partially so I can think it out and share, and partially to start conversation about it.

Pros

  • Generally a 60% decrease in characters typed
  • Greatly increased legibility (in my opinion)
  • Still relies on HTML style markup thought process — which is a proven model
  • Makes CSS code-style seem more relevant to layout

Cons

  • No native browser support (A big deal, actually. This is a virtual template layer currently.)
  • Adding script and style tags with code in them just looks weird. Functional, but just looks weird. I prefer for these things to be in external files anyway, but sometimes you must
  • Not sure how easily this could work with custom tags and/or web components
  • Still relies on HTML as a standard; the concept of which is good, but it makes Jade a port of a markup language rather than an actual markup language

I plan on using Jade for internal projects and maybe slowly working into production projects. My development model is to have a debug-mode and release-mode version of my work anyway. The release mode will just compile my Jade into HTML and Coffeescript to Javascript and LESS to CSS. (Though if I ever have to emergency-fix something on a live environment remotely, I'll hate myself a little.)

These aren't some new age, bleeding edge, can't-work-in-the-real-world technologies. They all compile down to things that are in use today. Native support for them would be great, but the real value is rapid development with them in a development environment, and compatible output in a production environment.

to comment, login using [ google, twitter, facebook ]

Chrome Canary Dev Tools – Have your cake and eat it, too.
Mar 22, 2012 - 6:59:04 am

UPDATE I can't guarantee the following method will work all the time always. For instance, the latest builds of dev-tools require some of the bits that are included in Canary. You may have to go back a little bit in the continuous build index to find a version that is compatible with Chrome Stable.

I can't really take credit for this. I caught +Paul Irish after a SXSWi dev-tools panel and asked him, “Is there a way I can get the new Chrome Canary hotness running in Chrome stable?” To which he humorously replied, “Geez! You people can't even wait five weeks?!” And then something along the lines of “I know. I can't go back from the new stuff, either.”

And then he showed me some (relatively) very simple magic.

Elitist Disclaimer: Normally, all my examples I show are in Linux, but I figure most of the people that will find this useful will be on Apple hardware. And most Linux users are smart enough to figure out how to translate the following OS X steps into what they need.

So here's what you do (trust me it's worth it)

  1. Have Google Chrome stable installed. If you're here, hopefully you've already done this.
  2. Download the latest dev-tools from the <reverb>Chrome Continuous Build Index</reverb>
    1. Do that by going here: http://commondatastorage.googleapis.com/chromium-browser-continuous/index.html
    2. Find your OS.
    3. Scroll all the way down and find the latest build. (128075 at the time of this post)
    4. Download devtools_frontend.zip
  3. Extract the dev-tools some place that is appropriate. I like to put mine in a ~/lib/dev-tools/ or /usr/local/lib/dev-tools/ directory.
  4. Now here's the OS X stuff:
    1. In Finder navigate to your Google Chrome (stable) in the Applications folder.
    2. Right-click and Show Package Contents:
    3. Rename MacOS/Google Chrome to something like MacOS/Google Chrome Actual
    4. Highlight your renamed file, and Command + C (Copy).
    5. Open up Terminal and run vim /Applications/Google\ Chrome.app/MacOS/Google\ Chrome
    6. Press i for insert and then Command + V (Paste).
    7. Add –debug-devtools-frontend=/usr/local/lib/dev-tools (or wherever) to the end. Should now have /Applications/Google\ Chrome.app/MacOS/Google\ Chrome – debug...
    8. Press Escape and type :wq to save it.
    9. Then sudo chmod +x /Applications/Google\ Chrome.app/MacOS/Google\ Chrome
    10. Run Chrome and you've got the new dev tools.

Now, why would someone do this?

Why go through all this rather than just download Chrome Canary? Sometimes something you think Chrome stable supports isn't there, but it's in Canary but a) possibly unstable or b) just plain brand new. Theoretical example: What if you use a CSS3 transition that say Canary and Opera Next support, but is not in Chrome stable yet? I know. Small chance, but it could happen.

Another reason I'd like to cite is because you can. And it's cool. So why not take advantage of it?

Doing this means I get the luxuries of the great dev-tool additions that Chrome Canary provides without the worries of Canary-only layout issues. I am using the following features in Chrome stable now, before they have actually been "released".

  • Color picker:
  • User Agent header overrides:
  • Javascript console auto-complete:
  • Pretty Print minified Javascript:

And probably more that I didn't even know about. The beautiful thing is I can use these tools for my development process and not worry about something I've done in my html+css3 that might be “edge”.

to comment, login using [ google, twitter, facebook ]

Actionscript 3 Garbage Collection -- Tools to track down your Flash Player 10-11 memory leaks
Mar 01, 2012 - 10:50:51 pm

I recently had some issues with NetStream/NetConnection never giving up the RAM.
Here's some tips to help in trouble shooting garbage collection in Flash:

You can force garbage collection (only works in the Flash Debug Player architecture)

Use System.gc()
this is really only helpful when determining if all your references have been removed properly. Essentially, if you've done all the things you should, the objects you want to be rid of should go away in RAM once this is called. Don't rely on this to do your cleaning since it's not usable in production.

Track memory usage with AS3

While not the most accurate number, it's still really helpful to use System.privateMemory, System.totalMemory/System.totalMemoryNumber, and System.freeMemory. Something like trace(System.privateMemory) before and after you run System.gc() can tell you quite a bit.

If you really have to get rid of something

If you've got a flash.net.NetStream that just won't go away and seems to insist on squatting in your precious RAM. Break it out and put it into a separate swf file. That's right. I said it. Load it dynamically with a flash.display.Loader. Why? Because of the unloadAndStop() method. This method forces whatever was loaded to not only go away, but to garbage collect right after it does it. Closest thing to System.gc() one can get, really.

Flash Player 11 NetStream.dispose()

If you're fortunate enough to target Flash Player 11 specifically and you're having problems getting rid of a NetStream's data, use NetStream.dispose() when you're done with it. This is basically the same as saying NetStream.close(); System.gc(); except it works in a production Flash Player. Very helpful.
You'll need to be able to target Flash Player 11. If you're not using Flash Builder or the Flex SDK for some crazy reason, here's how to export for Flash Player 11 in the Flash IDE: Adding Flash Player 11 support to Flash Pro CS5 and CS5.5

From my experience, NetStreams and BitmapData are the most common culprits when it comes to memory leaks. BitmapData are easy to handle (hint: BitmapData.dispose() ). NetStreams are the ones that Flash Player seems to have the hardest time letting go of.

I'm sure there are more, but whenever I have issues with memory I mostly use these methods to track them down. Mostly.

to comment, login using [ google, twitter, facebook ]

Sublime Text 2 Build 2181 is out with a new icon.
Feb 22, 2012 - 9:14:07 pm

I know. It might seem silly to post about a post, but this is really a follow-up for my previous Sublime Text post.

The new icon for Sublime Text 2 is quite nice:

The icon for Gnome 3 most likely won't automatically update itself, unless you do a full re-install. So follow steps 2 and 5 on my previous post). Except find the path to the application itself and use the 128x128 icon folder there: For me this is /home/oliver/Applications/Sublime Text 2/Icon/128x128/sublimetext.png

TL;DR just run gnome-desktop-item-edit ~/.local/share/applications/Sublime\ Text\ 2.desktop, click the icon in the window that appears, then navigate to /home/oliver/Applications/Sublime Text 2/Icon/128x128/sublimetext.png

to comment, login using [ google, twitter, facebook ]

How to add Sublime Text 2 to your Gnome 3 applications.
Feb 05, 2012 - 9:22:54 pm

I'm a huge fan of Sublime Text 2. I'm also a pretty big fan of Gnome 3. The problem is that at the time of this post, they don't really like each other when you first get set up. So here's how it's done, son.

The basic trick is that you have to have a .desktop shortcut.

  1. If you haven't already run Sublime Text from it's installed location, do it now.
    Why? To unpack all the packages so we can use the icon.
  2. In gnome-terminal, run gnome-desktop-item-edit ~/.local/share/applications/Sublime\ Text\ 2.desktop.
  3. Fill in the Launcher Properties like so:


  4. Make sure the Command field is an absolute path to your sublime_text executable.
  5. To set the icon, click the "spring-board" icon on there, then navigate to: ~/.config/sublime-text-2/Packages/Default/Icon.png

When you press your super key and search for "Sublime", the launcher you just created should show up. Personally, the first thing I did was right click and "Add to Favorites".

Bonus points: Command line shortcut

  1. Open up your /home/you/bin folder in Nautilus.
  2. In a new window, navigate to your Sublime Text 2 installation.
  3. Hold Control+Alt+Shift and drag the sublime_text executable to the bin folder to create a symbolic link.
  4. Rename that link to "sub"

Now any time you're in terminal and you want to open the current folder in Sublime Text, you just type sub . I use this excessively.

to comment, login using [ google, twitter, facebook ]

PHP CLI sample (argument processing without getopts)
Feb 01, 2012 - 8:37:51 pm

I wanted a more versatile way to parse arguments in php, so I threw this one together. (This is a follow-up to my previous post.) Parsing arguments in php with getopts and such is fine, but if you want unix-like or even windows-like delimiting there's a bunch of funny logic that can go along with that. Re-writing an option parser from scratch every time you need one is well... dumb.

Admittedly, this option parser isn't as straight-forward as the use of boost in C++, but I think it sticks if you use it once or twice. (I wrote it, so how would I know?)

At the beginning of your php script

$app_name = array_shift($argv);
$arguments = array();
$arg_names = array(
    "-h" => "--help",
    "-t:" => "--test:"
);
$arg_count = count($argv);
for ($i=0; $i < $arg_count; $i++) { 
    $arg = $argv[$i];
    $is_arg = strpos($arg, '-') == 0;
    if ($is_arg) {
        foreach ($arg_names as $arg_name => $arg_long_name) {
            $expects_value = strpos($arg_name, ':') !== false;
            $eq_pos = strpos($arg, '=');
            $sets = $eq_pos !== false && $eq_pos != strlen($arg)-1;

            if ($sets) {
                $arg_value = substr($arg, $eq_pos+1);
                $arg = substr($arg, 0, $eq_pos);
            }

            if ($arg == str_replace(':', '', $arg_name) || $arg == str_replace(':', '', $arg_long_name)) {
                if (!$expects_value) {
                    $arguments[$arg_name] = true;
                } else {
                    
                    if ($sets) {
                        $arguments[$arg_name] = $arg_value;
                    }
                    else {
                        $i++;
                        $arguments[$arg_name] = $argv[$i];
                    }
                }
                break;
            }
        }
    }
}

function print_help($app_name) {
    echo "Usage: $app_name [-t|--test-arg] whattosetitto\n";
    echo "\t$app_name description and notes go here\n\n";

}

if (array_key_exists('-h', $arguments)) {
    print_help($app_name);
    exit;
}

$test_arg = $arguments['-t:'];

This method supports the following formats:

  • script_name -s "value"
  • script_name --full-name value
  • script_name --full-name=value
  • script_name -w
  • script_name --whatever
This allows the user to put things into the command line the same way they would for any standard unix/linux command.

Getting the values from the command line is done by just accessing an array using the switch's short-hand as the key. For Example:

//pull the value from an argument that has one;
// $# php ./args_test.php --argument="I just set this to anything I want."
$some_value = $arguments['-a:'];
echo $some_value; //outputs: "I just set this to anything I want."

//find out if someone turned on a non-settable argument
// $# php ./args_test.php -h
$is_switch_on = $arguments['-h'];
echo $is_switch_on === true; //outputs "1"
to comment, login using [ google, twitter, facebook ]

C++ CLI Template sample (argument processing without getopts)
Jan 20, 2012 - 6:49:04 pm

If you've ever had the need to make a C++ CLI application and just want to put something together quickly, you probably want to take in arguments from terminal. All right, but then you have to write all that out. I know it's trivial, but I hate writing that out every time. So here's a template to make your lives easier.

It uses boost libraries.

main.cpp

#include <string>
#include <boost/program_options.hpp>

using namespace std;
using namespace boost::program_options;

void print_help(options_description desc, string app_name) {
    cout << app_name << " [options]" << endl;
    cout << "\tList what the application does here." << endl;
    cout << "Options:" << endl;
    desc.print(cout);
    cout << endl << endl << "Example:" << endl;
    cout << "\t" << app_name << " sample command" << endl << endl;
}

int main (int argc, char * const argv[]) {
    //some docs first
    options_description desc;
    desc.add_options()
        ("help", "Shows this help message.")
        ("sample", value<string>(), "A sample thing.")
        ;

    //read the options
    variables_map vm_arg;
    store(parse_command_line(argc, argv, desc), vm_arg);
    notify(vm_arg);
    
    if (vm_arg.find("help") != vm_arg.end() || argc == 1) {
        print_help(desc, argv[0]);
    }

    //do your stuff here

    return 0;
}

Like I said, this guy uses boost so your Makefile will need to include the boost lib. Here's mine:

Makefile

CC = /usr/bin/gcc
LNK_OPTIONS = \
        -L/usr/lib \
        -L/usr/local/lib \
        -Llib \
        -lboost_program_options-mt 
        
DEBUG_OUTPUT = 1;

#ifeq ($(UNAME), Darwin)
MACOSX_DEPLOYMENT_TARGET_i386 = 10.6
MACOSX_DEPLOYMENT_TARGET_x86_64 = 10.6
SDKROOT_i386 = /Developer/SDKs/MacOSX10.6u.sdk
SDKROOT_x86_64 = /Developer/SDKs/MacOSX10.6u.sdk
CC = /usr/bin/g++
#endif

#
# INCLUDE directories
#
INCLUDE = -I. -I/usr/include -I/usr/local/include -Iinclude

#
# Build cli_template
#

cli_template: 
        rm -f ./main.o;
        make ./main.o 
    $(CC) $(INCLUDE) $(LNK_OPTIONS) \
        ./main.o \
        -o build/Debug/cli_template 

clean: 
        rm -f \
        ./main.o 

install:
        make cli_template;
        cp build/Debug/cli_template /usr/local/bin/cli_template

#
# Build the parts of cli_template
#

# Item # 1 -- main --
./main.o: main.cpp
    $(CC) $(CC_OPTIONS) main.cpp -c $(INCLUDE) -o ./main.o

If anyone has something they use that is cleaner, I'd love to see it. This just goes fast for me.

to comment, login using [ google, twitter, facebook ]