]> source.dussan.org Git - vaadin-framework.git/commitdiff
Renamed UI package which accidentally had been renamed to upper case
authorArtur Signell <artur@vaadin.com>
Tue, 4 Sep 2012 19:27:23 +0000 (22:27 +0300)
committerArtur Signell <artur@vaadin.com>
Tue, 4 Sep 2012 19:27:23 +0000 (22:27 +0300)
client-compiler/src/com/vaadin/server/widgetsetutils/WidgetMapGenerator.java
client/src/com/vaadin/client/ApplicationConnection.java
client/src/com/vaadin/client/ComponentLocator.java
client/src/com/vaadin/client/VDebugConsole.java
client/src/com/vaadin/client/ui/AbstractComponentConnector.java
client/src/com/vaadin/client/ui/UI/UIConnector.java [deleted file]
client/src/com/vaadin/client/ui/UI/VUI.java [deleted file]
client/src/com/vaadin/client/ui/ui/UIConnector.java [new file with mode: 0644]
client/src/com/vaadin/client/ui/ui/VUI.java [new file with mode: 0644]

index b90791d61b752abcf69006baf3b40114c7ca57b3..c1fb6df88322b58325f6087a9979a5e570adefc9 100644 (file)
@@ -37,7 +37,7 @@ import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
 import com.google.gwt.user.rebind.SourceWriter;
 import com.vaadin.client.ServerConnector;
 import com.vaadin.client.ui.UnknownComponentConnector;
-import com.vaadin.client.ui.UI.UIConnector;
+import com.vaadin.client.ui.ui.UIConnector;
 import com.vaadin.server.ClientConnector;
 import com.vaadin.shared.Connector;
 import com.vaadin.shared.ui.Connect;
index 6a1474fa45a020c795d14a68a3ebe1a3a6ff510d..a4de5dd4ad20a765ba145ecd22b82ef4f3e7f21f 100644 (file)
@@ -70,10 +70,10 @@ import com.vaadin.client.metadata.TypeData;
 import com.vaadin.client.ui.AbstractComponentConnector;
 import com.vaadin.client.ui.AbstractConnector;
 import com.vaadin.client.ui.VContextMenu;
-import com.vaadin.client.ui.UI.UIConnector;
 import com.vaadin.client.ui.dd.VDragAndDropManager;
 import com.vaadin.client.ui.notification.VNotification;
 import com.vaadin.client.ui.notification.VNotification.HideEvent;
+import com.vaadin.client.ui.ui.UIConnector;
 import com.vaadin.client.ui.window.WindowConnector;
 import com.vaadin.shared.ApplicationConstants;
 import com.vaadin.shared.ComponentState;
index 0701d4ff215f0f0f510a788ef9ffb6bf7514f0db..89e022c1795bd83dec40be075fb9f4182d38979d 100644 (file)
@@ -25,10 +25,10 @@ import com.google.gwt.user.client.ui.HasWidgets;
 import com.google.gwt.user.client.ui.RootPanel;
 import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.client.ui.SubPartAware;
-import com.vaadin.client.ui.UI.VUI;
 import com.vaadin.client.ui.gridlayout.VGridLayout;
 import com.vaadin.client.ui.orderedlayout.VMeasuringOrderedLayout;
 import com.vaadin.client.ui.tabsheet.VTabsheetPanel;
+import com.vaadin.client.ui.ui.VUI;
 import com.vaadin.client.ui.window.VWindow;
 import com.vaadin.client.ui.window.WindowConnector;
 import com.vaadin.shared.ComponentState;
index 2db5e028cfd562b59333c872cb16eba5b125c30c..51504ae4e132f08bf97f139b556833063c52d6f2 100644 (file)
@@ -69,8 +69,8 @@ import com.google.gwt.user.client.ui.VerticalPanel;
 import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.client.ui.VLazyExecutor;
 import com.vaadin.client.ui.VOverlay;
-import com.vaadin.client.ui.UI.UIConnector;
 import com.vaadin.client.ui.notification.VNotification;
+import com.vaadin.client.ui.ui.UIConnector;
 import com.vaadin.client.ui.window.WindowConnector;
 import com.vaadin.shared.Version;
 
index 294d793050c4abb75094e21da109ebbfdb4491f1..2e30fbbc0291e2a057e451e033cc65c0d158c0d7 100644 (file)
@@ -37,8 +37,8 @@ import com.vaadin.client.communication.StateChangeEvent;
 import com.vaadin.client.metadata.NoDataException;
 import com.vaadin.client.metadata.Type;
 import com.vaadin.client.metadata.TypeData;
-import com.vaadin.client.ui.UI.UIConnector;
 import com.vaadin.client.ui.datefield.PopupDateFieldConnector;
+import com.vaadin.client.ui.ui.UIConnector;
 import com.vaadin.shared.ComponentConstants;
 import com.vaadin.shared.ComponentState;
 import com.vaadin.shared.Connector;
