16.3.12

Moving to Wordpress, and complaining about Blogger

This will be my last post on Blogger. I've bought my own domain (with a great web hosting provider, A Small Orange) and I've imported everything to Wordpress! You can find my wonderful new Wordpress blog at http://blog.minite.ch/. It has a great new theme, too.

Now, I'll complain about Blogger. I'm sure you've been waiting for this.

  • Blogger's editor is terrible. It floats images by default, which causes several layout problems that require manual HTML editing to fix; it puts seemingly random <br />s everywhere; its HTML editor is severely lacking in features, too, such as tabbing and not replacing all of your custom HTML when you want to preview it in the Compose panel.
  • There are no good themes, and making a custom one is a very unpleasant experience. I ended up hacking in some CSS to make my blogs look prettier. They didn't. Also, did I mention the markup is bloated?
  • There are too many bugs in the CMS. About half the time I log on to Blogger, some part of it is not working, usually the analytics.

I'm going to stop now because I've run out of things off the top of my head to complain about. Maybe that's all of them. Who cares, it's enough, and I'm moving to Wordpress, which is better on so many levels. And it offered to import everything, and it was actually easier than Blogger to set up.

Once again; http://blog.minite.ch/. I am never posting here again and I'll delete this blog next month. Goodbye!

9.3.12

Why I love the new JavaScript autocompletion

JavaScript is a great language. In fact, it is my all-time favourite language, simply because of the amazing flexibility it lends you, and all the situations it can be applied to. Of course, there's the usual JavaScript, client-side, run-in-a-browser JavaScript. Then there's server-side JavaScript, like node.js. JavaScript is used as the scripting language for automation in several programs, like Adobe InDesign. You can use it to do simple math quickly. It's great and it's been around a long time, hence has a ton of great features and libraries.

Now, you can use JavaScript to create Windows 8 Metro apps. This was a good idea. JavaScript, HTML, and CSS are by far the easiest ways to develop a rich application. Attempts at similar ease-of-coding, like XAML and WPF, don't even compare. This is all great. Even better is that Metro apps are just normal webpages. There's no magic syntax involved - but there are all the CSS3 features and more.

Now I'm usually not a fan of autocompletion, except in VB.NET (and to a lesser extent, C#) where it truly shines - VB.NET code is compiled whenever you type a line, and so the IntelliSense is always* accurate and helpful. In HTML, it might be a little annoying. No, I didn't want to indent that; no, I didn't want an end tag just yet. But Visual Studio 11 has been pretty good with the rest - not auto-indenting any tags, allowing you (like most other editors) to type the closing ", >, </p>, etc. by yourself, even if it was automatically placed there. Livable.

It gets a little worse in CSS. First of all, there's the fact that, when you type a property name and a colon, it adds a space. Unlike the HTML editor, if you type another space (which I always do) it'll keep the original space. No thank you. But that's a minor complaint. Then there's the odd default formatting - why do my rules get indented so far? Oh wait, the default behaviour is to indent what it deems "sub-rules". No thank you. Luckily, this can be changed back.

Then we get to the JavaScript autocomplete. And it's actually, really, really good! You can customize all the formatting options, so no problems there. It's nearly the "native" autocompletion of C# and VB.NET. You can't even trip it up with eval('for(var i = 0; i < 100; i++) if(Math.sqrt(i) === Math.sqrt(i) | 0) i;')['toFixed'], because it actually just evaluates the expressions. It is a resounding success, in my opinion. Now whether I'll actually use it is a different matter :)

7.3.12

The real way to clean user HTML in PHP

After much hard work, gruelling effort and arduous toil, I have finally created a worthy HTML-escaping function in PHP. Here it is in all its beauty:

final class Filter {
    private function __construct() {}
    
    const SafeTags = 'a abbr acronym address b bdo big blockquote br caption center cite code col colgroup dd del dfn dir div dl dt em font h1 h2 h3 h4 h5 h6 hr i img ins kbd legend li ol p pre q s samp small span strike strong sub sup table tbody td tfoot th thead tr tt u ul var article aside figure footer header nav section rp rt ruby dialog hgroup mark time';
    const SafeAttributes = 'href src title alt type rowspan colspan lang';
    const URLAttributes  = 'href src';
    
