diff options
author | Henrik Paul <henrik@vaadin.com> | 2015-03-31 14:44:23 +0300 |
---|---|---|
committer | Henrik Paul <henrik@vaadin.com> | 2015-03-31 14:44:23 +0300 |
commit | 844b2c6c41d57d4db1238eb6096f225c9fdb8314 (patch) | |
tree | ffdd57cd35da2df500fbfae5981de381439d1f5c /server | |
parent | 2080f86e03552c56d52f488e4dcd72282cd64f62 (diff) | |
parent | 3ab82ace45827365e87f9540fad3dffaed0679b5 (diff) | |
download | vaadin-framework-844b2c6c41d57d4db1238eb6096f225c9fdb8314.tar.gz vaadin-framework-844b2c6c41d57d4db1238eb6096f225c9fdb8314.zip |
Merge remote-tracking branch 'origin/master' into grid-7.5
Change-Id: Ife8c6d2a5f6c134a6e28e862f524b6e687199cc8
Diffstat (limited to 'server')
31 files changed, 1477 insertions, 198 deletions
diff --git a/server/src/com/vaadin/server/Constants.java b/server/src/com/vaadin/server/Constants.java index b7c2a1ff3e..f3cdd48d58 100644 --- a/server/src/com/vaadin/server/Constants.java +++ b/server/src/com/vaadin/server/Constants.java @@ -132,12 +132,11 @@ public interface Constants { static final String SERVLET_PARAMETER_RESOURCE_CACHE_TIME = "resourceCacheTime"; static final String SERVLET_PARAMETER_HEARTBEAT_INTERVAL = "heartbeatInterval"; static final String SERVLET_PARAMETER_CLOSE_IDLE_SESSIONS = "closeIdleSessions"; + static final String SERVLET_PARAMETER_PUSH_MODE = "pushMode"; static final String SERVLET_PARAMETER_UI_PROVIDER = "UIProvider"; static final String SERVLET_PARAMETER_LEGACY_PROPERTY_TOSTRING = "legacyPropertyToString"; static final String SERVLET_PARAMETER_SYNC_ID_CHECK = "syncIdCheck"; static final String SERVLET_PARAMETER_SENDURLSASPARAMETERS = "sendUrlsAsParameters"; - static final String SERVLET_PARAMETER_PUSH_MODE = "pushMode"; - static final String SERVLET_PARAMETER_PUSH_PATH = "pushPath"; // Configurable parameter names static final String PARAMETER_VAADIN_RESOURCES = "Resources"; diff --git a/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java b/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java index 5402979be8..b26e048431 100644 --- a/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java +++ b/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java @@ -61,13 +61,6 @@ public class DefaultDeploymentConfiguration extends public static final boolean DEFAULT_SEND_URLS_AS_PARAMETERS = true; - /** - * Default value for {@link #getPushPath()} = {@value} . - * - * @since 7.4.1 - */ - public static final String DEFAULT_PUSH_PATH = "PUSH"; - private final Properties initParameters; private boolean productionMode; private boolean xsrfProtectionEnabled; @@ -292,18 +285,6 @@ public class DefaultDeploymentConfiguration extends } /** - * {@inheritDoc} - * <p> - * The default path {@link DEFAULT_PUSH_PATH} can be changed by using init - * parameter {@link Constants.SERVLET_PARAMETER_PUSH_PATH}. - */ - @Override - public String getPushPath() { - return getApplicationOrSystemProperty( - Constants.SERVLET_PARAMETER_PUSH_PATH, DEFAULT_PUSH_PATH); - } - - /** * Log a warning if Vaadin is not running in production mode. */ private void checkProductionMode() { diff --git a/server/src/com/vaadin/server/DeploymentConfiguration.java b/server/src/com/vaadin/server/DeploymentConfiguration.java index 06556e28a7..968ec7c0c3 100644 --- a/server/src/com/vaadin/server/DeploymentConfiguration.java +++ b/server/src/com/vaadin/server/DeploymentConfiguration.java @@ -195,7 +195,7 @@ public interface DeploymentConfiguration extends Serializable { * * @since 7.4 * - * @return the name of the widgetset + * @return UI class name */ public String getWidgetset(String defaultValue); @@ -214,14 +214,6 @@ public interface DeploymentConfiguration extends Serializable { public String getClassLoaderName(); /** - * Returns the push path configuration option value. Should never be null. - * - * @since 7.4.1 - * @return the path used with server push - */ - public String getPushPath(); - - /** * Returns to legacy Property.toString() mode used. See * {@link AbstractProperty#isLegacyToStringEnabled()} for more information. * diff --git a/server/src/com/vaadin/server/ExternalResource.java b/server/src/com/vaadin/server/ExternalResource.java index 0c724ae19f..e3b026dde8 100644 --- a/server/src/com/vaadin/server/ExternalResource.java +++ b/server/src/com/vaadin/server/ExternalResource.java @@ -124,5 +124,4 @@ public class ExternalResource implements Resource, Serializable { public void setMIMEType(String mimeType) { this.mimeType = mimeType; } - } diff --git a/server/src/com/vaadin/server/FileResource.java b/server/src/com/vaadin/server/FileResource.java index b32905f972..28de124fe9 100644 --- a/server/src/com/vaadin/server/FileResource.java +++ b/server/src/com/vaadin/server/FileResource.java @@ -156,5 +156,4 @@ public class FileResource implements ConnectorResource { public void setBufferSize(int bufferSize) { this.bufferSize = bufferSize; } - } diff --git a/server/src/com/vaadin/server/ServletPortletHelper.java b/server/src/com/vaadin/server/ServletPortletHelper.java index 1f0c7f02b9..197d9fe416 100644 --- a/server/src/com/vaadin/server/ServletPortletHelper.java +++ b/server/src/com/vaadin/server/ServletPortletHelper.java @@ -124,8 +124,7 @@ public class ServletPortletHelper implements Serializable { } public static boolean isPushRequest(VaadinRequest request) { - return hasPathPrefix(request, request.getService() - .getDeploymentConfiguration().getPushPath() + '/'); + return hasPathPrefix(request, ApplicationConstants.PUSH_PATH + '/'); } public static void initDefaultUIProvider(VaadinSession session, diff --git a/server/src/com/vaadin/server/communication/UIInitHandler.java b/server/src/com/vaadin/server/communication/UIInitHandler.java index 02b4e64159..3a6dc1e55f 100644 --- a/server/src/com/vaadin/server/communication/UIInitHandler.java +++ b/server/src/com/vaadin/server/communication/UIInitHandler.java @@ -198,11 +198,10 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler { PushMode pushMode = provider.getPushMode(event); if (pushMode == null) { - pushMode = session.getConfiguration().getPushMode(); + pushMode = session.getService().getDeploymentConfiguration() + .getPushMode(); } ui.getPushConfiguration().setPushMode(pushMode); - ui.getPushConfiguration().setPushPath( - session.getConfiguration().getPushPath()); Transport transport = provider.getPushTransport(event); if (transport != null) { diff --git a/server/src/com/vaadin/ui/AbstractMedia.java b/server/src/com/vaadin/ui/AbstractMedia.java index 0bd8c3ea77..a0344624d7 100644 --- a/server/src/com/vaadin/ui/AbstractMedia.java +++ b/server/src/com/vaadin/ui/AbstractMedia.java @@ -18,12 +18,17 @@ package com.vaadin.ui; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.jsoup.nodes.Attributes; +import org.jsoup.nodes.Element; +import org.jsoup.nodes.Node; + import com.vaadin.server.ConnectorResource; import com.vaadin.server.DownloadStream; import com.vaadin.server.Resource; @@ -34,6 +39,8 @@ import com.vaadin.server.VaadinSession; import com.vaadin.shared.communication.URLReference; import com.vaadin.shared.ui.AbstractMediaState; import com.vaadin.shared.ui.MediaControl; +import com.vaadin.ui.declarative.DesignAttributeHandler; +import com.vaadin.ui.declarative.DesignContext; /** * Abstract base class for the HTML5 media components. @@ -256,4 +263,49 @@ public abstract class AbstractMedia extends AbstractComponent { getRpcProxy(MediaControl.class).play(); } + @Override + public void writeDesign(Element design, DesignContext designContext) { + super.writeDesign(design, designContext); + + String altText = getAltText(); + if (altText != null && !altText.isEmpty()) { + design.append(altText); + } + + for (Resource r : getSources()) { + Attributes attr = design.appendElement("source").attributes(); + DesignAttributeHandler.writeAttribute("href", attr, r, null, + Resource.class); + } + } + + @Override + public void readDesign(Element design, DesignContext designContext) { + super.readDesign(design, designContext); + + String altText = ""; + for (Node child : design.childNodes()) { + if (child instanceof Element + && ((Element) child).tagName().equals("source") + && child.hasAttr("href")) { + addSource(DesignAttributeHandler.readAttribute("href", + child.attributes(), Resource.class)); + } else { + altText += child.toString(); + } + } + + altText = altText.trim(); + if (!altText.isEmpty()) { + setAltText(altText); + } + } + + @Override + protected Collection<String> getCustomAttributes() { + Collection<String> result = super.getCustomAttributes(); + result.add("alt-text"); + return result; + } + } diff --git a/server/src/com/vaadin/ui/AbstractSplitPanel.java b/server/src/com/vaadin/ui/AbstractSplitPanel.java index af73fca6a8..8a7b9086c2 100644 --- a/server/src/com/vaadin/ui/AbstractSplitPanel.java +++ b/server/src/com/vaadin/ui/AbstractSplitPanel.java @@ -64,6 +64,8 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { @Override public void setSplitterPosition(float position) { getSplitterState().position = position; + fireEvent(new SplitPositionChangeEvent(AbstractSplitPanel.this, + position, getSplitPositionUnit())); } }; @@ -331,6 +333,8 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { splitterState.positionUnit = unit.getSymbol(); splitterState.positionReversed = reverse; posUnit = unit; + fireEvent(new SplitPositionChangeEvent(AbstractSplitPanel.this, pos, + posUnit)); } /** @@ -520,6 +524,54 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { } + /** + * Interface for listening for {@link SplitPositionChangeEvent}s fired by a + * SplitPanel. + * + * @since + */ + public interface SplitPositionChangeListener extends ConnectorEventListener { + + public static final Method moveMethod = ReflectTools.findMethod( + SplitPositionChangeListener.class, "onSplitPositionChanged", + SplitPositionChangeEvent.class); + + /** + * SplitPanel splitter position has been changed. + * + * @param event + * SplitPositionChangeEvent event. + */ + public void onSplitPositionChanged(SplitPositionChangeEvent event); + } + + /** + * Event that indicates a change in SplitPanel's splitter position. + * + * @since + */ + public static class SplitPositionChangeEvent extends Component.Event { + + private final float position; + private final Unit unit; + + public SplitPositionChangeEvent(final Component source, + final float position, final Unit unit) { + super(source); + this.position = position; + this.unit = unit; + } + + public float getSplitPosition() { + return position; + } + + public Unit getSplitPositionUnit() { + return unit; + } + + } + public void addSplitterClickListener(SplitterClickListener listener) { addListener(EventId.CLICK_EVENT_IDENTIFIER, SplitterClickEvent.class, listener, SplitterClickListener.clickMethod); @@ -548,6 +600,31 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { removeSplitterClickListener(listener); } + /** + * Register a listener to handle {@link SplitPositionChangeEvent}s. + * + * @since + * @param listener + * {@link SplitPositionChangeListener} to be registered. + */ + public void addSplitPositionChangeListener( + SplitPositionChangeListener listener) { + addListener(SplitPositionChangeEvent.class, listener, + SplitPositionChangeListener.moveMethod); + } + + /** + * Removes a {@link SplitPositionChangeListener}. + * + * @since + * @param listener + * SplitPositionChangeListener to be removed. + */ + public void removeSplitPositionChangeListener( + SplitPositionChangeListener listener) { + removeListener(SplitPositionChangeEvent.class, listener); + } + @Override protected AbstractSplitPanelState getState() { return (AbstractSplitPanelState) super.getState(); diff --git a/server/src/com/vaadin/ui/Calendar.java b/server/src/com/vaadin/ui/Calendar.java index 48c024026e..acddbe308b 100644 --- a/server/src/com/vaadin/ui/Calendar.java +++ b/server/src/com/vaadin/ui/Calendar.java @@ -22,6 +22,7 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Date; import java.util.EventListener; import java.util.GregorianCalendar; @@ -37,6 +38,9 @@ import java.util.TimeZone; import java.util.logging.Level; import java.util.logging.Logger; +import org.jsoup.nodes.Attributes; +import org.jsoup.nodes.Element; + import com.vaadin.data.Container; import com.vaadin.data.util.BeanItemContainer; import com.vaadin.event.Action; @@ -84,6 +88,8 @@ import com.vaadin.ui.components.calendar.handler.BasicEventMoveHandler; import com.vaadin.ui.components.calendar.handler.BasicEventResizeHandler; import com.vaadin.ui.components.calendar.handler.BasicForwardHandler; import com.vaadin.ui.components.calendar.handler.BasicWeekClickHandler; +import com.vaadin.ui.declarative.DesignAttributeHandler; +import com.vaadin.ui.declarative.DesignContext; /** * <p> @@ -334,6 +340,10 @@ public class Calendar extends AbstractComponent implements */ public Date getStartDate() { if (startDate == null) { + currentCalendar.set(java.util.Calendar.MILLISECOND, 0); + currentCalendar.set(java.util.Calendar.SECOND, 0); + currentCalendar.set(java.util.Calendar.MINUTE, 0); + currentCalendar.set(java.util.Calendar.HOUR_OF_DAY, 0); currentCalendar.set(java.util.Calendar.DAY_OF_WEEK, currentCalendar.getFirstDayOfWeek()); return currentCalendar.getTime(); @@ -363,6 +373,10 @@ public class Calendar extends AbstractComponent implements */ public Date getEndDate() { if (endDate == null) { + currentCalendar.set(java.util.Calendar.MILLISECOND, 0); + currentCalendar.set(java.util.Calendar.SECOND, 59); + currentCalendar.set(java.util.Calendar.MINUTE, 59); + currentCalendar.set(java.util.Calendar.HOUR_OF_DAY, 23); currentCalendar.set(java.util.Calendar.DAY_OF_WEEK, currentCalendar.getFirstDayOfWeek() + 6); return currentCalendar.getTime(); @@ -655,8 +669,14 @@ public class Calendar extends AbstractComponent implements */ public TimeFormat getTimeFormat() { if (currentTimeFormat == null) { - SimpleDateFormat f = (SimpleDateFormat) SimpleDateFormat - .getTimeInstance(SimpleDateFormat.SHORT, getLocale()); + SimpleDateFormat f; + if (getLocale() == null) { + f = (SimpleDateFormat) SimpleDateFormat + .getTimeInstance(SimpleDateFormat.SHORT); + } else { + f = (SimpleDateFormat) SimpleDateFormat.getTimeInstance( + SimpleDateFormat.SHORT, getLocale()); + } String p = f.toPattern(); if (p.indexOf("HH") != -1 || p.indexOf("H") != -1) { return TimeFormat.Format24H; @@ -1925,4 +1945,51 @@ public class Calendar extends AbstractComponent implements return getState(false).eventCaptionAsHtml; } + @Override + public void readDesign(Element design, DesignContext designContext) { + super.readDesign(design, designContext); + + Attributes attr = design.attributes(); + if (design.hasAttr("time-format")) { + setTimeFormat(TimeFormat.valueOf("Format" + + design.attr("time-format").toUpperCase())); + } + + if (design.hasAttr("start-date")) { + setStartDate(DesignAttributeHandler.readAttribute("start-date", + attr, Date.class)); + } + if (design.hasAttr("end-date")) { + setEndDate(DesignAttributeHandler.readAttribute("end-date", attr, + Date.class)); + } + }; + + @Override + public void writeDesign(Element design, DesignContext designContext) { + super.writeDesign(design, designContext); + + if (currentTimeFormat != null) { + design.attr("time-format", + (currentTimeFormat == TimeFormat.Format12H ? "12h" : "24h")); + } + if (startDate != null) { + design.attr("start-date", df_date.format(getStartDate())); + } + if (endDate != null) { + design.attr("end-date", df_date.format(getEndDate())); + } + if (!getTimeZone().equals(TimeZone.getDefault())) { + design.attr("time-zone", getTimeZone().getID()); + } + } + + @Override + protected Collection<String> getCustomAttributes() { + Collection<String> customAttributes = super.getCustomAttributes(); + customAttributes.add("time-format"); + customAttributes.add("start-date"); + customAttributes.add("end-date"); + return customAttributes; + } } diff --git a/server/src/com/vaadin/ui/CustomLayout.java b/server/src/com/vaadin/ui/CustomLayout.java index a9c266b0b9..ceb47e1e7a 100644 --- a/server/src/com/vaadin/ui/CustomLayout.java +++ b/server/src/com/vaadin/ui/CustomLayout.java @@ -23,12 +23,16 @@ import java.io.InputStreamReader; import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; +import org.jsoup.nodes.Element; + import com.vaadin.server.JsonPaintTarget; import com.vaadin.server.PaintException; import com.vaadin.server.PaintTarget; import com.vaadin.shared.ui.customlayout.CustomLayoutState; +import com.vaadin.ui.declarative.DesignContext; /** * <p> @@ -71,8 +75,8 @@ public class CustomLayout extends AbstractLayout implements LegacyComponent { * {@link #setTemplateName(String)}, that makes layout fetch the template * from theme, or {@link #setTemplateContents(String)}. */ - protected CustomLayout() { - setWidth(100, UNITS_PERCENTAGE); + public CustomLayout() { + setWidth(100, Unit.PERCENTAGE); } /** @@ -305,4 +309,32 @@ public class CustomLayout extends AbstractLayout implements LegacyComponent { } } + @Override + public void readDesign(Element design, DesignContext designContext) { + super.readDesign(design, designContext); + + for (Element child : design.children()) { + + Component childComponent = designContext.readDesign(child); + + if (child.hasAttr(":location")) { + addComponent(childComponent, child.attr(":location")); + } else { + addComponent(childComponent); + } + } + } + + @Override + public void writeDesign(Element design, DesignContext designContext) { + super.writeDesign(design, designContext); + + for (Entry<String, Component> slot : slots.entrySet()) { + Element child = designContext.createElement(slot.getValue()); + if (slots.size() > 1 || !"".equals(slot.getKey())) { + child.attr(":location", slot.getKey()); + } + design.appendChild(child); + } + } } diff --git a/server/src/com/vaadin/ui/DragAndDropWrapper.java b/server/src/com/vaadin/ui/DragAndDropWrapper.java index 6e4ec903d2..b813973861 100644 --- a/server/src/com/vaadin/ui/DragAndDropWrapper.java +++ b/server/src/com/vaadin/ui/DragAndDropWrapper.java @@ -24,6 +24,8 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import org.jsoup.nodes.Element; + import com.vaadin.event.Transferable; import com.vaadin.event.TransferableImpl; import com.vaadin.event.dd.DragSource; @@ -38,6 +40,7 @@ import com.vaadin.shared.MouseEventDetails; import com.vaadin.shared.ui.dd.HorizontalDropLocation; import com.vaadin.shared.ui.dd.VerticalDropLocation; import com.vaadin.shared.ui.draganddropwrapper.DragAndDropWrapperConstants; +import com.vaadin.ui.declarative.DesignContext; @SuppressWarnings("serial") public class DragAndDropWrapper extends CustomComponent implements DropTarget, @@ -185,7 +188,12 @@ public class DragAndDropWrapper extends CustomComponent implements DropTarget, private Set<String> sentIds = new HashSet<String>(); - private DragAndDropWrapper() { + /** + * This is an internal constructor. Use + * {@link DragAndDropWrapper#DragAndDropWrapper(Component)} instead. + */ + @Deprecated + public DragAndDropWrapper() { super(); } @@ -458,4 +466,31 @@ public class DragAndDropWrapper extends CustomComponent implements DropTarget, } + @Override + public void readDesign(Element design, DesignContext designContext) { + super.readDesign(design, designContext); + + for (Element child : design.children()) { + Component component = designContext.readDesign(child); + if (getDragStartMode() == DragStartMode.COMPONENT_OTHER + && child.hasAttr(":drag-image")) { + setDragImageComponent(component); + } else if (getCompositionRoot() == null) { + setCompositionRoot(component); + } + } + } + + @Override + public void writeDesign(Element design, DesignContext designContext) { + super.writeDesign(design, designContext); + + design.appendChild(designContext.createElement(getCompositionRoot())); + if (getDragStartMode() == DragStartMode.COMPONENT_OTHER) { + Element child = designContext + .createElement(getDragImageComponent()); + child.attr(":drag-image", ""); + design.appendChild(child); + } + } } diff --git a/server/src/com/vaadin/ui/MenuBar.java b/server/src/com/vaadin/ui/MenuBar.java index 6b6555c0a2..747ce42727 100644 --- a/server/src/com/vaadin/ui/MenuBar.java +++ b/server/src/com/vaadin/ui/MenuBar.java @@ -17,17 +17,25 @@ package com.vaadin.ui; import java.io.Serializable; import java.util.ArrayList; +import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Stack; +import org.jsoup.nodes.Attributes; +import org.jsoup.nodes.Element; +import org.jsoup.nodes.Node; +import org.jsoup.parser.Tag; + import com.vaadin.server.PaintException; import com.vaadin.server.PaintTarget; import com.vaadin.server.Resource; import com.vaadin.shared.ui.menubar.MenuBarConstants; import com.vaadin.shared.ui.menubar.MenuBarState; import com.vaadin.ui.Component.Focusable; +import com.vaadin.ui.declarative.DesignAttributeHandler; +import com.vaadin.ui.declarative.DesignContext; /** * <p> @@ -932,7 +940,150 @@ public class MenuBar extends AbstractComponent implements LegacyComponent, this.checked = checked; markAsDirty(); } - }// class MenuItem + @Override + public void writeDesign(Element design, DesignContext designContext) { + super.writeDesign(design, designContext); + for (MenuItem item : getItems()) { + design.appendChild(createMenuElement(item)); + } + + // in many cases there seems to be an empty more menu item + if (getMoreMenuItem() != null && !getMoreMenuItem().getText().isEmpty()) { + Element moreMenu = createMenuElement(getMoreMenuItem()); + moreMenu.attr("more", ""); + design.appendChild(moreMenu); + } + + if (!htmlContentAllowed) { + design.attr(DESIGN_ATTR_PLAIN_TEXT, ""); + } + } + + protected Element createMenuElement(MenuItem item) { + Element menuElement = new Element(Tag.valueOf("menu"), ""); + // Defaults + MenuItem def = new MenuItem("", null, null); + + Attributes attr = menuElement.attributes(); + DesignAttributeHandler.writeAttribute("icon", attr, item.getIcon(), + def.getIcon(), Resource.class); + DesignAttributeHandler.writeAttribute("disabled", attr, + !item.isEnabled(), !def.isEnabled(), boolean.class); + DesignAttributeHandler.writeAttribute("visible", attr, + item.isVisible(), def.isVisible(), boolean.class); + DesignAttributeHandler.writeAttribute("separator", attr, + item.isSeparator(), def.isSeparator(), boolean.class); + DesignAttributeHandler.writeAttribute("checkable", attr, + item.isCheckable(), def.isCheckable(), boolean.class); + DesignAttributeHandler.writeAttribute("checked", attr, + item.isChecked(), def.isChecked(), boolean.class); + DesignAttributeHandler.writeAttribute("description", attr, + item.getDescription(), def.getDescription(), String.class); + DesignAttributeHandler.writeAttribute("style-name", attr, + item.getStyleName(), def.getStyleName(), String.class); + + menuElement.append(item.getText()); + + if (item.hasChildren()) { + for (MenuItem subMenu : item.getChildren()) { + menuElement.appendChild(createMenuElement(subMenu)); + } + } + + return menuElement; + } + + protected MenuItem readMenuElement(Element menuElement) { + Resource icon = null; + if (menuElement.hasAttr("icon")) { + icon = DesignAttributeHandler.getFormatter().parse( + menuElement.attr("icon"), Resource.class); + } + + String caption = ""; + List<Element> subMenus = new ArrayList<Element>(); + for (Node node : menuElement.childNodes()) { + if (node instanceof Element + && ((Element) node).tagName().equals("menu")) { + subMenus.add((Element) node); + } + caption += node.toString(); + } + MenuItem menu = new MenuItem(caption.trim(), icon, null); + + Attributes attr = menuElement.attributes(); + if (menuElement.hasAttr("icon")) { + menu.setIcon(DesignAttributeHandler.readAttribute("icon", attr, + Resource.class)); + } + if (menuElement.hasAttr("disabled")) { + menu.setEnabled(!DesignAttributeHandler.readAttribute("disabled", + attr, boolean.class)); + } + if (menuElement.hasAttr("visible")) { + menu.setVisible(DesignAttributeHandler.readAttribute("visible", + attr, boolean.class)); + } + if (menuElement.hasAttr("separator")) { + menu.setSeparator(DesignAttributeHandler.readAttribute("separator", + attr, boolean.class)); + } + if (menuElement.hasAttr("checkable")) { + menu.setCheckable(DesignAttributeHandler.readAttribute("checkable", + attr, boolean.class)); + } + if (menuElement.hasAttr("checked")) { + menu.setChecked(DesignAttributeHandler.readAttribute("checked", + attr, boolean.class)); + } + if (menuElement.hasAttr("description")) { + menu.setDescription(DesignAttributeHandler.readAttribute( + "description", attr, String.class)); + } + if (menuElement.hasAttr("style-name")) { + menu.setStyleName(DesignAttributeHandler.readAttribute( + "style-name", attr, String.class)); + } + + if (!subMenus.isEmpty()) { + menu.itsChildren = new ArrayList<MenuItem>(); + } + + for (Element subMenu : subMenus) { + MenuItem newItem = readMenuElement(subMenu); + + newItem.setParent(menu); + menu.itsChildren.add(newItem); + } + + return menu; + } + + @Override + public void readDesign(Element design, DesignContext designContext) { + super.readDesign(design, designContext); + + for (Element itemElement : design.children()) { + if (itemElement.tagName().equals("menu")) { + MenuItem menuItem = readMenuElement(itemElement); + if (itemElement.hasAttr("more")) { + setMoreMenuItem(menuItem); + } else { + menuItems.add(menuItem); + } + } + } + + setHtmlContentAllowed(!design.hasAttr(DESIGN_ATTR_PLAIN_TEXT)); + } + + @Override + protected Collection<String> getCustomAttributes() { + Collection<String> result = super.getCustomAttributes(); + result.add(DESIGN_ATTR_PLAIN_TEXT); + result.add("html-content-allowed"); + return result; + } }// class MenuBar diff --git a/server/src/com/vaadin/ui/PushConfiguration.java b/server/src/com/vaadin/ui/PushConfiguration.java index d5e89b4b14..90ad28542c 100644 --- a/server/src/com/vaadin/ui/PushConfiguration.java +++ b/server/src/com/vaadin/ui/PushConfiguration.java @@ -105,26 +105,6 @@ public interface PushConfiguration extends Serializable { public void setFallbackTransport(Transport fallbackTransport); /** - * Sets the path that is used with push. - * - * @since 7.4.1 - * @param pushPath - * The path to be used with push - * - * @throws IllegalArgumentException - * if the argument is null or empty. - */ - public void setPushPath(String pushPath); - - /** - * Returns the path used with push. - * - * @since 7.4.1 - * @return The path that is used with push - */ - public String getPushPath(); - - /** * Returns the given parameter, if set. * <p> * This method provides low level access to push parameters and is typically @@ -278,32 +258,6 @@ class PushConfigurationImpl implements PushConfiguration { /* * (non-Javadoc) * - * @see com.vaadin.ui.PushConfiguration#setPushPath(java.lang.String) - */ - @Override - public void setPushPath(String pushPath) { - if (pushPath != null && !pushPath.isEmpty()) { - getState().pushPath = pushPath; - } else { - throw new IllegalArgumentException( - "Push path can't be empty or null"); - } - - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.PushConfiguration#getPushPath() - */ - @Override - public String getPushPath() { - return getState(false).pushPath; - } - - /* - * (non-Javadoc) - * * @see com.vaadin.ui.PushConfiguration#getParameter(java.lang.String) */ @Override @@ -336,4 +290,5 @@ class PushConfigurationImpl implements PushConfiguration { return Collections.unmodifiableCollection(getState(false).parameters .keySet()); } + } diff --git a/server/src/com/vaadin/ui/Slider.java b/server/src/com/vaadin/ui/Slider.java index 99e1e8d5e9..40a4047d53 100644 --- a/server/src/com/vaadin/ui/Slider.java +++ b/server/src/com/vaadin/ui/Slider.java @@ -16,9 +16,16 @@ package com.vaadin.ui; +import java.util.Collection; + +import org.jsoup.nodes.Attributes; +import org.jsoup.nodes.Element; + import com.vaadin.shared.ui.slider.SliderOrientation; import com.vaadin.shared.ui.slider.SliderServerRpc; import com.vaadin.shared.ui.slider.SliderState; +import com.vaadin.ui.declarative.DesignAttributeHandler; +import com.vaadin.ui.declarative.DesignContext; /** * A component for selecting a numerical value within a range. @@ -353,4 +360,35 @@ public class Slider extends AbstractField<Double> { // Slider is never really "empty" return false; } + + @Override + public void readDesign(Element design, DesignContext context) { + super.readDesign(design, context); + Attributes attr = design.attributes(); + if (attr.hasKey("vertical")) { + setOrientation(SliderOrientation.VERTICAL); + } + if (!attr.get("value").isEmpty()) { + setValue(DesignAttributeHandler.readAttribute("value", attr, + Double.class)); + } + } + + @Override + public void writeDesign(Element design, DesignContext context) { + super.writeDesign(design, context); + if (getOrientation() == SliderOrientation.VERTICAL) { + design.attr("vertical", ""); + } + Slider defaultSlider = context.getDefaultInstance(this); + DesignAttributeHandler.writeAttribute(this, "value", + design.attributes(), defaultSlider); + } + + @Override + protected Collection<String> getCustomAttributes() { + Collection<String> result = super.getCustomAttributes(); + result.add("orientation"); + return result; + } } diff --git a/server/src/com/vaadin/ui/Video.java b/server/src/com/vaadin/ui/Video.java index e690218e6f..46a4293b36 100644 --- a/server/src/com/vaadin/ui/Video.java +++ b/server/src/com/vaadin/ui/Video.java @@ -16,9 +16,17 @@ package com.vaadin.ui; +import java.util.Collection; + +import org.jsoup.nodes.Attributes; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + import com.vaadin.server.Resource; import com.vaadin.shared.ui.video.VideoConstants; import com.vaadin.shared.ui.video.VideoState; +import com.vaadin.ui.declarative.DesignAttributeHandler; +import com.vaadin.ui.declarative.DesignContext; /** * The Video component translates into an HTML5 <video> element and as @@ -89,4 +97,35 @@ public class Video extends AbstractMedia { return getResource(VideoConstants.POSTER_RESOURCE); } + @Override + public void readDesign(Element design, DesignContext designContext) { + Elements elems = design.getElementsByTag("poster"); + for (Element poster : elems) { + if (getPoster() == null && poster.hasAttr("href")) { + setPoster(DesignAttributeHandler.readAttribute("href", + poster.attributes(), Resource.class)); + } + poster.remove(); + } + + // Poster is extracted so AbstractMedia does not include it in alt text + super.readDesign(design, designContext); + } + + @Override + public void writeDesign(Element design, DesignContext designContext) { + super.writeDesign(design, designContext); + if (getPoster() != null) { + Attributes attr = design.appendElement("poster").attributes(); + DesignAttributeHandler.writeAttribute("href", attr, getPoster(), + null, Resource.class); + } + } + + @Override + protected Collection<String> getCustomAttributes() { + Collection<String> result = super.getCustomAttributes(); + result.add("poster"); + return result; + } } diff --git a/server/src/com/vaadin/ui/declarative/Design.java b/server/src/com/vaadin/ui/declarative/Design.java index 1b8585e6f6..6634e5248a 100644 --- a/server/src/com/vaadin/ui/declarative/Design.java +++ b/server/src/com/vaadin/ui/declarative/Design.java @@ -33,6 +33,7 @@ import org.jsoup.parser.Parser; import org.jsoup.select.Elements; import com.vaadin.annotations.DesignRoot; +import com.vaadin.shared.util.SharedUtil; import com.vaadin.ui.Component; import com.vaadin.ui.declarative.DesignContext.ComponentCreatedEvent; import com.vaadin.ui.declarative.DesignContext.ComponentCreationListener; @@ -68,7 +69,6 @@ public class Design implements Serializable { * Use {@link Design#setComponentFactory(ComponentFactory)} to configure * Vaadin to use a custom component factory. * - * * @since 7.4.1 */ public interface ComponentFactory extends Serializable { @@ -88,6 +88,50 @@ public class Design implements Serializable { } /** + * Delegate for handling the mapping between tag names and component + * instances. + * <p> + * Use {@link Design#setComponentMapper(ComponentMapper)} to configure + * Vaadin to use a custom component mapper. + * + * @since + * @author Vaadin Ltd + */ + public interface ComponentMapper extends Serializable { + /** + * Resolves and creates a component using the provided component factory + * based on a tag name. + * <p> + * This method should be in sync with + * {@link #componentToTag(Component, DesignContext)} so that the + * resolved tag for a created component is the same as the tag for which + * the component was created. + * + * @param tag + * the tag name to create a component for + * @param componentFactory + * the component factory that actually creates a component + * based on a fully qualified class name + * @param context + * the design context for which the component is created + * @return a newly created component + */ + public Component tagToComponent(String tag, + ComponentFactory componentFactory, DesignContext context); + + /** + * Resolves a tag name from a component. + * + * @param component + * the component to get a tag name for + * @param context + * the design context for which the tag name is needed + * @return the tag name corresponding to the component + */ + public String componentToTag(Component component, DesignContext context); + } + + /** * Default implementation of {@link ComponentFactory}, using * <code>Class.forName(className).newInstance()</code> for finding the * component class and creating a component instance. @@ -135,7 +179,100 @@ public class Design implements Serializable { } + /** + * Default implementation of {@link ComponentMapper}, + * + * @since + */ + public static class DefaultComponentMapper implements ComponentMapper { + + @Override + public Component tagToComponent(String tagName, + ComponentFactory componentFactory, DesignContext context) { + // Extract the package and class names. + // Otherwise, get the full class name using the prefix to package + // mapping. Example: "v-vertical-layout" -> + // "com.vaadin.ui.VerticalLayout" + String[] parts = tagName.split("-", 2); + if (parts.length < 2) { + throw new DesignException("The tagname '" + tagName + + "' is invalid: missing prefix."); + } + String prefixName = parts[0]; + String packageName = context.getPackage(prefixName); + if (packageName == null) { + throw new DesignException("Unknown tag: " + tagName); + } + String[] classNameParts = parts[1].split("-"); + String className = ""; + for (String classNamePart : classNameParts) { + // Split will ignore trailing and multiple dashes but that + // should be + // ok + // <v-button--> will be resolved to <v-button> + // <v--button> will be resolved to <v-button> + className += SharedUtil.capitalize(classNamePart); + } + String qualifiedClassName = packageName + "." + className; + + Component component = componentFactory.createComponent( + qualifiedClassName, context); + + if (component == null) { + throw new DesignException("Got unexpected null component from " + + componentFactory.getClass().getName() + " for class " + + qualifiedClassName); + } + + return component; + } + + @Override + public String componentToTag(Component component, DesignContext context) { + Class<?> componentClass = component.getClass(); + String packageName = componentClass.getPackage().getName(); + String prefix = context.getPackagePrefix(packageName); + if (prefix == null) { + prefix = packageName.replace('.', '_'); + context.addPackagePrefix(prefix, packageName); + } + prefix = prefix + "-"; + String className = classNameToElementName(componentClass + .getSimpleName()); + String tagName = prefix + className; + + return tagName; + } + + /** + * Creates the name of the html tag corresponding to the given class + * name. The name is derived by converting each uppercase letter to + * lowercase and inserting a dash before the letter. No dash is inserted + * before the first letter of the class name. + * + * @param className + * the name of the class without a package name + * @return the html tag name corresponding to className + */ + private String classNameToElementName(String className) { + StringBuilder result = new StringBuilder(); + for (int i = 0; i < className.length(); i++) { + Character c = className.charAt(i); + if (Character.isUpperCase(c)) { + if (i > 0) { + result.append("-"); + } + result.append(Character.toLowerCase(c)); + } else { + result.append(c); + } + } + return result.toString(); + } + } + private static volatile ComponentFactory componentFactory = new DefaultComponentFactory(); + private static volatile ComponentMapper componentMapper = new DefaultComponentMapper(); /** * Sets the component factory that is used for creating component instances @@ -171,6 +308,39 @@ public class Design implements Serializable { } /** + * Sets the component mapper that is used for resolving between tag names + * and component instances. + * <p> + * Please note that this setting is global, so care should be taken to avoid + * conflicting changes. + * + * @param componentMapper + * the component mapper to set; not <code>null</code> + * + * @since + */ + public static void setComponentMapper(ComponentMapper componentMapper) { + if (componentMapper == null) { + throw new IllegalArgumentException( + "Cannot set null component mapper"); + } + Design.componentMapper = componentMapper; + } + + /** + * Gets the currently used component mapper. + * + * @see #setComponentMapper(ComponentMapper) + * + * @return the component mapper + * + * @since + */ + public static ComponentMapper getComponentMapper() { + return componentMapper; + } + + /** * Parses the given input stream into a jsoup document * * @param html diff --git a/server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java b/server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java index 215afd5041..2b446bda0e 100644 --- a/server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java +++ b/server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java @@ -38,7 +38,6 @@ import org.jsoup.nodes.Node; import com.vaadin.data.util.converter.Converter; import com.vaadin.shared.util.SharedUtil; -import com.vaadin.ui.Component; /** * Default attribute handler implementation used when parsing designs to @@ -192,8 +191,8 @@ public class DesignAttributeHandler implements Serializable { * @param defaultInstance * the default instance for comparing default values */ - public static void writeAttribute(Component component, String attribute, - Attributes attr, Component defaultInstance) { + public static void writeAttribute(Object component, String attribute, + Attributes attr, Object defaultInstance) { Method getter = findGetterForAttribute(component.getClass(), attribute); if (getter == null) { getLogger().warning( diff --git a/server/src/com/vaadin/ui/declarative/DesignContext.java b/server/src/com/vaadin/ui/declarative/DesignContext.java index 218774c72d..f991b3013a 100644 --- a/server/src/com/vaadin/ui/declarative/DesignContext.java +++ b/server/src/com/vaadin/ui/declarative/DesignContext.java @@ -17,6 +17,8 @@ package com.vaadin.ui.declarative; import java.io.Serializable; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -28,10 +30,10 @@ import org.jsoup.nodes.Element; import org.jsoup.nodes.Node; import com.vaadin.annotations.DesignRoot; -import com.vaadin.shared.util.SharedUtil; import com.vaadin.ui.Component; import com.vaadin.ui.HasComponents; import com.vaadin.ui.declarative.Design.ComponentFactory; +import com.vaadin.ui.declarative.Design.ComponentMapper; /** * This class contains contextual information that is collected when a component @@ -79,7 +81,7 @@ public class DesignContext implements Serializable { defaultPrefixes.put("v", "com.vaadin.ui"); for (String prefix : defaultPrefixes.keySet()) { String packageName = defaultPrefixes.get(prefix); - mapPrefixToPackage(prefix, packageName); + addPackagePrefix(prefix, packageName); } } @@ -236,20 +238,65 @@ public class DesignContext implements Serializable { } /** - * Creates a two-way mapping between a prefix and a package name. Return - * true if prefix was already mapped to some package name or packageName to - * some prefix. + * Creates a two-way mapping between a prefix and a package name. * * @param prefix * the prefix name without an ending dash (for instance, "v" is - * always used for "com.vaadin.ui") + * by default used for "com.vaadin.ui") * @param packageName * the name of the package corresponding to prefix - * @return whether there was a mapping from prefix to some package name or - * from packageName to some prefix. + * + * @see #getPackagePrefixes() + * @see #getPackagePrefix(String) + * @see #getPackage(String) + * @since + */ + public void addPackagePrefix(String prefix, String packageName) { + twoWayMap(prefix, packageName, prefixToPackage, packageToPrefix); + } + + /** + * Gets the prefix mapping for a given package, or <code>null</code> if + * there is no mapping for the package. + * + * @see #addPackagePrefix(String, String) + * @see #getPackagePrefixes() + * + * @since + * @param packageName + * the package name to get a prefix for + * @return the prefix for the package, or <code>null</code> if no prefix is + * registered + */ + public String getPackagePrefix(String packageName) { + return packageToPrefix.get(packageName); + } + + /** + * Gets all registered package prefixes. + * + * + * @since + * @see #getPackage(String) + * @return a collection of package prefixes */ - private boolean mapPrefixToPackage(String prefix, String packageName) { - return twoWayMap(prefix, packageName, prefixToPackage, packageToPrefix); + public Collection<String> getPackagePrefixes() { + return Collections.unmodifiableCollection(prefixToPackage.keySet()); + } + + /** + * Gets the package corresponding to the give prefix, or <code>null</code> + * no package has been registered for the prefix + * + * @since + * @see #addPackagePrefix(String, String) + * @param prefix + * the prefix to find a package for + * @return the package prefix, or <code>null</code> if no package is + * registered for the provided prefix + */ + public String getPackage(String prefix) { + return prefixToPackage.get(prefix); } /** @@ -309,8 +356,7 @@ public class DesignContext implements Serializable { } String prefixName = parts[0]; String packageName = parts[1]; - twoWayMap(prefixName, packageName, prefixToPackage, - packageToPrefix); + addPackagePrefix(prefixName, packageName); } } } @@ -328,14 +374,13 @@ public class DesignContext implements Serializable { */ public void writePackageMappings(Document doc) { Element head = doc.head(); - for (String prefix : prefixToPackage.keySet()) { + for (String prefix : getPackagePrefixes()) { // Only store the prefix-name mapping if it is not a default mapping // (such as "v" -> "com.vaadin.ui") if (defaultPrefixes.get(prefix) == null) { Node newNode = doc.createElement("meta"); newNode.attr("name", "package-mapping"); - String prefixToPackageName = prefix + ":" - + prefixToPackage.get(prefix); + String prefixToPackageName = prefix + ":" + getPackage(prefix); newNode.attr("content", prefixToPackageName); head.appendChild(newNode); } @@ -355,17 +400,11 @@ public class DesignContext implements Serializable { * childComponent. */ public Element createElement(Component childComponent) { - Class<?> componentClass = childComponent.getClass(); - String packageName = componentClass.getPackage().getName(); - String prefix = packageToPrefix.get(packageName); - if (prefix == null) { - prefix = packageName.replace('.', '_'); - twoWayMap(prefix, packageName, prefixToPackage, packageToPrefix); - } - prefix = prefix + "-"; - String className = classNameToElementName(componentClass - .getSimpleName()); - Element newElement = doc.createElement(prefix + className); + ComponentMapper componentMapper = Design.getComponentMapper(); + + String tagName = componentMapper.componentToTag(childComponent, this); + + Element newElement = doc.createElement(tagName); childComponent.writeDesign(newElement, this); // Handle the local id. Global id and caption should have been taken // care of by writeDesign. @@ -377,32 +416,6 @@ public class DesignContext implements Serializable { } /** - * Creates the name of the html tag corresponding to the given class name. - * The name is derived by converting each uppercase letter to lowercase and - * inserting a dash before the letter. No dash is inserted before the first - * letter of the class name. - * - * @param className - * the name of the class without a package name - * @return the html tag name corresponding to className - */ - private String classNameToElementName(String className) { - StringBuilder result = new StringBuilder(); - for (int i = 0; i < className.length(); i++) { - Character c = className.charAt(i); - if (Character.isUpperCase(c)) { - if (i > 0) { - result.append("-"); - } - result.append(Character.toLowerCase(c)); - } else { - result.append(c); - } - } - return result.toString(); - } - - /** * Reads the given design node and creates the corresponding component tree * * @param componentDesign @@ -473,15 +486,22 @@ public class DesignContext implements Serializable { * @return a Component corresponding to node, with no attributes set. */ private Component instantiateComponent(Node node) { - // Extract the package and class names. - String qualifiedClassName = tagNameToClassName(node); + String tag = node.nodeName(); + + ComponentMapper componentMapper = Design.getComponentMapper(); + Component component = componentMapper.tagToComponent(tag, + Design.getComponentFactory(), this); - return instantiateClass(qualifiedClassName); + assert tag.equals(componentMapper.componentToTag(component, this)); + + return component; } /** * Instantiates given class via ComponentFactory. - * @param qualifiedClassName class name to instantiate + * + * @param qualifiedClassName + * class name to instantiate * @return instance of a given class */ private Component instantiateClass(String qualifiedClassName) { @@ -498,44 +518,6 @@ public class DesignContext implements Serializable { } /** - * Returns the qualified class name corresponding to the given html tree - * node. The class name is extracted from the tag name of node. - * - * @param node - * an html tree node - * @return The qualified class name corresponding to the given node. - */ - private String tagNameToClassName(Node node) { - String tagName = node.nodeName(); - if (tagName.equals("v-addon")) { - return node.attr("class"); - } - // Otherwise, get the full class name using the prefix to package - // mapping. Example: "v-vertical-layout" -> - // "com.vaadin.ui.VerticalLayout" - String[] parts = tagName.split("-", 2); - if (parts.length < 2) { - throw new DesignException("The tagname '" + tagName - + "' is invalid: missing prefix."); - } - String prefixName = parts[0]; - String packageName = prefixToPackage.get(prefixName); - if (packageName == null) { - throw new DesignException("Unknown tag: " + tagName); - } - String[] classNameParts = parts[1].split("-"); - String className = ""; - for (String classNamePart : classNameParts) { - // Split will ignore trailing and multiple dashes but that should be - // ok - // <v-button--> will be resolved to <v-button> - // <v--button> will be resolved to <v-button> - className += SharedUtil.capitalize(classNamePart); - } - return packageName + "." + className; - } - - /** * Returns the root component of a created component hierarchy. * * @return the root component of the hierarchy diff --git a/server/src/com/vaadin/ui/declarative/converters/DesignResourceConverter.java b/server/src/com/vaadin/ui/declarative/converters/DesignResourceConverter.java index 70e46b8e7f..21f20e6403 100644 --- a/server/src/com/vaadin/ui/declarative/converters/DesignResourceConverter.java +++ b/server/src/com/vaadin/ui/declarative/converters/DesignResourceConverter.java @@ -39,7 +39,8 @@ public class DesignResourceConverter implements Converter<String, Resource> { public Resource convertToModel(String value, Class<? extends Resource> targetType, Locale locale) throws Converter.ConversionException { - if (value.startsWith("http://")) { + if (value.startsWith("http://") || value.startsWith("https://") + || value.startsWith("ftp://") || value.startsWith("ftps://")) { return new ExternalResource(value); } else if (value.startsWith("theme://")) { return new ThemeResource(value.substring(8)); diff --git a/server/tests/src/com/vaadin/server/AbstractDeploymentConfigurationTest.java b/server/tests/src/com/vaadin/server/AbstractDeploymentConfigurationTest.java index ccdbfea150..0518bea650 100644 --- a/server/tests/src/com/vaadin/server/AbstractDeploymentConfigurationTest.java +++ b/server/tests/src/com/vaadin/server/AbstractDeploymentConfigurationTest.java @@ -158,9 +158,5 @@ public class AbstractDeploymentConfigurationTest { return DefaultDeploymentConfiguration.DEFAULT_SEND_URLS_AS_PARAMETERS; } - @Override - public String getPushPath() { - return null; - } } } diff --git a/server/tests/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropWrapperDeclarativeTest.java b/server/tests/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropWrapperDeclarativeTest.java new file mode 100644 index 0000000000..735216c474 --- /dev/null +++ b/server/tests/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropWrapperDeclarativeTest.java @@ -0,0 +1,66 @@ +/* + * Copyright 2000-2014 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.tests.components.draganddropwrapper; + +import org.junit.Test; + +import com.vaadin.tests.design.DeclarativeTestBase; +import com.vaadin.ui.Button; +import com.vaadin.ui.DragAndDropWrapper; +import com.vaadin.ui.DragAndDropWrapper.DragStartMode; +import com.vaadin.ui.declarative.DesignContext; + +public class DragAndDropWrapperDeclarativeTest extends + DeclarativeTestBase<DragAndDropWrapper> { + + @Test + public void testDefaultDnDWrapper() { + Button okButton = new Button("OK"); + String input = "<v-drag-and-drop-wrapper>" + + new DesignContext().createElement(okButton) + + "</v-drag-and-drop-wrapper>"; + DragAndDropWrapper wrapper = new DragAndDropWrapper(okButton); + testWrite(input, wrapper); + testRead(input, wrapper); + } + + @Test + public void testNoDragImage() { + Button okButton = new Button("OK"); + String input = "<v-drag-and-drop-wrapper drag-start-mode='wrapper'>" + + new DesignContext().createElement(okButton) + + "</v-drag-and-drop-wrapper>"; + DragAndDropWrapper wrapper = new DragAndDropWrapper(okButton); + wrapper.setDragStartMode(DragStartMode.WRAPPER); + testWrite(input, wrapper); + testRead(input, wrapper); + } + + @Test + public void testWithDragImage() { + Button dragImage = new Button("Cancel"); + Button okButton = new Button("OK"); + String input = "<v-drag-and-drop-wrapper drag-start-mode='component_other'>" + + new DesignContext().createElement(okButton) + + new DesignContext().createElement(dragImage).attr( + ":drag-image", "") + "</v-drag-and-drop-wrapper>"; + DragAndDropWrapper wrapper = new DragAndDropWrapper(okButton); + wrapper.setDragStartMode(DragStartMode.COMPONENT_OTHER); + wrapper.setDragImageComponent(dragImage); + testWrite(input, wrapper); + testRead(input, wrapper); + } +} diff --git a/server/tests/src/com/vaadin/tests/components/menubar/MenuBarDeclarativeTest.java b/server/tests/src/com/vaadin/tests/components/menubar/MenuBarDeclarativeTest.java new file mode 100644 index 0000000000..e6dee44812 --- /dev/null +++ b/server/tests/src/com/vaadin/tests/components/menubar/MenuBarDeclarativeTest.java @@ -0,0 +1,139 @@ +/* + * Copyright 2000-2014 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.tests.components.menubar; + +import java.io.IOException; + +import org.junit.Test; + +import com.vaadin.server.ExternalResource; +import com.vaadin.server.ThemeResource; +import com.vaadin.tests.design.DeclarativeTestBase; +import com.vaadin.ui.MenuBar; +import com.vaadin.ui.MenuBar.MenuItem; + +/** + * Tests declarative support for menu bars. + * + * @since 7.4 + * @author Vaadin Ltd + */ +public class MenuBarDeclarativeTest extends DeclarativeTestBase<MenuBar> { + + @Test + // #16328 + public void testReadWrite() throws IOException { + String design = "<v-menu-bar auto-open='true' tabindex=5>" + + "<menu checkable='true'>Save</menu>" + + "<menu description='Open a file'>Open</menu>" + + "<menu disabled='true'>Close</menu>" + + "<menu icon='http://foo.bar/ico.png'>Help</menu>" + + "<menu visible='false'>About</menu>" + + "<menu>Sub<menu>Item</menu></menu>" + + "<menu more>WTF?!</menu>" + "</v-menu-bar>"; + MenuBar bar = new MenuBar(); + bar.setAutoOpen(true); + bar.setHtmlContentAllowed(true); + bar.setTabIndex(5); + + bar.addItem("Save", null).setCheckable(true); + bar.addItem("Open", null).setDescription("Open a file"); + bar.addItem("Close", null).setEnabled(false); + bar.addItem("Help", null).setIcon( + new ExternalResource("http://foo.bar/ico.png")); + bar.addItem("About", null).setVisible(false); + + bar.addItem("Sub", null).addItem("Item", null); + + bar.setMoreMenuItem(bar.new MenuItem("WTF?!", null, null)); + + testWrite(design, bar); + testRead(design, bar); + } + + @Test + // #16328 + public void testTicketSpec1() throws IOException { + String design = "<v-menu-bar auto-open='true' plain-text tabindex=5> " + + "<menu>File" + + "<menu>Save</menu>" + + "<menu icon=\"theme://../runo/icons/16/folder.png\">Open</menu>" + + "<menu separator='true' />" + + "<menu disabled='true'>Exit</menu>" + + "<menu visible='false'>Not for everybody</menu>" + + "</menu>" + + "<menu description=\"This contains many items in sub menus\">Other" + + "<menu style-name=\"fancy\">Sub" + + "<menu checkable='true' checked='true'>Option 1 - no <b>html</b></menu>" + + "<menu checkable='true'>Option 2</menu>" + + "<menu checkable='true'>Option 3</menu>" // + + "</menu>" // + + "</menu>" // + + "<menu more icon=\"theme://icon.png\">foo</menu>" + + "</v-menu-bar>"; + // for one reason or another, no component has a correct .equals + // implementation, which makes tests a bit annoying + MenuBar menuBar = new MenuBar(); + menuBar.setHtmlContentAllowed(false); + menuBar.setTabIndex(5); + menuBar.setAutoOpen(true); + // File menu + MenuItem fileMenu = menuBar.addItem("File", null); + fileMenu.addItem("Save", null); + fileMenu.addItem("Open", new ThemeResource( + "../runo/icons/16/folder.png"), null); + fileMenu.addSeparator(); + fileMenu.addItem("Exit", null).setEnabled(false); + fileMenu.addItem("Not for everybody", null).setVisible(false); + MenuItem otherMenu = menuBar.addItem("Other", null); + otherMenu.setDescription("This contains many items in sub menus"); + MenuItem subMenu = otherMenu.addItem("Sub", null); + subMenu.setStyleName("fancy"); + MenuItem option1 = subMenu.addItem("Option 1 - no <b>html</b>", null); + option1.setCheckable(true); + option1.setChecked(true); + subMenu.addItem("Option 2", null).setCheckable(true); + subMenu.addItem("Option 3", null).setCheckable(true); + menuBar.setMoreMenuItem(null); + MenuItem moreMenu = menuBar.getMoreMenuItem(); + moreMenu.setIcon(new ThemeResource("icon.png")); + moreMenu.setText("foo"); + testRead(design, menuBar); + testWrite(design, menuBar); + } + + @Test + // #16328 + public void testTicketSpec2() throws IOException { + String design = "<v-menu-bar>" + + "<menu><b>File</b>" + + "<menu><font style=\"color: red\">Save</font></menu>" + + "<menu icon=\"theme://../runo/icons/16/folder.png\">Open</menu>" + + "<menu separator='true' />" + + "<menu disabled='true'>Exit</menu>" // + + "</menu></v-menu-bar>"; + MenuBar menuBar = new MenuBar(); + menuBar.setHtmlContentAllowed(true); + MenuItem fileMenu = menuBar.addItem("<b>File</b>", null); + fileMenu.addItem("<font style='color: red'>Save</font>", null); + fileMenu.addItem("Open", new ThemeResource( + "../runo/icons/16/folder.png"), null); + fileMenu.addSeparator(); + fileMenu.addItem("Exit", null).setEnabled(false); + testRead(design, menuBar); + testWrite(design, menuBar); + } +}
\ No newline at end of file diff --git a/server/tests/src/com/vaadin/tests/design/ComponentMapperTest.java b/server/tests/src/com/vaadin/tests/design/ComponentMapperTest.java new file mode 100644 index 0000000000..c6e8c15109 --- /dev/null +++ b/server/tests/src/com/vaadin/tests/design/ComponentMapperTest.java @@ -0,0 +1,129 @@ +/* + * Copyright 2000-2014 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.tests.design; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.ui.Component; +import com.vaadin.ui.Label; +import com.vaadin.ui.declarative.Design; +import com.vaadin.ui.declarative.Design.ComponentFactory; +import com.vaadin.ui.declarative.Design.ComponentMapper; +import com.vaadin.ui.declarative.DesignContext; + +public class ComponentMapperTest { + private static final ComponentMapper defaultMapper = Design + .getComponentMapper(); + + private static final ThreadLocal<ComponentMapper> currentMapper = new ThreadLocal<ComponentMapper>(); + + static { + Design.setComponentMapper(new ComponentMapper() { + @Override + public Component tagToComponent(String tag, + ComponentFactory componentFactory, DesignContext context) { + return getActualMapper().tagToComponent(tag, componentFactory, + context); + } + + @Override + public String componentToTag(Component component, + DesignContext context) { + return getActualMapper().componentToTag(component, context); + } + + private ComponentMapper getActualMapper() { + ComponentMapper mapper = currentMapper.get(); + if (mapper == null) { + mapper = defaultMapper; + } + return mapper; + } + }); + } + + private final class CustomComponentMapper extends + Design.DefaultComponentMapper { + @Override + public Component tagToComponent(String tag, + ComponentFactory componentFactory, DesignContext context) { + if (tag.startsWith("custom-")) { + ComponentWithCustomTagName component = (ComponentWithCustomTagName) componentFactory + .createComponent( + ComponentWithCustomTagName.class.getName(), + context); + component.tagName = tag; + return component; + } else { + return super.tagToComponent(tag, componentFactory, context); + } + } + + @Override + public String componentToTag(Component component, DesignContext context) { + if (component instanceof ComponentWithCustomTagName) { + ComponentWithCustomTagName withCustomTagName = (ComponentWithCustomTagName) component; + return withCustomTagName.tagName; + } else { + return super.componentToTag(component, context); + } + } + } + + public static class ComponentWithCustomTagName extends Label { + private String tagName; + } + + @Test + public void testCustomComponentMapperRead() { + currentMapper.set(new CustomComponentMapper()); + + Component component = Design.read(new ByteArrayInputStream( + "<custom-foobar />".getBytes())); + + Assert.assertTrue("<custom-foobar> should resolve " + + ComponentWithCustomTagName.class.getSimpleName(), + component instanceof ComponentWithCustomTagName); + Assert.assertEquals("custom-foobar", + ((ComponentWithCustomTagName) component).tagName); + } + + @Test + public void testCustomComponentMapperWrite() throws IOException { + currentMapper.set(new CustomComponentMapper()); + + ComponentWithCustomTagName component = new ComponentWithCustomTagName(); + component.tagName = "custom-special"; + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + Design.write(component, bos); + String writtenDesign = new String(bos.toByteArray()); + + Assert.assertTrue( + "Written design should contain \"<custom-special\", but instead got " + + writtenDesign, + writtenDesign.contains("<custom-special")); + } + + public void cleanup() { + currentMapper.remove(); + } +} diff --git a/server/tests/src/com/vaadin/tests/server/component/audio/AudioDeclarativeTest.java b/server/tests/src/com/vaadin/tests/server/component/audio/AudioDeclarativeTest.java new file mode 100644 index 0000000000..4390499c4e --- /dev/null +++ b/server/tests/src/com/vaadin/tests/server/component/audio/AudioDeclarativeTest.java @@ -0,0 +1,63 @@ +/* + * Copyright 2000-2014 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.tests.server.component.audio; + +import java.io.File; + +import org.junit.Test; + +import com.vaadin.server.ExternalResource; +import com.vaadin.server.FileResource; +import com.vaadin.tests.design.DeclarativeTestBase; +import com.vaadin.ui.Audio; + +/** + * Tests specs of declarative support for abstract media and its + * implementations. + * + * @since 7.4 + * @author Vaadin Ltd + */ +public class AudioDeclarativeTest extends DeclarativeTestBase<Audio> { + + @Test + public void testEmptyAudio() { + String design = "<v-audio />"; + Audio audio = new Audio(); + testRead(design, audio); + testWrite(design, audio); + } + + @Test + public void testAudioMultipleSources() { + String design = "<v-audio muted='true' show-controls='false'>" + + "some <b>text</b>" // + + "<source href='http://foo.pl' />" + + "<source href='https://bar.pl' />" // + + "<source href='ohai' />" // + + "</v-audio>"; + Audio audio = new Audio(); + audio.setAltText("some <b>text</b>"); + audio.setAutoplay(false); + audio.setMuted(true); + audio.setShowControls(false); + audio.setSources(new ExternalResource("http://foo.pl"), + new ExternalResource("https://bar.pl"), new FileResource( + new File("ohai"))); + testRead(design, audio); + testWrite(design, audio); + } +} diff --git a/server/tests/src/com/vaadin/tests/server/component/audio/VideoDeclarativeTest.java b/server/tests/src/com/vaadin/tests/server/component/audio/VideoDeclarativeTest.java new file mode 100644 index 0000000000..fc0b3d9512 --- /dev/null +++ b/server/tests/src/com/vaadin/tests/server/component/audio/VideoDeclarativeTest.java @@ -0,0 +1,59 @@ +/* + * Copyright 2000-2014 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.tests.server.component.audio; + +import java.io.File; + +import org.junit.Test; + +import com.vaadin.server.ExternalResource; +import com.vaadin.server.FileResource; +import com.vaadin.tests.design.DeclarativeTestBase; +import com.vaadin.ui.Video; + +public class VideoDeclarativeTest extends DeclarativeTestBase<Video> { + + @Test + public void testEmptyVideo() { + String design = "<v-video />"; + Video audio = new Video(); + testRead(design, audio); + testWrite(design, audio); + } + + @Test + public void testVideoMultipleSources() { + String design = "<v-video muted='true' show-controls='false'>" + + "some <b>text</b>" // + + "<source href='http://foo.pl' />" + + "<source href='https://bar.pl' />" // + + "<source href='ohai' />" // + + "<poster href='http://foo.pl/poster' />" // + + "</v-video>"; + Video video = new Video(); + video.setAltText("some <b>text</b>"); + video.setAutoplay(false); + video.setMuted(true); + video.setShowControls(false); + video.setSources(new ExternalResource("http://foo.pl"), + new ExternalResource("https://bar.pl"), new FileResource( + new File("ohai"))); + video.setPoster(new ExternalResource("http://foo.pl/poster")); + testRead(design, video); + testWrite(design, video); + } + +} diff --git a/server/tests/src/com/vaadin/tests/server/component/calendar/CalendarDeclarativeTest.java b/server/tests/src/com/vaadin/tests/server/component/calendar/CalendarDeclarativeTest.java new file mode 100644 index 0000000000..d866878fc7 --- /dev/null +++ b/server/tests/src/com/vaadin/tests/server/component/calendar/CalendarDeclarativeTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2000-2014 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.tests.server.component.calendar; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.TimeZone; + +import org.junit.Test; + +import com.vaadin.tests.design.DeclarativeTestBase; +import com.vaadin.ui.Calendar; +import com.vaadin.ui.Calendar.TimeFormat; + +public class CalendarDeclarativeTest extends DeclarativeTestBase<Calendar> { + + @Test + public void testEmpty() { + verifyDeclarativeDesign("<v-calendar></v-calendar>", new Calendar()); + } + + @Test + public void testCalendarAllFeatures() throws ParseException { + String design = "<v-calendar start-date='2014-11-17' end-date='2014-11-23' " + + "first-visible-day-of-week=2 last-visible-day-of-week=5 " + + "time-zone='EST' time-format='12h' first-visible-hour-of-day=8 " + + "last-visible-hour-of-day=18 weekly-caption-format='mmm MM/dd' />"; + + DateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + Calendar calendar = new Calendar(); + calendar.setStartDate(format.parse("2014-11-17")); + calendar.setEndDate(format.parse("2014-11-23")); + calendar.setFirstVisibleDayOfWeek(2); + calendar.setLastVisibleDayOfWeek(5); + calendar.setTimeZone(TimeZone.getTimeZone("EST")); + calendar.setTimeFormat(TimeFormat.Format12H); + calendar.setFirstVisibleHourOfDay(8); + calendar.setLastVisibleHourOfDay(18); + calendar.setWeeklyCaptionFormat("mmm MM/dd"); + verifyDeclarativeDesign(design, calendar); + } + + protected void verifyDeclarativeDesign(String design, Calendar expected) { + testRead(design, expected); + testWrite(design, expected); + } +} diff --git a/server/tests/src/com/vaadin/tests/server/component/customlayout/CustomLayoutDeclarativeTest.java b/server/tests/src/com/vaadin/tests/server/component/customlayout/CustomLayoutDeclarativeTest.java new file mode 100644 index 0000000000..44261a61dc --- /dev/null +++ b/server/tests/src/com/vaadin/tests/server/component/customlayout/CustomLayoutDeclarativeTest.java @@ -0,0 +1,96 @@ +/* + * Copyright 2000-2014 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.tests.server.component.customlayout; + +import org.junit.Test; + +import com.vaadin.tests.design.DeclarativeTestBase; +import com.vaadin.ui.Button; +import com.vaadin.ui.CustomLayout; +import com.vaadin.ui.Label; + +/** + * Tests declarative support for {@link CustomLayout}. + * + * @since + * @author Vaadin Ltd + */ +public class CustomLayoutDeclarativeTest extends + DeclarativeTestBase<CustomLayout> { + + @Test + public void testEmpty() { + String design = "<v-custom-layout>"; + CustomLayout expected = new CustomLayout(); + test(design, expected); + } + + @Test + public void testWithChildren() { + String design = "<v-custom-layout>" + // + "<v-button plain-text :location='b'></v-button>" + // + "<v-label plain-text :location='l'></v-label>" + // + "</v-custom-layout>"; + + CustomLayout expected = new CustomLayout(); + expected.addComponent(new Button(), "b"); + expected.addComponent(new Label(), "l"); + + test(design, expected); + } + + @Test + public void testWithOneChild() { + String design = "<v-custom-layout><v-button plain-text></v-button></v-custom-layout>"; + + CustomLayout expected = new CustomLayout(); + expected.addComponent(new Button()); + + test(design, expected); + } + + @Test + public void testWithTemplate() { + String design = "<v-custom-layout template-name='template.html'></v-custom-layout>"; + CustomLayout expected = new CustomLayout("template.html"); + test(design, expected); + } + + @Test + public void testWithDuplicateLocations() { + String design = "<v-custom-layout>" + // + "<v-button plain-text :location='foo'></v-button>" + // + "<v-label plain-text :location='foo'></v-label>" + // + "</v-custom-layout>"; + + CustomLayout expected = new CustomLayout(); + expected.addComponent(new Button(), "foo"); + expected.addComponent(new Label(), "foo"); + + testRead(design, expected); + + String written = "<v-custom-layout>" + // + "<v-label plain-text :location='foo'></v-label>" + // + "</v-custom-layout>"; + + testWrite(written, expected); + } + + protected void test(String design, CustomLayout expected) { + testRead(design, expected); + testWrite(design, expected); + } +} diff --git a/server/tests/src/com/vaadin/tests/server/component/slider/SliderDeclarativeTest.java b/server/tests/src/com/vaadin/tests/server/component/slider/SliderDeclarativeTest.java new file mode 100644 index 0000000000..9ef28afb82 --- /dev/null +++ b/server/tests/src/com/vaadin/tests/server/component/slider/SliderDeclarativeTest.java @@ -0,0 +1,66 @@ +/* + * Copyright 2000-2014 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.tests.server.component.slider; + +import org.junit.Test; + +import com.vaadin.shared.ui.slider.SliderOrientation; +import com.vaadin.tests.design.DeclarativeTestBase; +import com.vaadin.ui.Slider; + +/** + * Tests declarative support for implementations of {@link Slider}. + * + * @since + * @author Vaadin Ltd + */ +public class SliderDeclarativeTest extends DeclarativeTestBase<Slider> { + + @Test + public void testDefault() { + String design = "<v-slider>"; + + Slider expected = new Slider(); + + testRead(design, expected); + testWrite(design, expected); + } + + @Test + public void testHorizontal() { + String design = "<v-slider min=10 max=20 resolution=1 value=12.3>"; + + Slider expected = new Slider(); + expected.setMin(10.0); + expected.setMax(20.0); + expected.setResolution(1); + expected.setValue(12.3); + + testRead(design, expected); + testWrite(design, expected); + } + + @Test + public void testVertical() { + String design = "<v-slider vertical>"; + + Slider expected = new Slider(); + expected.setOrientation(SliderOrientation.VERTICAL); + + testRead(design, expected); + testWrite(design, expected); + } +} diff --git a/server/tests/src/com/vaadin/tests/util/MockDeploymentConfiguration.java b/server/tests/src/com/vaadin/tests/util/MockDeploymentConfiguration.java index 175dcb2b94..ddee23a9ec 100644 --- a/server/tests/src/com/vaadin/tests/util/MockDeploymentConfiguration.java +++ b/server/tests/src/com/vaadin/tests/util/MockDeploymentConfiguration.java @@ -22,7 +22,6 @@ public class MockDeploymentConfiguration extends private LegacyProperyToStringMode legacyPropertyToStringMode = LegacyProperyToStringMode.DISABLED; private boolean syncIdCheckEnabled = true; private boolean sendUrlsAsParameters = true; - private String pushPath = "PUSH"; @Override public boolean isProductionMode() { @@ -126,9 +125,4 @@ public class MockDeploymentConfiguration extends return sendUrlsAsParameters; } - @Override - public String getPushPath() { - return pushPath; - } - } diff --git a/server/tests/src/com/vaadin/ui/SplitPositionChangeListenerTest.java b/server/tests/src/com/vaadin/ui/SplitPositionChangeListenerTest.java new file mode 100644 index 0000000000..02dc412cd9 --- /dev/null +++ b/server/tests/src/com/vaadin/ui/SplitPositionChangeListenerTest.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2014 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.ui; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import org.junit.Test; + +import com.vaadin.server.Sizeable.Unit; +import com.vaadin.ui.AbstractSplitPanel.SplitPositionChangeEvent; +import com.vaadin.ui.AbstractSplitPanel.SplitPositionChangeListener; + +/** + * Test for {@link SplitPositionChangeListener} + * + * @author Vaadin Ltd + */ +public class SplitPositionChangeListenerTest { + + @Test + public void testSplitPositionListenerIsTriggered() throws Exception { + final HorizontalSplitPanel splitPanel = new HorizontalSplitPanel(); + SplitPositionChangeListener splitPositionChangeListener = mock(SplitPositionChangeListener.class); + splitPanel.addSplitPositionChangeListener(splitPositionChangeListener); + splitPanel.setSplitPosition(50, Unit.PERCENTAGE); + verify(splitPositionChangeListener).onSplitPositionChanged( + any(SplitPositionChangeEvent.class)); + } +} |