IE7 Beta1 available

According to the IE Blog, IE7 Beta 1 was released to MSDN subscribers recently.

According to the comments, though – …well – let’s just say they should have listened to the community.

The technical documentation on what has changed in the CSS (one of the most important things in IE, according to my own profession), boils down to “we’ve solved at least two bugs”.

However, according to some of the commenters, this beta does even worse in the Acid Test than IE6 (screenshot). I’m viewing it currently in Konqueror for KDE 3.4, and it’s almost perfect – it’s unbelievable how bad that screenshot is!

I’m looking forward to trying this out – surely something which has been in development for so long must have some saving graces?

update: I got a copy of IE7 for myself and have it installed. At first, it refused to display my website, but I managed to get that fixed by applying Dean Edwards’ IE7 script (can’t remember what he’s changing it to) to all IE versions below 8 – not just 7 – evidentally, the browser still sucks.

using Sajax with multiple scripts

My CMS is getting pretty large. So, in order to save the end-user from downloading potentially 100ks of javascript, I’ve started modularising my code; separating the scripts based on their overall purpose.

A problem arose today, where I was using Sajax from two separate external scripts for two different parts of my document. Suddenly, I was getting Error: some_function not callable alerts.

A bit of digging revealed that the stub handler of Sajax, sajax_do_call(), has the URL of the script that created it hard-coded into itself.

Because the handler is a function, it meant that when script A and script B were loaded, the stub handler of script B would overwrite the handler for script A, so the scripts would basically forget how to call the PHP side of the transactions.

So, there was a dilemma – fix Sajax, or only use one Ajax script per page. The answer to that was simple – fix Sajax.

The solution is to rip out the hardcoded URL in sajax_do_call():

 uri = "<?php echo $sajax_remote_uri; ?>";

and replace it with a more extendable version:

 uri = function_urls[func_name];

So now, when Sajax is asked to handle a function, instead of requesting the server response from a hard-coded source, it checks frist to see what source the function was defined by.

To fill the function_url with its required values, place the following line after the definition of x_<?php echo $func_name; ?>() (it’s in sajax_get_one_stub()):

function_urls['<?=$func_name;?>']='<?=sajax_get_my_uri();?>';

The next bit was tricky – we need to initialise the array function_urls, but only if the variable has not already been initialised (otherwise, script B would again overwrite script A).

I couldn’t find a JavaScript equivalent of isset(), so had to come up with an ugly piece of code which does the job (which I described in an earlier post).

 try{
if(function_urls)blah=1/0;
}catch(e){
function_urls=[];
}

isset for javascript

I’ve just fruitlessly searched for an isset() function for javascript, so that I could create an empty array only if one doesn’t already exist.

So, for those of you that are also searching fruitlessly, here’s a way to do it:

try{
      if(variablename)blah=1/0;
}catch(e){
      variablename=[];
}

Fscking ugly, isn’t it?

Anyone know a better way?

why am I trying to build a robot anyway?

People look at me as if I’m insane, when I tell them of my efforts to build a robot capable of automatically growing and caring for vegetables. – or they laugh and say I will still be trying in twenty years time.

To the latter, I just smile, and say “probably”. To the former, though – I don’t understand why people think it is crazy.

This post should hopefully explain my rationale, and maybe even convince you that it’s insane to not at least try it.

Ever since they were invented, computers have been touted as the device which would make everything so much more efficient than before.

But then – so is the same said of every other tool – the plough, for example, helps to till the ground faster, the printing press allows books to be shared faster. The insert-tool-here allows you to insert-job-here faster.

However – in all cases, creating faster and more efficient tools simply allows you to do more work – it doesn’t save you any labour – it just allows you to do more labour in the same time.

Are you working a five hour week? If not, then you are still working around the same lengthy hours that people have done for centuries – you’re just getting more of it done on time.

Efficiency is not the solution! The solution is to remove the need for the work altogether – not to make the work easier to do.

So – here is an alternative idea:

Sit back and relax. Now, think to yourself – why are you working? Is it to get money? What do you need money for?

When I think of it, the reasons for money can be broken into two essential categories and an “optional” category:

  • Essential: housing
  • Essential: food
  • Optional: everything else

The “Optional” category includes such crap as Entertainment, Clothing, Transport, etc. I am not advocating that you should completely ignore those things in your quest for an efficient life – just be aware that they are optional – they are not absolutely necessary for you to be able to live comfortably and without hassle.

