The Good Life... a weblog about life, technology, and the Opera Web browser

Gmail Rich Text Editing Toolbar (Updated!)

If you use Gmail in Opera 9.0 Preview 1, you've probably noticed that the rich text editing toolbar isn't formatted as it is in other browsers:

Image of Gmail in Opera 9.0 Preview 1

Gmail in Opera 9.0 Preview 1

Image of Gmail in Mozilla 1.8

Gmail in Mozilla 1.8

Instead of all the buttons being on one line, they're bunched together on the left. This is caused by legacy CSS styling on the toolbar.

In CSS1, multiple TABLEs could be displayed on the same line by setting display: inline on the TABLE element. In CSS2.1, this is done using display: inline-table (test case 1, test case 2). If you take the time to wade through the Gmail source code, you'll find that the rich text editing toolbar in Gmail is made via the following function:

function uG(a) {
  var b = "<table cellpadding=0 cellspacing=0 unselectable=on class=tbr><tr>";
  var c = [b];
  var d = 0;
  var e = B ? "tbb2" : "tbb";
  for (var f=0; f < us.length; f++) {
    var g = us[f];
    var h = g[0];
    if (h == "|") {
      c[c.length] = '</table><span class="sv"></span>'+b;
      d++;
    }
    else{
      c[c.length] = "<td><div class="+e+' id="'+La+h+"_"+a+'" unselectable=on ondragstart="return false">'+'<img src="'+qN+'" style="margin-left:-'+(f-d)*18+'px" '+'title="'+g[1]+'"></div></td>'
    }
  }
  c[c.length] = "</table>";
  c[c.length] = wG(a);
  return c.join("")
}

Once that function is run, we end up with the following pseudo-code:

  <table class="tbr">
    <tr>
      <td>
        <div>
          <img>
        </div>
      </td>
    </tr>
  </table>
  <span></span>

The toolbar is made of five such TABLEs in total, which causes the five rows of buttons seen in Opera. The .tbr CSS rule is as follows: .tbr {display:inline;-moz-user-select:none}. As you can see, they specify display: inline;, which won't have the desired effect in a CSS2.1 compliant browser, such as Opera.

The "« Plain text" link at the end of the toolbar isn't included in the code above. Here's the relevant code for it:

function XA (a, b) { 
  var c = a.e() ? uG (a.id) + "  " : "";
  var d =
  var d = "<tr><td><td" + (Gf ? " colspan=2>" : ">") + '<div class="' + "tbo" + '" unselectable=on>' + '<table cellpadding=0 cellspacing=0 style="float:right"><tr>' + '<td style="text-align:right;' + "padding: " + (a.e() ? "5" : "0") + "px 8px 0 8px;" + '-moz-user-select:none;white-space:nowrap"' + " unselectable=on>" + ("<span class=sl" + (B ? ' style="font-size:90%"' : "") + ' id="' + "spck_" + a.id + '">' + Kv(b, a.id) + "</span>" + "<span id=" + "cspd_" + a.id + ' style="display:none"> - ' + '<span class="' + "lk" + " " + "sl" + (B ? '" style="font-size:90%' : "") + '" id="' + "cspck" + '">' + "Done" + "</span></span>") + "</table>" + " " + c + (Es() ? ' <table cellpadding=0 cellspacing=0 style="display:inline"><tr><td style="vertical-align:middle;" id=ht_' + a.id + ' class="' + "lk" + '"><span style="font-size:' + (B ? "90" : "100") + '%">' + jB(a) + "</span></table>" : "") + "</div>";
  return d;
}
function jB(a) {
  if (a.e()) {
    ;
    return "« Plain text";
  }
  else {
    ;
    return "Rich formatting »"
  }
}

That basically boils down to the following:

  <div class="tbo">
    <table>
      <tr>
        <td>
        </td>
      </tr>
    </table>
    <table style="display: inline;">
      <tr>
        <td>
          « Plain text
        </td>
      </tr>
    </table>
  </div>

The .tbo class on the DIV is as follows .tbo {width:100%;background: /* some JS variable */ ;padding-top:2px;-moz-user-select:none}. Since the DIV also contains the problematic toolbar TABLEs mentioned above, we can solve both issues by using the following style override on .tbo: .tbo > table { display: inline-table !important; }.

In Opera 9.0 Preview 2, users will be able to use site-specific CSS rules to override .tbo and fix this problem themselves. Meanwhile, in Opera 9.0 Preview 1, adding the above override to your user CSS will solve the problem. Someone can probably come up with a pretty simple user JS script to fix this in Opera 9.0 Preview 1, too.

