Skip navigation.

exploreopera

| Help

Sign up | Help

Posts tagged with "web"

Poor Javascript Coding Quality

, , ,

What is it with Javascript programmers these days? Doesn't anybody know how to program?

I was investigating why tinyMCE 2 (.1.3) is failing in Opera in some circumstances, and what did I find?

Exhibit 1:
if (tos.getEditorTemplate) editorTemplate = tos.getEditorTemplate(this.settings, this.editorId);
deltaWidth = editorTemplate.delta_width ? editorTemplate.delta_width: 0;
The if statement is there for a reason - to initialize editorTemplate to something useful - but what happens if the statement is false? editorTemplate does not get initialized. Look at the following statement - the potentially uninitialized editorTemplate is used! That would generate an error in any browser.

Exhibit 2:
getRng: function() {
  var s = this.getSel();
  if (s == null) return null;
  if (tinyMCE.isRealIE) return s.createRange();
  if (tinyMCE.isSafari && !s.getRangeAt) return '' + window.getSelection();
  if (s.rangeCount > 0) return s.getRangeAt(0);
  return null
},
isCollapsed: function() {
  var r = this.getRng();
  if (r.item) return false;
  return r.boundingWidth == 0 || this.getSel().isCollapsed
},
getRng is obviously capable of returning null. The very next function, isCollapsed, calls it and immediately uses the returned value without checking for null. That will generate an error in any browser.

It doesn't matter how other browsers somehow manage to avoid these obvious bugs - this is just plain crappy coding.

The worst thing is, this is typical of the sort of code that makes the web go. It's a wonder it works at all.

The Myth of the Robustness Principle

, , , ...

... As It Applies To The Web

