Tuesday, November 12, 2013

Quirks Mode

"The good thing about standards is that there are so many to choose from."  I had a good laugh when I read that years ago. Andrew Tanenbaum, in his book Computer Networks, is quite correct.  It was true of computer networks twenty years ago (remember SNA, DECNet, Arpanet, and BITNET, just to name a few), and it's true of web standards and web browsers today.

After laying out a page with <div> tags and testing the page with Internet Explorer, Chrome, Safari, and Firefox, one tester reported the page was not displaying properly.  A bit of investigation revealed that the tester was using Internet Explorer 9.  As of this writing, IE9 is only one release behind the current IE10, so we were puzzled why  IE9 did not render the page as expected.   Further investigation revealed that IE9 behaves differently when viewing intra-net pages and inter-net pages.  For pages served within our corporate firewall, IE 9 runs in "quirks mode", and behaves like IE 5!  "The good thing about standards..."  For pages served from the external network, IE9 behaves like a modern browser.  Google "IE quirks mode", and you will find lots of discussion regarding IE in quirks mode and standards mode. 

We are using APEX to deliver the problem page, so we'll examine one solution to handling this problem in APEX.  Our page just displays information with some links,  and we are not collecting any information nor interacting with the end-user.  This makes things much simpler. Our solution will consist of three parts:
  • we will detect the browser and save the browser in an Apex item
  • we will use two APEX regions, one for newer browsers and a second for older browsers
  • Each region will have a Condition, and we will display the region (or not) depending on the browser
 I discussed browser detection in an earlier post, so I grabbed some code from the demo page. After adding a hidden item in the first region named "P1_BROWSER",  add this PL/SQL anonymous block to a "Before Header" process on the Apex page:
declare

   v_browser_string varchar2(512) := null;

begin

   v_browser_string := upper(owa_util.get_cgi_env('HTTP_USER_AGENT') ) ;

   if instr(v_browser_string,'MOZILLA/4.0') > 0       -- older browser
         or instr(v_browser_string,'MSIE 9') > 0 then -- IE9
      :p1_browser := 'OLD';
   else
      :p1_browser := 'NEW';
   end if;
    

end;

Unfortunately, when we have an IE9 browser, we can't tell what document mode the browser is in.  We could examine the client's IP address, too, but now we're introducing network variables into our code. And the end-user can switch document modes, too.   So, we'll just treat IE9 as an old browser.

Our modern browser region was laid out in three columns with <div> tags.  For older browsers, we can lay out the page with <table> tags:
<table width=100%>
  <tbody>
   <tr>
      <td width=20%>
         <!-- Column 1 content -->
      </td>
      <td width=40%>
         <!-- Column 2 content -->
      </td>
      <td width=40%>
         <!-- Column 2 content -->
      </td>
   </tr>
   </tbody>
</table>      
Next, we need to add a Condition to the modern browser region and the old browser region. The condition should be "PL/SQL Function Body Returning a Boolean", and the code should look like the first line for the modern browser region or the second line for the old browser region.
return :p1_browser = 'NEW';

return :p1_browser <> 'NEW';
Now when a browser requests our page, we detect the browser and display the region that is appropriate for that browser. Modern browsers get the <div> layout, older browers get the <table> layout, and our end-users see the same layout.

Finally, a rant and a plug. When I read Tanenbaum's Computer Networks, I was really impressed by how well written the book is.  Computer Networks was a pleasure to read; I can not say that about many technical books.  Why shouldn't a technical book read as well as a good novel?  Sure, we're all geeks, and we love to learn; but I could read Tanenbaum's book just for the fun of reading it.

No comments:

Post a Comment