    public static function HTML($html) {
        # Get array representations of the safe tags and attributes:
        $safeTags = explode(' ', self::SafeTags);
        $safeAttributes = explode(' ', self::SafeAttributes);
        $urlAttributes = explode(' ', self::URLAttributes);
        
        # Parse the HTML into a document object:
        $dom = new DOMDocument();
        $dom->loadHTML('<div>' . $html . '</div>');
        
        # Loop through all of the nodes:
        $stack = new SplStack();
        $stack->push($dom->documentElement);
        
        while($stack->count() > 0) {
            # Get the next element for processing:
            $element = $stack->pop();
            
            # Add all the element's child nodes to the stack:
            foreach($element->childNodes as $child) {
                if($child instanceof DOMElement) {
                    $stack->push($child);
                }
            }
            
            # And now, we do the filtering:
            if(!in_array(strtolower($element->nodeName), $safeTags)) {
                # It's not a safe tag; unwrap it:
                while($element->hasChildNodes()) {
                    $element->parentNode->insertBefore($element->firstChild, $element);
                }
                
                # Finally, delete the offending element:
                $element->parentNode->removeChild($element);
            } else {
                # The tag is safe; now filter its attributes:
                for($i = 0; $i < $element->attributes->length; $i++) {
                    $attribute = $element->attributes->item($i);
                    $name = strtolower($attribute->name);
                    
                    if(!in_array($name, $safeAttributes) || (in_array($name, $urlAttributes) && substr($attribute->value, 0, 7) !== 'http://')) {
                        # Found an unsafe attribute; remove it:
                        $element->removeAttribute($attribute->name);
                        $i--;
                    }
                }
            }
        }
        
        # Finally, return the safe HTML, minus the DOCTYPE, <html> and <body>:
        $html  = $dom->saveHTML();
        $start = strpos($html, '<div>');
        $end   = strrpos($html, '</div>');
        
        return substr($html, $start + 5, $end - $start - 5);
    }
}

Enjoy! You may want to modify SafeTags, SafeAttributes and URLAttributes, as well as the URL filtering, depending on your particular needs.

5.3.12

My version of the production/development switch

As the title states, here's my attempt at the most elegant production/development switch. PHP.

    const Environment = //
                             'production'/*/'development'/**/
A star between the // means development, and a simple // means production.

3.3.12

Windows 8: Second impressions

My first impression of Windows 8, in the developer preview, wasn't that good. Maybe it was the square corners, the lack of animation, the ugly Start button, or the frustrating login screen and scrollbars. But I've changed my tune.

A little background: I started downloading the Consumer Preview of Windows 8 the night of February 29th, and tried to upgrade it in the morning. The upgrade utility got to 99%, then failed with an unknown error after about an hour and a half. That was definitely annoying. So, I decided to install Windows 8 on a separate partition; mistake. I already dual-boot Ubuntu, and apparently there was a conflict. I could no longer boot into Windows 7, and I have no Windows 7 installation disc; being the cheapskate that I am, I got mine pre-built at Staples. Windows 8 was nice, but I wanted to go back. So I tried to recover from the Asus recovery partition; another mistake, as it turns out. Unlike the recovery discs that I refused to make, the recovery partition does not include display drivers. That meant no Aero and a stretched screen - not good, and I'd just wasted 3 more hours.

What did I do then? Well, I reinstalled Windows 8, getting rid of the recovery partition, my Windows 7 partition, my Linux partition, and all my data. No problems there - I keep literally all my important data inside my Dropbox, so I was able to recover it within the hour, even on my slow connection. By now, I was absolutely frustrated, vowing to never install Windows 8 again.

Then I actually tried Windows 8 (after all, I didn't have much choice) for real. Got to know it a little. Well, it's awesome. I still miss the round corners, but apart from that... the entire thing is really my kind of operating system. For one, I got away from those stupid Asus drivers that kept making Windows crash on hibernate or sleep. But I also got 8-second boot times. Instant lock, unlock, and resume. 3-second logon and sleep. 3 extra hours of battery life.

So, to sum up: I think I can live with it after all. It's Windows 7, minus nice round corners and a little bit of flexibility, plus a Windows Store and speed. And I did like Windows 7 to say the least :)

Point of irony: I am typing this on a Mac.

18.2.12

Making sketchy text with CSS3, plus a little Webkit goodness.

I recently created an interesting text effect for text with a "sketched" look, similar to that used on Stack Exchange websites in beta. Here's a live demo, best viewed in Google Chrome, of course. The problem, however, is that the color: transparent; makes the text invisible (or just a shadow) on other browsers:

In Webkit-based browsers:

In Firefox:

And in any current version of Internet Explorer, the text is completely invisible. So, how can this be fixed? Well, it turns out that the property (which I thought was completely useless) -webkit-text-fill-color overrides color. So:

color: white;
-webkit-text-fill-color: transparent;

Voilà! We have gracefully degrading sketchy text, or whatever else you'd like to apply. (Now whether this actually looks good remains to be seen.)

12.2.12

Mildly more intuitive database access

PHP, just in general as a language, has a few quirks. Notably (and annoyingly), you can't do this:

$database->query('some query')[0]['value']

No. For some reason, PHP developers thought it would be just grand to disallow array access after a method call, or after any parenthesis. Translation: )[ is always illegal. No expression-then-get-value:

<?php
$array1 = array('1' => 'one', '2' => 'two');
$array2 = array('3' => 'three', '4' => 'four');

echo ($array1 + $array2)['1'];
?>

That just doesn't work. You can get around it by doing this:

<?php
$array1 = array('1' => 'one', '2' => 'two');
$array2 = array('3' => 'three', '4' => 'four');
$result = $array1 + $array2;

echo $result['1'];
?>

Yay, it works now. But it's not exactly a nice solution to the problem. What if we used objects? Now, in this particular case, there's no way to make things better with objects. The + operator isn't overloaded for arrays cast to objects. So, what do we do? Well, in some other cases, you can just use objects. In databases, say. And for reasons unknown, -> can follow a closing parenthesis. So:

$database->query('some query')->item(0)->{'value'}

Yay. Mildly more intuitive database access.