Skip navigation.

exploreopera

| Help

Sign up | Help

Claws, fangs, fur...

...the bear essentials

Pop-Under Script Updated

, , , ...

For those of you that have been awed by my unobtrusive Pop-Under Script, or at least using it, you might be interested to know that I've updated it to:

  • include navigation,
  • work correctly in MSIE8,
  • work mostly correctly in Apple Safari and Google Chrome,
  • and moved its appearance from Windows Vista to Lightbox.


Check it out.

Next stop: adding functionality to show hidden divs in a similar manner. Don't hold your breath.

Google Chrome Beta

, , ,

Good points:
  • installs without needing Admin privileges (increased computer security)
  • seems to start up fast
  • allows to set chrome language apart from preferred web site language
  • some redraw problems with the rendering of embedded media
  • javascript parsing seems pretty fast
  • has developer tools like Opera's Dragonfly
  • loads faster than Apple Safari though both use the same rendering engine (WebKit)


Bad points:
  • installs and activates an updater service without asking (decreased computer security)
  • completely ignores the colour scheme specified in the operating system by the user (especially problematic for people with bad eyesight like me)
  • in the options dialogue: partially takes on the user colour scheme (good) and partially uses its own scheme (bad) which results in completely unreadable texts (black text on black background) (unusable)
  • detected my location or my OS language, and automatically selected the local language as the preferred language
  • page rendering is provided by AppleWebKit (Safari)... the fact that Google failed to publish a Linux version is inexplicable, since WebKit itself is meant for a Unix variant...
  • WebKit has some issues with respecting the user's colour scheme settings
  • WebKit has some issues with recognising HTML5 elements like the audio element, and does not recognise Vorbis nor Theora sources on my system
  • Complete failure to include accessibility options, as opposed to every competitive browser
  • No warning for mismatched security certificates


Conclusion: Google's Chrome is a knock-off of Apple's Safari, with a faster shell.

Harmonica script for BBCode, the OmegaJunior way

, , , ...

So... you implemented a CMS (content management system) that allows for BBCode in an article text... and you want to employ a Harmonica effect to make your article better readable? But since your article contains BBCode you can't set ID's nor Classes... can we still do it?

Yes, we can!
Harmonica Example
Harmonica Javascript

It takes a small bit of unobtrusive javascript, primarily manipulating the DOM, to ensure the original text is available unharmed to visitors who can't use javascript. Let's break down what the script does:

1. It finds the container for the Harmonica. Luckily, that part is a div with an ID... it's the container of the BBCode article. The page is generated using PHP, which picks up the BBCode article, parses the BBCode to HTML and spits it out over the net.

2. It walks through the container's DOM tree, looking for HTMLElements. Because I created the BBCode article, I can predict in what order those elements will appear: a B element followed by text, and that several times in a row.

3. It starts converting the elements into Harmonica elements... B elements will become the Harmonica titles, and the texts in between will be the Harmonica bodies. Unfortunately the texts themselves aren't elements... they're text nodes: blocks of text without elements, thrown into the container div. So we can't collect all P elements, for instance. Instead, we have to walk the DOM tree and look for any node, then figure out whether it's an element or a text node, and react accordingly. The text nodes are converted into P elements, after which we can traverse them the normal way, and we can apply CSS.

4. My BBCode parser turns empty lines into BR elements. They look good outside of a Harmonica, but inside it they only confuse. So they have to go.

5. Because I want to have some kind of animation, collapsing and expanding the Harmonica bodies, I need each P element to hold several bits of information. This is stored in a special, custom object, added to each P element. Since the B elements and the new P elements are all siblings, owner identifications are applied to the P elements as well, in the same custom object. That way, when someone clicks the Harmonica titles to expand its body, we can recognise the correct P elements to expand.

6. To make the animation run smoothly, a window.setInterval is used. That way, the animation shouldn't lock up the browser window nor the visitor's entire computer. To make the animation stop, that interval handle has to be removed. That requires saving the interval handle in a place from where it can be retrieved. Initially I tried saving it in the same custom object as before... I could save it, but not retrieve it. So I had to make a global array to hold all the separate intervals.

7. A bit of CSS and image application creates a different look for the Harmonica, helping the seeing visitors recognise it. I applied separate styles for screen, mobile and print media.

To see what a similar script can do when applying a different bit of CSS, take a look at this
Tab Page Example

Have a look!

Updating the OmegaJunior.Net, using KISS

For those interested in the technology behind the new layout engine of the OmegaJunior.Net (which, entirely uncoincidentally, is my personal web site), here's a bit of disclosure.

