Archive for May, 2009

Fade transition plugin for jQuery

Monday, May 25th, 2009

Update
After requests from Juanma and Manic, below is a modified version of the plugin which demonstrates custom navigation:

All source code is completed untested on any browser except FF3.5, and comes without warranty of any kind. Source code is contained within this file

I’ve been a huge fan of jQuery for a few years now, and it is incorporated in most of my online projects. I’ve never created a plugin for jQuery though, so I thought that maybe I should try my hand at it. My attempt builds on some code I wrote quite a while ago to transition a sequence of images (or any HTML elements, for that matter) by fading out one image, and fading in another. There are plenty of other plugins which achieve the same effect (and are probably better), but feel free to experiment with this one.

There’s really not much source code to this plugin:

(function ($) {
  $.fn.fadeTransition = function(options) {
    var options = $.extend({pauseTime: 5000, transitionTime: 2000, ignore: null, delayStart: 0, pauseNavigation: false}, options);
    var transitionObject;

    Trans = function(obj) {
      var timer = null;
      var current = 0;
      var els = (options.ignore)?$("> *:not(" + options.ignore + ")", obj):$("> *", obj);
      $(obj).css("position", "relative");
      els.css("display", "none").css("left", "0").css("top", "0").css("position", "absolute");

      if (options.delayStart > 0) {
        setTimeout(showFirst, options.delayStart);
      }
      else
        showFirst();

      function showFirst() {
        if (options.ignore) {
          $(options.ignore, obj).fadeOut(options.transitionTime);
          $(els[current]).fadeIn(options.transitionTime);
        }
        else {
          $(els[current]).css("display", "block");
        }
      }

      function transition(next) {
        $(els[current]).fadeOut(options.transitionTime);
        $(els[next]).fadeIn(options.transitionTime);
        current = next;
        cue();
      };

      function cue() {
        if ($("> *", obj).length < 2) return false;
        if (timer) clearTimeout(timer);
        if (!options.pauseNavigation) {
          timer = setTimeout(function() { transition((current + 1) % els.length | 0)} , options.pauseTime);
        }
      };

      this.showItem = function(item) {
        if (timer) clearTimeout(timer);
        transition(item);
      };

      cue();
    }

    this.showItem = function(item) {
      transitionObject.showItem(item);
    };

    return this.each(function() {
      transitionObject = new Trans(this);
    });
  }

})(jQuery);

Usage is also quite straightforward. Include jQuery, and the plugin source, and use this:

    $(document).ready(function() { $(".container").fadeTransition(); });

There are a couple of options to configure the animation properties:

  $(".container").fadeTransition({pauseTime: 5000, transitionTime: 2000, ignore: "#introslide", delayStart: 3000, pauseNavigation: true});

pauseTime is the number of milliseconds each child of .container will be displayed for.
transitionTime is the number of milliseconds the fade in / fade out animation will last for.
ignore is a jquery selector that excludes a particular element from being included in the animation cycle. This is useful for showing an "introductory" slide
delayStart is a time in milliseconds that must elapse before the animation begins
pauseNavigation only allows the fade transition to occur when the user clicks on the navigation buttons

Download the plugin here

See also: DHTML Fade Effect

PHP and the UTF-8 Byte Order Mark

Monday, May 18th, 2009

Another day, another curious problem to be solved…

Today I found that a recently developed project wasn’t rendering too well in (every web developers favourite) Internet Explorer. There were a few tell-tale signs that pointed to IE not understanding the doc-type declaration at the beginning of the file. The first few lines of the generated file were:


< ?xml version="1.0" ?>
< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

Well, there’s nothing obviously wrong with that. As is usually the case, Firefox rendered everything correctly. The HTML output was fully XHTML strict compliant, and the CSS validated too. To add to my confusion, the exact same code hosted on my development server was rendering correctly in all browsers. This gave me a chance to compare the output of the two installations. Here’s what I found:

For my development server:
wget -O- http://dev.server/index.php | hexdump -C | head -n1

gave the following output:

00000000 3c 3f 78 6d 6c 20 76 65 72 73 69 6f 6e 3d 22 31 |< ?xml version="1|

For the live server:
wget -O- http://live.server/index.php | hexdump -C | head -n1

resulted in:

00000000 ef bb bf ef bb bf 3c 3f 78 6d 6c 20 76 65 72 73 |......< ?xml vers |

Aha! The dreaded double byte order mark! UTF-8 files don't need a byte order mark, but somehow at least two had slipped into my source files on the live server, and were causing IE to get all confused. But which files? You can't just view the files, because a byte order marker is not displayed in a text editor. I managed to track down the offending source files using the following script:

for i in `find ./ -type f -name '*.php'`; do hexdump -C $i | head -n1 | grep -i 'ef bb bf' && echo $i; done

This nice bit of bash script finds all files with a “.php” extension, does a hex dump of each and searches for the UTF-8 BOM. If the BOM is found, the first line of the hex dump is displayed and the filename printed below.

On Malware & Antivirus

Friday, May 15th, 2009

My father contacted me recently with a problem with his computer. Whenever he tried to open the windows command prompt (either by clicking on the “command prompt” icon in his start menu, or by typing “cmd” in Start | Run), the window would appear for a brief second on the screen, then close again almost immediately.

It turned out that cmd.exe wasn’t the only application affected. The computer also refused to run regedit, reged32, netstat and others. Added to this, my father reported that his AVG antivirus was having trouble updating, which he presumed was simply because their update server was busy. All of this clearly implies there was at least one piece of malware on his computer, which has somehow slipped past AVG, and disabled it’s update process.

After some Googling, I eventually found a clue on the Avira Antivirus forums. By taking a copy of regedit.exe, and renaming it to something arbitrary, we were able to get the program to run again. The malware had inserted a registry entry into HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Drivers32, and it was being loaded up as a driver on system startup. In this case, the “driver” file being loaded was called “nnpug.wbn“, although I’m sure this varies depending on the whim* of the malware. Deleting this registry value and rebooting had a dramatic effect – all of the reported problems were now gone: cmd.exe and it’s friends would run again, and AVG could now perform updates as normal. We didn’t delete the “nnpug.wbn” file, because we wanted to let the antivirus software identify it, so we could determine what damage had been done.

AVG was updated, and after a full scan it had not detected that our rogue file was a virus! We ended up installing the Avira antivirus program, and that did thankfully pick up the malware and identify it: Trojan-PWS.Delf.AH. There is very little information about this malware on the web at the time of writing, although the one site that had a brief description gave us the worst possible news: the malware harvests usernames and passwords, and hands them back to a remote machine. #$@&*!

So, where does this leave my father’s computer? He’s normally extremely careful about what sites he visits, doesn’t generally open email that isn’t from a known sender, and keeps his machine patched and up-to-date. Yet somehow, this devious malware still managed to install itself as a system driver. Had it not disabled cmd.exe – he would never have even known it was there! Are there any other files lurking on his machine that are as-yet undetected? He’s reluctant to do a complete reinstall of Windows because of the hassle – but surely it must be worth it for the peace of mind?

It’s a pretty sad state of affairs when you need to run two different anti-virus solutions, plus Ad-Aware and SpyBlock just to keep your computer free from nasties, and your personal information personal. This post was never meant to be an anti-Microsoft rant, but really – the world of personal computing has gone insane! Why should we have to install software that makes our computers perform like their running through treacle? Processors shouldn’t be using 1/4 of their capabilities scanning every file that is opened, downloaded, or saved, scanning for registry or system changes just to ensure you’re not infected by some crapware. There must be a better way to safely browse the internet…

There is. Linux (or Mac, if you’re that way inclined).

*I know you’re not supposed to anthropomorphise computers because they don’t like it.