The Robustness Principle (AKA Postel's Law) was conceived during the writing of the TCP Internet communications protocol, back in 1981. It is often quoted as:
Be conservative in what you send, liberal in what you accept.

Sometimes it is quoted on the Opera user support forums by people frustrated with Opera's seeming inability to handle web sites as well as Internet Explorer or Firefox. The reasons behind all the web compatibility problems are many and varied, and beyond the scope of this post. The purpose of this post is to show that the application of the Robustness Principle is at least partly responsible for some of the so-called Opera compatility problems.

Application of the Principle

When it comes to web browsers, it's typically the second part of the Principle that's stressed, never the first. The truth is, for robust "it just works" functionality, both parts are equally important.

It is vitally important that when faced with some hiccup in the data, browsers do not fall over. Hence, "be liberal in what you accept". It is just as important when sending data, to make sure that it conforms to all the published rules. Any communication involves at least two parties, and in order to be successful, the language used must be the same. If you're not certain exactly how your language may be interpreted by the receiver, you should make sure what you say is as simple and correct as possible. Hence, "be conservative in what you send".

Browser developers have almost turned themselves inside-out doing the "be liberal in what you accept" part. Web developers have virtually ignored the "be conservative in what you send part".

What does "being conservative" mean for a web developer? At the very least it means the code should conform to published standards, namely the HTML/XHTML, CSS and ECMAScript standards from the W3C and ECMA organisations respectively. That's the only way to ensure that everybody (browsers and developers) are speaking the same language.

Where the specifications are clear, web developers should follow the spec. Where the specifications are unclear, or where they say things like "the results are implementation dependent", then web developers must expect different browsers to do different things and code accordingly (the most robust thing to do would be to avoid unclear functionally completely).

Beyond that, it also means web developers should limit themselves to features widely supported by most browsers. As an example, for nearly a decade HTML 4.01 has specified that you can align table cell contents on a character - for instance, "." to align on decimal points. Very handy for tables of numbers, yet I don't know of a single browser that supports that. (In the defence of browsers, support for that feature is not required.)

If you were to sample sites on the web at random, and test them to see if they conformed to published standards, you'd find probably more than 99% would fail. In essence, that means that web developers have failed to meet their half of the Robustness Principle.

However, even simply following the published rules is not enough. The fundamental problem with the Robustness Principle is that the rules change. Things that were incorrect and therefore ignored according to the Principle, can become correct and require specific behavior as they are implemented. As browsers implement new functionality their behavior naturally changes from earlier browsers that ignored unimplemented features. This is where some "incompatibilities" emerge.

WebForms2

WebForms2 is an extensive addition to the HTML specification. It adds significant functionality to the form controls provided by web browsers, including date (calendar) pickers and field format validation, among many others.

This new functionality has naturally required new HTML parameters (attributes) to be defined in order to request the new functionality. The problem is that many web sites were already using the same parameters for their own use!

The thing is, before WebForms2, the use of such parameters was illegal if you followed the HTML standard. Technically speaking, web sites should not have been using such parameters at all, but following the guide of the Robustness Principle, browsers silently accepted the illegal code.

Then a year or so back, Opera became the first browser to implement WebForms2. Web sites broke, because the illegal attributes they had been using suddenly took on new meaning and different functionality under WebForms2.

For example, this is the reason Opera cannot download printer drivers from the Epson Australia web site. One of the pages in the download process uses a WebForms2 parameter in such a way as to break the Epson Australia server scripts, which results in a never-ending loop of download questions, and Opera never getting to the actual download.

addEventListener

This is how standards-compliant browsers such as Opera, Firefox and Safari allow events to be used on web pages. This function takes three parameters: the type of event to be listened for, the function listening for the event (handling it), and a flag indicating if it is a "capturing" listener or not. Don't worry about what "capturing" means. The truth is, I don't really know the specifics! The specifics aren't important, anyway.

What's important is that up until a few months ago not one browser supported the "capturing" mode - the only mode they supported was the "non-capturing" mode. Following the Robustness Principle, if a web developer happened to request the "capturing" mode, the browsers all helpfully ignored that request and selected the "non-capturing" mode instead.

The problem is that a few months ago, Opera became the first browser to support the "capturing" mode. Suddenly, a good number of web sites stopped working. This was because they were requesting "capturing" mode event listeners, but were coded to only work correctly in the "non-capturing" mode. Browsers had previously accepted the unsupported "capturing" mode without a murmur, giving web developers no indication anything was wrong.

display:inline-block

This is a bit of CSS that is well-supported by Opera and Safari, poorly supported by Internet Explorer, and not supported at all by Firefox. Nevertheless, I have seen several web sites use it, and always in such a way that Internet Explorer ignored it. The result is that Internet Explorer and Firefox effectively ignored the command (following the Robustness Principle), while Opera and Safari understood and processed it. The result is a corrupted web site display in Opera and Safari, but a perfect looking web site in Internet Explorer and Firefox.

"display:inline-block" isn't the only problem CSS. Threads on the Microsoft TechNet forum have huge extra spaces all over the place. This is because the site uses "white-space:pre-wrap", which is again only supported by Opera and Safari. The forthcoming Firefox 3 adds support for that CSS, so Firefox 3 has worse compatibility with that site compared with Firefox 2.

Being Robust is not Being Compatible

This post should by now have clearly demonstrated that simple acceptance of incorrect code will have significant consequences later on. The pain avoided today is simply deferred until tomorrow.

In many ways, the Robustness Principle is actually creating a web that is less robust! It certainly does nothing to fix compatibility problems - rather it creates them!

The solution to web site compatibility problems cannot be found in the Robustness Principle.

No Clear Solution

There is no easy solution to these sorts of problems. The only real solution is to get web developers to avoid unsupported features and to rigorously stick to published rules for HTML, CSS and JavaScript. However, the first browser to dump the Robustness Principle and refuse to accept broken code would quickly become an outcast and ignored by both web developers and users alike.

Education, while keeping the Robustness Principle is in my opinion one of the better solutions. The best example of this I've seen is the iCab smiley. If all browsers could implement a similar feature it would provide a subtle hint to web developers that all is not right with their code. They might be less likely to produce incorrect code if they knew that their visitors could easily see that their code was incorrect.

Such a feature would not fix all incompatibility problems, but it would be a big step in the right direction.

Everybody - web surfers, web developers, browser developers - we all want a web that "just works". Blind acceptance of incorrect code is not the answer. The solution must lie elsewhere.

TPG Web Menus

, ,

There's been some discussion on the Opera forums about Opera and web compatibility, which has prompted me to blog this for future reference...

The navigation menus on the TPG web site are nearly unreadable in Opera, but fine in IE, Firefox, etc. More code Opera just can't handle?

Nope.

http://www.tpg.com.au/res/js/stm31a.js

These are old SoThink menus, long since updated by SoThink, but TPG persists in using them.

Line 1010:
nVER=parseFloat(a.substring(a.indexOf("Opera ")+6,a.length));


The menus are sniffing for "Opera " - note the space. That only appears in the User Agent string when Opera is identifying as Firefox or IE (which works around the problem). For Opera identifying as itself, the space isn't there, which results in the sniffing failing and the script determining that Opera is version 0! Which is too old for the script to handle.

The fix is trivial - delete the space:
nVER=parseFloat(a.substring(a.indexOf("Opera")+6,a.length));


I emailed the TPG web master many, many months ago (probably a year or two, now), giving them the exact file name, line number and change to make. Could they find the time to delete a single character? I guess not. :frown:

Opera 10 is too old!

, , ,

Not that Opera have released version 10 (yet!), but it looks like at least one site is going to reject Opera when they do. And where there's one site, no doubt there's hundreds of others :frown: Thankfully, a quick search doesn't quickly turn up anything similar, although there are plenty of other bad examples.

Anyway, here's the problem code:
if (navigator.userAgent.toLowerCase().indexOf("opera") != -1)
{
   isOpera = true;
   i = navigator.userAgent.indexOf("Opera") + 6;
   v = parseInt(navigator.userAgent.substring(i, i+1));
   if(v < 7)
      isOperaOld = true;
}
Need a clue? The substring will return exactly one character.

If you're one of those people irritated at how poorly Opera appears to handle web site scripting - this is one of the bigger reasons. It's straight-out careless programming without thought.

I'll mention that the site in question isn't delivering bugs to just Opera. Their corresponding IE code had the exact same problem, except that IE is quite a bit further away from version 10 than Opera.

The problem remains for Opera:
  1. Opera release version 10.
  2. Web sites stop working in Opera, all other browsers work fine.
  3. "Opera is a crappy browser, never works!"
Yet, where is the bug? What should Opera do about it? Never release a browser with a version where the first digit is between zero and six inclusive? Will the Opera after 9.5 be 70.0? :insane:

Congrats to Safari on Acid 3

, , , ...

Many congratulations to the WebKit team on the first public release of Safari that passes Acid3 - the first browser to do so! :hat:

This is on the same day that Opera announce reaching 100/100 on the Javascript part of Acid3. Congratulations all round!

The Acid tests are great for bragging rights, but it's important to remember that they test only a tiny fraction of the web technology browsers and developers use. Jeff Schiller points out that while Acid3 has some SMIL tests, the Acid3-passing Safari only passes 5 out 116 SVG animation tests. In other words, SVG animation is still probably unusable in Safari.

Opera doesn't pass Acid1, but that hasn't stopped it from passing Acid2, almost passing Acid3, and being a great all-round browser. The current release of Firefox doesn't even pass Acid2, but that doesn't seem to be causing them any problems.

Ian Hickson has expressed surprise that Acid3 was conquered so soon. It make me feel that perhaps Acid3 spent too much time testing little-used corner cases, that while important, aren't the sort of things web developers are really looking for.

The Acid tests provide a nice, high-profile publicity point for browser developers. They're a quick "media bite" for journalists and those not too familiar with web technology. However, I'm not so sure they progress web standards support that much.

I think I'd much rather see more effort put into developing comprehensive test suites for the various standards. Microsoft recently submitted a CSS2 test suite to the W3C. That type of thing seems to me to be a more productive use of developer's time.

I'm hoping the next Acid test (they'll just keep on coming!) will include features that web developers are wanting to use now. That's not saying the existing Acid tests don't already do that, but I'm thinking of things like rounded corners and multi-column support. I know that the specs for those aren't even done yet - that's why they need to be accelerated and tested. A high-profile test that encourages implementation of useful things, but is still capable of being changed in response to developer experience is what's needed IMHO. I don't think we should be waiting for specs to finalize in their own time. Judicious implementation and testing should be able to force things along faster.