The layout engine is a single PHP file that accepts an article name as its only parameter. The article name matches a folder name. If no such folder exists, a 404 message will be presented to the browser.

If such a folder does exist, the layout engine looks for a couple of files, named exactly the same in each folder. This is similar to reading fields in a database record... without the database.

For each file that is found, a layout is generated. The title file is echoed into the page title, the description file is echoed into the page description. The body file is parsed using a BBCode parser borrowed from someone else: that allows for a rather basic mark-up, which suffices for most of my needs. The links file is parsed as an ULHTMLElement, containing a list of hyperlinks. The rest is static text in the layout engine.

The layout engine is extremely simple. The data storage is extremely simple. The CSS is extremely simple. Using the BBCode in the article's body is extremely simple. The impact however, is extremely high.

It's quite a bit of work to update the entire site, seeing how many articles I've published thus far. And though it is a lot... it remains easy.

I'm a professional CMS implementor. I've seen a couple of CMS-es and a couple of internet forum and discussion board systems. Of course, those systems sport a user administration, version control, article workflow and moderation, caching mechanisms... but mine is an extremely fast, easy to use layout engine, coupled to an extremely easy to use storage and update system.

KISS (Keep It Simple, Stupid) will be my motto for now.

With KISS, I can ignore the site's layout engine, and concentrate on the contents of the articles, which most of the time is not so simple.

mysql_paramquery

http://www.omegajunior.net/code/mysql_paramquery.html

PHP 4 and 5 have a built-in function to execute SQL statements on MySQL databases, called 'mysql_query()'.

This function comes in quite handy, but it allows for SQL injection where the parameters are filled with values. In the description of the function this behaviour is acknowledged, and a best-practice is formulated whereby developers should use sprintf() with the auxilary function 'mysql_real_escape_string()'. I found this method quite verbose. Based on the comments I read on the php.net site, and looking at the way various content management systems implemented it, I came up with the following method to allow unlimited numbers of parameters in various places in the SQL statement.

I tested this in a recent project where it proved to work way faster than string replacement methods... but I obviously haven't tested it in every possible circumstance and it's likely I forgot a case or two. Any comments to improve this little piece of code will be appreciated.

Use at your own peril.

HTML5 and other unknown elements for non-HTML5-browsers

, , , ...

Just to see whether I could make sense of the specification-in-progress, I decided to create HTML5-versions of several of the pages in my website, including its homepage. Conclusion: it's feasable, but I'm sure less experienced web authors could use a "Web Authors' Guide to HTML5" (yup, this counts as prior art p: ).

I proceeded to testing how web browsers by various manufacturors displayed that HTML5-page. The results:
  • Opera 9.27: pass
  • Safari 3.1: pass
  • Firefox 3 (latest nightly build): pass
  • Firefox 2: fail
  • Internet Explorer 7: fail


Haven't tried it in MSIE8 yet... I'm part of the feedback program but I didn't want to risk having that beta application wreaking havoc on my system.

Now what's interesting about that list?

Wait, what? Opera 9.27? Does it know HTML5? It may have some basic understanding but I doubt Opera implemented the entire spec... if only because the spec is being developed as we speak. So how can it pass this test? And how is it that Firefox 2 and Microsoft's excuse for a browser fail?

My best guess: it's because of the way browsers handle unknown elements.

Huh?

Point in case: HTML5 has a SECTION element. With it, an author can divide just about any part of the body in, you guessed it, sections. How should such a section be rendered? Should it be a block? A table row? A floating square? The specification doesn't say... it leaves that directive to CSS.

So what should a browser do, when running into an element it doesn't recognise? It could simply ignore the element... but none of the current major browsers chose that option. Bravely, they try their best at displaying it anyway.

With one major difference:

where some browsers (Opera 9, Safari 3, Firefox 3) display the unknown element and apply CSS and javascript rules to that element as provided by the author, some others (Internet Explorer 7, Firefox 2) display the unknown element bare, meaning without CSS and / or without javascript.

Why? Is it a strategic management decision? Is it developer short-sightedness? Is it a technical difficulty? And if so, in what part of the browser? In the HTML-parser, or in the CSS-parser, or in the javascript parser? In all 3? Somewhere else?

It can't be a technical difficulty. After all, all of the tested browsers can handle XML and do render CSS on XML documents... and XML by definition is riddled with unknown elements.

It shouldn't be a CSS-parser problem, as the CSS that I wrote isn't all that difficult and does work when applied to known elements.