Since Internet Explorer and Mozilla don't support inline-table, Google can theoretically solve this issue by changing the .tbr rule to .tbr {display:inline;display:inline-table;-moz-user-select:none}. Thanks to the error-handling rules in CSS, browsers that don't support display: inline-table; will ignore it, leaving them with the CSS1 display: inline rule to style the TABLEs (test case 3). They'll also need to override the inline CSS rule used for the "« Plain text" link.

But wait, there's more! That fix won't work in IE because it tries to do something with display: inline-table even though it doesn't support it. There are plenty of IE CSS hacks that can be used to get around this problem, so I hope it won't stop Google from fixing their error. We've contacted them and asked them to do so, but haven't seen results yet.


Update: I got an e-mail from a CSS Working Group member stating that the handling of display: inline for TABLE will change in the next public CSS2.1 draft. When display: inline is used on a TABLE, an anonymous table element will be created and set to display: inline-table. Assuming this change makes it into the next public draft, we'll update our rendering engine to conform and this issue will go away without Gmail needing to change anything.

I want to stress that Opera is following the current public draft, so this isn't an error in our implementation. I guess this is one of the problems when implementing working drafts.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Note: Comments with a light blue background were made by the site owner.

I think someone in Opera...

I think someone in Opera ( ;) ) should just make Hallvord update browser.js and post a note to check for updates (thus updating browser.js) in the forums.

Those who don't surf the forums also probably don't know about the option to disable the updating, so their browser.js will get updated at some point anyhow.

Gmail is important enough to warrant a "quick fix" from Opera and not just contacting them and asking from someone from the community to write a UserJS for it.

Browser.js is usually

Browser.js is usually reserved for severe problems. This is just a minor display annoyance. Furthermore, since it's only really a problem in a preview release, we'll wait to see if Google acts before the final release before doing anything.

Change the spec?

The problem is that the CSS spec says an anonymous "table" element should be inserted if there isn't one. If that's because the table has been changed to inline, then maybe the spec should specify an inline-table?

Hrm. Wouldn't the inserted

Hrm. Wouldn't the inserted table be display: table, thus block-level? I guess that isn't well-defined.

One of the CSS WG members tells me there are some changes in the current internal draft, so we'll see what happens.

Recent Gecko

Firefox-1.5 can't pass all of your test case, but latest nightly passes them all. Confirmed with Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.9a1) Gecko/20060107 SeaMonkey/1.5a
So the issue is when they(Moz Found.) release the next version, I think.

Firefox 1.5, the latest

Firefox 1.5, the latest Firefox nightly (Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9a1) Gecko/20060107 Firefox/1.6a1), and the latest SeaMonkey nightly (Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9a1) Gecko/20060107 SeaMonkey/1.5a) seem to act exactly the same (as CSS1 compliant browsers) here. According to the Mozilla 1.9 roadmap, inline-table should be available in Mozilla 1.9 and Firefox 3 (due Q1 2007).

Bug 18217 seems to be the Mozilla bug report on the issue.

Only Google has the power to

Only Google has the power to change the specs to conform to their bugs...

The change makes a lot of

The change makes a lot of sense and I doubt Google had much/anything to do with it.

Nice timing though.

Nice timing though.

If you mean to imply that

If you mean to imply that Google pressured the CSS WG into changing this because they saw that it broke Opera 9.0 Preview 1, then your timeline is off. The issue was resolved by the CSS WG (see the last comment) by July 12, 2005, three months before the release of Opera 9.0 Preview 1.

There's just no conspiracy here.

Thanks for this Gmail rich

Thanks for this Gmail rich text explanation, Tim.

I've also noticed that the quoting function doesn't seem to work in v9.0p1, as well... Is this in any way related to this display glitch or totally separate...?

/k

So, how can we fix this?

Sorry but my english may not enough to understand what we have to do.
How can we fix the format of that gmail's text editor in opera? Can someone explain please?

You can:a) Wait until Opera

You can:

a) Wait until Opera 9.0 Preview 2
b) Add a user stylesheet with the rule '.tbo > table { display: inline-table !important; }'
c) Create a user JS to fix the problem

Can this be fixed too?

Thanks for the info. I've just fixed with adding that line you've explained above.

Sorry for bothering but i don't know css enough and couldn't handle this problem. Please look at here: http://my.opera.com/community/forums/topic.dml?id=121483
Do you think it can be fixed with user.css?