diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java | 168 | ||||
-rw-r--r-- | src/com/vaadin/terminal/gwt/client/ui/VPanel.java | 43 | ||||
-rw-r--r-- | src/com/vaadin/terminal/gwt/client/ui/VTextField.java | 12 | ||||
-rw-r--r-- | src/com/vaadin/terminal/gwt/client/ui/VView.java | 14 | ||||
-rw-r--r-- | src/com/vaadin/terminal/gwt/client/ui/VWindow.java | 9 | ||||
-rw-r--r-- | src/com/vaadin/ui/AbsoluteLayout.java | 19 | ||||
-rw-r--r-- | src/com/vaadin/ui/Embedded.java | 69 | ||||
-rw-r--r-- | src/com/vaadin/ui/Panel.java | 39 | ||||
-rw-r--r-- | src/com/vaadin/ui/Window.java | 28 |
9 files changed, 336 insertions, 65 deletions
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java b/src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java index f1d61029d4..a0f7cc649c 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java @@ -1,4 +1,4 @@ -/* +/* @ITMillApache2LicenseForJavaFiles@ */ @@ -137,35 +137,9 @@ public class VEmbedded extends HTML implements Paintable { } else if (uidl.hasAttribute("mimetype")) { final String mime = uidl.getStringAttribute("mimetype"); if (mime.equals("application/x-shockwave-flash")) { - addStyleName(CLASSNAME + "-flash"); - String html = "<object " - + "type=\"application/x-shockwave-flash\" " - + "width=\"" + width + "\" height=\"" + height + "\">"; + // Handle embedding of Flash + setHTML(createFlashEmbed(uidl)); - Map<String, String> parameters = getParameters(uidl); - if (parameters.get("movie") == null) { - parameters.put("movie", getSrc(uidl, client)); - } - - // Add the parameters to the Object - for (String name : parameters.keySet()) { - html += "<param name=\"" + escapeAttribute(name) - + "\" value=\"" - + escapeAttribute(parameters.get(name)) + "\"/>"; - } - - html += "<embed src=\"" + getSrc(uidl, client) + "\" width=\"" - + width + "\" height=\"" + height + "\" " - + "type=\"application/x-shockwave-flash\" "; - - // Add the parameters to the Embed - for (String name : parameters.keySet()) { - html += escapeAttribute(name) + "=\"" - + escapeAttribute(parameters.get(name)) + "\" "; - } - - html += "></embed></object>"; - setHTML(html); } else if (mime.equals("image/svg+xml")) { addStyleName(CLASSNAME + "-svg"); String data; @@ -185,6 +159,26 @@ public class VEmbedded extends HTML implements Paintable { if (height != null) { obj.getStyle().setProperty("height", "100%"); } + if (uidl.hasAttribute("classid")) { + obj.setAttribute("classid", + uidl.getStringAttribute(escapeAttribute("classid"))); + } + if (uidl.hasAttribute("codebase")) { + obj.setAttribute("codebase", uidl + .getStringAttribute(escapeAttribute("codebase"))); + } + if (uidl.hasAttribute("codetype")) { + obj.setAttribute("codetype", uidl + .getStringAttribute(escapeAttribute("codetype"))); + } + if (uidl.hasAttribute("archive")) { + obj.setAttribute("archive", + uidl.getStringAttribute(escapeAttribute("archive"))); + } + if (uidl.hasAttribute("standby")) { + obj.setAttribute("standby", + uidl.getStringAttribute(escapeAttribute("standby"))); + } getElement().appendChild(obj); } else { @@ -197,7 +191,123 @@ public class VEmbedded extends HTML implements Paintable { if (clearBrowserElement) { browserElement = null; } + } + + /** + * Creates the Object and Embed tags for the Flash plugin so it works + * cross-browser + * + * @param uidl + * The UIDL + * @return Tags concatenated into a string + */ + private String createFlashEmbed(UIDL uidl) { + addStyleName(CLASSNAME + "-flash"); + + /* + * To ensure cross-browser compatibility we are using the twice-cooked + * method to embed flash i.e. we add a OBJECT tag for IE ActiveX and + * inside it a EMBED for all other browsers. + */ + + StringBuilder html = new StringBuilder(); + + // Start the object tag + html.append("<object "); + + /* + * Add classid required for ActiveX to recognize the flash. This is a + * predefined value which ActiveX recognizes and must be the given + * value. More info can be found on + * http://kb2.adobe.com/cps/415/tn_4150.html. Allow user to override + * this by setting his own classid. + */ + if (uidl.hasAttribute("classid")) { + html.append("classid=\"" + + escapeAttribute(uidl.getStringAttribute("classid")) + + "\" "); + } else { + html.append("classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" "); + } + + /* + * Add codebase required for ActiveX and must be exactly this according + * to http://kb2.adobe.com/cps/415/tn_4150.html to work with the above + * given classid. Again, see more info on + * http://kb2.adobe.com/cps/415/tn_4150.html. Limiting Flash version to + * 6.0.0.0 and above. Allow user to override this by setting his own + * codebase + */ + if (uidl.hasAttribute("codebase")) { + html.append("codebase=\"" + + escapeAttribute(uidl.getStringAttribute("codebase")) + + "\" "); + } else { + html.append("codebase=\"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0\" "); + } + + // Add width and height + html.append("width=\"" + width + "\" "); + html.append("height=\"" + height + "\" "); + html.append("type=\"application/x-shockwave-flash\" "); + + // Codetype + if (uidl.hasAttribute("codetype")) { + html.append("codetype=\"" + uidl.getStringAttribute("codetype") + + "\" "); + } + + // Standby + if (uidl.hasAttribute("standby")) { + html.append("standby=\"" + uidl.getStringAttribute("standby") + + "\" "); + } + + // Archive + if (uidl.hasAttribute("archive")) { + html.append("archive=\"" + uidl.getStringAttribute("archive") + + "\" "); + } + + // End object tag + html.append(">"); + + // Ensure we have an movie parameter + Map<String, String> parameters = getParameters(uidl); + if (parameters.get("movie") == null) { + parameters.put("movie", getSrc(uidl, client)); + } + + // Add parameters to OBJECT + for (String name : parameters.keySet()) { + html.append("<param "); + html.append("name=\"" + escapeAttribute(name) + "\" "); + html.append("value=\"" + escapeAttribute(parameters.get(name)) + + "\" "); + html.append("/>"); + } + + // Build inner EMBED tag + html.append("<embed "); + html.append("src=\"" + getSrc(uidl, client) + "\" "); + html.append("width=\"" + width + "\" "); + html.append("height=\"" + height + "\" "); + html.append("type=\"application/x-shockwave-flash\" "); + + // Add the parameters to the Embed + for (String name : parameters.keySet()) { + html.append(escapeAttribute(name)); + html.append("="); + html.append("\"" + escapeAttribute(parameters.get(name)) + "\""); + } + + // End embed tag + html.append("></embed>"); + + // End object tag + html.append("</object>"); + return html.toString(); } /** diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPanel.java b/src/com/vaadin/terminal/gwt/client/ui/VPanel.java index 586e04ed10..692b8a4858 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VPanel.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VPanel.java @@ -1,4 +1,4 @@ -/* +/* @ITMillApache2LicenseForJavaFiles@ */ @@ -21,6 +21,7 @@ import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.BrowserInfo; import com.vaadin.terminal.gwt.client.Container; +import com.vaadin.terminal.gwt.client.Focusable; import com.vaadin.terminal.gwt.client.Paintable; import com.vaadin.terminal.gwt.client.RenderInformation; import com.vaadin.terminal.gwt.client.RenderSpace; @@ -29,7 +30,7 @@ import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner; public class VPanel extends SimplePanel implements Container, - ShortcutActionHandlerOwner { + ShortcutActionHandlerOwner, Focusable { public static final String CLICK_EVENT_IDENTIFIER = "click"; public static final String CLASSNAME = "v-panel"; @@ -103,7 +104,16 @@ public class VPanel extends SimplePanel implements Container, bottomDecoration.setClassName(CLASSNAME + "-deco"); getElement().appendChild(captionWrap); + + /* + * Make contentNode focusable only by using the setFocus() method. This + * behaviour can be changed by invoking setTabIndex() in the serverside + * implementation + */ + contentNode.setTabIndex(-1); + getElement().appendChild(contentNode); + getElement().appendChild(bottomDecoration); setStyleName(CLASSNAME); DOM.sinkEvents(getElement(), Event.ONKEYDOWN); @@ -117,6 +127,30 @@ public class VPanel extends SimplePanel implements Container, }, TouchStartEvent.getType()); } + /** + * Sets the keyboard focus on the Panel + * + * @param focus + * Should the panel have focus or not. + */ + public void setFocus(boolean focus) { + if (focus) { + getContainerElement().focus(); + } else { + getContainerElement().blur(); + } + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.terminal.gwt.client.Focusable#focus() + */ + public void focus() { + setFocus(true); + + } + @Override protected Element getContainerElement() { return contentNode; @@ -236,6 +270,11 @@ public class VPanel extends SimplePanel implements Container, // scrollTop runHacks(false); + // And apply tab index + if (uidl.hasVariable("tabindex")) { + contentNode.setTabIndex(uidl.getIntVariable("tabindex")); + } + rendering = false; } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTextField.java b/src/com/vaadin/terminal/gwt/client/ui/VTextField.java index 49d18f0867..edf4261988 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTextField.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTextField.java @@ -145,12 +145,14 @@ public class VTextField extends TextBoxBase implements Paintable, Field, @Override public void run() { - updateCursorPosition(); - boolean textChanged = communicateTextValueToServer(); - if (textChanged) { - client.sendPendingVariableChanges(); + if (isAttached()) { + updateCursorPosition(); + boolean textChanged = communicateTextValueToServer(); + if (textChanged) { + client.sendPendingVariableChanges(); + } + scheduled = false; } - scheduled = false; } }; private boolean scheduled = false; diff --git a/src/com/vaadin/terminal/gwt/client/ui/VView.java b/src/com/vaadin/terminal/gwt/client/ui/VView.java index ea43deba9d..5d7cc18945 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VView.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VView.java @@ -43,7 +43,7 @@ import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHan * */ public class VView extends SimplePanel implements Container, ResizeHandler, - Window.ClosingHandler, ShortcutActionHandlerOwner { + Window.ClosingHandler, ShortcutActionHandlerOwner, Focusable { private static final String CLASSNAME = "v-view"; @@ -110,6 +110,10 @@ public class VView extends SimplePanel implements Container, ResizeHandler, public VView() { 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); } /** @@ -691,9 +695,9 @@ public class VView extends SimplePanel implements Container, ResizeHandler, DOM.setStyleAttribute(fElem, "position", "absolute"); DOM.setStyleAttribute(fElem, "opacity", "0.1"); DOM.appendChild(getElement(), fElem); - Util.focus(fElem); + fElem.focus(); } else { - Util.focus(getElement()); + getElement().focus(); } parentFrame = getParentFrame(); @@ -703,4 +707,8 @@ public class VView extends SimplePanel implements Container, ResizeHandler, return actionHandler; } + public void focus() { + getElement().focus(); + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VWindow.java b/src/com/vaadin/terminal/gwt/client/ui/VWindow.java index 8e03ca89d7..395d6f6ea0 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VWindow.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VWindow.java @@ -1,4 +1,4 @@ -/* +/* @ITMillApache2LicenseForJavaFiles@ */ @@ -35,6 +35,7 @@ import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.BrowserInfo; 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.Paintable; import com.vaadin.terminal.gwt.client.RenderSpace; import com.vaadin.terminal.gwt.client.UIDL; @@ -50,7 +51,7 @@ import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHan */ public class VWindow extends VOverlay implements Container, ShortcutActionHandlerOwner, ScrollHandler, KeyDownHandler, - FocusHandler, BlurHandler, BeforeShortcutActionListener { + FocusHandler, BlurHandler, BeforeShortcutActionListener, Focusable { /** * Minimum allowed height of a window. This refers to the content area, not @@ -1307,4 +1308,8 @@ public class VWindow extends VOverlay implements Container, // blur/focus ) } + public void focus() { + contentPanel.focus(); + } + } diff --git a/src/com/vaadin/ui/AbsoluteLayout.java b/src/com/vaadin/ui/AbsoluteLayout.java index 3b0239af7b..c7a1583d28 100644 --- a/src/com/vaadin/ui/AbsoluteLayout.java +++ b/src/com/vaadin/ui/AbsoluteLayout.java @@ -122,8 +122,23 @@ public class AbsoluteLayout extends AbstractLayout implements * The css position string */ public void addComponent(Component c, String cssPosition) { - addComponent(c); - getPosition(c).setCSSString(cssPosition); + /* + * Create position instance and add it to componentToCoordinates map. We + * need to do this before we call addComponent so the attachListeners + * can access this position. #6368 + */ + ComponentPosition position = new ComponentPosition(); + position.setCSSString(cssPosition); + componentToCoordinates.put(c, position); + + try { + addComponent(c); + + } catch (IllegalArgumentException e) { + // Remove component coordinates if adding fails + componentToCoordinates.remove(c); + throw e; + } } /** diff --git a/src/com/vaadin/ui/Embedded.java b/src/com/vaadin/ui/Embedded.java index 85d67ae105..55991eafb2 100644 --- a/src/com/vaadin/ui/Embedded.java +++ b/src/com/vaadin/ui/Embedded.java @@ -1,4 +1,4 @@ -/* +/* @ITMillApache2LicenseForJavaFiles@ */ @@ -205,8 +205,9 @@ public class Embedded extends AbstractComponent { } /** - * Gets the codebase, the root-path used to access resources with relative - * paths. + * This attribute specifies the base path used to resolve relative URIs + * specified by the classid, data, and archive attributes. When absent, its + * default value is the base URI of the current document. * * @return the code base. */ @@ -233,20 +234,22 @@ public class Embedded extends AbstractComponent { } /** - * Gets the standby text displayed when the object is loading. + * This attribute specifies a message that a user agent may render while + * loading the object's implementation and data. * - * @return the standby text. + * @return The text displayed when loading */ public String getStandby() { return standby; } /** - * Sets the codebase, the root-path used to access resources with relative - * paths. + * This attribute specifies the base path used to resolve relative URIs + * specified by the classid, data, and archive attributes. When absent, its + * default value is the base URI of the current document. * * @param codebase - * the codebase to set. + * The base path */ public void setCodebase(String codebase) { if (codebase != this.codebase @@ -257,7 +260,11 @@ public class Embedded extends AbstractComponent { } /** - * Sets the codetype, the MIME-Type of the code. + * This attribute specifies the content type of data expected when + * downloading the object specified by classid. This attribute is optional + * but recommended when classid is specified since it allows the user agent + * to avoid loading information for unsupported content types. When absent, + * it defaults to the value of the type attribute. * * @param codetype * the codetype to set. @@ -296,10 +303,11 @@ public class Embedded extends AbstractComponent { } /** - * Sets the standby, the text to display while loading the object. + * This attribute specifies a message that a user agent may render while + * loading the object's implementation and data. * * @param standby - * the standby to set. + * The text to display while loading */ public void setStandby(String standby) { if (standby != this.standby @@ -310,16 +318,18 @@ public class Embedded extends AbstractComponent { } /** - * Gets the classId attribute. + * This attribute may be used to specify the location of an object's + * implementation via a URI. * - * @return the class id. + * @return the classid. */ public String getClassId() { return classId; } /** - * Sets the classId attribute. + * This attribute may be used to specify the location of an object's + * implementation via a URI. * * @param classId * the classId to set. @@ -410,19 +420,31 @@ public class Embedded extends AbstractComponent { } /** - * Gets the archive attribute. + * This attribute may be used to specify a space-separated list of URIs for + * archives containing resources relevant to the object, which may include + * the resources specified by the classid and data attributes. Preloading + * archives will generally result in reduced load times for objects. + * Archives specified as relative URIs should be interpreted relative to the + * codebase attribute. * - * @return the archive attribute. + * @return Space-separated list of URIs with resources relevant to the + * object */ public String getArchive() { return archive; } /** - * Sets the archive attribute. + * This attribute may be used to specify a space-separated list of URIs for + * archives containing resources relevant to the object, which may include + * the resources specified by the classid and data attributes. Preloading + * archives will generally result in reduced load times for objects. + * Archives specified as relative URIs should be interpreted relative to the + * codebase attribute. * * @param archive - * the archive string to set. + * Space-separated list of URIs with resources relevant to the + * object */ public void setArchive(String archive) { if (archive != this.archive @@ -458,6 +480,12 @@ public class Embedded extends AbstractComponent { removeListener(CLICK_EVENT, ClickEvent.class, listener); } + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.AbstractComponent#changeVariables(java.lang.Object, + * java.util.Map) + */ @SuppressWarnings("unchecked") @Override public void changeVariables(Object source, Map<String, Object> variables) { @@ -468,6 +496,11 @@ public class Embedded extends AbstractComponent { } + /** + * Notifies click-listeners that a mouse click event has occurred. + * + * @param parameters + */ private void fireClick(Map<String, Object> parameters) { MouseEventDetails mouseDetails = MouseEventDetails .deSerialize((String) parameters.get("mouseDetails")); diff --git a/src/com/vaadin/ui/Panel.java b/src/com/vaadin/ui/Panel.java index 4d00cddfdd..7ffa11a325 100644 --- a/src/com/vaadin/ui/Panel.java +++ b/src/com/vaadin/ui/Panel.java @@ -1,4 +1,4 @@ -/* +/* @ITMillApache2LicenseForJavaFiles@ */ @@ -17,6 +17,7 @@ import com.vaadin.terminal.PaintTarget; import com.vaadin.terminal.Scrollable; import com.vaadin.terminal.gwt.client.MouseEventDetails; import com.vaadin.terminal.gwt.client.ui.VPanel; +import com.vaadin.ui.Component.Focusable; import com.vaadin.ui.themes.Reindeer; import com.vaadin.ui.themes.Runo; @@ -32,7 +33,7 @@ import com.vaadin.ui.themes.Runo; @ClientWidget(VPanel.class) public class Panel extends AbstractComponentContainer implements Scrollable, ComponentContainer.ComponentAttachListener, - ComponentContainer.ComponentDetachListener, Action.Notifier { + ComponentContainer.ComponentDetachListener, Action.Notifier, Focusable { private static final String CLICK_EVENT = VPanel.CLICK_EVENT_IDENTIFIER; @@ -75,6 +76,13 @@ public class Panel extends AbstractComponentContainer implements Scrollable, protected ActionManager actionManager; /** + * By default the Panel is not in the normal document focus flow and can + * only be focused by using the focus()-method. Change this to 0 if you want + * to have the Panel in the normal focus flow. + */ + private int tabIndex = -1; + + /** * Creates a new empty panel. A VerticalLayout is used as content. */ public Panel() { @@ -234,6 +242,8 @@ public class Panel extends AbstractComponentContainer implements Scrollable, public void paintContent(PaintTarget target) throws PaintException { content.paint(target); + target.addVariable(this, "tabindex", getTabIndex()); + if (isScrollable()) { target.addVariable(this, "scrollLeft", getScrollLeft()); target.addVariable(this, "scrollTop", getScrollTop()); @@ -582,4 +592,29 @@ public class Panel extends AbstractComponentContainer implements Scrollable, fireEvent(new ClickEvent(this, mouseDetails)); } + + /** + * {@inheritDoc} + */ + public int getTabIndex() { + return tabIndex; + } + + /** + * {@inheritDoc} + */ + public void setTabIndex(int tabIndex) { + this.tabIndex = tabIndex; + requestRepaint(); + } + + /** + * Moves keyboard focus to the component. {@see Focusable#focus()} + * + */ + @Override + public void focus() { + super.focus(); + } + } diff --git a/src/com/vaadin/ui/Window.java b/src/com/vaadin/ui/Window.java index b31255cb26..5c2769c756 100644 --- a/src/com/vaadin/ui/Window.java +++ b/src/com/vaadin/ui/Window.java @@ -1,4 +1,4 @@ -/* +/* @ITMillApache2LicenseForJavaFiles@ */ @@ -1120,6 +1120,10 @@ public class Window extends Panel implements URIHandler, ParameterHandler, if (parent == null) { fireClose(); } else { + + // focus is restored to the parent window + parent.focus(); + // subwindow is removed from parent parent.removeWindow(this); } @@ -2089,7 +2093,7 @@ public class Window extends Panel implements URIHandler, ParameterHandler, * <code> * // within the window using helper * subWindow.setCloseShortcut(KeyCode.ESCAPE, null); - * + * * // or globally * getWindow().addAction(new Window.CloseShortcut(subWindow, KeyCode.ESCAPE)); * </code> @@ -2180,4 +2184,24 @@ public class Window extends Panel implements URIHandler, ParameterHandler, removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener); } + /** + * {@inheritDoc} + * + * If the window is a sub-window focusing will cause the sub-window to be + * brought on top of other sub-windows on gain keyboard focus. + */ + @Override + public void focus() { + if (getParent() != null) { + /* + * When focusing a sub-window it basically means it should be + * brought to the front. Instead of just moving the keyboard focus + * we focus the window and bring it top-most. + */ + bringToFront(); + } else { + super.focus(); + } + } + } |