It shouldn't be an HTML-parser problem, as all of the tested browsers are well-adept at handling TAG SOUP, especially Internet Explorer (yay, history!).

So that leaves... that leaves a browser trying to render TAG SOUP using standards-compliant render-mode for a doctype that has no DTD where one is expected. It is one thing to have NO doctype, as is the case with many XML documents. It is quite another, to have a document that claims to have a doctype and then breaks the rules by providing neither a public nor a system identifier... which is normal for HTML5, but not for HTML4 nor the XHTMLs.

So unless a browser is instructed to handle such cases, it will behave in unexpected ways. If anything, the fact that both Internet Explorer 7 and Firefox 2 do display the unknown elements shows that the developers did expect some unexpected authoring and made sure their browsers wouldn't crash, which is quite commendable. That makes the fail largely a strategic management decision.

Conclusion: Microsoft's flagship browser and Firefox 2 don't necessarily fail at HTML5... they simply fail at handling unrecognised doctypes altogether.

Thank you absolutely not, mr. Geert Wilders.

, , , ...

I have something to say about Dutch politician Geert Wilders. It was said somewhere else first, and since this partical blog here on the Opera Community site is not intended for political rants, I will provide a link instead:
http://xentor.livejournal.com/28764.html

Javascript Circular Charting

, , , ...

There are multiple ways to create circular charts and diagrams. Usually, a chart is created by a server application, and served as an image to be included in a web page. This has all the usual advantages.

But what if the data for creating a chart / diagram isn't on the server? With all the new AJAX- and other javascript based web applications, the data might live in the client's computer only... it'd be downright silly to send these to the server if the only objective is to have a chart created. (Silly for obvious reasons: speed, bandwidth, server load, security, etc.)

So... if the data exists in the client, why not generate the charts in the client too?

Because browsers don't do graphics.

Sure, they can display graphics, and create new image objects too... but they aren't meant to be a drawing canvas. Any web application allowing such is either based on a plug-in, or an approximation of a drawing application.

Ah, you say, what's wrong with the java, flash, and active-x based plug-ins that allow us to draw up charts and diagrams? Surely they can work with data from the client?

Few things are wrong with those... except for the fact that they are plug-ins. How many browsers do you know that support SVG natively? Microsoft's flagship browser doesn't... instead it offers Microsoft's own variety of xml drawing, supported by no other browser. This means that authors are forced to continue catering to various browser and / or plug-in vendors.

No, thank you.

And some of you may even know that HTML5 will house the CANVAS element, for easy drawing purposes, including circles... however the few implementations I've seen don't work together yet.

Thus I came up with JCC: a method to create circular charts and diagrams using a few images of a disc, a bit of CSS and a bit of unobtrusive javascript.

Currently the methods are able to showcase the technology, but don't allow for real integration with data, yet. That will be the next step.

Examples include:
- 2 circle diagrams
- 3 Venn diagrams

Please note that Venn diagram programming is a specialty I have yet to master. As such, the method showcased is merely an example, ready to be improved by those in the field of programming Venn diagrams.

Also note that the examples in their current state work on 3 browsers:
- Opera 9 and newer (possibly including Opera Mini and Opera Mobile)
- Safari 3 and newer (and thus all kinds of KHTML browsers)
- Firefox 2, 3 beta and newer (and thus all kinds of Gecko browsers)

Thus far only Internet Explorer 6 fails to render the diagrams correctly, due to margin inconsistencies and lack of 24-bit Alpha Transparancy. Internet Explorer 7 does manage to render the diagrams, but miscalculates the image placement. Some tweaking may be needed.

Of course it doesn't stop here. What about pie charts? What about animated discs? What about hyperlinks on each section of a chart? Plenty of room to improve, I'd say.

Link: Javascript Charting

As soon as the HTML5 CANVAS element is implemented in mainstream browsers, JCC will be a thing of the past... but in the mean time: game on!

I hate MSIE (yet again)

, , , ...

Things found as a bug in MSIE7:

1

Set a background colour on generic input elements using CSS, and MSIE7 will apply that background on the outside of radio and checkbox inputs as well... and I found nothing to prevent that, short of not setting it at all.

We could set the background to transparent, but browsers like Opera, Firefox and Safari actually obey that order, rendering the element invisible.

We could use an attribute selector like input[type=text] but some older versions of Microsoft's excuse for a browser don't recognise that.

Thus we are forced to add classes to all our inputs... still.


2