When it comes down to it, food is really the most important thing you can spend money on. You can live without entertainment, clothes and a place to live, but you cannot live without food. Let’s ignore the homeless route, though – it’s not comfortable, and we want to be comfortable.

So, assuming we own our own house (work with me here…), the only thing left that you require, that is costing you money, is food. You need to learn to provide food for yourself, without using money.

The easiest way to do this is through gardening (or “farming” – whatever you want to call it). To grow potatoes, for instance, it’s just necessary that you put some potatoes onto some soil, and dump some compost or dead weeds on top of them, and weed it every now and then.

However, that’s just exchanging your office job for a job in the garden – I mean, you could just as well be working for the same amount of hours and buy the potatoes without touching the garden (back to square one). The true way to escape from the drudgery is to have someone else do the job for you.

But – who? If you hire a gardener to do it, then you’ll need to get a job in order to pay the gardener (back to square one again), so you need to somehow get your gardening done from someone that does not require payment.

Let’s take a detour: imagine what your life would be like if you owned your own house, and your food was provided completely free…

You would never need to work, except if you wanted to purchase something. I cannot emphasise how important that is – you would never need to work, unless you wanted to purchase something.

In fact, you could, if you wanted, live out your entire life just chilling out in the back garden of your house, as your robot toiled in the fields. You could learn to enjoy watching the clouds instead of TV. You could learn to get over your need for neat clothes and just let it all hang out. Anything you ever did that could be called “work” would be done purely for the pleasure of it.

If you do feel the need for entertainment, then why not pop around and play a game of cards with someone, or join a band, etc? If you feel the need for clothes, then learn to make your own, or barter for them from someone else.

Once you have everything that you need, the pressure to provided things that you want will disappear.

Sounds fantastic, right?

That’s where my robot comes in.

Robots do not require any form of pay, except in the form of electricity, which can be provided freely anyway, once you’ve installed a wind farm, sterling engine, solar array, or any other alternative renewable electricity source.

I really do not understand why people don’t see it as essential that this dream be brought to fruition – I consider it personally to be the ultimate goal in any civilization to free themselves from all drudgery and allow themselves to do just basically what they want, whenever they want, and without needing to spend 90% of their waking hours hunched over a keyboard.

Building a tree of links with arrays

My CMS‘s admin area has a lot of customisable features, so the navigation needs to be flexible.

Recently, the number of features grew to the point that I needed to implement a hierarchical menu structure, instead of the simple linear one that I had been using.

The script that I use (magicmenu – visible in action here) is an unobtrusive JavaScript which takes an list-tree of links, and converts it dynamically into drop-down menus.

The difficulty is in defining the tree, yet letting your validation scripts do this flexibly. Up until this point, I had drawn out the links immediately upon validating that the user had access to the link, but this is very difficult to do in a hierarchical manner

For example, consider this simple list:

Let’s say you have a user who does not have rights to edit user accounts in any way. In that case, a linear method would draw the Users tree root, but it would not have any leaf nodes:

Ideally, the Users root should not appear. By building the tree in an array beforehand, we can avoid that. Here is a bit of code that builds the above in an array format:

function addMenuItem(&$arr,$file,$nav){
  if(ereg('>',$nav)){
    $bits=explode(' > ',$nav);
    if(!isset($arr[$bits[0]]))$arr[$bits[0]]=array();
    addMenuItem($arr[$bits[0]],$file,str_replace($bits[0].' > ','',$nav));
  }else{
    $arr[$nav]=$file;
  }
}
$arrayMenu=array();
addMenuItem($menuArray,'pages.php','Pages');
addMenuItem($menuArray,'user-accounts.php','Users > user accounts');
addMenuItem($menuArray,'user-groups.php','Users > user groups');
addMenuItem($menuArray,'user-admins.php','Users > admins');
addMenuItem($menuArray,'help.php','Help');

With the above, you do not need to pre-create the Users root – just tell the function you want to create the sub-node, and it will do it for you.

To draw that out, you need one more function, and a line of code:

function drawMenu($menuArray){
  $c='';
  foreach($menuArray as $name=>$item){
    $c.='<li>';
    if(is_array($item)){
      $c.='<a href="#">'.htmlspecialchars($name).'</a>';
      $c.='<ul>'.drawMenu($item).'</ul>';
    }else{
      $c.='<a href="'.$item.'">'.htmlspecialchars($name).'</a>';
    }
    $c.='</li>';
  }
  return $c;
}
echo '<ul class="magicmenutop">'.drawMenu($menuArray).'</ul>';

