Work around IE6's inability to set innerHTML on a tbody element
Microsoft Internet Explorer 6 and later won't permit JavaScript to set the innerHTML property of a tbody element to arbitrary text, yet every other major browser supports this just fine. To support IE we need to build our HTML inside of a dummy table, and then move the DOM node for the new tbody over to the old table. This requires reaching into the guts of HTMLTable and changing its private final bodyElem field, not something we really should be doing, but it works "well enough" in GWT 1.5.3 that we can get away with it. For now. The better fix is to completely rewrite our FancyFlexTable such that it better supports bulk rendering modes and isn't so tied to the stock HTMLTable GWT implementation. Bug: GERRIT-62 Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
<module>
|
||||
<!-- openid.AllowFrameImpl -->
|
||||
<replace-with class="com.google.gerrit.client.openid.AllowFrameImplSafari">
|
||||
<when-type-is class="com.google.gerrit.client.openid.AllowFrameImpl" />
|
||||
<any>
|
||||
<when-property-is name="user.agent" value="safari"/>
|
||||
</any>
|
||||
</replace-with>
|
||||
<replace-with class="com.google.gerrit.client.openid.AllowFrameImplSafari">
|
||||
<when-type-is class="com.google.gerrit.client.openid.AllowFrameImpl" />
|
||||
<any>
|
||||
<when-property-is name="user.agent" value="safari"/>
|
||||
</any>
|
||||
</replace-with>
|
||||
|
||||
<replace-with class="com.google.gerrit.client.openid.AllowFrameImpl">
|
||||
<when-type-is class="com.google.gerrit.client.openid.AllowFrameImpl"/>
|
||||
</replace-with>
|
||||
<!-- /openid.AllowFrameImpl -->
|
||||
<replace-with class="com.google.gerrit.client.ui.FancyFlexTableImplIE6">
|
||||
<when-type-is class="com.google.gerrit.client.ui.FancyFlexTableImpl" />
|
||||
<any>
|
||||
<when-property-is name="user.agent" value="ie6"/>
|
||||
</any>
|
||||
</replace-with>
|
||||
</module>
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package com.google.gerrit.client.ui;
|
||||
|
||||
import com.google.gerrit.client.Gerrit;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.user.client.Command;
|
||||
import com.google.gwt.user.client.DOM;
|
||||
import com.google.gwt.user.client.DeferredCommand;
|
||||
@@ -38,6 +39,9 @@ import java.util.Map.Entry;
|
||||
|
||||
public abstract class FancyFlexTable<RowItem> extends Composite implements
|
||||
HasFocus {
|
||||
private static final FancyFlexTableImpl impl =
|
||||
GWT.create(FancyFlexTableImpl.class);
|
||||
|
||||
protected static final String MY_STYLE = "gerrit-ChangeTable";
|
||||
protected static final String S_ICON_HEADER = "IconHeader";
|
||||
protected static final String S_DATA_HEADER = "DataHeader";
|
||||
@@ -111,7 +115,7 @@ public abstract class FancyFlexTable<RowItem> extends Composite implements
|
||||
i.next();
|
||||
i.remove();
|
||||
}
|
||||
DOM.setInnerHTML(table.getBodyElement(), body);
|
||||
impl.resetHtml(table, body);
|
||||
}
|
||||
|
||||
protected boolean onKeyPress(final char keyCode, final int modifiers) {
|
||||
@@ -276,10 +280,6 @@ public abstract class FancyFlexTable<RowItem> extends Composite implements
|
||||
}
|
||||
|
||||
protected static class MyFlexTable extends FlexTable {
|
||||
@Override
|
||||
public Element getBodyElement() {
|
||||
return super.getBodyElement();
|
||||
}
|
||||
}
|
||||
|
||||
private static final native <ItemType> void setRowItem(Element td, ItemType c)/*-{ td["__gerritRowItem"] = c; }-*/;
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright 2009 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.client.ui;
|
||||
|
||||
import com.google.gerrit.client.ui.FancyFlexTable.MyFlexTable;
|
||||
import com.google.gwt.user.client.DOM;
|
||||
import com.google.gwt.user.client.Element;
|
||||
import com.google.gwt.user.client.ui.HTMLTable;
|
||||
|
||||
public class FancyFlexTableImpl {
|
||||
public void resetHtml(final MyFlexTable myTable, final String body) {
|
||||
DOM.setInnerHTML(getBodyElement(myTable), body);
|
||||
}
|
||||
|
||||
protected static native Element getBodyElement(HTMLTable myTable)
|
||||
/*-{ return myTable.@com.google.gwt.user.client.ui.HTMLTable::bodyElem; }-*/;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// Copyright 2009 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.client.ui;
|
||||
|
||||
import com.google.gerrit.client.ui.FancyFlexTable.MyFlexTable;
|
||||
import com.google.gwt.user.client.DOM;
|
||||
import com.google.gwt.user.client.Element;
|
||||
import com.google.gwt.user.client.ui.HTMLTable;
|
||||
|
||||
public class FancyFlexTableImplIE6 extends FancyFlexTableImpl {
|
||||
@Override
|
||||
public void resetHtml(final MyFlexTable myTable, final String bodyHtml) {
|
||||
final Element oldBody = getBodyElement(myTable);
|
||||
final Element newBody = parseBody(bodyHtml);
|
||||
assert newBody != null;
|
||||
|
||||
final Element tableElem = DOM.getParent(oldBody);
|
||||
DOM.removeChild(tableElem, oldBody);
|
||||
setBodyElement(myTable, newBody);
|
||||
DOM.appendChild(tableElem, newBody);
|
||||
}
|
||||
|
||||
private static Element parseBody(final String body) {
|
||||
final Element div = DOM.createDiv();
|
||||
DOM.setInnerHTML(div, "<table>" + body + "</table>");
|
||||
|
||||
final Element newTable = DOM.getChild(div, 0);
|
||||
for (Element e = DOM.getFirstChild(newTable); e != null; e =
|
||||
DOM.getNextSibling(e)) {
|
||||
if ("tbody".equals(e.getTagName().toLowerCase())) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static native void setBodyElement(HTMLTable myTable, Element newBody)
|
||||
/*-{ myTable.@com.google.gwt.user.client.ui.HTMLTable::bodyElem = newBody; }-*/;
|
||||
}
|
||||
Reference in New Issue
Block a user