Create an absolutely positioned SELECT element in runtime using createElement and set the focus to that element upon clicking f.i. a button. Make the new element appear next to the button clicked. If the page is longer than the window is high (which is common), MSIE7 (not 6!) makes the page jump... sometimes so far that the focussed SELECT element no longer is in view...

We want to focus the element because creating it in runtime breaks tab order, meaning a user without a mouse can't focus it themselves. But MSIE7 scrolling that element out of view completely destroys that benefit.

Suffice to say that none of the competitors (Safari, Opera, Firefox) display this unfriendliness.


3

Save session scope cookies to the browser, and MSIE7 (and maybe older versions too) will fail to clean them up when the user tells the browser to remove its cookies. All the competitors have a mechanism to remove these...


4

Set a div's CSS position to 'fixed', and MSIE7 will miscalculate all its childrens' heights and widths... instead of calculating in relation to their fixed container, MSIE7 starts calculating in relation to the body, the html, the window... or whatever it chooses at that moment. This is particularly visible if the child element is an IFRAME or an OBJECT.

Solution: make all the children of the fixed container fixed as well, and hand different sizes for those elements to MSIE7 only.

The competition behaves as expected: calculating in relation to the container.


5

MSIE7's XSS prevention (cross site scripting) is a bit too strong to my liking: tell an IFRAME to load a page from a different site, it will... but tell an OBJECT to do the same, and it won't... not even when the correct classid is set for loading text/html. Load a page from the same site and the two elements behave interchangebly.

For the competitive browsers this problem does not exist.


6

Try loading images into OBJECT elements and you will notice that MSIE7 is unable to load JPG and BMP... and maybe more.


7

Serve an XHTML page to MSIE7 as application/xhtml+xml and find that MSIE7 will refuse to render it... it does not know application/xhtml+xml and since Microsoft is keeping hush about MSIE8 it seems they won't be adding support for it any time soon.

Luckily all the other browsers big and small know it, so we can serve real applications to those, while MSIE7 prefers reading TAG SOUP.


8

First tell MSIE7 to load an image with a certain size. Don't supply width and height attributes. Then change the image to something with a different (but near enough) size. Hit ctrl-F5 to force reload without cache. MSIE7 will load the new image... but displays it with the old image's size.

Try opening the image in a new tab page and load it. MSIE7 will load the image nicely, with the correct size. Go back to the original tab and reload the page... still wrong.

Close MSIE7, open the Control Panel for Internet Options, and empty the temporary internet files. Restart the computer, just to be sure. Go back to the page and reload... still wrong.

Still wrong!

Try holding ctrl while clicking the little reload button on the screen, next to the address bar. Finally, MSIE7 decides to read the new image's sizes and display them correctly.

Do I even need to say how the competition fares in this respect?

Adding javascript to a real xhtml page, unobtrusively

Death to document.write()!

Why should we kill the trustful document.write()? It's been around for ages and serves good purpose in lots of web sites!

It's because Google Maps and other web sites continue to use document.write() in XHTML pages, where it is harmful to the web pages and destroys functionality. Google Maps also uses it in their examples, teaching new script adepts wrong techniques. (Outlined in this other article.)

(By the way: the problem is not in the XHTML... nor is it in using document.write() in application/xhtml+xml, as in that mime type the browser simply refuses to execute it. No, the problem is in text/html, where it bloody well overwrites the current document. Wyciwyg...)

There is a different way.

The document.createElement() function (javascript, DOM 1) can create a script element. (Of course, once created and identified, we can reuse the same script element over and over again.) Using element.setAttribute() we can assign a script source. Then we append the new script to the document and we're set.

Here's the code, which I succesfully applied in a different page on my site, including a call-back inside the external script... resulting in a complete and utter annihilation of AJAX-need. :D

if ((document)&&(document.createElement)) {
 var theNewScript = document.createElement('script');
 if ((theNewScript)&&(theNewScript.setAttribute)) {
  theNewScript.setAttribute('id','myNewScript');
  theNewScript.setAttribute('type','text/javascript');
  theNewScript.setAttribute('src','http://domain/dir/script.js');
 }
 if (document.body.appendChild) {
  document.body.appendChild(theNewScript);
 } else if (document.documentElement.appendChild) {
  document.documentElement.appendChild(theNewScript);
 } else if (document.appendChild) {
  document.appendChild(theNewScript);
 }
}


Oh yeah. The script you inject this way, should not contain any document.write() statements itself... In application/xhtml+xml they won't work, and in text/html they may overwrite the entire document... I created a test case for this specific issue:
http://www.omegajunior.net/code/javascriptinjection.php

Happy coding!