[Skip top navbar]

Andrew Gregory's Web Pages

View from Snake Hill, Lake Ballard, 29°26'40"S 120°36'19"E




When Google introduced Gmail on 2004-04-01, they did not initially support Opera. The main sticking point was Opera's lack of XMLHttpRequest support.

Around 2004-06-02 "Mendrik" developed some JavaScript code that more or less emulated the GET functionality of XMLHttpRequest. It did not deal with POST functionality, nor did it attempt to emulate the XMLHttpRequest API.

After looking at his code and thinking about it for a bit, I realised it was possible to develop a drop-in emulation of XMLHttpRequest for Opera. You can read all about it on my web page, Cross-Browser XMLHttpRequest. Note that while the code I have finished up with is over 240 lines long, Gmail support can be provided in as little as 70 (while still keeping it looking nice).

After sorting that out, I continued investigating the Gmail code and found three more issues: one was a bug in Google's own event handling code (fixed by copying event handling code used in a different part of Gmail where Google got it right), one was a trivial cross-browser difference in the numbering of mouse buttons (a one line fix), and the last one was an initialisation issue that only occured with Opera, but was easily worked around (another one line fix). The exact fixes I came up with are given further down this page.

In short, there was no technical reason why Gmail could not have supported Opera from day one, albiet requiring the use of Java. A total of just over 70 lines of code, or about 2.5KB (compared to Gmail's over 250KB of code) was all that was needed. Plus a little will-power from Google.

Some people have used Opera's poor Gmail compatibility as evidence of Opera's poor JavaScript compatibility in general. After working through the problem in detail, and coming up with actual solutions, I came to the opposite conclusion. The XMLHttpRequest support did not require any modifications to the existing Google code. After that, the actual changes that needed to be made to Google's code amounted to about 4 lines of code: 2 lines fixing Google's own bugs, 1 line adding Opera to the IE and Safari mouse button support, and just 1 line working around an Opera issue.

Given the thousands of lines of code comprising Gmail, considered one of the most complicated scripts of its' time, Opera was already compatible with over 99.9% of it! That's not a sign of poor JavaScript compatibility. More like a sign of lack of testing (on the part of Google).

Gmail Now Works With Opera

Within a few months of my figuring out my patches, Google started obfuscating their Gmail code, making it unreadable and preventing my fixes from working!

Thankfully, by that time Opera had released beta versions of their 7.60 browser, which has now become their new 8.0 browser. The new beta included XMLHttpRequest support, plus other fixes to allow Gmail to work with practically no problems. So my fixes were no longer really needed.

Even more recently, Google has unveiled new "legacy" browser support. Unfortunately, in a typical display of browser white-listing, only Internet Explorer, Mozilla browsers, and Safari were deemed as not needing the legacy support. In spite of Opera's complete compatibility with the more advanced and more functional Gmail code, Gmail started switching Opera users over to the legacy version. Naturally, someone came up with a solution!

Gmail POP Settings

Recent versions of Opera automatically fill in the correct server settings when you create a new POP email account using an "@gmail.com" address. However, if you're using a version of Opera that's not quite up-to-date (or simply a different email client), then this web forum post has a screen shot showing the correct settings.

Detailed Information

Shown below are the exact fixes that I came up with. Since the solutions involved modifying the Gmail code slightly, a special proxy server that can change web pages as they are downloaded, such as The Proxomitron, was required.

Each fix was implemented as a separate filter. The first four are the actual fixes that were required to get Gmail working with Opera. The last two were non-critical cosmetic improvements.

Gmail XMLHttpRequest Patch

I developed this patch to insert my XMLHttpRequest emulation at the beginning of the Gmail Javascript code.

Name = "Gmail XMLHttpRequest Patch" Active = TRUE URL = "gmail.google.com" Limit = 256 Match = "<script><!--\s" "var js_load_time" Replace = "<script type="text/javascript" src="http://local.ptron/xmlhttprequest.js"></script>" "<script><!--\n" "var js_load_time" "$STOP()"

Gmail Init Patch

I developed this to work around the issue of Opera not setting an initialisation flag until after Gmail had looked for it!

The Gmail function Init_CreatePage wrote out the complete Gmail web page code in one shot. The page was made up of a number of <IFRAME> elements, each one with an onload event handler. Each event handler required top.js.init to be set before working. Opera appeared to wait after either doc.write or doc.close for the page to load (and hence for the onload event handlers to run). The Gmail code did not set top.js.init until just after doc.close. I could only assume other browsers load the page in the background, allowing the flag to be set before the requested page actually loads.

Name = "Gmail Init Patch" Active = TRUE URL = "gmail.google.com" Limit = 256 Match = "doc\.write\(html\);doc\.close\(\);" Replace = "if(window.opera)top.js.init=true;doc.write(html);doc.close();" "$STOP()"

Gmail Mouse Button Patch

I developed this to handle a cross-browser issue related to identifying the left mouse button.

Some browsers start counting mouse buttons at zero. Others start at one. The Gmail code assumed only Safari and Internet Explorer started counting at one, and every other browser started counting at zero. Unfortunately, Opera is not "every other browser". It starts counting at one like Safari and IE!

Name = "Gmail Mouse Button Patch" Active = TRUE URL = "gmail.google.com" Limit = 256 Match = "FIRST_BUTTON=\(is_safari\|\|is_ie\)\?1:0;" Replace = "FIRST_BUTTON=(is_safari||is_ie||window.opera)?1:0;"

Gmail Compose Events Fix

I developed this to fix a bug in Google event registration code for the email composition screen. The bug would cause Opera to crash. Specifically, in the functions CM_InitComposeEventHandlers and CM_InitSendButtonEventHandlers Google had only implemented an Internet Explorer event handler. I modelled my replacement on code Google had used elsewhere in Gmail to provide cross-browser event support (the CreateEventHandler function).

Name = "Gmail Compose Events Fix" Active = TRUE URL = "gmail.google.com" Limit = 512 Match = "(textarea|button)\1\.on([^=]*)\2=win\.eval\("tmp=function([^\)]*\))\3{return top\.js\.(CM_On[^\(]*)\4\(window,([^\)]*)\5\)(;|;}|};|;};)\6"\);" Replace = "if(is_ie){\1.on\2=win.eval("t=function\3{return top.js.\4(window,\5)}");}" "else{\1.on\2=function\3{return top.js.\4(window,\5);};}"

