From bdb89b555123312c1b0f954f8ba05723b7c7a93d Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Thu, 21 Jun 2012 15:21:56 +0300 Subject: [PATCH] Store measuredSize in map instead of in DOM in IE8 (#8717) --- .../terminal/gwt/client/LayoutManager.java | 30 +++- .../terminal/gwt/client/LayoutManagerIE8.java | 43 ++++-- .../orderedlayout/LayoutResizeTest.java | 140 ++++++++++++++++++ 3 files changed, 200 insertions(+), 13 deletions(-) create mode 100644 tests/testbench/com/vaadin/tests/components/orderedlayout/LayoutResizeTest.java diff --git a/src/com/vaadin/terminal/gwt/client/LayoutManager.java b/src/com/vaadin/terminal/gwt/client/LayoutManager.java index 2281b4ab9c..1b9c184b62 100644 --- a/src/com/vaadin/terminal/gwt/client/LayoutManager.java +++ b/src/com/vaadin/terminal/gwt/client/LayoutManager.java @@ -120,7 +120,7 @@ public class LayoutManager { /** * Assigns a measured size to an element. Method defined as protected to - * allow separate implementation for IE8 in which delete not always works. + * allow separate implementation for IE8. * * @param element * the dom element to attach the measured size to @@ -138,7 +138,17 @@ public class LayoutManager { } }-*/; - private static native final MeasuredSize getMeasuredSize(Element element, + /** + * Gets the measured size for an element. Method defined as protected to + * allow separate implementation for IE8. + * + * @param element + * The element to get measured size for + * @param defaultSize + * The size to return if no measured size could be found + * @return The measured size for the element or {@literal defaultSize} + */ + protected native MeasuredSize getMeasuredSize(Element element, MeasuredSize defaultSize) /*-{ return element.vMeasuredSize || defaultSize; @@ -389,8 +399,13 @@ public class LayoutManager { ((PostLayoutListener) connector).postLayout(); } } - VConsole.log("Invoke post layout listeners in " - + (totalDuration.elapsedMillis() - postLayoutStart) + " ms"); + int postLayoutDone = (totalDuration.elapsedMillis() - postLayoutStart); + VConsole.log("Invoke post layout listeners in " + postLayoutDone + + " ms"); + + cleanMeasuredSizes(); + int cleaningDone = (totalDuration.elapsedMillis() - postLayoutDone); + VConsole.log("Cleaned old measured sizes in " + cleaningDone + "ms"); VConsole.log("Total layout phase time: " + totalDuration.elapsedMillis() + "ms"); @@ -1190,4 +1205,11 @@ public class LayoutManager { public void setEverythingNeedsMeasure() { everythingNeedsMeasure = true; } + + /** + * Clean measured sizes which are no longer needed. Only for IE8. + */ + protected void cleanMeasuredSizes() { + } + } diff --git a/src/com/vaadin/terminal/gwt/client/LayoutManagerIE8.java b/src/com/vaadin/terminal/gwt/client/LayoutManagerIE8.java index 2b677985b5..742594671f 100644 --- a/src/com/vaadin/terminal/gwt/client/LayoutManagerIE8.java +++ b/src/com/vaadin/terminal/gwt/client/LayoutManagerIE8.java @@ -3,21 +3,46 @@ */ package com.vaadin.terminal.gwt.client; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + import com.google.gwt.dom.client.Element; +import com.google.gwt.user.client.ui.RootPanel; public class LayoutManagerIE8 extends LayoutManager { + private Map measuredSizes = new HashMap(); + + @Override + protected void setMeasuredSize(Element element, MeasuredSize measuredSize) { + if (measuredSize != null) { + measuredSizes.put(element, measuredSize); + } else { + measuredSizes.remove(element); + } + } + @Override - protected native void setMeasuredSize(Element element, - MeasuredSize measuredSize) - // IE8 cannot do delete element.vMeasuredSize, at least in the case when - // element is not attached to the document (e.g. when a caption is removed) - /*-{ - if (measuredSize) { - element.vMeasuredSize = measuredSize; + protected MeasuredSize getMeasuredSize(Element element, + MeasuredSize defaultSize) { + MeasuredSize measured = measuredSizes.get(element); + if (measured != null) { + return measured; } else { - element.vMeasuredSize = undefined; + return defaultSize; } - }-*/; + } + @Override + protected void cleanMeasuredSizes() { + Iterator i = measuredSizes.keySet().iterator(); + while (i.hasNext()) { + Element e = i.next(); + if (e.getOwnerDocument() != RootPanel.get().getElement() + .getOwnerDocument()) { + i.remove(); + } + } + } } diff --git a/tests/testbench/com/vaadin/tests/components/orderedlayout/LayoutResizeTest.java b/tests/testbench/com/vaadin/tests/components/orderedlayout/LayoutResizeTest.java new file mode 100644 index 0000000000..455c16c425 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/orderedlayout/LayoutResizeTest.java @@ -0,0 +1,140 @@ +package com.vaadin.tests.components.orderedlayout; + +import com.vaadin.terminal.ThemeResource; +import com.vaadin.terminal.gwt.client.ui.label.ContentMode; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Embedded; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.HorizontalSplitPanel; +import com.vaadin.ui.JavaScript; +import com.vaadin.ui.Label; +import com.vaadin.ui.Table; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.VerticalSplitPanel; +import com.vaadin.ui.themes.Reindeer; + +public class LayoutResizeTest extends TestBase { + + @Override + protected void setup() { + getLayout().setSizeFull(); + + HorizontalSplitPanel split1 = new HorizontalSplitPanel(); + split1.setSizeFull(); + addComponent(split1); + + VerticalLayout left = new VerticalLayout(); + left.setSizeFull(); + split1.setFirstComponent(left); + + left.setSpacing(true); + left.setMargin(true); + + left.addComponent(new Label("

Layout resize test

", + ContentMode.XHTML)); + + Button resize = new Button("Resize to 700x400", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + JavaScript + .getCurrent() + .execute( + "setTimeout(function() {window.resizeTo(700,400)}, 500)"); + } + }); + left.addComponent(resize); + + resize = new Button("Resize to 900x600", new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + JavaScript + .getCurrent() + .execute( + "setTimeout(function() {window.resizeTo(900,600)}, 500)"); + } + }); + left.addComponent(resize); + + left.addComponent(new Label( + "Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin vel ante a orci tempus eleifend ut et magna. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus luctus urna sed urna ultricies.")); + + Table table1 = new Table(); + table1.setSizeFull(); + table1.addContainerProperty("Column", String.class, ""); + for (int i = 1; i <= 100; i++) { + table1.addItem(new Object[] { "Value " + i }, i); + } + left.addComponent(table1); + left.setExpandRatio(table1, 1); + + VerticalSplitPanel split2 = new VerticalSplitPanel(); + split2.setSizeFull(); + split1.setSecondComponent(split2); + + Table table2 = new Table(); + table2.setSizeFull(); + table2.addContainerProperty("Column 1", String.class, ""); + table2.addContainerProperty("Column 2", String.class, ""); + table2.addContainerProperty("Column 3", String.class, ""); + table2.addContainerProperty("Column 4", String.class, ""); + for (int i = 1; i <= 100; i++) { + table2.addItem(new Object[] { "Value " + i, "Value " + i, + "Value " + i, "Value " + i }, i); + } + split2.setFirstComponent(table2); + + VerticalLayout rows = new VerticalLayout(); + rows.setWidth("100%"); + rows.setSpacing(true); + rows.setMargin(true); + for (int i = 1; i <= 100; i++) { + rows.addComponent(getRow(i)); + } + split2.setSecondComponent(rows); + } + + private HorizontalLayout getRow(int i) { + HorizontalLayout row = new HorizontalLayout(); + row.setWidth("100%"); + row.setSpacing(true); + + Embedded icon = new Embedded(null, new ThemeResource( + "../runo/icons/32/document.png")); + row.addComponent(icon); + row.setComponentAlignment(icon, Alignment.MIDDLE_LEFT); + + Label text = new Label( + "Row content #" + + i + + ". In pellentesque faucibus vestibulum. Nulla at nulla justo, eget luctus tortor. Nulla facilisi. Duis aliquet."); + row.addComponent(text); + row.setExpandRatio(text, 1); + + Button button = new Button("Edit"); + button.addStyleName(Reindeer.BUTTON_SMALL); + row.addComponent(button); + row.setComponentAlignment(button, Alignment.MIDDLE_LEFT); + + button = new Button("Delete"); + button.addStyleName(Reindeer.BUTTON_SMALL); + row.addComponent(button); + row.setComponentAlignment(button, Alignment.MIDDLE_LEFT); + + return row; + } + + @Override + protected String getDescription() { + // TODO Auto-generated method stub + return null; + } + + @Override + protected Integer getTicketNumber() { + // TODO Auto-generated method stub + return null; + } + +} -- 2.39.5