summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorMatti Hosio <mhosio@vaadin.com>2014-12-11 16:22:41 +0200
committerMatti Hosio <mhosio@vaadin.com>2014-12-12 10:27:18 +0200
commitccb76e6608adbdf652748899779a458cd795ac3a (patch)
tree4aa5dd26c73441ba61cae2d9b595c535b8597b8a /server
parent64a029571955ee52b0c416b597fb718bc0a66c46 (diff)
downloadvaadin-framework-ccb76e6608adbdf652748899779a458cd795ac3a.tar.gz
vaadin-framework-ccb76e6608adbdf652748899779a458cd795ac3a.zip
Declarative support for TabSheet and Accordion (#7749)
Change-Id: Iee4689814f08ddbb852cfb3e51c9873fbe42d901
Diffstat (limited to 'server')
-rw-r--r--server/src/com/vaadin/ui/TabSheet.java167
-rw-r--r--server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java4
-rw-r--r--server/tests/src/com/vaadin/tests/layoutparser/all-components.html31
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/abstractcomponent/TestSynchronizeFromDesign.java5
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/tabsheet/TestSynchronizeFromDesign.java137
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/tabsheet/TestSynchronizeToDesign.java109
6 files changed, 450 insertions, 3 deletions
diff --git a/server/src/com/vaadin/ui/TabSheet.java b/server/src/com/vaadin/ui/TabSheet.java
index d3410464a2..dd9beb07f0 100644
--- a/server/src/com/vaadin/ui/TabSheet.java
+++ b/server/src/com/vaadin/ui/TabSheet.java
@@ -19,11 +19,15 @@ package com.vaadin.ui;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import org.jsoup.nodes.Attributes;
+import org.jsoup.nodes.Element;
+
import com.vaadin.event.FieldEvents.BlurEvent;
import com.vaadin.event.FieldEvents.BlurListener;
import com.vaadin.event.FieldEvents.BlurNotifier;
@@ -40,6 +44,9 @@ import com.vaadin.shared.ui.tabsheet.TabsheetClientRpc;
import com.vaadin.shared.ui.tabsheet.TabsheetServerRpc;
import com.vaadin.shared.ui.tabsheet.TabsheetState;
import com.vaadin.ui.Component.Focusable;
+import com.vaadin.ui.declarative.DesignAttributeHandler;
+import com.vaadin.ui.declarative.DesignContext;
+import com.vaadin.ui.declarative.DesignException;
import com.vaadin.ui.themes.Reindeer;
import com.vaadin.ui.themes.Runo;
@@ -1447,4 +1454,164 @@ public class TabSheet extends AbstractComponentContainer implements Focusable,
protected TabsheetState getState() {
return (TabsheetState) super.getState();
}
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.ui.AbstractComponent#synchronizeFromDesign(org.jsoup.nodes
+ * .Element, com.vaadin.ui.declarative.DesignContext)
+ */
+ @Override
+ public void synchronizeFromDesign(Element design,
+ DesignContext designContext) {
+ super.synchronizeFromDesign(design, designContext);
+ Attributes attr = design.attributes();
+ TabSheet def = designContext.getDefaultInstance(this.getClass());
+ // handle tab index
+ int tabIndex = DesignAttributeHandler.readAttribute("tabindex", attr,
+ def.getTabIndex(), Integer.class);
+ setTabIndex(tabIndex);
+ // clear old tabs
+ removeAllComponents();
+ // create new tabs
+ for (Element tab : design.children()) {
+ if (!tab.tagName().equals("tab")) {
+ throw new DesignException("Invalid tag name for tabsheet tab "
+ + tab.tagName());
+ }
+ readTabFromDesign(tab, designContext);
+ }
+ }
+
+ /**
+ * Reads the given tab element from design
+ *
+ * @since 7.4
+ *
+ * @param tabElement
+ * the element to be read
+ * @param designContext
+ * the design context
+ */
+ private void readTabFromDesign(Element tabElement,
+ DesignContext designContext) {
+ Attributes attr = tabElement.attributes();
+ if (tabElement.children().size() != 1) {
+ throw new DesignException(
+ "A tab must have exactly one child element");
+ }
+ // create the component that is in tab content
+ Element content = tabElement.child(0);
+ DesignSynchronizable child = designContext.createChild(content);
+ Tab tab = this.addTab(child);
+ tab.setVisible(DesignAttributeHandler.readAttribute("visible", attr,
+ tab.isVisible(), Boolean.class));
+ tab.setClosable(DesignAttributeHandler.readAttribute("closable", attr,
+ tab.isClosable(), Boolean.class));
+ tab.setCaption(DesignAttributeHandler.readAttribute("caption", attr,
+ tab.getCaption(), String.class));
+ tab.setEnabled(DesignAttributeHandler.readAttribute("enabled", attr,
+ tab.isEnabled(), Boolean.class));
+ tab.setIcon(DesignAttributeHandler.readAttribute("icon", attr,
+ tab.getIcon(), Resource.class));
+ tab.setIconAlternateText(DesignAttributeHandler.readAttribute(
+ "icon-alt", attr, tab.getIconAlternateText(), String.class));
+ tab.setDescription(DesignAttributeHandler.readAttribute("description",
+ attr, tab.getDescription(), String.class));
+ tab.setStyleName(DesignAttributeHandler.readAttribute("style-name",
+ attr, tab.getStyleName(), String.class));
+ tab.setId(DesignAttributeHandler.readAttribute("id", attr, tab.getId(),
+ String.class));
+ boolean selected = DesignAttributeHandler.readAttribute("selected",
+ attr, false, Boolean.class);
+ if (selected) {
+ this.setSelectedTab(tab.getComponent());
+ }
+ }
+
+ /**
+ * Writes the given tab to design
+ *
+ * @since 7.4
+ * @param design
+ * the design node for tabsheet
+ * @param designContext
+ * the design context
+ * @param tab
+ * the tab to be written
+ */
+ private void writeTabToDesign(Element design, DesignContext designContext,
+ Tab tab) {
+ // get default tab instance
+ Tab def = new TabSheetTabImpl(null, null, null);
+ // create element for tab
+ Element tabElement = design.appendElement("tab");
+ // add tab content
+ tabElement.appendChild(designContext
+ .createNode((DesignSynchronizable) tab.getComponent()));
+ Attributes attr = tabElement.attributes();
+ // write attributes
+ DesignAttributeHandler.writeAttribute("visible", attr, tab.isVisible(),
+ def.isVisible(), Boolean.class);
+ DesignAttributeHandler.writeAttribute("closable", attr,
+ tab.isClosable(), def.isClosable(), Boolean.class);
+ DesignAttributeHandler.writeAttribute("caption", attr,
+ tab.getCaption(), def.getCaption(), String.class);
+ DesignAttributeHandler.writeAttribute("enabled", attr, tab.isEnabled(),
+ def.isEnabled(), Boolean.class);
+ DesignAttributeHandler.writeAttribute("icon", attr, tab.getIcon(),
+ def.getIcon(), Resource.class);
+ DesignAttributeHandler.writeAttribute("icon-alt", attr,
+ tab.getIconAlternateText(), def.getIconAlternateText(),
+ String.class);
+ DesignAttributeHandler.writeAttribute("description", attr,
+ tab.getDescription(), def.getDescription(), String.class);
+ DesignAttributeHandler.writeAttribute("style-name", attr,
+ tab.getStyleName(), def.getStyleName(), String.class);
+ DesignAttributeHandler.writeAttribute("id", attr, tab.getId(),
+ def.getId(), String.class);
+ if (getSelectedTab() != null
+ && getSelectedTab().equals(tab.getComponent())) {
+ // use write attribute to get consistent handling for boolean
+ DesignAttributeHandler.writeAttribute("selected", attr, true,
+ false, boolean.class);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.ui.AbstractComponent#getCustomAttributes()
+ */
+ @Override
+ protected Collection<String> getCustomAttributes() {
+ Collection<String> attributes = super.getCustomAttributes();
+ attributes.add("tabindex");
+ // no need to list tab attributes since they are considered internal
+ return attributes;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.ui.AbstractComponent#synchronizeToDesign(org.jsoup.nodes.Element
+ * , com.vaadin.ui.declarative.DesignContext)
+ */
+ @Override
+ public void synchronizeToDesign(Element design, DesignContext designContext) {
+ super.synchronizeToDesign(design, designContext);
+ TabSheet def = designContext.getDefaultInstance(this.getClass());
+ Attributes attr = design.attributes();
+ // handle tab index
+ DesignAttributeHandler.writeAttribute("tabindex", attr, getTabIndex(),
+ def.getTabIndex(), Integer.class);
+ // write tabs
+ for (Component component : this) {
+ Tab tab = this.getTab(component);
+ writeTabToDesign(design, designContext, tab);
+ }
+ }
+
}
diff --git a/server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java b/server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java
index 2992771521..0c370b8da7 100644
--- a/server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java
+++ b/server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java
@@ -295,7 +295,7 @@ public class DesignAttributeHandler implements Serializable {
+ inputType.getName() + " not supported");
}
if (!SharedUtil.equals(value, defaultValue)) {
- String attributeValue = toAttributeValue(value.getClass(), value);
+ String attributeValue = toAttributeValue(inputType, value);
attributes.put(attribute, attributeValue);
}
}
@@ -464,7 +464,7 @@ public class DesignAttributeHandler implements Serializable {
*/
private static Resource parseResource(String value) {
if (value.startsWith("http://")) {
- return new ExternalResource("value");
+ return new ExternalResource(value);
} else if (value.startsWith("theme://")) {
return new ThemeResource(value.substring(8));
} else if (value.startsWith("font://")) {
diff --git a/server/tests/src/com/vaadin/tests/layoutparser/all-components.html b/server/tests/src/com/vaadin/tests/layoutparser/all-components.html
index f633b06cb3..3fdae56e76 100644
--- a/server/tests/src/com/vaadin/tests/layoutparser/all-components.html
+++ b/server/tests/src/com/vaadin/tests/layoutparser/all-components.html
@@ -47,6 +47,37 @@
<!-- text area -->
<v-text-area rows=5 wordwrap=false >test value</v-text-area>
+ <!-- tabsheet -->
+ <v-tab-sheet tabindex=5>
+ <tab visible=false closable caption="My first tab">
+ <v-vertical-layout>
+ <v-text-field/>
+ </v-vertical-layout>
+ </tab>
+ <tab enabled=false caption="Disabled second tab">
+ <v-button>In disabled tab - can’t be shown by default</v-button>
+ </tab>
+ <tab icon="theme://../runo/icons/16/ok.png" icon-alt="Ok png from Runo - very helpful" description="Click to show a text field" style-name="red" id="uniqueDomId">
+ <v-text-field input-prompt="Icon only in tab" />
+ </tab>
+ </v-tab-sheet>
+
+ <!-- accordion -->
+ <v-accordion tabindex=5>
+ <tab visible=false closable caption="My first tab">
+ <v-vertical-layout>
+ <v-text-field/>
+ </v-vertical-layout>
+ </tab>
+ <tab enabled=false caption="Disabled second tab">
+ <v-button>In disabled tab - can’t be shown by default</v-button>
+ </tab>
+ <tab icon="theme://../runo/icons/16/ok.png" icon-alt="Ok png from Runo - very helpful" description="Click to show a text field" style-name="red" id="uniqueDomId">
+ <v-text-field input-prompt="Icon only in tab" />
+ </tab>
+ </v-accordion>
+
+
</v-vertical-layout>
</body>
</html> \ No newline at end of file
diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractcomponent/TestSynchronizeFromDesign.java b/server/tests/src/com/vaadin/tests/server/component/abstractcomponent/TestSynchronizeFromDesign.java
index 5153d92706..df6fb47bf2 100644
--- a/server/tests/src/com/vaadin/tests/server/component/abstractcomponent/TestSynchronizeFromDesign.java
+++ b/server/tests/src/com/vaadin/tests/server/component/abstractcomponent/TestSynchronizeFromDesign.java
@@ -81,6 +81,8 @@ public class TestSynchronizeFromDesign extends TestCase {
component.synchronizeFromDesign(design, ctx);
assertTrue("Incorrect resource type returned", component.getIcon()
.getClass().isAssignableFrom(ExternalResource.class));
+ assertEquals("http://example.com/example.gif",
+ ((ExternalResource) component.getIcon()).getURL());
}
public void testSynchronizeThemeIcon() {
@@ -115,7 +117,8 @@ public class TestSynchronizeFromDesign extends TestCase {
component.synchronizeFromDesign(design, ctx);
assertEquals(false, component.isImmediate());
assertEquals(Boolean.FALSE, getExplicitImmediate(component));
- // Synchronize with a design having immediate = "" - should correspond to
+ // Synchronize with a design having immediate = "" - should correspond
+ // to
// true.
design = createDesign("immediate", "");
component.synchronizeFromDesign(design, ctx);
diff --git a/server/tests/src/com/vaadin/tests/server/component/tabsheet/TestSynchronizeFromDesign.java b/server/tests/src/com/vaadin/tests/server/component/tabsheet/TestSynchronizeFromDesign.java
new file mode 100644
index 0000000000..4c0a2863f0
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/tabsheet/TestSynchronizeFromDesign.java
@@ -0,0 +1,137 @@
+/*
+ * 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.tabsheet;
+
+import junit.framework.TestCase;
+
+import org.jsoup.nodes.Attributes;
+import org.jsoup.nodes.Element;
+import org.jsoup.parser.Tag;
+
+import com.vaadin.server.ExternalResource;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.TabSheet;
+import com.vaadin.ui.TabSheet.Tab;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.declarative.DesignContext;
+
+/**
+ * Test case from reading TabSheet from design
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class TestSynchronizeFromDesign extends TestCase {
+
+ private TabSheet sheet;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ sheet = createTabSheet();
+ }
+
+ public void testChildCount() {
+ assertEquals(1, sheet.getComponentCount());
+ }
+
+ public void testTabIndex() {
+ assertEquals(5, sheet.getTabIndex());
+ }
+
+ public void testTabAttributes() {
+ Tab tab = sheet.getTab(0);
+ assertEquals("test-caption", tab.getCaption());
+ assertEquals(false, tab.isVisible());
+ assertEquals(false, tab.isClosable());
+ assertEquals(false, tab.isEnabled());
+ assertEquals("http://www.vaadin.com/test.png",
+ ((ExternalResource) tab.getIcon()).getURL());
+ assertEquals("OK", tab.getIconAlternateText());
+ assertEquals("test-desc", tab.getDescription());
+ assertEquals("test-style", tab.getStyleName());
+ assertEquals("test-id", tab.getId());
+ }
+
+ public void testSelectedComponent() {
+ TabSheet tabSheet = new TabSheet();
+ tabSheet.synchronizeFromDesign(createFirstTabSelectedDesign(),
+ new DesignContext());
+ assertEquals(tabSheet.getTab(0).getComponent(),
+ tabSheet.getSelectedTab());
+ }
+
+ public void testTabContent() {
+ assertTrue("The child for the tabsheet should be textfield", sheet
+ .getTab(0).getComponent() instanceof TextField);
+ }
+
+ private TabSheet createTabSheet() {
+ TabSheet tabSheet = new TabSheet();
+ // add some tabs that should be cleared on sync
+ tabSheet.addComponent(new Label("tab1"));
+ tabSheet.addComponent(new Label("tab2"));
+ DesignContext ctx = new DesignContext();
+ Element design = createDesign();
+ tabSheet.synchronizeFromDesign(design, ctx);
+ return tabSheet;
+ }
+
+ private Element createDesign() {
+ // create root design
+ Attributes rootAttributes = new Attributes();
+ rootAttributes.put("tabindex", "5");
+ Element node = new Element(Tag.valueOf("v-tab-sheet"), "",
+ rootAttributes);
+ // create tab design
+ Attributes tabAttributes = new Attributes();
+ tabAttributes.put("caption", "test-caption");
+ tabAttributes.put("visible", "false");
+ tabAttributes.put("closable", "false");
+ tabAttributes.put("enabled", "false");
+ tabAttributes.put("icon", "http://www.vaadin.com/test.png");
+ tabAttributes.put("icon-alt", "OK");
+ tabAttributes.put("description", "test-desc");
+ tabAttributes.put("style-name", "test-style");
+ tabAttributes.put("id", "test-id");
+ Element tab = new Element(Tag.valueOf("tab"), "", tabAttributes);
+ // add child component to tab
+ tab.appendChild(new Element(Tag.valueOf("v-text-field"), "",
+ new Attributes()));
+ // add tab to root design
+ node.appendChild(tab);
+ return node;
+ }
+
+ private Element createFirstTabSelectedDesign() {
+ // create root design
+ Attributes rootAttributes = new Attributes();
+ Element node = new Element(Tag.valueOf("v-tab-sheet"), "",
+ rootAttributes);
+ // create tab design
+ Attributes tabAttributes = new Attributes();
+ tabAttributes.put("selected", "");
+ tabAttributes.put("caption", "test-caption");
+ Element tab = new Element(Tag.valueOf("tab"), "", tabAttributes);
+ // add child component to tab
+ tab.appendChild(new Element(Tag.valueOf("v-text-field"), "",
+ new Attributes()));
+ // add tab to root design
+ node.appendChild(tab);
+ return node;
+
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/tabsheet/TestSynchronizeToDesign.java b/server/tests/src/com/vaadin/tests/server/component/tabsheet/TestSynchronizeToDesign.java
new file mode 100644
index 0000000000..c33a1da4d7
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/tabsheet/TestSynchronizeToDesign.java
@@ -0,0 +1,109 @@
+/*
+ * 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.tabsheet;
+
+import junit.framework.TestCase;
+
+import org.jsoup.nodes.Attributes;
+import org.jsoup.nodes.Element;
+import org.jsoup.parser.Tag;
+
+import com.vaadin.server.ExternalResource;
+import com.vaadin.ui.TabSheet;
+import com.vaadin.ui.TabSheet.Tab;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.declarative.DesignContext;
+
+/**
+ * Test case for writing TabSheet to design
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class TestSynchronizeToDesign extends TestCase {
+
+ private TabSheet sheet;
+ private Element design;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ sheet = createTabSheet();
+ design = createDesign();
+ sheet.synchronizeToDesign(design, createDesignContext());
+ }
+
+ public void testOnlyOneTab() {
+ assertEquals("There should be only one child", 1, design.children()
+ .size());
+ }
+
+ public void testAttributes() {
+ Element tabDesign = design.child(0);
+ assertEquals("5", design.attr("tabindex"));
+ assertEquals("test-caption", tabDesign.attr("caption"));
+ assertEquals("false", tabDesign.attr("visible"));
+ assertTrue(tabDesign.hasAttr("closable"));
+ assertTrue(tabDesign.attr("closable").equals("true")
+ || tabDesign.attr("closable").equals(""));
+ assertEquals("false", tabDesign.attr("enabled"));
+ assertEquals("http://www.vaadin.com/test.png", tabDesign.attr("icon"));
+ assertEquals("OK", tabDesign.attr("icon-alt"));
+ assertEquals("test-desc", tabDesign.attr("description"));
+ assertEquals("test-style", tabDesign.attr("style-name"));
+ assertEquals("test-id", tabDesign.attr("id"));
+ }
+
+ public void testContent() {
+ Element tabDesign = design.child(0);
+ Element content = tabDesign.child(0);
+ assertEquals("Tab must have only one child", 1, tabDesign.children()
+ .size());
+ assertEquals("v-text-field", content.tagName());
+ }
+
+ private Element createDesign() {
+ // make sure that the design node has old content that should be removed
+ Element node = new Element(Tag.valueOf("v-tab-sheet"), "",
+ new Attributes());
+ node.appendChild(new Element(Tag.valueOf("tab"), "", new Attributes()));
+ node.appendChild(new Element(Tag.valueOf("tab"), "", new Attributes()));
+ node.appendChild(new Element(Tag.valueOf("tab"), "", new Attributes()));
+ return node;
+ }
+
+ private DesignContext createDesignContext() {
+ return new DesignContext();
+ }
+
+ private TabSheet createTabSheet() {
+ TabSheet sheet = new TabSheet();
+ sheet.setTabIndex(5);
+ sheet.addTab(new TextField());
+ Tab tab = sheet.getTab(0);
+ tab.setCaption("test-caption");
+ tab.setVisible(false);
+ tab.setClosable(true);
+ tab.setEnabled(false);
+ tab.setIcon(new ExternalResource("http://www.vaadin.com/test.png"));
+ tab.setIconAlternateText("OK");
+ tab.setDescription("test-desc");
+ tab.setStyleName("test-style");
+ tab.setId("test-id");
+ return sheet;
+ }
+
+}