Gmail Browser Supported Patch

I developed this to fix the sign-on page so it immediately showed the username and password fields if everything appeared to be set up correctly. It did some simple checks to see if you had Java enabled, set Opera to Identify As Opera, and had the XMLHttpRequest patch correctly installed. If any of the tests failed, Opera was reported as an unsupported browser.

Name = "Gmail Browser Supported Patch" Active = TRUE URL = "gmail.google.com" Limit = 256 Match = "function BrowserSupportedByGmail\(\) {" Replace = "function BrowserSupportedByGmail() {" "if(window.opera){var msg='';" "if(navigator.userAgent.substr(0,6)!='Opera/')msg+=' * Opera to Identify as Opera\\n';" "if(!navigator.javaEnabled())msg+=' * Java to be enabled\\n';" "if(!window.XMLHttpRequest)msg+=' * XMLHttpRequest.js to be installed\\n';" "if(msg!=''){alert('These Gmail patches require:\\n'+msg+'A file may not be correctly installed, or you might need to press F12 and adjust some settings.');return false;}" "return true;" "}return OriginalBrowserSupportedByGmail();" "}\n" "//--> </script>" "<script type="text/javascript" src="http://local.ptron/xmlhttprequest.js"></script>" "<script type="text/javascript"><!--\n" "function OriginalBrowserSupportedByGmail() {" "$STOP()"

Gmail Thread Display Patch

A fellow Opera Forum member, umrain, identified the web page code responsible for a poor email list display and also provided the necessary style fix. I modified the solution slightly to more tightly target the specific web page elements.

Name = "Gmail Thread Display Patch" Active = TRUE URL = "gmail.google.com" Limit = 256 Match = "<head\1>" Replace = "<head\1><style type="text/css">table#threads tr.ur td,table#threads tr.rr td{width:auto !important}</style>" "$STOP()"