]> source.dussan.org Git - vaadin-framework.git/commitdiff
#8324 Split VView and VWindow into paintable and widget
authorArtur Signell <artur@vaadin.com>
Tue, 31 Jan 2012 11:52:09 +0000 (13:52 +0200)
committerArtur Signell <artur@vaadin.com>
Tue, 31 Jan 2012 13:08:31 +0000 (15:08 +0200)
src/com/vaadin/terminal/gwt/client/ComponentLocator.java
src/com/vaadin/terminal/gwt/client/VDebugConsole.java
src/com/vaadin/terminal/gwt/client/ui/VView.java
src/com/vaadin/terminal/gwt/client/ui/VViewPaintable.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/client/ui/VWindow.java
src/com/vaadin/terminal/gwt/client/ui/VWindowPaintable.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java
src/com/vaadin/ui/Window.java

index b03bc708e2c560f847bbd87494c70c2e50c7071e..f49f99a477d51c82d47bed4f4f520e0104f97647 100644 (file)
@@ -375,7 +375,7 @@ public class ComponentLocator {
         } else if (w instanceof VWindow) {
             VWindow win = (VWindow) w;
             ArrayList<VWindow> subWindowList = client.getView()
-                    .getSubWindowList();
+                    .getWidgetForPaintable().getSubWindowList();
             int indexOfSubWindow = subWindowList.indexOf(win);
             return PARENTCHILD_SEPARATOR + "VWindow[" + indexOfSubWindow + "]";
         } else if (w instanceof RootPanel) {
@@ -435,7 +435,7 @@ public class ComponentLocator {
             if (part.equals(ROOT_ID)) {
                 w = RootPanel.get();
             } else if (part.equals("")) {
-                w = client.getView();
+                w = client.getView().getWidgetForPaintable();
             } else if (w == null) {
                 // Must be static pid (PID_S*)
                 w = ((VPaintableWidget) VPaintableMap.get(client).getPaintable(
@@ -465,7 +465,8 @@ public class ComponentLocator {
                  * compatibility
                  */
                 if (widgetClassName.equals("VWindow")) {
-                    iterator = client.getView().getSubWindowList().iterator();
+                    iterator = client.getView().getWidgetForPaintable()
+                            .getSubWindowList().iterator();
                 } else if (widgetClassName.equals("VContextMenu")) {
                     return client.getContextMenu();
                 } else {
index fdaf944b9f8628cade26f7a79fe6d03d8725e4cc..76c312676a97530612df35ca2a0612bb5241fccd 100644 (file)
@@ -91,7 +91,7 @@ public class VDebugConsole extends VOverlay implements Console {
                 for (ApplicationConnection a : ApplicationConfiguration
                         .getRunningApplications()) {
                     VPaintableWidget paintable = Util.getPaintableForElement(a,
-                            a.getView(), eventTarget);
+                            a.getView().getWidgetForPaintable(), eventTarget);
                     if (paintable == null) {
                         paintable = Util.getPaintableForElement(a,
                                 RootPanel.get(), eventTarget);
@@ -120,7 +120,7 @@ public class VDebugConsole extends VOverlay implements Console {
                 for (ApplicationConnection a : ApplicationConfiguration
                         .getRunningApplications()) {
                     VPaintableWidget paintable = Util.getPaintableForElement(a,
-                            a.getView(), eventTarget);
+                            a.getView().getWidgetForPaintable(), eventTarget);
                     if (paintable == null) {
                         paintable = Util.getPaintableForElement(a,
                                 RootPanel.get(), eventTarget);
@@ -534,8 +534,7 @@ public class VDebugConsole extends VOverlay implements Console {
             emphasisInUi.addClickHandler(new ClickHandler() {
                 public void onClick(ClickEvent event) {
                     if (paintable != null) {
-                        Element element2 = layout.getWidgetForPaintable()
-                                .getElement();
+                        Element element2 = ((Widget) layout).getElement();
                         Widget.setStyleName(element2, "invalidlayout",
                                 emphasisInUi.getValue());
                     }
index e3aba2109678a1130ee91320d79c08ffe69cba36..7002c6279f57b71c7c4ed5229757157d87812c9c 100644 (file)
@@ -5,8 +5,6 @@
 package com.vaadin.terminal.gwt.client.ui;
 
 import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.Set;
 
@@ -17,12 +15,10 @@ import com.google.gwt.dom.client.Document;
 import com.google.gwt.dom.client.Element;
 import com.google.gwt.dom.client.Style;
 import com.google.gwt.dom.client.Style.Display;
-import com.google.gwt.event.dom.client.DomEvent.Type;
 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.EventHandler;
 import com.google.gwt.event.shared.HandlerRegistration;
 import com.google.gwt.user.client.Command;
 import com.google.gwt.user.client.DOM;
@@ -30,7 +26,6 @@ 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.RootPanel;
 import com.google.gwt.user.client.ui.SimplePanel;
 import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
@@ -56,15 +51,15 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
 
     public static final String NOTIFICATION_HTML_CONTENT_NOT_ALLOWED = "useplain";
 
-    private String theme;
+    String theme;
 
-    private VPaintableWidget layout;
+    VPaintableWidget layout;
 
-    private final LinkedHashSet<VWindow> subWindows = new LinkedHashSet<VWindow>();
+    final LinkedHashSet<VWindow> subWindows = new LinkedHashSet<VWindow>();
 
-    private String id;
+    String id;
 
-    private ShortcutActionHandler actionHandler;
+    ShortcutActionHandler actionHandler;
 
     /** stored width for IE resize optimization */
     private int width;
@@ -72,7 +67,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
     /** stored height for IE resize optimization */
     private int height;
 
-    private ApplicationConnection connection;
+    ApplicationConnection connection;
 
     /** Identifies the click event */
     public static final String CLICK_EVENT_ID = "click";
@@ -85,17 +80,17 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
      */
     private Timer resizeTimer;
 
-    private int scrollTop;
+    int scrollTop;
 
-    private int scrollLeft;
+    int scrollLeft;
 
-    private boolean rendering;
+    boolean rendering;
 
-    private boolean scrollable;
+    boolean scrollable;
 
-    private boolean immediate;
+    boolean immediate;
 
-    private boolean resizeLazy = false;
+    boolean resizeLazy = false;
 
     /**
      * Attribute name for the lazy resize setting .
@@ -106,7 +101,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
      * Reference to the parent frame/iframe. Null if there is no parent (i)frame
      * or if the application and parent frame are in different domains.
      */
-    private Element parentFrame;
+    Element parentFrame;
 
     private HandlerRegistration historyHandlerRegistration;
 
@@ -114,7 +109,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
      * The current URI fragment, used to avoid sending updates if nothing has
      * changed.
      */
-    private String currentFragment;
+    String currentFragment;
 
     /**
      * Listener for URI fragment changes. Notifies the server of the new value
@@ -133,16 +128,6 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
         }
     };
 
-    private ClickEventHandler clickEventHandler = new ClickEventHandler(this,
-            VPanel.CLICK_EVENT_IDENTIFIER) {
-
-        @Override
-        protected <H extends EventHandler> HandlerRegistration registerHandler(
-                H handler, Type<H> type) {
-            return addDomHandler(handler, type);
-        }
-    };
-
     private VLazyExecutor delayedResizeExecutor = new VLazyExecutor(200,
             new ScheduledCommand() {
                 public void execute() {
@@ -212,7 +197,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
     /**
      * Used to reload host page on theme changes.
      */
-    private static native void reloadHostPage()
+    static native void reloadHostPage()
     /*-{
          $wnd.location.reload();
      }-*/;
@@ -223,7 +208,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
      * @param script
      *            Script to be executed.
      */
-    private static native void eval(String script)
+    static native void eval(String script)
     /*-{
       try {
          if (script == null) return;
@@ -244,229 +229,6 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
                 .contains(ApplicationConnection.GENERATED_BODY_CLASSNAME);
     }
 
-    public void updateFromUIDL(final UIDL uidl, ApplicationConnection client) {
-        rendering = true;
-
-        id = uidl.getId();
-        boolean firstPaint = connection == null;
-        connection = client;
-
-        immediate = uidl.hasAttribute("immediate");
-        resizeLazy = uidl.hasAttribute(RESIZE_LAZY);
-        String newTheme = uidl.getStringAttribute("theme");
-        if (theme != null && !newTheme.equals(theme)) {
-            // Complete page refresh is needed due css can affect layout
-            // calculations etc
-            reloadHostPage();
-        } else {
-            theme = newTheme;
-        }
-        if (uidl.hasAttribute("style")) {
-            setStyleName(getStylePrimaryName() + " "
-                    + uidl.getStringAttribute("style"));
-        }
-
-        clickEventHandler.handleEventHandlerRegistration(client);
-
-        if (!isEmbedded() && uidl.hasAttribute("caption")) {
-            // only change window title if we're in charge of the whole page
-            com.google.gwt.user.client.Window.setTitle(uidl
-                    .getStringAttribute("caption"));
-        }
-
-        // 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() {
-                    public void execute() {
-                        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;
-                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
-            rendering = false;
-            return;
-        }
-
-        // Draw this application level window
-        UIDL childUidl = uidl.getChildUIDL(childIndex);
-        final VPaintableWidget lo = client.getPaintable(childUidl);
-
-        if (layout != null) {
-            if (layout != lo) {
-                // remove old
-                client.unregisterPaintable(layout);
-                // add new
-                setWidget(lo.getWidgetForPaintable());
-                layout = lo;
-            }
-        } else {
-            setWidget(lo.getWidgetForPaintable());
-            layout = lo;
-        }
-
-        layout.updateFromUIDL(childUidl, client);
-        if (!childUidl.getBooleanAttribute("cached")) {
-            updateParentFrameSize();
-        }
-
-        // Save currently open subwindows to track which will need to be closed
-        final HashSet<VWindow> removedSubWindows = new HashSet<VWindow>(
-                subWindows);
-
-        // Handle other UIDL children
-        while ((childUidl = uidl.getChildUIDL(++childIndex)) != null) {
-            String tag = childUidl.getTag().intern();
-            if (tag == "actions") {
-                if (actionHandler == null) {
-                    actionHandler = new ShortcutActionHandler(id, client);
-                }
-                actionHandler.updateActionMap(childUidl);
-            } else if (tag == "execJS") {
-                String script = childUidl.getStringAttribute("script");
-                eval(script);
-            } else if (tag == "notifications") {
-                for (final Iterator<?> it = childUidl.getChildIterator(); it
-                        .hasNext();) {
-                    final UIDL notification = (UIDL) it.next();
-                    VNotification.showNotification(client, notification);
-                }
-            } else {
-                // subwindows
-                final VPaintableWidget w = client.getPaintable(childUidl);
-                if (subWindows.contains(w)) {
-                    removedSubWindows.remove(w);
-                } else {
-                    subWindows.add((VWindow) w);
-                }
-                w.updateFromUIDL(childUidl, client);
-            }
-        }
-
-        // Close old windows which where not in UIDL anymore
-        for (final Iterator<VWindow> rem = removedSubWindows.iterator(); rem
-                .hasNext();) {
-            final VWindow w = rem.next();
-            client.unregisterPaintable(w);
-            subWindows.remove(w);
-            w.hide();
-        }
-
-        if (uidl.hasAttribute("focused")) {
-            // set focused component when render phase is finished
-            Scheduler.get().scheduleDeferred(new Command() {
-                public void execute() {
-                    VPaintableWidget paintable = (VPaintableWidget) uidl
-                            .getPaintableAttribute("focused", connection);
-
-                    final Widget toBeFocused = paintable
-                            .getWidgetForPaintable();
-                    /*
-                     * 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(this);
-            Window.addResizeHandler(this);
-        }
-
-        onResize();
-
-        // finally set scroll position from UIDL
-        if (uidl.hasVariable("scrollTop")) {
-            scrollable = true;
-            scrollTop = uidl.getIntVariable("scrollTop");
-            DOM.setElementPropertyInt(getElement(), "scrollTop", scrollTop);
-            scrollLeft = uidl.getIntVariable("scrollLeft");
-            DOM.setElementPropertyInt(getElement(), "scrollLeft", scrollLeft);
-        } else {
-            scrollable = false;
-        }
-
-        // Safari workaround must be run after scrollTop is updated as it sets
-        // scrollTop using a deferred command.
-        if (BrowserInfo.get().isSafari()) {
-            Util.runWebkitOverflowAutoFix(getElement());
-        }
-
-        scrollIntoView(uidl);
-
-        if (uidl.hasAttribute(FRAGMENT_VARIABLE)) {
-            currentFragment = uidl.getStringAttribute(FRAGMENT_VARIABLE);
-            if (!currentFragment.equals(History.getToken())) {
-                History.newItem(currentFragment, true);
-            }
-        } else {
-            // Initial request for which the server doesn't yet have a fragment
-            // (and haven't shown any interest in getting one)
-            currentFragment = History.getToken();
-
-            // Include current fragment in the next request
-            client.updateVariable(id, FRAGMENT_VARIABLE, currentFragment, false);
-        }
-
-        rendering = false;
-    }
-
     /**
      * Tries to scroll paintable referenced from given UIDL snippet to be
      * visible.
@@ -530,7 +292,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
     /**
      * Called when a resize event is received.
      */
-    private void onResize() {
+    void onResize() {
         /*
          * IE (pre IE9 at least) will give us some false resize events due to
          * problems with scrollbars. Firefox 3 might also produce some extra
@@ -742,7 +504,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
 
     }
 
-    private void updateParentFrameSize() {
+    void updateParentFrameSize() {
         if (parentFrame == null) {
             return;
         }
@@ -754,7 +516,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
         parentFrame.getStyle().setPropertyPx("height", childHeight);
     }
 
-    private static native Element getParentFrame()
+    static native Element getParentFrame()
     /*-{
         try {
             var frameElement = $wnd.frameElement;
@@ -769,10 +531,6 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
         return null;
     }-*/;
 
-    public void updateCaption(VPaintableWidget component, UIDL uidl) {
-        // NOP Subwindows never draw caption for their first child (layout)
-    }
-
     /**
      * Return an iterator for current subwindows. This method is meant for
      * testing purposes only.
@@ -787,42 +545,6 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
         return windows;
     }
 
-    public void init(String rootPanelId,
-            ApplicationConnection applicationConnection) {
-        DOM.sinkEvents(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(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("");
-        // For backwards compatibility with static index pages only.
-        // No longer added by AbstractApplicationServlet/Portlet
-        root.removeStyleName("v-app-loading");
-
-        String themeUri = applicationConnection.getConfiguration()
-                .getThemeUri();
-        String themeName = themeUri.substring(themeUri.lastIndexOf('/'));
-        themeName = themeName.replaceAll("[^a-zA-Z0-9]", "");
-        root.addStyleName("v-theme-" + themeName);
-
-        root.add(this);
-
-        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).
-            getElement().focus();
-        }
-
-        parentFrame = getParentFrame();
-    }
-
     public ShortcutActionHandler getShortcutActionHandler() {
         return actionHandler;
     }
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VViewPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VViewPaintable.java
new file mode 100644 (file)
index 0000000..ebec292
--- /dev/null
@@ -0,0 +1,331 @@
+package com.vaadin.terminal.gwt.client.ui;\r
+\r
+import java.util.HashSet;\r
+import java.util.Iterator;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.core.client.Scheduler;\r
+import com.google.gwt.event.dom.client.DomEvent.Type;\r
+import com.google.gwt.event.shared.EventHandler;\r
+import com.google.gwt.event.shared.HandlerRegistration;\r
+import com.google.gwt.user.client.Command;\r
+import com.google.gwt.user.client.DOM;\r
+import com.google.gwt.user.client.Event;\r
+import com.google.gwt.user.client.History;\r
+import com.google.gwt.user.client.Window;\r
+import com.google.gwt.user.client.ui.RootPanel;\r
+import com.google.gwt.user.client.ui.Widget;\r
+import com.vaadin.terminal.gwt.client.ApplicationConnection;\r
+import com.vaadin.terminal.gwt.client.BrowserInfo;\r
+import com.vaadin.terminal.gwt.client.Focusable;\r
+import com.vaadin.terminal.gwt.client.UIDL;\r
+import com.vaadin.terminal.gwt.client.Util;\r
+import com.vaadin.terminal.gwt.client.VConsole;\r
+import com.vaadin.terminal.gwt.client.VPaintableMap;\r
+import com.vaadin.terminal.gwt.client.VPaintableWidget;\r
+\r
+public class VViewPaintable extends VAbstractPaintableWidgetContainer {\r
+\r
+    private static final String CLICK_EVENT_IDENTIFIER = VPanelPaintable.CLICK_EVENT_IDENTIFIER;\r
+\r
+    public void updateFromUIDL(final UIDL uidl, ApplicationConnection client) {\r
+        getWidgetForPaintable().rendering = true;\r
+\r
+        getWidgetForPaintable().id = uidl.getId();\r
+        boolean firstPaint = getWidgetForPaintable().connection == null;\r
+        getWidgetForPaintable().connection = client;\r
+\r
+        getWidgetForPaintable().immediate = uidl.hasAttribute("immediate");\r
+        getWidgetForPaintable().resizeLazy = uidl\r
+                .hasAttribute(VView.RESIZE_LAZY);\r
+        String newTheme = uidl.getStringAttribute("theme");\r
+        if (getWidgetForPaintable().theme != null\r
+                && !newTheme.equals(getWidgetForPaintable().theme)) {\r
+            // Complete page refresh is needed due css can affect layout\r
+            // calculations etc\r
+            getWidgetForPaintable().reloadHostPage();\r
+        } else {\r
+            getWidgetForPaintable().theme = newTheme;\r
+        }\r
+        if (uidl.hasAttribute("style")) {\r
+            getWidgetForPaintable().setStyleName(\r
+                    getWidgetForPaintable().getStylePrimaryName() + " "\r
+                            + uidl.getStringAttribute("style"));\r
+        }\r
+\r
+        clickEventHandler.handleEventHandlerRegistration(client);\r
+\r
+        if (!getWidgetForPaintable().isEmbedded()\r
+                && uidl.hasAttribute("caption")) {\r
+            // only change window title if we're in charge of the whole page\r
+            com.google.gwt.user.client.Window.setTitle(uidl\r
+                    .getStringAttribute("caption"));\r
+        }\r
+\r
+        // Process children\r
+        int childIndex = 0;\r
+\r
+        // Open URL:s\r
+        boolean isClosed = false; // was this window closed?\r
+        while (childIndex < uidl.getChildCount()\r
+                && "open".equals(uidl.getChildUIDL(childIndex).getTag())) {\r
+            final UIDL open = uidl.getChildUIDL(childIndex);\r
+            final String url = client.translateVaadinUri(open\r
+                    .getStringAttribute("src"));\r
+            final String target = open.getStringAttribute("name");\r
+            if (target == null) {\r
+                // source will be opened to this browser window, but we may have\r
+                // to finish rendering this window in case this is a download\r
+                // (and window stays open).\r
+                Scheduler.get().scheduleDeferred(new Command() {\r
+                    public void execute() {\r
+                        VView.goTo(url);\r
+                    }\r
+                });\r
+            } else if ("_self".equals(target)) {\r
+                // This window is closing (for sure). Only other opens are\r
+                // relevant in this change. See #3558, #2144\r
+                isClosed = true;\r
+                VView.goTo(url);\r
+            } else {\r
+                String options;\r
+                if (open.hasAttribute("border")) {\r
+                    if (open.getStringAttribute("border").equals("minimal")) {\r
+                        options = "menubar=yes,location=no,status=no";\r
+                    } else {\r
+                        options = "menubar=no,location=no,status=no";\r
+                    }\r
+\r
+                } else {\r
+                    options = "resizable=yes,menubar=yes,toolbar=yes,directories=yes,location=yes,scrollbars=yes,status=yes";\r
+                }\r
+\r
+                if (open.hasAttribute("width")) {\r
+                    int w = open.getIntAttribute("width");\r
+                    options += ",width=" + w;\r
+                }\r
+                if (open.hasAttribute("height")) {\r
+                    int h = open.getIntAttribute("height");\r
+                    options += ",height=" + h;\r
+                }\r
+\r
+                Window.open(url, target, options);\r
+            }\r
+            childIndex++;\r
+        }\r
+        if (isClosed) {\r
+            // don't render the content, something else will be opened to this\r
+            // browser view\r
+            getWidgetForPaintable().rendering = false;\r
+            return;\r
+        }\r
+\r
+        // Draw this application level window\r
+        UIDL childUidl = uidl.getChildUIDL(childIndex);\r
+        final VPaintableWidget lo = client.getPaintable(childUidl);\r
+\r
+        if (getWidgetForPaintable().layout != null) {\r
+            if (getWidgetForPaintable().layout != lo) {\r
+                // remove old\r
+                client.unregisterPaintable(getWidgetForPaintable().layout);\r
+                // add new\r
+                getWidgetForPaintable().setWidget(lo.getWidgetForPaintable());\r
+                getWidgetForPaintable().layout = lo;\r
+            }\r
+        } else {\r
+            getWidgetForPaintable().setWidget(lo.getWidgetForPaintable());\r
+            getWidgetForPaintable().layout = lo;\r
+        }\r
+\r
+        getWidgetForPaintable().layout.updateFromUIDL(childUidl, client);\r
+        if (!childUidl.getBooleanAttribute("cached")) {\r
+            getWidgetForPaintable().updateParentFrameSize();\r
+        }\r
+\r
+        // Save currently open subwindows to track which will need to be closed\r
+        final HashSet<VWindow> removedSubWindows = new HashSet<VWindow>(\r
+                getWidgetForPaintable().subWindows);\r
+\r
+        // Handle other UIDL children\r
+        while ((childUidl = uidl.getChildUIDL(++childIndex)) != null) {\r
+            String tag = childUidl.getTag().intern();\r
+            if (tag == "actions") {\r
+                if (getWidgetForPaintable().actionHandler == null) {\r
+                    getWidgetForPaintable().actionHandler = new ShortcutActionHandler(\r
+                            getWidgetForPaintable().id, client);\r
+                }\r
+                getWidgetForPaintable().actionHandler\r
+                        .updateActionMap(childUidl);\r
+            } else if (tag == "execJS") {\r
+                String script = childUidl.getStringAttribute("script");\r
+                VView.eval(script);\r
+            } else if (tag == "notifications") {\r
+                for (final Iterator<?> it = childUidl.getChildIterator(); it\r
+                        .hasNext();) {\r
+                    final UIDL notification = (UIDL) it.next();\r
+                    VNotification.showNotification(client, notification);\r
+                }\r
+            } else {\r
+                // subwindows\r
+                final VPaintableWidget w = client.getPaintable(childUidl);\r
+                if (getWidgetForPaintable().subWindows.contains(w)) {\r
+                    removedSubWindows.remove(w);\r
+                } else {\r
+                    getWidgetForPaintable().subWindows.add((VWindow) w);\r
+                }\r
+                w.updateFromUIDL(childUidl, client);\r
+            }\r
+        }\r
+\r
+        // Close old windows which where not in UIDL anymore\r
+        for (final Iterator<VWindow> rem = removedSubWindows.iterator(); rem\r
+                .hasNext();) {\r
+            final VWindow w = rem.next();\r
+            client.unregisterPaintable(VPaintableMap.get(getConnection())\r
+                    .getPaintable(w));\r
+            getWidgetForPaintable().subWindows.remove(w);\r
+            w.hide();\r
+        }\r
+\r
+        if (uidl.hasAttribute("focused")) {\r
+            // set focused component when render phase is finished\r
+            Scheduler.get().scheduleDeferred(new Command() {\r
+                public void execute() {\r
+                    VPaintableWidget paintable = (VPaintableWidget) uidl\r
+                            .getPaintableAttribute("focused", getConnection());\r
+\r
+                    final Widget toBeFocused = paintable\r
+                            .getWidgetForPaintable();\r
+                    /*\r
+                     * Two types of Widgets can be focused, either implementing\r
+                     * GWT HasFocus of a thinner Vaadin specific Focusable\r
+                     * interface.\r
+                     */\r
+                    if (toBeFocused instanceof com.google.gwt.user.client.ui.Focusable) {\r
+                        final com.google.gwt.user.client.ui.Focusable toBeFocusedWidget = (com.google.gwt.user.client.ui.Focusable) toBeFocused;\r
+                        toBeFocusedWidget.setFocus(true);\r
+                    } else if (toBeFocused instanceof Focusable) {\r
+                        ((Focusable) toBeFocused).focus();\r
+                    } else {\r
+                        VConsole.log("Could not focus component");\r
+                    }\r
+                }\r
+            });\r
+        }\r
+\r
+        // Add window listeners on first paint, to prevent premature\r
+        // variablechanges\r
+        if (firstPaint) {\r
+            Window.addWindowClosingHandler(getWidgetForPaintable());\r
+            Window.addResizeHandler(getWidgetForPaintable());\r
+        }\r
+\r
+        getWidgetForPaintable().onResize();\r
+\r
+        // finally set scroll position from UIDL\r
+        if (uidl.hasVariable("scrollTop")) {\r
+            getWidgetForPaintable().scrollable = true;\r
+            getWidgetForPaintable().scrollTop = uidl\r
+                    .getIntVariable("scrollTop");\r
+            DOM.setElementPropertyInt(getWidgetForPaintable().getElement(),\r
+                    "scrollTop", getWidgetForPaintable().scrollTop);\r
+            getWidgetForPaintable().scrollLeft = uidl\r
+                    .getIntVariable("scrollLeft");\r
+            DOM.setElementPropertyInt(getWidgetForPaintable().getElement(),\r
+                    "scrollLeft", getWidgetForPaintable().scrollLeft);\r
+        } else {\r
+            getWidgetForPaintable().scrollable = false;\r
+        }\r
+\r
+        // Safari workaround must be run after scrollTop is updated as it sets\r
+        // scrollTop using a deferred command.\r
+        if (BrowserInfo.get().isSafari()) {\r
+            Util.runWebkitOverflowAutoFix(getWidgetForPaintable().getElement());\r
+        }\r
+\r
+        getWidgetForPaintable().scrollIntoView(uidl);\r
+\r
+        if (uidl.hasAttribute(VView.FRAGMENT_VARIABLE)) {\r
+            getWidgetForPaintable().currentFragment = uidl\r
+                    .getStringAttribute(VView.FRAGMENT_VARIABLE);\r
+            if (!getWidgetForPaintable().currentFragment.equals(History\r
+                    .getToken())) {\r
+                History.newItem(getWidgetForPaintable().currentFragment, true);\r
+            }\r
+        } else {\r
+            // Initial request for which the server doesn't yet have a fragment\r
+            // (and haven't shown any interest in getting one)\r
+            getWidgetForPaintable().currentFragment = History.getToken();\r
+\r
+            // Include current fragment in the next request\r
+            client.updateVariable(getWidgetForPaintable().id,\r
+                    VView.FRAGMENT_VARIABLE,\r
+                    getWidgetForPaintable().currentFragment, false);\r
+        }\r
+\r
+        getWidgetForPaintable().rendering = false;\r
+    }\r
+\r
+    public void init(String rootPanelId,\r
+            ApplicationConnection applicationConnection) {\r
+        DOM.sinkEvents(getWidgetForPaintable().getElement(), Event.ONKEYDOWN\r
+                | Event.ONSCROLL);\r
+\r
+        // iview is focused when created so element needs tabIndex\r
+        // 1 due 0 is at the end of natural tabbing order\r
+        DOM.setElementProperty(getWidgetForPaintable().getElement(),\r
+                "tabIndex", "1");\r
+\r
+        RootPanel root = RootPanel.get(rootPanelId);\r
+\r
+        // Remove the v-app-loading or any splash screen added inside the div by\r
+        // the user\r
+        root.getElement().setInnerHTML("");\r
+        // For backwards compatibility with static index pages only.\r
+        // No longer added by AbstractApplicationServlet/Portlet\r
+        root.removeStyleName("v-app-loading");\r
+\r
+        String themeUri = applicationConnection.getConfiguration()\r
+                .getThemeUri();\r
+        String themeName = themeUri.substring(themeUri.lastIndexOf('/'));\r
+        themeName = themeName.replaceAll("[^a-zA-Z0-9]", "");\r
+        root.addStyleName("v-theme-" + themeName);\r
+\r
+        root.add(getWidgetForPaintable());\r
+\r
+        if (applicationConnection.getConfiguration().isStandalone()) {\r
+            // set focus to iview element by default to listen possible keyboard\r
+            // shortcuts. For embedded applications this is unacceptable as we\r
+            // don't want to steal focus from the main page nor we don't want\r
+            // side-effects from focusing (scrollIntoView).\r
+            getWidgetForPaintable().getElement().focus();\r
+        }\r
+\r
+        getWidgetForPaintable().parentFrame = VView.getParentFrame();\r
+    }\r
+\r
+    private ClickEventHandler clickEventHandler = new ClickEventHandler(this,\r
+            CLICK_EVENT_IDENTIFIER) {\r
+\r
+        @Override\r
+        protected <H extends EventHandler> HandlerRegistration registerHandler(\r
+                H handler, Type<H> type) {\r
+            return getWidgetForPaintable().addDomHandler(handler, type);\r
+        }\r
+    };\r
+\r
+    public void updateCaption(VPaintableWidget component, UIDL uidl) {\r
+        // NOP The main view never draws caption for its layout\r
+    }\r
+\r
+    @Override\r
+    public VView getWidgetForPaintable() {\r
+        return (VView) super.getWidgetForPaintable();\r
+    }\r
+\r
+    @Override\r
+    protected Widget createWidget() {\r
+        return GWT.create(VView.class);\r
+    }\r
+\r
+}\r
index 95ab0dc7735eab7cb9d19fa881bc81caf3d19a82..662b77a7b01a83216ebbeb45082e3614ffb0be2f 100644 (file)
@@ -13,21 +13,17 @@ import com.google.gwt.core.client.Scheduler;
 import com.google.gwt.core.client.Scheduler.ScheduledCommand;
 import com.google.gwt.event.dom.client.BlurEvent;
 import com.google.gwt.event.dom.client.BlurHandler;
-import com.google.gwt.event.dom.client.DomEvent.Type;
 import com.google.gwt.event.dom.client.FocusEvent;
 import com.google.gwt.event.dom.client.FocusHandler;
 import com.google.gwt.event.dom.client.KeyDownEvent;
 import com.google.gwt.event.dom.client.KeyDownHandler;
 import com.google.gwt.event.dom.client.ScrollEvent;
 import com.google.gwt.event.dom.client.ScrollHandler;
-import com.google.gwt.event.shared.EventHandler;
-import com.google.gwt.event.shared.HandlerRegistration;
 import com.google.gwt.user.client.Command;
 import com.google.gwt.user.client.DOM;
 import com.google.gwt.user.client.Element;
 import com.google.gwt.user.client.Event;
 import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.ui.Frame;
 import com.google.gwt.user.client.ui.HasWidgets;
 import com.google.gwt.user.client.ui.RootPanel;
 import com.google.gwt.user.client.ui.Widget;
@@ -38,10 +34,8 @@ import com.vaadin.terminal.gwt.client.Container;
 import com.vaadin.terminal.gwt.client.EventId;
 import com.vaadin.terminal.gwt.client.Focusable;
 import com.vaadin.terminal.gwt.client.RenderSpace;
-import com.vaadin.terminal.gwt.client.UIDL;
 import com.vaadin.terminal.gwt.client.Util;
 import com.vaadin.terminal.gwt.client.VPaintableWidget;
-import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.BeforeShortcutActionListener;
 import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner;
 
 /**
@@ -51,7 +45,7 @@ import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHan
  */
 public class VWindow extends VOverlay implements Container,
         ShortcutActionHandlerOwner, ScrollHandler, KeyDownHandler,
-        FocusHandler, BlurHandler, BeforeShortcutActionListener, Focusable {
+        FocusHandler, BlurHandler, Focusable {
 
     /**
      * Minimum allowed height of a window. This refers to the content area, not
@@ -88,9 +82,9 @@ public class VWindow extends VOverlay implements Container,
 
     public static final int Z_INDEX = 10000;
 
-    private VPaintableWidget layout;
+    VPaintableWidget layout;
 
-    private Element contents;
+    Element contents;
 
     private Element header;
 
@@ -98,7 +92,7 @@ public class VWindow extends VOverlay implements Container,
 
     private Element resizeBox;
 
-    private final FocusableScrollPanel contentPanel = new FocusableScrollPanel();
+    final FocusableScrollPanel contentPanel = new FocusableScrollPanel();
 
     private boolean dragging;
 
@@ -116,11 +110,11 @@ public class VWindow extends VOverlay implements Container,
 
     private int origH;
 
-    private Element closeBox;
+    Element closeBox;
 
     protected ApplicationConnection client;
 
-    private String id;
+    String id;
 
     ShortcutActionHandler shortcutHandler;
 
@@ -130,13 +124,13 @@ public class VWindow extends VOverlay implements Container,
     /** Last known positiony read from UIDL or updated to application connection */
     private int uidlPositionY = -1;
 
-    private boolean vaadinModality = false;
+    boolean vaadinModality = false;
 
-    private boolean resizable = true;
+    boolean resizable = true;
 
     private boolean draggable = true;
 
-    private boolean resizeLazy = false;
+    boolean resizeLazy = false;
 
     private Element modalityCurtain;
     private Element draggingCurtain;
@@ -163,23 +157,13 @@ public class VWindow extends VOverlay implements Container,
 
     private String height;
 
-    private boolean immediate;
+    boolean immediate;
 
     private Element wrapper, wrapper2;
 
-    private ClickEventHandler clickEventHandler = new ClickEventHandler(this,
-            VPanel.CLICK_EVENT_IDENTIFIER) {
+    boolean visibilityChangesDisabled;
 
-        @Override
-        protected <H extends EventHandler> HandlerRegistration registerHandler(
-                H handler, Type<H> type) {
-            return addDomHandler(handler, type);
-        }
-    };
-
-    private boolean visibilityChangesDisabled;
-
-    private int bringToFrontSequence = -1;
+    int bringToFrontSequence = -1;
 
     private VLazyExecutor delayedContentsSizeUpdater = new VLazyExecutor(200,
             new ScheduledCommand() {
@@ -284,230 +268,12 @@ public class VWindow extends VOverlay implements Container,
 
     }
 
-    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-        id = uidl.getId();
-        this.client = client;
-
-        // Workaround needed for Testing Tools (GWT generates window DOM
-        // slightly different in different browsers).
-        DOM.setElementProperty(closeBox, "id", id + "_window_close");
-
-        if (uidl.hasAttribute("invisible")) {
-            hide();
-            return;
-        }
-
-        if (!uidl.hasAttribute("cached")) {
-            if (uidl.getBooleanAttribute("modal") != vaadinModality) {
-                setVaadinModality(!vaadinModality);
-            }
-            if (!isAttached()) {
-                setVisible(false); // hide until possible centering
-                show();
-            }
-            if (uidl.getBooleanAttribute("resizable") != resizable) {
-                setResizable(!resizable);
-            }
-            resizeLazy = uidl.hasAttribute(VView.RESIZE_LAZY);
-
-            setDraggable(!uidl.hasAttribute("fixedposition"));
-
-            // Caption must be set before required header size is measured. If
-            // the caption attribute is missing the caption should be cleared.
-            setCaption(uidl.getStringAttribute("caption"),
-                    uidl.getStringAttribute("icon"));
-        }
-
-        visibilityChangesDisabled = true;
-        if (client.updateComponent(this, uidl, false)) {
-            return;
-        }
-        visibilityChangesDisabled = false;
-
-        clickEventHandler.handleEventHandlerRegistration(client);
-
-        immediate = uidl.hasAttribute("immediate");
-
-        setClosable(!uidl.getBooleanAttribute("readonly"));
-
-        // Initialize the position form UIDL
-        int positionx = uidl.getIntVariable("positionx");
-        int positiony = uidl.getIntVariable("positiony");
-        if (positionx >= 0 || positiony >= 0) {
-            if (positionx < 0) {
-                positionx = 0;
-            }
-            if (positiony < 0) {
-                positiony = 0;
-            }
-            setPopupPosition(positionx, positiony);
-        }
-
-        boolean showingUrl = false;
-        int childIndex = 0;
-        UIDL childUidl = uidl.getChildUIDL(childIndex++);
-        while ("open".equals(childUidl.getTag())) {
-            // TODO multiple opens with the same target will in practice just
-            // open the last one - should we fix that somehow?
-            final String parsedUri = client.translateVaadinUri(childUidl
-                    .getStringAttribute("src"));
-            if (!childUidl.hasAttribute("name")) {
-                final Frame frame = new Frame();
-                DOM.setStyleAttribute(frame.getElement(), "width", "100%");
-                DOM.setStyleAttribute(frame.getElement(), "height", "100%");
-                DOM.setStyleAttribute(frame.getElement(), "border", "0px");
-                frame.setUrl(parsedUri);
-                contentPanel.setWidget(frame);
-                showingUrl = true;
-            } else {
-                final String target = childUidl.getStringAttribute("name");
-                Window.open(parsedUri, target, "");
-            }
-            childUidl = uidl.getChildUIDL(childIndex++);
-        }
-
-        final VPaintableWidget lo = client.getPaintable(childUidl);
-        if (layout != null) {
-            if (layout != lo) {
-                // remove old
-                client.unregisterPaintable(layout);
-                contentPanel.remove(layout.getWidgetForPaintable());
-                // add new
-                if (!showingUrl) {
-                    contentPanel.setWidget(lo.getWidgetForPaintable());
-                }
-                layout = lo;
-            }
-        } else if (!showingUrl) {
-            contentPanel.setWidget(lo.getWidgetForPaintable());
-            layout = lo;
-        }
-
-        dynamicWidth = !uidl.hasAttribute("width");
-        dynamicHeight = !uidl.hasAttribute("height");
-
-        layoutRelativeWidth = uidl.hasAttribute("layoutRelativeWidth");
-        layoutRelativeHeight = uidl.hasAttribute("layoutRelativeHeight");
-
-        if (dynamicWidth && layoutRelativeWidth) {
-            /*
-             * Relative layout width, fix window width before rendering (width
-             * according to caption)
-             */
-            setNaturalWidth();
-        }
-
-        layout.updateFromUIDL(childUidl, client);
-        if (!dynamicHeight && layoutRelativeWidth) {
-            /*
-             * Relative layout width, and fixed height. Must update the size to
-             * be able to take scrollbars into account (layout gets narrower
-             * space if it is higher than the window) -> only vertical scrollbar
-             */
-            client.runDescendentsLayout(this);
-        }
-
-        /*
-         * No explicit width is set and the layout does not have relative width
-         * so fix the size according to the layout.
-         */
-        if (dynamicWidth && !layoutRelativeWidth) {
-            setNaturalWidth();
-        }
-
-        if (dynamicHeight && layoutRelativeHeight) {
-            // Prevent resizing until height has been fixed
-            resizable = false;
-        }
-
-        // we may have actions and notifications
-        if (uidl.getChildCount() > 1) {
-            final int cnt = uidl.getChildCount();
-            for (int i = 1; i < cnt; i++) {
-                childUidl = uidl.getChildUIDL(i);
-                if (childUidl.getTag().equals("actions")) {
-                    if (shortcutHandler == null) {
-                        shortcutHandler = new ShortcutActionHandler(id, client);
-                    }
-                    shortcutHandler.updateActionMap(childUidl);
-                }
-            }
-
-        }
-
-        // setting scrollposition must happen after children is rendered
-        contentPanel.setScrollPosition(uidl.getIntVariable("scrollTop"));
-        contentPanel.setHorizontalScrollPosition(uidl
-                .getIntVariable("scrollLeft"));
-
-        // Center this window on screen if requested
-        // This has to be here because we might not know the content size before
-        // everything is painted into the window
-        if (uidl.getBooleanAttribute("center")) {
-            // mark as centered - this is unset on move/resize
-            centered = true;
-            center();
-        } else {
-            // don't try to center the window anymore
-            centered = false;
-        }
-        updateShadowSizeAndPosition();
-        setVisible(true);
-
-        boolean sizeReduced = false;
-        // ensure window is not larger than browser window
-        if (getOffsetWidth() > Window.getClientWidth()) {
-            setWidth(Window.getClientWidth() + "px");
-            sizeReduced = true;
-        }
-        if (getOffsetHeight() > Window.getClientHeight()) {
-            setHeight(Window.getClientHeight() + "px");
-            sizeReduced = true;
-        }
-
-        if (dynamicHeight && layoutRelativeHeight) {
-            /*
-             * Window height is undefined, layout is 100% high so the layout
-             * should define the initial window height but on resize the layout
-             * should be as high as the window. We fix the height to deal with
-             * this.
-             */
-
-            int h = contents.getOffsetHeight() + getExtraHeight();
-            int w = getElement().getOffsetWidth();
-
-            client.updateVariable(id, "height", h, false);
-            client.updateVariable(id, "width", w, true);
-        }
-
-        if (sizeReduced) {
-            // If we changed the size we need to update the size of the child
-            // component if it is relative (#3407)
-            client.runDescendentsLayout(this);
-        }
-
-        Util.runWebkitOverflowAutoFix(contentPanel.getElement());
-
-        client.getView().scrollIntoView(uidl);
-
-        if (uidl.hasAttribute("bringToFront")) {
-            /*
-             * Focus as a side-efect. Will be overridden by
-             * ApplicationConnection if another component was focused by the
-             * server side.
-             */
-            contentPanel.focus();
-            bringToFrontSequence = uidl.getIntAttribute("bringToFront");
-            deferOrdering();
-        }
-    }
-
     /**
      * Calling this method will defer ordering algorithm, to order windows based
      * on servers bringToFront and modality instructions. Non changed windows
      * will be left intact.
      */
-    private static void deferOrdering() {
+    static void deferOrdering() {
         if (!orderingDefered) {
             orderingDefered = true;
             Scheduler.get().scheduleFinally(new Command() {
@@ -562,7 +328,7 @@ public class VWindow extends VOverlay implements Container,
         }
     }
 
-    private void setDraggable(boolean draggable) {
+    void setDraggable(boolean draggable) {
         if (this.draggable == draggable) {
             return;
         }
@@ -573,7 +339,7 @@ public class VWindow extends VOverlay implements Container,
     }
 
     private void setCursorProperties() {
-        if (!this.draggable) {
+        if (!draggable) {
             header.getStyle().setProperty("cursor", "default");
             footer.getStyle().setProperty("cursor", "default");
         } else {
@@ -582,7 +348,7 @@ public class VWindow extends VOverlay implements Container,
         }
     }
 
-    private void setNaturalWidth() {
+    void setNaturalWidth() {
         /*
          * Use max(layout width, window width) i.e layout content width or
          * caption width. We remove the previous set width so the width is
@@ -676,7 +442,7 @@ public class VWindow extends VOverlay implements Container,
         super.hide();
     }
 
-    private void setVaadinModality(boolean modality) {
+    void setVaadinModality(boolean modality) {
         vaadinModality = modality;
         if (vaadinModality) {
             if (isAttached()) {
@@ -767,7 +533,7 @@ public class VWindow extends VOverlay implements Container,
         return curtain;
     }
 
-    private void setResizable(boolean resizability) {
+    void setResizable(boolean resizability) {
         resizable = resizability;
         if (resizability) {
             DOM.setElementProperty(footer, "className", CLASSNAME + "-footer");
@@ -832,7 +598,7 @@ public class VWindow extends VOverlay implements Container,
 
         if (client != null && header.isOrHasChild(target)) {
             // Handle window caption tooltips
-            client.handleTooltipEvent(event, this);
+            client.handleWidgetTooltipEvent(event, this);
         }
 
         if (resizing || resizeBox == target) {
@@ -1088,7 +854,7 @@ public class VWindow extends VOverlay implements Container,
 
     private int extraH = 0;
 
-    private int getExtraHeight() {
+    int getExtraHeight() {
         extraH = header.getOffsetHeight() + footer.getOffsetHeight();
         return extraH;
     }
@@ -1238,10 +1004,6 @@ public class VWindow extends VOverlay implements Container,
         return true;
     }
 
-    public void updateCaption(VPaintableWidget component, UIDL uidl) {
-        // NOP, window has own caption, layout captio not rendered
-    }
-
     public ShortcutActionHandler getShortcutActionHandler() {
         return shortcutHandler;
     }
@@ -1263,22 +1025,17 @@ public class VWindow extends VOverlay implements Container,
     }
 
     public void onBlur(BlurEvent event) {
-        if (client.hasEventListeners(this, EventId.BLUR)) {
+        if (client.hasWidgetEventListeners(this, EventId.BLUR)) {
             client.updateVariable(id, EventId.BLUR, "", true);
         }
     }
 
     public void onFocus(FocusEvent event) {
-        if (client.hasEventListeners(this, EventId.FOCUS)) {
+        if (client.hasWidgetEventListeners(this, EventId.FOCUS)) {
             client.updateVariable(id, EventId.FOCUS, "", true);
         }
     }
 
-    public void onBeforeShortcutAction(Event e) {
-        // NOP, nothing to update just avoid workaround ( causes excess
-        // blur/focus )
-    }
-
     public void focus() {
         contentPanel.focus();
     }
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VWindowPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VWindowPaintable.java
new file mode 100644 (file)
index 0000000..25fd951
--- /dev/null
@@ -0,0 +1,296 @@
+package com.vaadin.terminal.gwt.client.ui;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.event.dom.client.DomEvent.Type;\r
+import com.google.gwt.event.shared.EventHandler;\r
+import com.google.gwt.event.shared.HandlerRegistration;\r
+import com.google.gwt.user.client.DOM;\r
+import com.google.gwt.user.client.Event;\r
+import com.google.gwt.user.client.Window;\r
+import com.google.gwt.user.client.ui.Frame;\r
+import com.google.gwt.user.client.ui.Widget;\r
+import com.vaadin.terminal.gwt.client.ApplicationConnection;\r
+import com.vaadin.terminal.gwt.client.UIDL;\r
+import com.vaadin.terminal.gwt.client.Util;\r
+import com.vaadin.terminal.gwt.client.VPaintableWidget;\r
+import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.BeforeShortcutActionListener;\r
+\r
+public class VWindowPaintable extends VAbstractPaintableWidgetContainer\r
+        implements BeforeShortcutActionListener {\r
+\r
+    private static final String CLICK_EVENT_IDENTIFIER = VPanelPaintable.CLICK_EVENT_IDENTIFIER;\r
+\r
+    private ClickEventHandler clickEventHandler = new ClickEventHandler(this,\r
+            CLICK_EVENT_IDENTIFIER) {\r
+\r
+        @Override\r
+        protected <H extends EventHandler> HandlerRegistration registerHandler(\r
+                H handler, Type<H> type) {\r
+            return getWidgetForPaintable().addDomHandler(handler, type);\r
+        }\r
+    };\r
+\r
+    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
+        getWidgetForPaintable().id = uidl.getId();\r
+        getWidgetForPaintable().client = client;\r
+\r
+        // Workaround needed for Testing Tools (GWT generates window DOM\r
+        // slightly different in different browsers).\r
+        DOM.setElementProperty(getWidgetForPaintable().closeBox, "id",\r
+                getWidgetForPaintable().id + "_window_close");\r
+\r
+        if (uidl.hasAttribute("invisible")) {\r
+            getWidgetForPaintable().hide();\r
+            return;\r
+        }\r
+\r
+        if (!uidl.hasAttribute("cached")) {\r
+            if (uidl.getBooleanAttribute("modal") != getWidgetForPaintable().vaadinModality) {\r
+                getWidgetForPaintable().setVaadinModality(\r
+                        !getWidgetForPaintable().vaadinModality);\r
+            }\r
+            if (!getWidgetForPaintable().isAttached()) {\r
+                getWidgetForPaintable().setVisible(false); // hide until\r
+                                                           // possible centering\r
+                getWidgetForPaintable().show();\r
+            }\r
+            if (uidl.getBooleanAttribute("resizable") != getWidgetForPaintable().resizable) {\r
+                getWidgetForPaintable().setResizable(\r
+                        !getWidgetForPaintable().resizable);\r
+            }\r
+            getWidgetForPaintable().resizeLazy = uidl\r
+                    .hasAttribute(VView.RESIZE_LAZY);\r
+\r
+            getWidgetForPaintable().setDraggable(\r
+                    !uidl.hasAttribute("fixedposition"));\r
+\r
+            // Caption must be set before required header size is measured. If\r
+            // the caption attribute is missing the caption should be cleared.\r
+            getWidgetForPaintable().setCaption(\r
+                    uidl.getStringAttribute("caption"),\r
+                    uidl.getStringAttribute("icon"));\r
+        }\r
+\r
+        getWidgetForPaintable().visibilityChangesDisabled = true;\r
+        if (client.updateComponent(this, uidl, false)) {\r
+            return;\r
+        }\r
+        getWidgetForPaintable().visibilityChangesDisabled = false;\r
+\r
+        clickEventHandler.handleEventHandlerRegistration(client);\r
+\r
+        getWidgetForPaintable().immediate = uidl.hasAttribute("immediate");\r
+\r
+        getWidgetForPaintable().setClosable(\r
+                !uidl.getBooleanAttribute("readonly"));\r
+\r
+        // Initialize the position form UIDL\r
+        int positionx = uidl.getIntVariable("positionx");\r
+        int positiony = uidl.getIntVariable("positiony");\r
+        if (positionx >= 0 || positiony >= 0) {\r
+            if (positionx < 0) {\r
+                positionx = 0;\r
+            }\r
+            if (positiony < 0) {\r
+                positiony = 0;\r
+            }\r
+            getWidgetForPaintable().setPopupPosition(positionx, positiony);\r
+        }\r
+\r
+        boolean showingUrl = false;\r
+        int childIndex = 0;\r
+        UIDL childUidl = uidl.getChildUIDL(childIndex++);\r
+        while ("open".equals(childUidl.getTag())) {\r
+            // TODO multiple opens with the same target will in practice just\r
+            // open the last one - should we fix that somehow?\r
+            final String parsedUri = client.translateVaadinUri(childUidl\r
+                    .getStringAttribute("src"));\r
+            if (!childUidl.hasAttribute("name")) {\r
+                final Frame frame = new Frame();\r
+                DOM.setStyleAttribute(frame.getElement(), "width", "100%");\r
+                DOM.setStyleAttribute(frame.getElement(), "height", "100%");\r
+                DOM.setStyleAttribute(frame.getElement(), "border", "0px");\r
+                frame.setUrl(parsedUri);\r
+                getWidgetForPaintable().contentPanel.setWidget(frame);\r
+                showingUrl = true;\r
+            } else {\r
+                final String target = childUidl.getStringAttribute("name");\r
+                Window.open(parsedUri, target, "");\r
+            }\r
+            childUidl = uidl.getChildUIDL(childIndex++);\r
+        }\r
+\r
+        final VPaintableWidget lo = client.getPaintable(childUidl);\r
+        if (getWidgetForPaintable().layout != null) {\r
+            if (getWidgetForPaintable().layout != lo) {\r
+                // remove old\r
+                client.unregisterPaintable(getWidgetForPaintable().layout);\r
+                getWidgetForPaintable().contentPanel\r
+                        .remove(getWidgetForPaintable().layout\r
+                                .getWidgetForPaintable());\r
+                // add new\r
+                if (!showingUrl) {\r
+                    getWidgetForPaintable().contentPanel.setWidget(lo\r
+                            .getWidgetForPaintable());\r
+                }\r
+                getWidgetForPaintable().layout = lo;\r
+            }\r
+        } else if (!showingUrl) {\r
+            getWidgetForPaintable().contentPanel.setWidget(lo\r
+                    .getWidgetForPaintable());\r
+            getWidgetForPaintable().layout = lo;\r
+        }\r
+\r
+        getWidgetForPaintable().dynamicWidth = !uidl.hasAttribute("width");\r
+        getWidgetForPaintable().dynamicHeight = !uidl.hasAttribute("height");\r
+\r
+        getWidgetForPaintable().layoutRelativeWidth = uidl\r
+                .hasAttribute("layoutRelativeWidth");\r
+        getWidgetForPaintable().layoutRelativeHeight = uidl\r
+                .hasAttribute("layoutRelativeHeight");\r
+\r
+        if (getWidgetForPaintable().dynamicWidth\r
+                && getWidgetForPaintable().layoutRelativeWidth) {\r
+            /*\r
+             * Relative layout width, fix window width before rendering (width\r
+             * according to caption)\r
+             */\r
+            getWidgetForPaintable().setNaturalWidth();\r
+        }\r
+\r
+        getWidgetForPaintable().layout.updateFromUIDL(childUidl, client);\r
+        if (!getWidgetForPaintable().dynamicHeight\r
+                && getWidgetForPaintable().layoutRelativeWidth) {\r
+            /*\r
+             * Relative layout width, and fixed height. Must update the size to\r
+             * be able to take scrollbars into account (layout gets narrower\r
+             * space if it is higher than the window) -> only vertical scrollbar\r
+             */\r
+            client.runDescendentsLayout(getWidgetForPaintable());\r
+        }\r
+\r
+        /*\r
+         * No explicit width is set and the layout does not have relative width\r
+         * so fix the size according to the layout.\r
+         */\r
+        if (getWidgetForPaintable().dynamicWidth\r
+                && !getWidgetForPaintable().layoutRelativeWidth) {\r
+            getWidgetForPaintable().setNaturalWidth();\r
+        }\r
+\r
+        if (getWidgetForPaintable().dynamicHeight\r
+                && getWidgetForPaintable().layoutRelativeHeight) {\r
+            // Prevent resizing until height has been fixed\r
+            getWidgetForPaintable().resizable = false;\r
+        }\r
+\r
+        // we may have actions and notifications\r
+        if (uidl.getChildCount() > 1) {\r
+            final int cnt = uidl.getChildCount();\r
+            for (int i = 1; i < cnt; i++) {\r
+                childUidl = uidl.getChildUIDL(i);\r
+                if (childUidl.getTag().equals("actions")) {\r
+                    if (getWidgetForPaintable().shortcutHandler == null) {\r
+                        getWidgetForPaintable().shortcutHandler = new ShortcutActionHandler(\r
+                                getId(), client);\r
+                    }\r
+                    getWidgetForPaintable().shortcutHandler\r
+                            .updateActionMap(childUidl);\r
+                }\r
+            }\r
+\r
+        }\r
+\r
+        // setting scrollposition must happen after children is rendered\r
+        getWidgetForPaintable().contentPanel.setScrollPosition(uidl\r
+                .getIntVariable("scrollTop"));\r
+        getWidgetForPaintable().contentPanel.setHorizontalScrollPosition(uidl\r
+                .getIntVariable("scrollLeft"));\r
+\r
+        // Center this window on screen if requested\r
+        // This has to be here because we might not know the content size before\r
+        // everything is painted into the window\r
+        if (uidl.getBooleanAttribute("center")) {\r
+            // mark as centered - this is unset on move/resize\r
+            getWidgetForPaintable().centered = true;\r
+            getWidgetForPaintable().center();\r
+        } else {\r
+            // don't try to center the window anymore\r
+            getWidgetForPaintable().centered = false;\r
+        }\r
+        getWidgetForPaintable().updateShadowSizeAndPosition();\r
+        getWidgetForPaintable().setVisible(true);\r
+\r
+        boolean sizeReduced = false;\r
+        // ensure window is not larger than browser window\r
+        if (getWidgetForPaintable().getOffsetWidth() > Window.getClientWidth()) {\r
+            getWidgetForPaintable().setWidth(Window.getClientWidth() + "px");\r
+            sizeReduced = true;\r
+        }\r
+        if (getWidgetForPaintable().getOffsetHeight() > Window\r
+                .getClientHeight()) {\r
+            getWidgetForPaintable().setHeight(Window.getClientHeight() + "px");\r
+            sizeReduced = true;\r
+        }\r
+\r
+        if (getWidgetForPaintable().dynamicHeight\r
+                && getWidgetForPaintable().layoutRelativeHeight) {\r
+            /*\r
+             * Window height is undefined, layout is 100% high so the layout\r
+             * should define the initial window height but on resize the layout\r
+             * should be as high as the window. We fix the height to deal with\r
+             * this.\r
+             */\r
+\r
+            int h = getWidgetForPaintable().contents.getOffsetHeight()\r
+                    + getWidgetForPaintable().getExtraHeight();\r
+            int w = getWidgetForPaintable().getElement().getOffsetWidth();\r
+\r
+            client.updateVariable(getId(), "height", h, false);\r
+            client.updateVariable(getId(), "width", w, true);\r
+        }\r
+\r
+        if (sizeReduced) {\r
+            // If we changed the size we need to update the size of the child\r
+            // component if it is relative (#3407)\r
+            client.runDescendentsLayout(getWidgetForPaintable());\r
+        }\r
+\r
+        Util.runWebkitOverflowAutoFix(getWidgetForPaintable().contentPanel\r
+                .getElement());\r
+\r
+        client.getView().getWidgetForPaintable().scrollIntoView(uidl);\r
+\r
+        if (uidl.hasAttribute("bringToFront")) {\r
+            /*\r
+             * Focus as a side-efect. Will be overridden by\r
+             * ApplicationConnection if another component was focused by the\r
+             * server side.\r
+             */\r
+            getWidgetForPaintable().contentPanel.focus();\r
+            getWidgetForPaintable().bringToFrontSequence = uidl\r
+                    .getIntAttribute("bringToFront");\r
+            VWindow.deferOrdering();\r
+        }\r
+    }\r
+\r
+    public void updateCaption(VPaintableWidget component, UIDL uidl) {\r
+        // NOP, window has own caption, layout captio not rendered\r
+    }\r
+\r
+    public void onBeforeShortcutAction(Event e) {\r
+        // NOP, nothing to update just avoid workaround ( causes excess\r
+        // blur/focus )\r
+    }\r
+\r
+    @Override\r
+    public VWindow getWidgetForPaintable() {\r
+        return (VWindow) super.getWidgetForPaintable();\r
+    }\r
+\r
+    @Override\r
+    protected Widget createWidget() {\r
+        return GWT.create(VWindow.class);\r
+    }\r
+\r
+}\r
index d8115aac86c0f35e3e0b7004f0f306dcd43a7d54..76178baa6e3a461a2de24c4a5be023f27fca854d 100644 (file)
@@ -25,6 +25,7 @@ import com.google.gwt.user.rebind.SourceWriter;
 import com.vaadin.terminal.Paintable;
 import com.vaadin.terminal.gwt.client.VPaintableWidget;
 import com.vaadin.terminal.gwt.client.ui.VView;
+import com.vaadin.terminal.gwt.client.ui.VViewPaintable;
 import com.vaadin.ui.ClientWidget;
 import com.vaadin.ui.ClientWidget.LoadStyle;
 import com.vaadin.ui.Root;
@@ -384,7 +385,7 @@ public class WidgetMapGenerator extends Generator {
             Class<? extends Paintable> class1) {
         Class<? extends com.vaadin.terminal.gwt.client.VPaintableWidget> clientClass;
         if (Root.class == class1) {
-            clientClass = VView.class;
+            clientClass = VViewPaintable.class;
         } else {
             ClientWidget annotation = class1.getAnnotation(ClientWidget.class);
             clientClass = annotation.value();
index a860d371b086aa1188890b0c25a1a92257c50c35..e6c8642b84ac60e8c1704108c087fce82283bb7b 100644 (file)
@@ -23,7 +23,7 @@ import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.Sizeable;
 import com.vaadin.terminal.gwt.client.ui.VView;
-import com.vaadin.terminal.gwt.client.ui.VWindow;
+import com.vaadin.terminal.gwt.client.ui.VWindowPaintable;
 
 /**
  * A component that represents an application (browser native) window or a sub
@@ -71,7 +71,7 @@ import com.vaadin.terminal.gwt.client.ui.VWindow;
  * @since 3.0
  */
 @SuppressWarnings("serial")
-@ClientWidget(VWindow.class)
+@ClientWidget(VWindowPaintable.class)
 public class Window extends Panel implements FocusNotifier, BlurNotifier {
 
     /**