Acid3 is still so new it squeaks, but I'm already looking forward to Acid4! :devil:

Layout tables are nice

, , ,

:yuck: More anti-table zealotry!

Sure, I've seen stacks of sites that over-use tables for layout, but seriously, the existing CSS methods for emulating table layouts without tables are all ridiculously complex, fragile, and error-prone. The amount of hoops you have to jump through to produce a common three-column equal-height layout with header and footer without tables is just stupid. And all you need to do to make it fall apart is look at it the wrong way!

Let's face it - until there is broad support for the proper way to do table layouts (i.e. CSS display:table-* properties - I'm look at you, MSIE!), by far the simplest and most robust way to do a table layout is to use a table. CSS may technically be up to it, but browser CSS support is not.

Here's a case in point. I recently evaluated CMSimple for whipping up a quick and easy to use website. This is a slightly abridged version of the default page template:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head><?php echo head();?></head>
  <body bgcolor="#808080" <?php echo onload();?>>
    <a id="TOP" name="TOP"></a>
    <table align="center" width="750" border="0" cellpadding="0" cellspacing="0">
      <tr>
        <td valign="top" colspan="2">
          <table align="center" width="100%" border="0" cellpadding="10" cellspacing="0" bgcolor="black" style="background-image: url(<?php echo $pth['folder']['templateimages']?>top.jpg);">
            <tr>
              <td valign="bottom" class="sitename" height="80">
                <font color="white"><?php echo sitename();?></font>
              </td>
              <td valign="top" align="right">
                <table align="center" width="100%" border="0" cellpadding="10" cellspacing="0">
                  <tr>
                    <td valign="top" align="right" class="searchbox"><?php echo searchbox();?></td>
                  </tr>
                </table>
              </td>
            </tr>
          </table>
        </td>
      </tr>
      <tr>
        <td valign="top" width="200" bgcolor="#c0c0c0">
          <table align="center" width="100%" border="0" cellpadding="5" cellspacing="0">
            <tr>
              <td valign="top"><?php echo toc();?></td>
            </tr>
            <tr>
              <td valign="top" class="menu"><?php echo sitemaplink();?></td>
            </tr>
            <tr>
              <td valign="top" class="menu"><?php echo lastupdate();?></td>
            </tr>
          </table>
        </td>
        <td valign="top" width="550" bgcolor="white">
          <table align="center" width="100%" border="0" cellpadding="5" cellspacing="0">
            <tr>
              <td valign="top" class="locator" bgcolor="#808080"><?php echo locator();?></td>
            </tr>
            <tr>
              <td valign="top">
              <?php echo editmenu();?><?php echo content();?><?php echo submenu();?>
                <p>
                   
                </p>
              </td>
            </tr>
          </table>
        </td>
      </tr>
      <tr>
        <td bgcolor="#808080" align="center" class="navigator">
          <!-- YOU ARE NOT ALLOWED TO REMOVE OR HIDE THIS LINK WITHOUT A COMMERCIAL LICENCE-->
          <a href="http://www.cmsimple.dk/" class="navigator">Powered by CMSimple</a>
          <!-- IF REMOVE OR HIDE: Then you must pay for a licence - see http://www.cmsimple.dk/?Licence -->
        </td>
        <td bgcolor="black" valign="top">
          <table width="100%" border="0" cellpadding="5" cellspacing="0">
            <tr>
              <td width="33%" class="navigator" valign="top"><?php echo previouspage();?></td>
              <td align="center" width="33%" class="navigator" valign="top"><?php echo top();?></td>
              <td align="right" width="33%" class="navigator" valign="top"><?php echo nextpage();?></td>
            </tr>
          </table>
        </td>
      </tr>
    </table>
  </body>
