diff options
author | Mika Murtojarvi <mika@vaadin.com> | 2014-12-10 11:24:58 +0200 |
---|---|---|
committer | Artur Signell <artur@vaadin.com> | 2014-12-12 10:53:36 +0000 |
commit | e09ba97f64c19d5efcd2d99b7ebf9b7dfef144d7 (patch) | |
tree | 7cc1e42e9d46d1397e5199a33b4d7b6ba97a9b25 | |
parent | 7a73e9bd3bf469e4e16acfa0d7d2eb5a496de47a (diff) | |
download | vaadin-framework-e09ba97f64c19d5efcd2d99b7ebf9b7dfef144d7.tar.gz vaadin-framework-e09ba97f64c19d5efcd2d99b7ebf9b7dfef144d7.zip |
Declarative: add support for Panel (#7749).
Change-Id: I4e6414e2fd4941215a788f518862ce58f38f005f
5 files changed, 260 insertions, 2 deletions
diff --git a/server/src/com/vaadin/ui/AbstractSingleComponentContainer.java b/server/src/com/vaadin/ui/AbstractSingleComponentContainer.java index e7b5205f2d..c6e78447d5 100644 --- a/server/src/com/vaadin/ui/AbstractSingleComponentContainer.java +++ b/server/src/com/vaadin/ui/AbstractSingleComponentContainer.java @@ -18,9 +18,13 @@ package com.vaadin.ui; import java.util.Collections; import java.util.Iterator; +import org.jsoup.nodes.Element; + import com.vaadin.server.ComponentSizeValidator; import com.vaadin.server.VaadinService; import com.vaadin.server.VaadinSession; +import com.vaadin.ui.declarative.DesignContext; +import com.vaadin.ui.declarative.DesignException; /** * Abstract base class for component containers that have only one child @@ -274,4 +278,51 @@ public abstract class AbstractSingleComponentContainer extends repaintChangedChildTree(dirtyChild, childrenMayBecomeUndefined, true); } -} + /* + * (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) { + // process default attributes + super.synchronizeFromDesign(design, designContext); + // handle child element, checking that the design specifies at most one + // child + int childCount = design.children().size(); + if (childCount > 1) { + throw new DesignException("The container of type " + + getClass().toString() + + " can have only one child component."); + } else if (childCount == 1) { + Element childElement = design.children().get(0); + DesignSynchronizable newChild = designContext + .createChild(childElement); + setContent(newChild); + } else { + setContent(null); + } + } + + /* + * (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) { + // synchronize default attributes (also clears children and attributes) + super.synchronizeToDesign(design, designContext); + // handle child component + DesignSynchronizable child = (DesignSynchronizable) getContent(); + if (child != null) { + Element childNode = designContext.createNode(child); + design.appendChild(childNode); + } + } +}
\ No newline at end of file diff --git a/server/src/com/vaadin/ui/Panel.java b/server/src/com/vaadin/ui/Panel.java index 9b1d8fd5fa..46ad801a6d 100644 --- a/server/src/com/vaadin/ui/Panel.java +++ b/server/src/com/vaadin/ui/Panel.java @@ -16,8 +16,11 @@ package com.vaadin.ui; +import java.util.Collection; import java.util.Map; +import org.jsoup.nodes.Element; + import com.vaadin.event.Action; import com.vaadin.event.Action.Handler; import com.vaadin.event.ActionManager; @@ -31,6 +34,8 @@ import com.vaadin.shared.MouseEventDetails; import com.vaadin.shared.ui.panel.PanelServerRpc; import com.vaadin.shared.ui.panel.PanelState; import com.vaadin.ui.Component.Focusable; +import com.vaadin.ui.declarative.DesignAttributeHandler; +import com.vaadin.ui.declarative.DesignContext; /** * Panel - a simple single component container. @@ -339,4 +344,32 @@ public class Panel extends AbstractSingleComponentContainer implements return (PanelState) super.getState(markAsDirty); } + @Override + public void synchronizeFromDesign(Element design, + DesignContext designContext) { + super.synchronizeFromDesign(design, designContext); + // handle tabindex + Panel def = designContext.getDefaultInstance(this.getClass()); + int tabIndex = DesignAttributeHandler.readAttribute("tabindex", + design.attributes(), def.getTabIndex(), Integer.class); + setTabIndex(tabIndex); + } + + @Override + protected Collection<String> getCustomAttributes() { + Collection<String> attributes = super.getCustomAttributes(); + attributes.add("tabindex"); + attributes.add("tab-index"); + return attributes; + } + + @Override + public void synchronizeToDesign(Element design, DesignContext designContext) { + super.synchronizeToDesign(design, designContext); + // handle tabindex + Panel def = designContext.getDefaultInstance(this.getClass()); + DesignAttributeHandler.writeAttribute("tabindex", design.attributes(), + getTabIndex(), def.getTabIndex(), Integer.class); + } + } 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 94d8e6a965..9b05f29f9c 100644 --- a/server/tests/src/com/vaadin/tests/layoutparser/all-components.html +++ b/server/tests/src/com/vaadin/tests/layoutparser/all-components.html @@ -38,6 +38,11 @@ <v-table size-full /> </v-css-layout> + <!-- panel --> + <v-panel caption=”Hello world” tabindex=2 scroll-left="10" scroll-top="10"> + <v-table size-full /> + </v-panel> + <!-- abstract field --> <v-text-field buffered validation-visible=false invalid-committed invalid-allowed=false required required-error="This is a required field" conversion-error="Input {0} cannot be parsed" tabindex=3 readonly /> <!-- abstract text field, text field --> @@ -84,4 +89,4 @@ </v-vertical-layout> </body> -</html>
\ No newline at end of file +</html> diff --git a/server/tests/src/com/vaadin/tests/server/component/panel/TestSynchronizeFromDesign.java b/server/tests/src/com/vaadin/tests/server/component/panel/TestSynchronizeFromDesign.java new file mode 100644 index 0000000000..bc4a597a4e --- /dev/null +++ b/server/tests/src/com/vaadin/tests/server/component/panel/TestSynchronizeFromDesign.java @@ -0,0 +1,98 @@ +/* + * 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.panel; + +import junit.framework.TestCase; + +import org.jsoup.nodes.Element; +import org.jsoup.parser.Tag; + +import com.vaadin.ui.Panel; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.declarative.DesignContext; +import com.vaadin.ui.declarative.DesignException; + +/** + * Test case for reading the attributes of a Panel from design. + * + * @author Vaadin Ltd + */ +public class TestSynchronizeFromDesign extends TestCase { + DesignContext ctx; + + @Override + public void setUp() { + ctx = new DesignContext(); + } + + public void testAttributes() { + Element design = createDesign(); + Panel panel = new Panel(); + panel.synchronizeFromDesign(design, ctx); + assertEquals("A panel", panel.getCaption()); + assertEquals(2, panel.getTabIndex()); + assertEquals(10, panel.getScrollLeft()); + assertEquals(20, panel.getScrollTop()); + assertEquals(200f, panel.getWidth()); + assertEquals(150f, panel.getHeight()); + } + + public void testChild() { + Element design = createDesign(); + Panel panel = new Panel(); + panel.synchronizeFromDesign(design, ctx); + VerticalLayout vLayout = (VerticalLayout) panel.getContent(); + assertEquals(300f, vLayout.getWidth()); + assertEquals(400f, vLayout.getHeight()); + } + + public void testWithMoreThanOneChild() { + Element design = createDesign(); + // Add a new child to the panel element. An exception should be + // thrown when parsing the design. + Element newChild = new Element(Tag.valueOf("v-horizontal-layout"), ""); + design.appendChild(newChild); + Panel panel = new Panel(); + try { + panel.synchronizeFromDesign(design, ctx); + fail("Parsing a design containing a Panel with more than one child component should have failed."); + } catch (DesignException e) { + // Nothing needs to be done, this is the expected case. + } + } + + /* + * Creates an html document that can be parsed into a valid component + * hierarchy. + */ + private Element createDesign() { + // Create a node defining a Panel + Element panelElement = new Element(Tag.valueOf("v-panel"), ""); + panelElement.attr("caption", "A panel"); + panelElement.attr("tabindex", "2"); + panelElement.attr("scroll-left", "10"); + panelElement.attr("scroll-top", "20"); + panelElement.attr("width", "200px"); + panelElement.attr("height", "150px"); + // Add some content to the panel + Element layoutElement = new Element(Tag.valueOf("v-vertical-layout"), + ""); + layoutElement.attr("width", "300px"); + layoutElement.attr("height", "400px"); + panelElement.appendChild(layoutElement); + return panelElement; + } +}
\ No newline at end of file diff --git a/server/tests/src/com/vaadin/tests/server/component/panel/TestSynchronizeToDesign.java b/server/tests/src/com/vaadin/tests/server/component/panel/TestSynchronizeToDesign.java new file mode 100644 index 0000000000..56ff155612 --- /dev/null +++ b/server/tests/src/com/vaadin/tests/server/component/panel/TestSynchronizeToDesign.java @@ -0,0 +1,71 @@ +/* + * 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.panel; + +import junit.framework.TestCase; + +import org.jsoup.nodes.Element; +import org.jsoup.parser.Tag; + +import com.vaadin.ui.Panel; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.declarative.DesignContext; + +/** + * Test case for writing the attributes and the child element of a Panel to a + * design. + * + * @author Vaadin Ltd + */ +public class TestSynchronizeToDesign extends TestCase { + Element panelElement; + + @Override + public void setUp() { + // create a component hierarchy + Panel panel = new Panel("A panel"); + panel.setId("panelId"); + panel.setHeight("250px"); + panel.setScrollTop(50); + panel.setTabIndex(4); + VerticalLayout vLayout = new VerticalLayout(); + vLayout.setWidth("500px"); + panel.setContent(vLayout); + // synchronize to design + DesignContext ctx = new DesignContext(); + panelElement = new Element(Tag.valueOf("div"), ""); + panel.synchronizeToDesign(panelElement, ctx); + } + + public void testAttributes() { + // should have caption, id, height, scroll top and tab index + assertEquals(5, panelElement.attributes().size()); + // check the values of the attributes + assertEquals("A panel", panelElement.attr("caption")); + assertEquals("panelId", panelElement.attr("id")); + assertEquals("250px", panelElement.attr("height")); + assertEquals("50", panelElement.attr("scroll-top")); + assertEquals("4", panelElement.attr("tabindex")); + } + + public void testChild() { + // the panel element should have exactly one child, a v-vertical-layout + assertEquals(1, panelElement.childNodes().size()); + Element vLayoutElement = panelElement.child(0); + assertEquals("v-vertical-layout", vLayoutElement.nodeName()); + assertEquals("500px", vLayoutElement.attr("width")); + } +} |