diff --git a/client/src/com/vaadin/client/ui/UI/UIConnector.java b/client/src/com/vaadin/client/ui/UI/UIConnector.java
deleted file mode 100644 (file)
index cb8b0ec..0000000
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * Copyright 2011 Vaadin Ltd.
- * 
- * 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.vaadin.client.ui.UI;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import com.google.gwt.core.client.Scheduler;
-import com.google.gwt.dom.client.NativeEvent;
-import com.google.gwt.dom.client.Style;
-import com.google.gwt.dom.client.Style.Position;
-import com.google.gwt.event.logical.shared.ResizeEvent;
-import com.google.gwt.event.logical.shared.ResizeHandler;
-import com.google.gwt.user.client.Command;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.History;
-import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.ui.RootPanel;
-import com.google.gwt.user.client.ui.Widget;
-import com.google.web.bindery.event.shared.HandlerRegistration;
-import com.vaadin.client.ApplicationConnection;
-import com.vaadin.client.BrowserInfo;
-import com.vaadin.client.ComponentConnector;
-import com.vaadin.client.ConnectorHierarchyChangeEvent;
-import com.vaadin.client.ConnectorMap;
-import com.vaadin.client.Focusable;
-import com.vaadin.client.Paintable;
-import com.vaadin.client.UIDL;
-import com.vaadin.client.VConsole;
-import com.vaadin.client.communication.RpcProxy;
-import com.vaadin.client.communication.StateChangeEvent;
-import com.vaadin.client.communication.StateChangeEvent.StateChangeHandler;
-import com.vaadin.client.ui.AbstractComponentContainerConnector;
-import com.vaadin.client.ui.ClickEventHandler;
-import com.vaadin.client.ui.ShortcutActionHandler;
-import com.vaadin.client.ui.layout.MayScrollChildren;
-import com.vaadin.client.ui.notification.VNotification;
-import com.vaadin.client.ui.window.WindowConnector;
-import com.vaadin.shared.MouseEventDetails;
-import com.vaadin.shared.ui.ComponentStateUtil;
-import com.vaadin.shared.ui.Connect;
-import com.vaadin.shared.ui.Connect.LoadStyle;
-import com.vaadin.shared.ui.ui.PageClientRpc;
-import com.vaadin.shared.ui.ui.UIConstants;
-import com.vaadin.shared.ui.ui.UIServerRpc;
-import com.vaadin.shared.ui.ui.UIState;
-import com.vaadin.ui.UI;
-
-@Connect(value = UI.class, loadStyle = LoadStyle.EAGER)
-public class UIConnector extends AbstractComponentContainerConnector implements
-        Paintable, MayScrollChildren {
-
-    private UIServerRpc rpc = RpcProxy.create(UIServerRpc.class, this);
-
-    private HandlerRegistration childStateChangeHandlerRegistration;
-
-    private final StateChangeHandler childStateChangeHandler = new StateChangeHandler() {
-        @Override
-        public void onStateChanged(StateChangeEvent stateChangeEvent) {
-            // TODO Should use a more specific handler that only reacts to
-            // size changes
-            onChildSizeChange();
-        }
-    };
-
-    @Override
-    protected void init() {
-        super.init();
-        registerRpc(PageClientRpc.class, new PageClientRpc() {
-            @Override
-            public void setTitle(String title) {
-                com.google.gwt.user.client.Window.setTitle(title);
-            }
-        });
-        getWidget().addResizeHandler(new ResizeHandler() {
-            @Override
-            public void onResize(ResizeEvent event) {
-                rpc.resize(event.getHeight(), event.getWidth(),
-                        Window.getClientWidth(), Window.getClientHeight());
-                if (getState().immediate) {
-                    getConnection().sendPendingVariableChanges();
-                }
-            }
-        });
-    }
-
-    @Override
-    public void updateFromUIDL(final UIDL uidl, ApplicationConnection client) {
-        ConnectorMap paintableMap = ConnectorMap.get(getConnection());
-        getWidget().rendering = true;
-        getWidget().id = getConnectorId();
-        boolean firstPaint = getWidget().connection == null;
-        getWidget().connection = client;
-
-        getWidget().immediate = getState().immediate;
-        getWidget().resizeLazy = uidl.hasAttribute(UIConstants.RESIZE_LAZY);
-        String newTheme = uidl.getStringAttribute("theme");
-        if (getWidget().theme != null && !newTheme.equals(getWidget().theme)) {
-            // Complete page refresh is needed due css can affect layout
-            // calculations etc
-            getWidget().reloadHostPage();
-        } else {
-            getWidget().theme = newTheme;
-        }
-        // this also implicitly removes old styles
-        String styles = "";
-        styles += getWidget().getStylePrimaryName() + " ";
-        if (ComponentStateUtil.hasStyles(getState())) {
-            for (String style : getState().styles) {
-                styles += style + " ";
-            }
-        }
-        if (!client.getConfiguration().isStandalone()) {
-            styles += getWidget().getStylePrimaryName() + "-embedded";
-        }
-        getWidget().setStyleName(styles.trim());
-
-        getWidget().makeScrollable();
-
-        clickEventHandler.handleEventHandlerRegistration();
-
-        // Process children
-        int childIndex = 0;
-
-        // Open URL:s
-        boolean isClosed = false; // was this window closed?
-        while (childIndex < uidl.getChildCount()
-                && "open".equals(uidl.getChildUIDL(childIndex).getTag())) {
-            final UIDL open = uidl.getChildUIDL(childIndex);
-            final String url = client.translateVaadinUri(open
-                    .getStringAttribute("src"));
-            final String target = open.getStringAttribute("name");
-            if (target == null) {
-                // source will be opened to this browser window, but we may have
-                // to finish rendering this window in case this is a download
-                // (and window stays open).
-                Scheduler.get().scheduleDeferred(new Command() {
-                    @Override
-                    public void execute() {
-                        VUI.goTo(url);
-                    }
-                });
-            } else if ("_self".equals(target)) {
-                // This window is closing (for sure). Only other opens are
-                // relevant in this change. See #3558, #2144
-                isClosed = true;
-                VUI.goTo(url);
-            } else {
-                String options;
-                if (open.hasAttribute("border")) {
-                    if (open.getStringAttribute("border").equals("minimal")) {
-                        options = "menubar=yes,location=no,status=no";
-                    } else {
-                        options = "menubar=no,location=no,status=no";
-                    }
-
-                } else {
-                    options = "resizable=yes,menubar=yes,toolbar=yes,directories=yes,location=yes,scrollbars=yes,status=yes";
-                }
-
-                if (open.hasAttribute("width")) {
-                    int w = open.getIntAttribute("width");
-                    options += ",width=" + w;
-                }
-                if (open.hasAttribute("height")) {
-                    int h = open.getIntAttribute("height");
-                    options += ",height=" + h;
-                }
-
-                Window.open(url, target, options);
-            }
-            childIndex++;
-        }
-        if (isClosed) {
-            // don't render the content, something else will be opened to this
-            // browser view
-            getWidget().rendering = false;
-            return;
-        }
-
-        // Handle other UIDL children
-        UIDL childUidl;
-        while ((childUidl = uidl.getChildUIDL(childIndex++)) != null) {
-            String tag = childUidl.getTag().intern();
-            if (tag == "actions") {
-                if (getWidget().actionHandler == null) {
-                    getWidget().actionHandler = new ShortcutActionHandler(
-                            getWidget().id, client);
-                }
-                getWidget().actionHandler.updateActionMap(childUidl);
-            } else if (tag == "notifications") {
-                for (final Iterator<?> it = childUidl.getChildIterator(); it
-                        .hasNext();) {
-                    final UIDL notification = (UIDL) it.next();
-                    VNotification.showNotification(client, notification);
-                }
-            }
-        }
-
-        if (uidl.hasAttribute("focused")) {
-            // set focused component when render phase is finished
-            Scheduler.get().scheduleDeferred(new Command() {
-                @Override
-                public void execute() {
-                    ComponentConnector paintable = (ComponentConnector) uidl
-                            .getPaintableAttribute("focused", getConnection());
-
-                    final Widget toBeFocused = paintable.getWidget();
-                    /*
-                     * Two types of Widgets can be focused, either implementing
-                     * GWT HasFocus of a thinner Vaadin specific Focusable
-                     * interface.
-                     */
-                    if (toBeFocused instanceof com.google.gwt.user.client.ui.Focusable) {
-                        final com.google.gwt.user.client.ui.Focusable toBeFocusedWidget = (com.google.gwt.user.client.ui.Focusable) toBeFocused;
-                        toBeFocusedWidget.setFocus(true);
-                    } else if (toBeFocused instanceof Focusable) {
-                        ((Focusable) toBeFocused).focus();
-                    } else {
-                        VConsole.log("Could not focus component");
-                    }
-                }
-            });
-        }
-
-        // Add window listeners on first paint, to prevent premature
-        // variablechanges
-        if (firstPaint) {
-            Window.addWindowClosingHandler(getWidget());
-            Window.addResizeHandler(getWidget());
-        }
-
-        // finally set scroll position from UIDL
-        if (uidl.hasVariable("scrollTop")) {
-            getWidget().scrollable = true;
-            getWidget().scrollTop = uidl.getIntVariable("scrollTop");
-            DOM.setElementPropertyInt(getWidget().getElement(), "scrollTop",
-                    getWidget().scrollTop);
-            getWidget().scrollLeft = uidl.getIntVariable("scrollLeft");
-            DOM.setElementPropertyInt(getWidget().getElement(), "scrollLeft",
-                    getWidget().scrollLeft);
-        } else {
-            getWidget().scrollable = false;
-        }
-
-        if (uidl.hasAttribute("scrollTo")) {
-            final ComponentConnector connector = (ComponentConnector) uidl
-                    .getPaintableAttribute("scrollTo", getConnection());
-            scrollIntoView(connector);
-        }
-
-        if (uidl.hasAttribute(UIConstants.FRAGMENT_VARIABLE)) {
-            getWidget().currentFragment = uidl
-                    .getStringAttribute(UIConstants.FRAGMENT_VARIABLE);
-            if (!getWidget().currentFragment.equals(History.getToken())) {
-                History.newItem(getWidget().currentFragment, true);
-            }
-        } else {
-            // Initial request for which the server doesn't yet have a fragment
-            // (and haven't shown any interest in getting one)
-            getWidget().currentFragment = History.getToken();
-
-            // Include current fragment in the next request
-            client.updateVariable(getWidget().id,
-                    UIConstants.FRAGMENT_VARIABLE, getWidget().currentFragment,
-                    false);
-        }
-
-        if (firstPaint) {
-            // Queue the initial window size to be sent with the following
-            // request.
-            getWidget().sendClientResized();
-        }
-        getWidget().rendering = false;
-    }
-
-    public void init(String rootPanelId,
-            ApplicationConnection applicationConnection) {
-        DOM.sinkEvents(getWidget().getElement(), Event.ONKEYDOWN
-                | Event.ONSCROLL);
-
-        // iview is focused when created so element needs tabIndex
-        // 1 due 0 is at the end of natural tabbing order
-        DOM.setElementProperty(getWidget().getElement(), "tabIndex", "1");
-
-        RootPanel root = RootPanel.get(rootPanelId);
-
-        // Remove the v-app-loading or any splash screen added inside the div by
-        // the user
-        root.getElement().setInnerHTML("");
-
-        root.addStyleName("v-theme-"
-                + applicationConnection.getConfiguration().getThemeName());
-
-        root.add(getWidget());
-
-        if (applicationConnection.getConfiguration().isStandalone()) {
-            // set focus to iview element by default to listen possible keyboard
-            // shortcuts. For embedded applications this is unacceptable as we
-            // don't want to steal focus from the main page nor we don't want
-            // side-effects from focusing (scrollIntoView).
-            getWidget().getElement().focus();
-        }
-    }
-
-    private ClickEventHandler clickEventHandler = new ClickEventHandler(this) {
-
-        @Override
-        protected void fireClick(NativeEvent event,
-                MouseEventDetails mouseDetails) {
-            rpc.click(mouseDetails);
-        }
-
-    };
-
-    @Override
-    public void updateCaption(ComponentConnector component) {
-        // NOP The main view never draws caption for its layout
-    }
-
-    @Override
-    public VUI getWidget() {
-        return (VUI) super.getWidget();
-    }
-
-    protected ComponentConnector getContent() {
-        return (ComponentConnector) getState().content;
-    }
-
-    protected void onChildSizeChange() {
-        ComponentConnector child = getContent();
-        Style childStyle = child.getWidget().getElement().getStyle();
-        /*
-         * Must set absolute position if the child has relative height and
-         * there's a chance of horizontal scrolling as some browsers will
-         * otherwise not take the scrollbar into account when calculating the
-         * height. Assuming v-view does not have an undefined width for now, see
-         * #8460.
-         */
-        if (child.isRelativeHeight() && !BrowserInfo.get().isIE9()) {
-            childStyle.setPosition(Position.ABSOLUTE);
-        } else {
-            childStyle.clearPosition();
-        }
-    }
-
-    /**
-     * Checks if the given sub window is a child of this UI Connector
-     * 
-     * @deprecated Should be replaced by a more generic mechanism for getting
-     *             non-ComponentConnector children
-     * @param wc
-     * @return
-     */
-    @Deprecated
-    public boolean hasSubWindow(WindowConnector wc) {
-        return getChildComponents().contains(wc);
-    }
-
-    /**
-     * Return an iterator for current subwindows. This method is meant for
-     * testing purposes only.
-     * 
-     * @return
-     */
-    public List<WindowConnector> getSubWindows() {
-        ArrayList<WindowConnector> windows = new ArrayList<WindowConnector>();
-        for (ComponentConnector child : getChildComponents()) {
-            if (child instanceof WindowConnector) {
-                windows.add((WindowConnector) child);
-            }
-        }
-        return windows;
-    }
-
-    @Override
-    public UIState getState() {
-        return (UIState) super.getState();
-    }
-
-    @Override
-    public void onConnectorHierarchyChange(ConnectorHierarchyChangeEvent event) {
-        super.onConnectorHierarchyChange(event);
-
-        ComponentConnector oldChild = null;
-        ComponentConnector newChild = getContent();
-
-        for (ComponentConnector c : event.getOldChildren()) {
-            if (!(c instanceof WindowConnector)) {
-                oldChild = c;
-                break;
-            }
-        }
-
-        if (oldChild != newChild) {
-            if (childStateChangeHandlerRegistration != null) {
-                childStateChangeHandlerRegistration.removeHandler();
-                childStateChangeHandlerRegistration = null;
-            }
-            getWidget().setWidget(newChild.getWidget());
-            childStateChangeHandlerRegistration = newChild
-                    .addStateChangeHandler(childStateChangeHandler);
-            // Must handle new child here as state change events are already
-            // fired
-            onChildSizeChange();
-        }
-
-        for (ComponentConnector c : getChildComponents()) {
-            if (c instanceof WindowConnector) {
-                WindowConnector wc = (WindowConnector) c;
-                wc.setWindowOrderAndPosition();
-            }
-        }
-
-        // Close removed sub windows
-        for (ComponentConnector c : event.getOldChildren()) {
-            if (c.getParent() != this && c instanceof WindowConnector) {
-                ((WindowConnector) c).getWidget().hide();
-            }
-        }
-    }
-
-    /**
-     * Tries to scroll the viewport so that the given connector is in view.
-     * 
-     * @param componentConnector
-     *            The connector which should be visible
-     * 
-     */
-    public void scrollIntoView(final ComponentConnector componentConnector) {
-        if (componentConnector == null) {
-            return;
-        }
-
-        Scheduler.get().scheduleDeferred(new Command() {
-            @Override
-            public void execute() {
-                componentConnector.getWidget().getElement().scrollIntoView();
-            }
-        });
-    }
-}
diff --git a/client/src/com/vaadin/client/ui/UI/VUI.java b/client/src/com/vaadin/client/ui/UI/VUI.java
deleted file mode 100644 (file)
index c99dfeb..0000000
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * Copyright 2011 Vaadin Ltd.
- * 
- * 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.vaadin.client.ui.UI;
-
-import java.util.ArrayList;
-
-import com.google.gwt.core.client.Scheduler.ScheduledCommand;
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.event.logical.shared.HasResizeHandlers;
-import com.google.gwt.event.logical.shared.ResizeEvent;
-import com.google.gwt.event.logical.shared.ResizeHandler;
-import com.google.gwt.event.logical.shared.ValueChangeEvent;
-import com.google.gwt.event.logical.shared.ValueChangeHandler;
-import com.google.gwt.event.shared.HandlerRegistration;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.History;
-import com.google.gwt.user.client.Timer;
-import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.ui.SimplePanel;
-import com.vaadin.client.ApplicationConnection;
-import com.vaadin.client.BrowserInfo;
-import com.vaadin.client.ComponentConnector;
-import com.vaadin.client.ConnectorMap;
-import com.vaadin.client.Focusable;
-import com.vaadin.client.VConsole;
-import com.vaadin.client.ui.ShortcutActionHandler;
-import com.vaadin.client.ui.TouchScrollDelegate;
-import com.vaadin.client.ui.VLazyExecutor;
-import com.vaadin.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner;
-import com.vaadin.client.ui.TouchScrollDelegate.TouchScrollHandler;
-import com.vaadin.client.ui.textfield.VTextField;
-import com.vaadin.shared.ApplicationConstants;
-import com.vaadin.shared.ui.ui.UIConstants;
-
-/**
- *
- */
-public class VUI extends SimplePanel implements ResizeHandler,
-        Window.ClosingHandler, ShortcutActionHandlerOwner, Focusable,
-        HasResizeHandlers {
-
-    private static final String CLASSNAME = "v-view";
-
-    private static int MONITOR_PARENT_TIMER_INTERVAL = 1000;
-
-    String theme;
-
-    String id;
-
-    ShortcutActionHandler actionHandler;
-
-    /*
-     * Last known window size used to detect whether VView should be layouted
-     * again. Detection must check window size, because the VView size might be
-     * fixed and thus not automatically adapt to changed window sizes.
-     */
-    private int windowWidth;
-    private int windowHeight;
-
-    /*
-     * Last know view size used to detect whether new dimensions should be sent
-     * to the server.
-     */
-    private int viewWidth;
-    private int viewHeight;
-
-    ApplicationConnection connection;
-
-    /**
-     * Keep track of possible parent size changes when an embedded application.
-     * 
-     * Uses {@link #parentWidth} and {@link #parentHeight} as an optimization to
-     * keep track of when there is a real change.
-     */
-    private Timer resizeTimer;
-
-    /** stored width of parent for embedded application auto-resize */
-    private int parentWidth;
-
-    /** stored height of parent for embedded application auto-resize */
-    private int parentHeight;
-
-    int scrollTop;
-
-    int scrollLeft;
-
-    boolean rendering;
-
-    boolean scrollable;
-
-    boolean immediate;
-
-    boolean resizeLazy = false;
-
-    private HandlerRegistration historyHandlerRegistration;
-
-    private TouchScrollHandler touchScrollHandler;
-
-    /**
-     * The current URI fragment, used to avoid sending updates if nothing has
-     * changed.
-     */
-    String currentFragment;
-
-    /**
-     * Listener for URI fragment changes. Notifies the server of the new value
-     * whenever the value changes.
-     */
-    private final ValueChangeHandler<String> historyChangeHandler = new ValueChangeHandler<String>() {
-
-        @Override
-        public void onValueChange(ValueChangeEvent<String> event) {
-            String newFragment = event.getValue();
-
-            // Send the new fragment to the server if it has changed
-            if (!newFragment.equals(currentFragment) && connection != null) {
-                currentFragment = newFragment;
-                connection.updateVariable(id, UIConstants.FRAGMENT_VARIABLE,
-                        newFragment, true);
-            }
-        }
-    };
-
-    private VLazyExecutor delayedResizeExecutor = new VLazyExecutor(200,
-            new ScheduledCommand() {
-
-                @Override
-                public void execute() {
-                    performSizeCheck();
-                }
-
-            });
-
-    public VUI() {
-        super();
-        setStyleName(CLASSNAME);
-
-        // Allow focusing the view by using the focus() method, the view
-        // should not be in the document focus flow
-        getElement().setTabIndex(-1);
-        makeScrollable();
-    }
-
-    /**
-     * Start to periodically monitor for parent element resizes if embedded
-     * application (e.g. portlet).
-     */
-    @Override
-    protected void onLoad() {
-        super.onLoad();
-        if (isMonitoringParentSize()) {
-            resizeTimer = new Timer() {
-
-                @Override
-                public void run() {
-                    // trigger check to see if parent size has changed,
-                    // recalculate layouts
-                    performSizeCheck();
-                    resizeTimer.schedule(MONITOR_PARENT_TIMER_INTERVAL);
-                }
-            };
-            resizeTimer.schedule(MONITOR_PARENT_TIMER_INTERVAL);
-        }
-    }
-
-    @Override
-    protected void onAttach() {
-        super.onAttach();
-        historyHandlerRegistration = History
-                .addValueChangeHandler(historyChangeHandler);
-        currentFragment = History.getToken();
-    }
-
-    @Override
-    protected void onDetach() {
-        super.onDetach();
-        historyHandlerRegistration.removeHandler();
-        historyHandlerRegistration = null;
-    }
-
-    /**
-     * Stop monitoring for parent element resizes.
-     */
-
-    @Override
-    protected void onUnload() {
-        if (resizeTimer != null) {
-            resizeTimer.cancel();
-            resizeTimer = null;
-        }
-        super.onUnload();
-    }
-
-    /**
-     * Called when the window or parent div might have been resized.
-     * 
-     * This immediately checks the sizes of the window and the parent div (if
-     * monitoring it) and triggers layout recalculation if they have changed.
-     */
-    protected void performSizeCheck() {
-        windowSizeMaybeChanged(Window.getClientWidth(),
-                Window.getClientHeight());
-    }
-
-    /**
-     * Called when the window or parent div might have been resized.
-     * 
-     * This immediately checks the sizes of the window and the parent div (if
-     * monitoring it) and triggers layout recalculation if they have changed.
-     * 
-     * @param newWindowWidth
-     *            The new width of the window
-     * @param newWindowHeight
-     *            The new height of the window
-     * 
-     * @deprecated use {@link #performSizeCheck()}
-     */
-    @Deprecated
-    protected void windowSizeMaybeChanged(int newWindowWidth,
-            int newWindowHeight) {
-        boolean changed = false;
-        ComponentConnector connector = ConnectorMap.get(connection)
-                .getConnector(this);
-        if (windowWidth != newWindowWidth) {
-            windowWidth = newWindowWidth;
-            changed = true;
-            connector.getLayoutManager().reportOuterWidth(connector,
-                    newWindowWidth);
-            VConsole.log("New window width: " + windowWidth);
-        }
-        if (windowHeight != newWindowHeight) {
-            windowHeight = newWindowHeight;
-            changed = true;
-            connector.getLayoutManager().reportOuterHeight(connector,
-                    newWindowHeight);
-            VConsole.log("New window height: " + windowHeight);
-        }
-        Element parentElement = getElement().getParentElement();
-        if (isMonitoringParentSize() && parentElement != null) {
-            // check also for parent size changes
-            int newParentWidth = parentElement.getClientWidth();
-            int newParentHeight = parentElement.getClientHeight();
-            if (parentWidth != newParentWidth) {
-                parentWidth = newParentWidth;
-                changed = true;
-                VConsole.log("New parent width: " + parentWidth);
-            }
-            if (parentHeight != newParentHeight) {
-                parentHeight = newParentHeight;
-                changed = true;
-                VConsole.log("New parent height: " + parentHeight);
-            }
-        }
-        if (changed) {
-            /*
-             * If the window size has changed, layout the VView again and send
-             * new size to the server if the size changed. (Just checking VView
-             * size would cause us to ignore cases when a relatively sized VView
-             * should shrink as the content's size is fixed and would thus not
-             * automatically shrink.)
-             */
-            VConsole.log("Running layout functions due to window or parent resize");
-
-            // update size to avoid (most) redundant re-layout passes
-            // there can still be an extra layout recalculation if webkit
-            // overflow fix updates the size in a deferred block
-            if (isMonitoringParentSize() && parentElement != null) {
-                parentWidth = parentElement.getClientWidth();
-                parentHeight = parentElement.getClientHeight();
-            }
-
-            sendClientResized();
-
-            connector.getLayoutManager().layoutNow();
-        }
-    }
-
-    public String getTheme() {
-        return theme;
-    }
-
-    /**
-     * Used to reload host page on theme changes.
-     */
-    static native void reloadHostPage()
-    /*-{
-         $wnd.location.reload();
-     }-*/;
-
-    /**
-     * Returns true if the body is NOT generated, i.e if someone else has made
-     * the page that we're running in. Otherwise we're in charge of the whole
-     * page.
-     * 
-     * @return true if we're running embedded
-     */
-    public boolean isEmbedded() {
-        return !getElement().getOwnerDocument().getBody().getClassName()
-                .contains(ApplicationConstants.GENERATED_BODY_CLASSNAME);
-    }
-
-    /**
-     * Returns true if the size of the parent should be checked periodically and
-     * the application should react to its changes.
-     * 
-     * @return true if size of parent should be tracked
-     */
-    protected boolean isMonitoringParentSize() {
-        // could also perform a more specific check (Liferay portlet)
-        return isEmbedded();
-    }
-
-    @Override
-    public void onBrowserEvent(Event event) {
-        super.onBrowserEvent(event);
-        int type = DOM.eventGetType(event);
-        if (type == Event.ONKEYDOWN && actionHandler != null) {
-            actionHandler.handleKeyboardEvent(event);
-            return;
-        } else if (scrollable && type == Event.ONSCROLL) {
-            updateScrollPosition();
-        }
-    }
-
-    /**
-     * Updates scroll position from DOM and saves variables to server.
-     */
-    private void updateScrollPosition() {
-        int oldTop = scrollTop;
-        int oldLeft = scrollLeft;
-        scrollTop = DOM.getElementPropertyInt(getElement(), "scrollTop");
-        scrollLeft = DOM.getElementPropertyInt(getElement(), "scrollLeft");
-        if (connection != null && !rendering) {
-            if (oldTop != scrollTop) {
-                connection.updateVariable(id, "scrollTop", scrollTop, false);
-            }
-            if (oldLeft != scrollLeft) {
-                connection.updateVariable(id, "scrollLeft", scrollLeft, false);
-            }
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * com.google.gwt.event.logical.shared.ResizeHandler#onResize(com.google
-     * .gwt.event.logical.shared.ResizeEvent)
-     */
-
-    @Override
-    public void onResize(ResizeEvent event) {
-        triggerSizeChangeCheck();
-    }
-
-    /**
-     * Called when a resize event is received.
-     * 
-     * This may trigger a lazy refresh or perform the size check immediately
-     * depending on the browser used and whether the server side requests
-     * resizes to be lazy.
-     */
-    private void triggerSizeChangeCheck() {
-        /*
-         * IE (pre IE9 at least) will give us some false resize events due to
-         * problems with scrollbars. Firefox 3 might also produce some extra
-         * events. We postpone both the re-layouting and the server side event
-         * for a while to deal with these issues.
-         * 
-         * We may also postpone these events to avoid slowness when resizing the
-         * browser window. Constantly recalculating the layout causes the resize
-         * operation to be really slow with complex layouts.
-         */
-        boolean lazy = resizeLazy || BrowserInfo.get().isIE8();
-
-        if (lazy) {
-            delayedResizeExecutor.trigger();
-        } else {
-            performSizeCheck();
-        }
-    }
-
-    /**
-     * Send new dimensions to the server.
-     */
-    void sendClientResized() {
-        Element parentElement = getElement().getParentElement();
-        int viewHeight = parentElement.getClientHeight();
-        int viewWidth = parentElement.getClientWidth();
-
-        ResizeEvent.fire(this, viewWidth, viewHeight);
-    }
-
-    public native static void goTo(String url)
-    /*-{
-       $wnd.location = url;
-     }-*/;
-
-    @Override
-    public void onWindowClosing(Window.ClosingEvent event) {
-        // Change focus on this window in order to ensure that all state is
-        // collected from textfields
-        // TODO this is a naive hack, that only works with text fields and may
-        // cause some odd issues. Should be replaced with a decent solution, see
-        // also related BeforeShortcutActionListener interface. Same interface
-        // might be usable here.
-        VTextField.flushChangesFromFocusedTextField();
-    }
-
-    private native static void loadAppIdListFromDOM(ArrayList<String> list)
-    /*-{
-         var j;
-         for(j in $wnd.vaadin.vaadinConfigurations) {
-            // $entry not needed as function is not exported
-            list.@java.util.Collection::add(Ljava/lang/Object;)(j);
-         }
-     }-*/;
-
-    @Override
-    public ShortcutActionHandler getShortcutActionHandler() {
-        return actionHandler;
-    }
-
-    @Override
-    public void focus() {
-        getElement().focus();
-    }
-
-    /**
-     * Ensures the root is scrollable eg. after style name changes.
-     */
-    void makeScrollable() {
-        if (touchScrollHandler == null) {
-            touchScrollHandler = TouchScrollDelegate.enableTouchScrolling(this);
-        }
-        touchScrollHandler.addElement(getElement());
-    }
-
-    @Override
-    public HandlerRegistration addResizeHandler(ResizeHandler resizeHandler) {
-        return addHandler(resizeHandler, ResizeEvent.getType());
-    }
-
-}
diff --git a/client/src/com/vaadin/client/ui/ui/UIConnector.java b/client/src/com/vaadin/client/ui/ui/UIConnector.java
new file mode 100644 (file)
index 0000000..3b4e4e1
--- /dev/null
@@ -0,0 +1,457 @@
+/*
+ * Copyright 2011 Vaadin Ltd.
+ * 
+ * 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.vaadin.client.ui.ui;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.dom.client.Style;
+import com.google.gwt.dom.client.Style.Position;
+import com.google.gwt.event.logical.shared.ResizeEvent;
+import com.google.gwt.event.logical.shared.ResizeHandler;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.History;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.google.web.bindery.event.shared.HandlerRegistration;
+import com.vaadin.client.ApplicationConnection;
+import com.vaadin.client.BrowserInfo;
+import com.vaadin.client.ComponentConnector;
+import com.vaadin.client.ConnectorHierarchyChangeEvent;
+import com.vaadin.client.ConnectorMap;
+import com.vaadin.client.Focusable;
+import com.vaadin.client.Paintable;
+import com.vaadin.client.UIDL;
+import com.vaadin.client.VConsole;
+import com.vaadin.client.communication.RpcProxy;
+import com.vaadin.client.communication.StateChangeEvent;
+import com.vaadin.client.communication.StateChangeEvent.StateChangeHandler;
+import com.vaadin.client.ui.AbstractComponentContainerConnector;
+import com.vaadin.client.ui.ClickEventHandler;
+import com.vaadin.client.ui.ShortcutActionHandler;
+import com.vaadin.client.ui.layout.MayScrollChildren;
+import com.vaadin.client.ui.notification.VNotification;
+import com.vaadin.client.ui.window.WindowConnector;
+import com.vaadin.shared.MouseEventDetails;
+import com.vaadin.shared.ui.ComponentStateUtil;
+import com.vaadin.shared.ui.Connect;
+import com.vaadin.shared.ui.Connect.LoadStyle;
+import com.vaadin.shared.ui.ui.PageClientRpc;
+import com.vaadin.shared.ui.ui.UIConstants;
+import com.vaadin.shared.ui.ui.UIServerRpc;
+import com.vaadin.shared.ui.ui.UIState;
+import com.vaadin.ui.UI;
+
+@Connect(value = UI.class, loadStyle = LoadStyle.EAGER)
+public class UIConnector extends AbstractComponentContainerConnector implements
+        Paintable, MayScrollChildren {
+
+    private UIServerRpc rpc = RpcProxy.create(UIServerRpc.class, this);
+
+    private HandlerRegistration childStateChangeHandlerRegistration;
+
+    private final StateChangeHandler childStateChangeHandler = new StateChangeHandler() {
+        @Override
+        public void onStateChanged(StateChangeEvent stateChangeEvent) {
+            // TODO Should use a more specific handler that only reacts to
+            // size changes
+            onChildSizeChange();
+        }
+    };
+
+    @Override
+    protected void init() {
+        super.init();
+        registerRpc(PageClientRpc.class, new PageClientRpc() {
+            @Override
+            public void setTitle(String title) {
+                com.google.gwt.user.client.Window.setTitle(title);
+            }
+        });
+        getWidget().addResizeHandler(new ResizeHandler() {
+            @Override
+            public void onResize(ResizeEvent event) {
+                rpc.resize(event.getHeight(), event.getWidth(),
+                        Window.getClientWidth(), Window.getClientHeight());
+                if (getState().immediate) {
+                    getConnection().sendPendingVariableChanges();
+                }
+            }
+        });
+    }
+
+    @Override
+    public void updateFromUIDL(final UIDL uidl, ApplicationConnection client) {
+        ConnectorMap paintableMap = ConnectorMap.get(getConnection());
+        getWidget().rendering = true;
+        getWidget().id = getConnectorId();
+        boolean firstPaint = getWidget().connection == null;
+        getWidget().connection = client;
+
+        getWidget().immediate = getState().immediate;
+        getWidget().resizeLazy = uidl.hasAttribute(UIConstants.RESIZE_LAZY);
+        String newTheme = uidl.getStringAttribute("theme");
+        if (getWidget().theme != null && !newTheme.equals(getWidget().theme)) {
+            // Complete page refresh is needed due css can affect layout
+            // calculations etc
+            getWidget().reloadHostPage();
+        } else {
+            getWidget().theme = newTheme;
+        }
+        // this also implicitly removes old styles
+        String styles = "";
+        styles += getWidget().getStylePrimaryName() + " ";
+        if (ComponentStateUtil.hasStyles(getState())) {
+            for (String style : getState().styles) {
+                styles += style + " ";
+            }
+        }
+        if (!client.getConfiguration().isStandalone()) {
+            styles += getWidget().getStylePrimaryName() + "-embedded";
+        }
+        getWidget().setStyleName(styles.trim());
+
+        getWidget().makeScrollable();
+
+        clickEventHandler.handleEventHandlerRegistration();
+
+        // Process children
+        int childIndex = 0;
+
+        // Open URL:s
+        boolean isClosed = false; // was this window closed?
+        while (childIndex < uidl.getChildCount()
+                && "open".equals(uidl.getChildUIDL(childIndex).getTag())) {
+            final UIDL open = uidl.getChildUIDL(childIndex);
+            final String url = client.translateVaadinUri(open
+                    .getStringAttribute("src"));
+            final String target = open.getStringAttribute("name");
+            if (target == null) {
+                // source will be opened to this browser window, but we may have
+                // to finish rendering this window in case this is a download
+                // (and window stays open).
+                Scheduler.get().scheduleDeferred(new Command() {
+                    @Override
+                    public void execute() {
+                        VUI.goTo(url);
+                    }
+                });
+            } else if ("_self".equals(target)) {
+                // This window is closing (for sure). Only other opens are
+                // relevant in this change. See #3558, #2144
+                isClosed = true;
+                VUI.goTo(url);
+            } else {
+                String options;
+                if (open.hasAttribute("border")) {
+                    if (open.getStringAttribute("border").equals("minimal")) {
+                        options = "menubar=yes,location=no,status=no";
+                    } else {
+                        options = "menubar=no,location=no,status=no";
+                    }
+
+                } else {
+                    options = "resizable=yes,menubar=yes,toolbar=yes,directories=yes,location=yes,scrollbars=yes,status=yes";
+                }
+
+                if (open.hasAttribute("width")) {
+                    int w = open.getIntAttribute("width");
+                    options += ",width=" + w;
+                }
+                if (open.hasAttribute("height")) {
+                    int h = open.getIntAttribute("height");
+                    options += ",height=" + h;
+                }
+
+                Window.open(url, target, options);
+            }
+            childIndex++;
+        }
+        if (isClosed) {
+            // don't render the content, something else will be opened to this
+            // browser view
+            getWidget().rendering = false;
+            return;
+        }
+
+        // Handle other UIDL children
+        UIDL childUidl;
+        while ((childUidl = uidl.getChildUIDL(childIndex++)) != null) {
+            String tag = childUidl.getTag().intern();
+            if (tag == "actions") {
+                if (getWidget().actionHandler == null) {
+                    getWidget().actionHandler = new ShortcutActionHandler(
+                            getWidget().id, client);
+                }
+                getWidget().actionHandler.updateActionMap(childUidl);
+            } else if (tag == "notifications") {
+                for (final Iterator<?> it = childUidl.getChildIterator(); it
+                        .hasNext();) {
+                    final UIDL notification = (UIDL) it.next();
+                    VNotification.showNotification(client, notification);
+                }
+            }
+        }
+
+        if (uidl.hasAttribute("focused")) {
+            // set focused component when render phase is finished
+            Scheduler.get().scheduleDeferred(new Command() {
+                @Override
+                public void execute() {
+                    ComponentConnector paintable = (ComponentConnector) uidl
+                            .getPaintableAttribute("focused", getConnection());
+
+                    final Widget toBeFocused = paintable.getWidget();
+                    /*
+                     * Two types of Widgets can be focused, either implementing
+                     * GWT HasFocus of a thinner Vaadin specific Focusable
+                     * interface.
+                     */
+                    if (toBeFocused instanceof com.google.gwt.user.client.ui.Focusable) {
+                        final com.google.gwt.user.client.ui.Focusable toBeFocusedWidget = (com.google.gwt.user.client.ui.Focusable) toBeFocused;
+                        toBeFocusedWidget.setFocus(true);
+                    } else if (toBeFocused instanceof Focusable) {
+                        ((Focusable) toBeFocused).focus();
+                    } else {
+                        VConsole.log("Could not focus component");
+                    }
+                }
+            });
+        }
+
+        // Add window listeners on first paint, to prevent premature
+        // variablechanges
+        if (firstPaint) {
+            Window.addWindowClosingHandler(getWidget());
+            Window.addResizeHandler(getWidget());
+        }
+
+        // finally set scroll position from UIDL
+        if (uidl.hasVariable("scrollTop")) {
+            getWidget().scrollable = true;
+            getWidget().scrollTop = uidl.getIntVariable("scrollTop");
+            DOM.setElementPropertyInt(getWidget().getElement(), "scrollTop",
+                    getWidget().scrollTop);
+            getWidget().scrollLeft = uidl.getIntVariable("scrollLeft");
+            DOM.setElementPropertyInt(getWidget().getElement(), "scrollLeft",
+                    getWidget().scrollLeft);
+        } else {
+            getWidget().scrollable = false;
+        }
+
+        if (uidl.hasAttribute("scrollTo")) {
+            final ComponentConnector connector = (ComponentConnector) uidl
+                    .getPaintableAttribute("scrollTo", getConnection());
+            scrollIntoView(connector);
+        }
+
+        if (uidl.hasAttribute(UIConstants.FRAGMENT_VARIABLE)) {
+            getWidget().currentFragment = uidl
+                    .getStringAttribute(UIConstants.FRAGMENT_VARIABLE);
+            if (!getWidget().currentFragment.equals(History.getToken())) {
+                History.newItem(getWidget().currentFragment, true);
+            }
+        } else {
+            // Initial request for which the server doesn't yet have a fragment
+            // (and haven't shown any interest in getting one)
+            getWidget().currentFragment = History.getToken();
+
+            // Include current fragment in the next request
+            client.updateVariable(getWidget().id,
+                    UIConstants.FRAGMENT_VARIABLE, getWidget().currentFragment,
+                    false);
+        }
+
+        if (firstPaint) {
+            // Queue the initial window size to be sent with the following
+            // request.
+            getWidget().sendClientResized();
+        }
+        getWidget().rendering = false;
+    }
+
+    public void init(String rootPanelId,
+            ApplicationConnection applicationConnection) {
+        DOM.sinkEvents(getWidget().getElement(), Event.ONKEYDOWN
+                | Event.ONSCROLL);
+
+        // iview is focused when created so element needs tabIndex
+        // 1 due 0 is at the end of natural tabbing order
+        DOM.setElementProperty(getWidget().getElement(), "tabIndex", "1");
+
+        RootPanel root = RootPanel.get(rootPanelId);
+
+        // Remove the v-app-loading or any splash screen added inside the div by
+        // the user
+        root.getElement().setInnerHTML("");
+
+        root.addStyleName("v-theme-"
+                + applicationConnection.getConfiguration().getThemeName());
+
+        root.add(getWidget());
+
+        if (applicationConnection.getConfiguration().isStandalone()) {
+            // set focus to iview element by default to listen possible keyboard
+            // shortcuts. For embedded applications this is unacceptable as we
+            // don't want to steal focus from the main page nor we don't want
+            // side-effects from focusing (scrollIntoView).
+            getWidget().getElement().focus();
+        }
+    }
+
+    private ClickEventHandler clickEventHandler = new ClickEventHandler(this) {
+
+        @Override
+        protected void fireClick(NativeEvent event,
+                MouseEventDetails mouseDetails) {
+            rpc.click(mouseDetails);
+        }
+
+    };
+
+    @Override
+    public void updateCaption(ComponentConnector component) {
+        // NOP The main view never draws caption for its layout
+    }
+
+    @Override
+    public VUI getWidget() {
+        return (VUI) super.getWidget();
+    }
+
+    protected ComponentConnector getContent() {
+        return (ComponentConnector) getState().content;
+    }
+
+    protected void onChildSizeChange() {
+        ComponentConnector child = getContent();
+        Style childStyle = child.getWidget().getElement().getStyle();
+        /*
+         * Must set absolute position if the child has relative height and
+         * there's a chance of horizontal scrolling as some browsers will
+         * otherwise not take the scrollbar into account when calculating the
+         * height. Assuming v-view does not have an undefined width for now, see
+         * #8460.
+         */
+        if (child.isRelativeHeight() && !BrowserInfo.get().isIE9()) {
+            childStyle.setPosition(Position.ABSOLUTE);
+        } else {
+            childStyle.clearPosition();
+        }
+    }
+
+    /**
+     * Checks if the given sub window is a child of this UI Connector
+     * 
+     * @deprecated Should be replaced by a more generic mechanism for getting
+     *             non-ComponentConnector children
+     * @param wc
+     * @return
+     */
+    @Deprecated
+    public boolean hasSubWindow(WindowConnector wc) {
+        return getChildComponents().contains(wc);
+    }
+
+    /**
+     * Return an iterator for current subwindows. This method is meant for
+     * testing purposes only.
+     * 
+     * @return
+     */
+    public List<WindowConnector> getSubWindows() {
+        ArrayList<WindowConnector> windows = new ArrayList<WindowConnector>();
+        for (ComponentConnector child : getChildComponents()) {
+            if (child instanceof WindowConnector) {
+                windows.add((WindowConnector) child);
+            }
+        }
+        return windows;
+    }
+
+    @Override
+    public UIState getState() {
+        return (UIState) super.getState();
+    }
+
+    @Override
+    public void onConnectorHierarchyChange(ConnectorHierarchyChangeEvent event) {
+        super.onConnectorHierarchyChange(event);
+
+        ComponentConnector oldChild = null;
+        ComponentConnector newChild = getContent();
+
+        for (ComponentConnector c : event.getOldChildren()) {
+            if (!(c instanceof WindowConnector)) {
+                oldChild = c;
+                break;
+            }
+        }
+
+        if (oldChild != newChild) {
+            if (childStateChangeHandlerRegistration != null) {
+                childStateChangeHandlerRegistration.removeHandler();
+                childStateChangeHandlerRegistration = null;
+            }
+            getWidget().setWidget(newChild.getWidget());
+            childStateChangeHandlerRegistration = newChild
+                    .addStateChangeHandler(childStateChangeHandler);
+            // Must handle new child here as state change events are already
+            // fired
+            onChildSizeChange();
+        }
+
+        for (ComponentConnector c : getChildComponents()) {
+            if (c instanceof WindowConnector) {
+                WindowConnector wc = (WindowConnector) c;
+                wc.setWindowOrderAndPosition();
+            }
+        }
+
+        // Close removed sub windows
+        for (ComponentConnector c : event.getOldChildren()) {
+            if (c.getParent() != this && c instanceof WindowConnector) {
+                ((WindowConnector) c).getWidget().hide();
+            }
+        }
+    }
+
+    /**
+     * Tries to scroll the viewport so that the given connector is in view.
+     * 
+     * @param componentConnector
+     *            The connector which should be visible
+     * 
+     */
+    public void scrollIntoView(final ComponentConnector componentConnector) {
+        if (componentConnector == null) {
+            return;
+        }
+
+        Scheduler.get().scheduleDeferred(new Command() {
+            @Override
+            public void execute() {
+                componentConnector.getWidget().getElement().scrollIntoView();
+            }
+        });
+    }
+}
diff --git a/client/src/com/vaadin/client/ui/ui/VUI.java b/client/src/com/vaadin/client/ui/ui/VUI.java
new file mode 100644 (file)
index 0000000..9aa3331
--- /dev/null
@@ -0,0 +1,459 @@
+/*
+ * Copyright 2011 Vaadin Ltd.
+ * 
+ * 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.vaadin.client.ui.ui;
+
+import java.util.ArrayList;
+
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.event.logical.shared.HasResizeHandlers;
+import com.google.gwt.event.logical.shared.ResizeEvent;
+import com.google.gwt.event.logical.shared.ResizeHandler;
+import com.google.gwt.event.logical.shared.ValueChangeEvent;
+import com.google.gwt.event.logical.shared.ValueChangeHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.History;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.SimplePanel;
+import com.vaadin.client.ApplicationConnection;
+import com.vaadin.client.BrowserInfo;
+import com.vaadin.client.ComponentConnector;
+import com.vaadin.client.ConnectorMap;
+import com.vaadin.client.Focusable;
+import com.vaadin.client.VConsole;
+import com.vaadin.client.ui.ShortcutActionHandler;
+import com.vaadin.client.ui.TouchScrollDelegate;
+import com.vaadin.client.ui.VLazyExecutor;
+import com.vaadin.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner;
+import com.vaadin.client.ui.TouchScrollDelegate.TouchScrollHandler;
+import com.vaadin.client.ui.textfield.VTextField;
+import com.vaadin.shared.ApplicationConstants;
+import com.vaadin.shared.ui.ui.UIConstants;
+
+/**
+ *
+ */
+public class VUI extends SimplePanel implements ResizeHandler,
+        Window.ClosingHandler, ShortcutActionHandlerOwner, Focusable,
+        HasResizeHandlers {
+
+    private static final String CLASSNAME = "v-view";
+
+    private static int MONITOR_PARENT_TIMER_INTERVAL = 1000;
+
+    String theme;
+
+    String id;
+
+    ShortcutActionHandler actionHandler;
+
+    /*
+     * Last known window size used to detect whether VView should be layouted
+     * again. Detection must check window size, because the VView size might be
+     * fixed and thus not automatically adapt to changed window sizes.
+     */
+    private int windowWidth;
+    private int windowHeight;
+
+    /*
+     * Last know view size used to detect whether new dimensions should be sent
+     * to the server.
+     */
+    private int viewWidth;
+    private int viewHeight;
+
+    ApplicationConnection connection;
+
+    /**
+     * Keep track of possible parent size changes when an embedded application.
+     * 
+     * Uses {@link #parentWidth} and {@link #parentHeight} as an optimization to
+     * keep track of when there is a real change.
+     */
+    private Timer resizeTimer;
+
+    /** stored width of parent for embedded application auto-resize */
+    private int parentWidth;
+
+    /** stored height of parent for embedded application auto-resize */
+    private int parentHeight;
+
+    int scrollTop;
+
+    int scrollLeft;
+
+    boolean rendering;
+
+    boolean scrollable;
+
+    boolean immediate;
+
+    boolean resizeLazy = false;
+
+    private HandlerRegistration historyHandlerRegistration;
+
+    private TouchScrollHandler touchScrollHandler;
+
+    /**
+     * The current URI fragment, used to avoid sending updates if nothing has
+     * changed.
+     */
+    String currentFragment;
+
+    /**
+     * Listener for URI fragment changes. Notifies the server of the new value
+     * whenever the value changes.
+     */
+    private final ValueChangeHandler<String> historyChangeHandler = new ValueChangeHandler<String>() {
+
+        @Override
+        public void onValueChange(ValueChangeEvent<String> event) {
+            String newFragment = event.getValue();
+
+            // Send the new fragment to the server if it has changed
+            if (!newFragment.equals(currentFragment) && connection != null) {
+                currentFragment = newFragment;
+                connection.updateVariable(id, UIConstants.FRAGMENT_VARIABLE,
+                        newFragment, true);
+            }
+        }
+    };
+
+    private VLazyExecutor delayedResizeExecutor = new VLazyExecutor(200,
+            new ScheduledCommand() {
+
+                @Override
+                public void execute() {
+                    performSizeCheck();
+                }
+
+            });
+
+    public VUI() {
+        super();
+        setStyleName(CLASSNAME);
+
+        // Allow focusing the view by using the focus() method, the view
+        // should not be in the document focus flow
+        getElement().setTabIndex(-1);
+        makeScrollable();
+    }
+
+    /**
+     * Start to periodically monitor for parent element resizes if embedded
+     * application (e.g. portlet).
+     */
+    @Override
+    protected void onLoad() {
+        super.onLoad();
+        if (isMonitoringParentSize()) {
+            resizeTimer = new Timer() {
+
+                @Override
+                public void run() {
+                    // trigger check to see if parent size has changed,
+                    // recalculate layouts
+                    performSizeCheck();
+                    resizeTimer.schedule(MONITOR_PARENT_TIMER_INTERVAL);
+                }
+            };
+            resizeTimer.schedule(MONITOR_PARENT_TIMER_INTERVAL);
+        }
+    }
+
+    @Override
+    protected void onAttach() {
+        super.onAttach();
+        historyHandlerRegistration = History
+                .addValueChangeHandler(historyChangeHandler);
+        currentFragment = History.getToken();
+    }
+
+    @Override
+    protected void onDetach() {
+        super.onDetach();
+        historyHandlerRegistration.removeHandler();
+        historyHandlerRegistration = null;
+    }
+
+    /**
+     * Stop monitoring for parent element resizes.
+     */
+
+    @Override
+    protected void onUnload() {
+        if (resizeTimer != null) {
+            resizeTimer.cancel();
+            resizeTimer = null;
+        }
+        super.onUnload();
+    }
+
+    /**
+     * Called when the window or parent div might have been resized.
+     * 
+     * This immediately checks the sizes of the window and the parent div (if
+     * monitoring it) and triggers layout recalculation if they have changed.
+     */
+    protected void performSizeCheck() {
+        windowSizeMaybeChanged(Window.getClientWidth(),
+                Window.getClientHeight());
+    }
+
+    /**
+     * Called when the window or parent div might have been resized.
+     * 
+     * This immediately checks the sizes of the window and the parent div (if
+     * monitoring it) and triggers layout recalculation if they have changed.
+     * 
+     * @param newWindowWidth
+     *            The new width of the window
+     * @param newWindowHeight
+     *            The new height of the window
+     * 
+     * @deprecated use {@link #performSizeCheck()}
+     */
+    @Deprecated
+    protected void windowSizeMaybeChanged(int newWindowWidth,
+            int newWindowHeight) {
+        boolean changed = false;
+        ComponentConnector connector = ConnectorMap.get(connection)
+                .getConnector(this);
+        if (windowWidth != newWindowWidth) {
+            windowWidth = newWindowWidth;
+            changed = true;
+            connector.getLayoutManager().reportOuterWidth(connector,
+                    newWindowWidth);
+            VConsole.log("New window width: " + windowWidth);
+        }
+        if (windowHeight != newWindowHeight) {
+            windowHeight = newWindowHeight;
+            changed = true;
+            connector.getLayoutManager().reportOuterHeight(connector,
+                    newWindowHeight);
+            VConsole.log("New window height: " + windowHeight);
+        }
+        Element parentElement = getElement().getParentElement();
+        if (isMonitoringParentSize() && parentElement != null) {
+            // check also for parent size changes
+            int newParentWidth = parentElement.getClientWidth();
+            int newParentHeight = parentElement.getClientHeight();
+            if (parentWidth != newParentWidth) {
+                parentWidth = newParentWidth;
+                changed = true;
+                VConsole.log("New parent width: " + parentWidth);
+            }
+            if (parentHeight != newParentHeight) {
+                parentHeight = newParentHeight;
+                changed = true;
+                VConsole.log("New parent height: " + parentHeight);
+            }
+        }
+        if (changed) {
+            /*
+             * If the window size has changed, layout the VView again and send
+             * new size to the server if the size changed. (Just checking VView
+             * size would cause us to ignore cases when a relatively sized VView
+             * should shrink as the content's size is fixed and would thus not
+             * automatically shrink.)
+             */
+            VConsole.log("Running layout functions due to window or parent resize");
+
+            // update size to avoid (most) redundant re-layout passes
+            // there can still be an extra layout recalculation if webkit
+            // overflow fix updates the size in a deferred block
+            if (isMonitoringParentSize() && parentElement != null) {
+                parentWidth = parentElement.getClientWidth();
+                parentHeight = parentElement.getClientHeight();
+            }
+
+            sendClientResized();
+
+            connector.getLayoutManager().layoutNow();
+        }
+    }
+
+    public String getTheme() {
+        return theme;
+    }
+
+    /**
+     * Used to reload host page on theme changes.
+     */
+    static native void reloadHostPage()
+    /*-{
+         $wnd.location.reload();
+     }-*/;
+
+    /**
+     * Returns true if the body is NOT generated, i.e if someone else has made
+     * the page that we're running in. Otherwise we're in charge of the whole
+     * page.
+     * 
+     * @return true if we're running embedded
+     */
+    public boolean isEmbedded() {
+        return !getElement().getOwnerDocument().getBody().getClassName()
+                .contains(ApplicationConstants.GENERATED_BODY_CLASSNAME);
+    }
+
+    /**
+     * Returns true if the size of the parent should be checked periodically and
+     * the application should react to its changes.
+     * 
+     * @return true if size of parent should be tracked
+     */
+    protected boolean isMonitoringParentSize() {
+        // could also perform a more specific check (Liferay portlet)
+        return isEmbedded();
+    }
+
+    @Override
+    public void onBrowserEvent(Event event) {
+        super.onBrowserEvent(event);
+        int type = DOM.eventGetType(event);
+        if (type == Event.ONKEYDOWN && actionHandler != null) {
+            actionHandler.handleKeyboardEvent(event);
+            return;
+        } else if (scrollable && type == Event.ONSCROLL) {
+            updateScrollPosition();
+        }
+    }
+
+    /**
+     * Updates scroll position from DOM and saves variables to server.
+     */
+    private void updateScrollPosition() {
+        int oldTop = scrollTop;
+        int oldLeft = scrollLeft;
+        scrollTop = DOM.getElementPropertyInt(getElement(), "scrollTop");
+        scrollLeft = DOM.getElementPropertyInt(getElement(), "scrollLeft");
+        if (connection != null && !rendering) {
+            if (oldTop != scrollTop) {
+                connection.updateVariable(id, "scrollTop", scrollTop, false);
+            }
+            if (oldLeft != scrollLeft) {
+                connection.updateVariable(id, "scrollLeft", scrollLeft, false);
+            }
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * com.google.gwt.event.logical.shared.ResizeHandler#onResize(com.google
+     * .gwt.event.logical.shared.ResizeEvent)
+     */
+
+    @Override
+    public void onResize(ResizeEvent event) {
+        triggerSizeChangeCheck();
+    }
+
+    /**
+     * Called when a resize event is received.
+     * 
+     * This may trigger a lazy refresh or perform the size check immediately
+     * depending on the browser used and whether the server side requests
+     * resizes to be lazy.
+     */
+    private void triggerSizeChangeCheck() {
+        /*
+         * IE (pre IE9 at least) will give us some false resize events due to
+         * problems with scrollbars. Firefox 3 might also produce some extra
+         * events. We postpone both the re-layouting and the server side event
+         * for a while to deal with these issues.
+         * 
+         * We may also postpone these events to avoid slowness when resizing the
+         * browser window. Constantly recalculating the layout causes the resize
+         * operation to be really slow with complex layouts.
+         */
+        boolean lazy = resizeLazy || BrowserInfo.get().isIE8();
+
+        if (lazy) {
+            delayedResizeExecutor.trigger();
+        } else {
+            performSizeCheck();
+        }
+    }
+
+    /**
+     * Send new dimensions to the server.
+     */
+    void sendClientResized() {
+        Element parentElement = getElement().getParentElement();
+        int viewHeight = parentElement.getClientHeight();
+        int viewWidth = parentElement.getClientWidth();
+
+        ResizeEvent.fire(this, viewWidth, viewHeight);
+    }
+
+    public native static void goTo(String url)
+    /*-{
+       $wnd.location = url;
+     }-*/;
+
+    @Override
+    public void onWindowClosing(Window.ClosingEvent event) {
+        // Change focus on this window in order to ensure that all state is
+        // collected from textfields
+        // TODO this is a naive hack, that only works with text fields and may
+        // cause some odd issues. Should be replaced with a decent solution, see
+        // also related BeforeShortcutActionListener interface. Same interface
+        // might be usable here.
+        VTextField.flushChangesFromFocusedTextField();
+    }
+
+    private native static void loadAppIdListFromDOM(ArrayList<String> list)
+    /*-{
+         var j;
+         for(j in $wnd.vaadin.vaadinConfigurations) {
+            // $entry not needed as function is not exported
+            list.@java.util.Collection::add(Ljava/lang/Object;)(j);
+         }
+     }-*/;
+
+    @Override
+    public ShortcutActionHandler getShortcutActionHandler() {
+        return actionHandler;
+    }
+
+    @Override
+    public void focus() {
+        getElement().focus();
+    }
+
+    /**
+     * Ensures the root is scrollable eg. after style name changes.
+     */
+    void makeScrollable() {
+        if (touchScrollHandler == null) {
+            touchScrollHandler = TouchScrollDelegate.enableTouchScrolling(this);
+        }
+        touchScrollHandler.addElement(getElement());
+    }
+
+    @Override
+    public HandlerRegistration addResizeHandler(ResizeHandler resizeHandler) {
+        return addHandler(resizeHandler, ResizeEvent.getType());
+    }
+
+}