</html>
Yep - far too many nested tables. It's also a fixed width and proved very stubborn trying to make it into a flexible-width layout. In fact, with all the tables in there, I gave up. I pulled it apart and re-built it from scratch:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<?php echo head();?>
</head>
<body <?php echo onload();?>>
<div id="TOP"></div>
<div id="header">
<span class="sitename"><?php echo sitename(); ?></span>
<?php echo searchbox(); ?>
</div>
<table id="body" class="layout">
<tr><td id="nav">
<?php echo toc(); ?>
<div id="sitemaplink"><?php echo sitemaplink(); ?></div>
<div id="lastupdate"><?php echo lastupdate(); ?></div>
</td><td id="content">
<div id="locator"><?php echo locator(); ?></div>
<?php echo editmenu(); ?>
<?php echo content(); ?>
</td></tr>
</table>
<div id="copyright">
<!-- YOU ARE NOT ALLOWED TO REMOVE OR HIDE THIS LINK WITHOUT A COMMERCIAL LICENCE -->
<a href="http://www.cmsimple.dk/" class="copyright">Powered by CMSimple</a>
<!-- IF REMOVE OR HIDE: Then you must pay for a licence - see http://www.cmsimple.dk/?Licence -->
</div>
</body>
</html>
Much, much more simple! The effort put into the single layout table probably amounted to a minute or two. I know I would have spent hours trying to achieve the same thing without tables. I could have done it, I have no doubt, but it's just not worth the time.