This code will build a compact tree-list with just the bits that are required.

dynamically created elements and the ie7 script

As you all know, IE is a stupid browser. Luckily, most of the problems with its CSS compliance (and some JavaScript problems as well) can be fixed by applying the IE7 script to the code.

I had a frustrating problem this morning, where I was upgrading my CMS to use hierarchical menus in the administration area (I’ll write about the methods used, later today). The script for that rewrites a <ul> and creates a hierarchical menu from it, which is styled with classes.

The problem was that, once the IE7 script and the hierarchical menu (I call it “magicmenu”) had run, IE simply ignored the classes I’d created.

Eventually I narrowed it down to the order that the scripts were running.

It seems that IE7 removes all class info from elements, adds its own versions of them, and rewrites the existing styles to match the new identifiers. This is grand with simple sites, but hell with dynamic ones.

So, the solution is to run IE7 after all other potential style creation/editing has been done.

lamp.linux.ie

Linux.ie’s LAMP discussion forum is now open. No pushing; plenty of room for everyone.

There was a bit of discussion on the webdev mailing list about whether or not it was superfluous.

My own opinion, is that it was not – lamp.linux.ie’s main reason for existance is discussion of LAMP web-development, by Irish developers. As far as I know, no forum exists for that specific purpose, and it is required.

Advantages to having this specifically for Irish developers:

  • The readers will most likely be acquainted with each other either professionally or socially

  • Use of the forum will grow the readers’ social circle of like-minded people.
  • If a reader is having a particularly sticky problem, there may be someone on the board who can physically come around and help out (for the price of a pint or two, naturally).

I can’t think of any disadvantages.

As for whether or not the site becomes a popular development centre – we’ll just have to wait and see!

IE z-index bug

I was helping hostyle out with a puzzling z-index problem. An element he had given a z-index:100 was appearing below another element of z-index:0.

Finally, we managed to find the problem. It appears that if you have multiple position:relative elements in your code, then IE sets up separate Z layer contexts for each one, which ignore each other.

Here is an example of the bug. Note that Firefox displays it correctly, while IE does not.

Firefox screenshot IE screenshot

To solve it, try to keep the layered elements within the same position:relative context. Other than that, I’m not sure of a workaround.

changing an element’s CSS dynamically

Let’s say you want to change the display of an object to block, and it’s border to 1px solid red. You could do it with:

var el=document.getElementById('your_el');
el.style.display='block';
el.border='1px solid red';

The above will work fine, but in some cases, Internet Explorer will completely ignore what you’re trying to do.

To get around this, we can use setAttribute(), which would look something like this:

document.getElementById('your_el').setAttribute('style','display:block;border:1px solid red');

…which is more efficient anyway, and would be perfect – except that IE is non-standard and ignores that as well…

A version of the above that IE actually works is this:

document.getElementById('your_el').style.setAttribute('cssText','display:block;border:1px solid red');

Now, we can write a simple function to take care of this difference and handle the styling as needed:

function style_element(el,css){
    if(window.attachEvent)el.style.setAttribute('cssText',css);
    else el.setAttribute('style',css);
}
style_element(document.getElementById('your_el'),'display:block;border:1px solid red');

neatly indented folds in vim

If, like me, you use tabs for indenting your code, then you may have been annoyed to find that the amazing folds capability in vim indents its collapsed lines by default with spaces.

An example with bad indents:

      for(var b=0,n=nodeList[a].childNodes.length;b<n;++b){
        var node=nodeList[a].childNodes[b];
        switch(node.tagName){
     case 'A': {-------------------------------------------------------------------------------------------------------------------------------
     case 'UL': {------------------------------------------------------------------------------------------------------------------------------
        }
      }
 

Well, I decided to RTFM, and here is how to correct it.

Edit /usr/share/vim/vim63/syntax/javascript.vim and replace the following line:

set foldtext=getline(v:foldstart)

With this one:

set foldtext=substitute(getline(v:foldstart),'\ ','\ \ ','g')

Note that the first escaped character there is a tab – not a space.

With the above code in place, the broken indentation is easier to read:

      for(var b=0,n=nodeList[a].childNodes.length;b<n;++b){
        var node=nodeList[a].childNodes[b];
        switch(node.tagName){
          case 'A': {--------------------------------------------------------------------------------------------------------------------------
          case 'UL': {-------------------------------------------------------------------------------------------------------------------------
        }
      }