It's all about the right tool for the job. If the right tool (CSS display:table-*) is not available, then the second best (table markup) will have to do. A bunch of nested divs, with carefully matching widths and negative margins, etc is not an improvement!

I'm quite certain that the anti-table CSS mindset is second only to Internet Explorer itself for unproductive time lost forever.

Cloaked document.all support

, , ,

For the latest Opera snapshot, hidden document.all functionality has been implemented.

Even if this results in some web sites breaking, this is good news on the "web site compatibility" front, as now all non-IE browsers (Opera, Firefox and Safari) now handle document.all in more-or-less the same way. Web developers love consistency!

Microsofts Compatibility Problem

, , ,

So, the Microsoft team are busy working away on version 8, and they're finding all sorts of web sites are breaking.

Welcome to the world of web development, Microsoft! It's what everybody else has to deal with!

Make no mistake, this is a real problem for Microsoft. They have to support legacy web sites. Often such sites are unmaintained intranet sites that would need to be totally rebuilt to support a new standards-compliant browser.

In their quest for a solution, Microsoft decided to get some outside advice, and the best they could find was a browser-specific meta tag.

:yuck:

I've already left my take on the problem, but I'll repeat it here:

The problem is fundamentally a Microsoft problem. It's a problem where sites have not developed a "web site", but have instead developed an "Internet Explorer site". This is not a problem to be solved by standardizing a new tag for all browsers. It's a problem to be solved by Microsoft and Internet Explorer.

The best solution to handling "Internet Explorer sites" is to have a dedicated "Internet Explorer browser". In practice, that would have to be a standalone copy of Internet Explorer 6. Maybe version 7, but there's already plenty of grumblings from places who have blocked updates to IE7 because it breaks their IE6 sites.

It's already possible to have a "nearly standalone" copy of IE6. Some details such as conditional comments don't work properly, and maybe some other things too, but it's hard to see it being a massive task for Microsoft to sort those out and end up with a truely standalone version of IE6 to be used for those legacy sites.

That would 100% solve Microsoft's compatibility problems and free up their IE development team to concentrate on bug fixes and new standards-based features.

Note that Microsoft's existing VM-based browsers don't solve the problem, as their customers will certainly want to set up icons to launch their legacy sites in the old browser, and I don't see how that could be done with a VM.

Opera, Not XHTML+SVG+MathML Compatible?

, , , ...

A few days ago I posted IE, XHTML, MathML, and SVG! with instructions for how to set up a web page that could be served as application/xhtml+xml and contain SVG and/or MathML embedded into the XHTML to not just Opera, Firefox and Safari, but to IE as well.

That could have been a bit soon, though.

It seems every one of those mentioned browsers, except for Opera, supports the additional character entities defined in HTML/XHTML beyond those specified in XML. It means things like "&nbsp;" show as "&nbsp;" in Opera, but are the expected non-breaking space in all the others.

I think this has been reported before, but I'm not sure. It's quite disappointing anyway.

Stupid CSS Mistakes

, , ,

I was just perusing the Opera error console, having a peek at some of the CSS mistakes sites make. Usually it's just full of stupid mistakes that could be easily detected and corrected in seconds, if only the code had been run past the validator.

However, the following gem stood out for me:
vertical-align: right;

Congratulations, http://www.amazon.co.uk/ !
July 2008
SMTWTFS
June 2008August 2008
12345
6789101112
13141516171819
20212223242526
2728293031