+ Vaadin 7.1.11 fixes two security issues discovered during internal review.
+
+
Escaping of OptionGroup item icon URLs
+
+ The issue affects OptionGroup with item icons. Proper escaping of the
+ src-attribute on the client side was not ensured when using icons for
+ OptionGroup items. This could potentially, in certain situations, allow
+ a malicious user to inject content, such as javascript, in order to
+ perform a cross-site scripting (XSS) attack.
+
+
+ In order for an application to be vulnerable, user provided input must
+ be used to form a URL used to display an icon for an OptionGroup item,
+ when showing that Option Group to other users.
+ The vulnerability has been classified as moderate, due to it's limited
+ application.
+
+
Escaping of URLs in Util.getAbsoluteUrl()
+
+ The client side Util.getAbsoluteUrl() did not ensure proper escaping
+ of the given URL. This could potentially, in certain situations, allow
+ a malicious user to inject content, such as javascript, in order to
+ perform a cross-site scripting (XSS) attack.
+
+
+ The method is used internally by the framework in such a manner that it
+ is unlikely this attack vector can be utilized in practice. However,
+ third party components, or future use of the method, could make an
+ attack viable.
+ The vulnerability has been classified as moderate, due to it's limited
+ application.
+
+
Change log for Vaadin @version@
This release includes the following closed issues:
--
cgit v1.2.3
From 23cab23936813909c1837b54b6d125ea1eaa61d4 Mon Sep 17 00:00:00 2001
From: Jonatan Kronqvist
Date: Thu, 13 Feb 2014 13:17:49 +0200
Subject: Add a custom icon for the TestBench debug tab (#12479)
Updates the font icon files to add the official TestBench icon
Change-Id: I6f417aea761c5b2320c69d36f0616e1d746224a0
---
.../VAADIN/themes/base/debug/fonts/font.dev.svg | 39 -------------
WebContent/VAADIN/themes/base/debug/fonts/font.eot | Bin 6124 -> 7528 bytes
WebContent/VAADIN/themes/base/debug/fonts/font.svg | 65 ++++++++++-----------
WebContent/VAADIN/themes/base/debug/fonts/font.ttf | Bin 5944 -> 7364 bytes
.../VAADIN/themes/base/debug/fonts/font.woff | Bin 3336 -> 8060 bytes
.../src/com/vaadin/client/debug/internal/Icon.java | 4 +-
.../client/debug/internal/TestBenchSection.java | 2 +-
7 files changed, 35 insertions(+), 75 deletions(-)
delete mode 100644 WebContent/VAADIN/themes/base/debug/fonts/font.dev.svg
mode change 100644 => 100755 WebContent/VAADIN/themes/base/debug/fonts/font.eot
mode change 100644 => 100755 WebContent/VAADIN/themes/base/debug/fonts/font.svg
mode change 100644 => 100755 WebContent/VAADIN/themes/base/debug/fonts/font.ttf
mode change 100644 => 100755 WebContent/VAADIN/themes/base/debug/fonts/font.woff
(limited to 'WebContent')
diff --git a/WebContent/VAADIN/themes/base/debug/fonts/font.dev.svg b/WebContent/VAADIN/themes/base/debug/fonts/font.dev.svg
deleted file mode 100644
index 24fa9ceeed..0000000000
--- a/WebContent/VAADIN/themes/base/debug/fonts/font.dev.svg
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/WebContent/VAADIN/themes/base/debug/fonts/font.eot b/WebContent/VAADIN/themes/base/debug/fonts/font.eot
old mode 100644
new mode 100755
index 310a74dfce..c2a63b3f08
Binary files a/WebContent/VAADIN/themes/base/debug/fonts/font.eot and b/WebContent/VAADIN/themes/base/debug/fonts/font.eot differ
diff --git a/WebContent/VAADIN/themes/base/debug/fonts/font.svg b/WebContent/VAADIN/themes/base/debug/fonts/font.svg
old mode 100644
new mode 100755
index 8149b583fd..9d00e7b2fc
--- a/WebContent/VAADIN/themes/base/debug/fonts/font.svg
+++ b/WebContent/VAADIN/themes/base/debug/fonts/font.svg
@@ -1,39 +1,36 @@
\ No newline at end of file
diff --git a/WebContent/VAADIN/themes/base/debug/fonts/font.ttf b/WebContent/VAADIN/themes/base/debug/fonts/font.ttf
old mode 100644
new mode 100755
index e26c910020..eee808e07e
Binary files a/WebContent/VAADIN/themes/base/debug/fonts/font.ttf and b/WebContent/VAADIN/themes/base/debug/fonts/font.ttf differ
diff --git a/WebContent/VAADIN/themes/base/debug/fonts/font.woff b/WebContent/VAADIN/themes/base/debug/fonts/font.woff
old mode 100644
new mode 100755
index e23e3807d0..2cd069ffdf
Binary files a/WebContent/VAADIN/themes/base/debug/fonts/font.woff and b/WebContent/VAADIN/themes/base/debug/fonts/font.woff differ
diff --git a/client/src/com/vaadin/client/debug/internal/Icon.java b/client/src/com/vaadin/client/debug/internal/Icon.java
index 9ef6d833e2..70bac11175 100644
--- a/client/src/com/vaadin/client/debug/internal/Icon.java
+++ b/client/src/com/vaadin/client/debug/internal/Icon.java
@@ -44,7 +44,9 @@ public enum Icon {
// BAN_CIRCLE(""), //
MAXIMIZE(""), //
RESET(""), //
- PERSIST(""); //
+ PERSIST(""), //
+ TESTBENCH(""), //
+ ;
private String id;
diff --git a/client/src/com/vaadin/client/debug/internal/TestBenchSection.java b/client/src/com/vaadin/client/debug/internal/TestBenchSection.java
index 5be75f2003..b3b2d3ad86 100644
--- a/client/src/com/vaadin/client/debug/internal/TestBenchSection.java
+++ b/client/src/com/vaadin/client/debug/internal/TestBenchSection.java
@@ -85,7 +85,7 @@ public class TestBenchSection implements Section {
}
}
- private final DebugButton tabButton = new DebugButton(Icon.WARNING,
+ private final DebugButton tabButton = new DebugButton(Icon.TESTBENCH,
"Pick Vaadin TestBench selectors");
private final FlowPanel content = new FlowPanel();
--
cgit v1.2.3
From de70ee2f0132661c9bf771cb66a40d1961073037 Mon Sep 17 00:00:00 2001
From: Marc Englund
Date: Tue, 11 Feb 2014 10:15:07 +0200
Subject: Font icon support (#13152)
Renamed Icon to ImageIcon
Change-Id: I608815f17a3651b205fed81b5294385df0d68802
Extracted the abstract client-side Icon class
Change-Id: Ic32e270595a5796d0bbd1dd31f34282b56672aa9
Created the FontIcon class
Change-Id: Iad13871e7bf1807dee2c538c76306d4620191f5e
Renamed AbstractComponentConnector.getIcon to getIconUri
Change-Id: I6953ab79661993b561655d483c1bd013b66407f3
Added the AbstractComponentConnector.getIcon method
Change-Id: I6fb91dc643fb09da3ba53666b1a8a289901702e3
Refactored getIcon
Change-Id: Ibae39e66d0fb8449e20ac5209eb8c18b6ada4387
Made all existing uses of Icon compatible with FontIcons
Change-Id: I8f28ec5254f2e5282a887519d3f44bc1e27aba72
Initial server-side support for font icons - does not include an actual icon set yet (#13152)
Change-Id: Ie6c09b17dd577c726e0efc13567749f6f4d56d8d
Changed server side FontIcon URI generation to match the correct scheme
Change-Id: I3628b930b310b3f285bc58a3f471e31e641d307e
Initial server-side icon font (FontAwesome) with scss - to be considered placeholder for testing (#13152)
Change-Id: I361e62aba0d943a736471824e149d65c7eea9c76
Changed the FontIcon URI scheme
Change-Id: I15c92f6bb3d0aa0a800f3f0bfa80419979453e17
Added FontIcon support to AbstractOrderedLayoutConnector
Change-Id: I3b2b45b22d29622fd888dbe922aa0cc8a718104d
Added FontIcon support to table items
Change-Id: Id22ce94c96a892420aab1e39663688fc9f3bc282
Added FontIcon support to OptionGroup items
Change-Id: Ie08bef688f6802182ef5f8b2bf82cf8b1f9096bb
Switched to openly use FontAwesome (#13152)
Change-Id: I18c3325ce93915b7fd6e338c8c293a89711277bc
VaadinIcons are now FontAwesome (#13152)
Change-Id: I0ab2a80735cbf08b6e33d358e3e8c6a205626fc4
VCaption does not longer set icon to 0x0px if it's a FontIcon (#13152)
Change-Id: Ibcd96e0f79f0adf2e217a8580d17f1cc93705710
Fixed typo in @font-face, removed .otf (#13152)
Change-Id: I698ca32c560e5f198c32a6c44f7884d3030ee610
Make font icons behave more like img (display:inline-block) (#13152)
Change-Id: Ic79186c90f1fc566deae1f4d8d4ba2c21d89a42e
---
WebContent/VAADIN/themes/base/base.scss | 2 +
WebContent/VAADIN/themes/base/common/common.scss | 1 +
.../themes/base/fonts/fontawesome-webfont.eot | Bin 0 -> 38205 bytes
.../themes/base/fonts/fontawesome-webfont.svg | 414 +++++++++++++++++++
.../themes/base/fonts/fontawesome-webfont.ttf | Bin 0 -> 80652 bytes
.../themes/base/fonts/fontawesome-webfont.woff | Bin 0 -> 44432 bytes
WebContent/VAADIN/themes/base/fonts/fonts.scss | 25 ++
WebContent/license.html | 6 +-
WebContent/licenses/OFL.txt | 97 +++++
.../com/vaadin/client/ApplicationConnection.java | 24 ++
client/src/com/vaadin/client/VCaption.java | 52 +--
.../client/ui/AbstractComponentConnector.java | 15 +-
client/src/com/vaadin/client/ui/FontIcon.java | 149 +++++++
client/src/com/vaadin/client/ui/Icon.java | 73 ++--
client/src/com/vaadin/client/ui/ImageIcon.java | 76 ++++
client/src/com/vaadin/client/ui/VFormLayout.java | 20 +-
client/src/com/vaadin/client/ui/VMenuBar.java | 2 +-
client/src/com/vaadin/client/ui/VOptionGroup.java | 12 +-
client/src/com/vaadin/client/ui/VPanel.java | 17 +-
client/src/com/vaadin/client/ui/VScrollTable.java | 6 +-
client/src/com/vaadin/client/ui/VTree.java | 26 +-
.../vaadin/client/ui/button/ButtonConnector.java | 25 +-
.../client/ui/checkbox/CheckBoxConnector.java | 23 +-
.../com/vaadin/client/ui/form/FormConnector.java | 18 +-
.../com/vaadin/client/ui/link/LinkConnector.java | 16 +-
.../vaadin/client/ui/menubar/MenuBarConnector.java | 4 +-
.../ui/nativebutton/NativeButtonConnector.java | 24 +-
.../AbstractOrderedLayoutConnector.java | 7 +-
.../com/vaadin/client/ui/orderedlayout/Slot.java | 108 +++--
.../com/vaadin/client/ui/panel/PanelConnector.java | 4 +-
.../vaadin/client/ui/window/WindowConnector.java | 4 +-
server/src/com/vaadin/server/FontAwesome.java | 447 +++++++++++++++++++++
server/src/com/vaadin/server/FontIcon.java | 67 +++
.../src/com/vaadin/server/ResourceReference.java | 7 +
.../com/vaadin/shared/ApplicationConstants.java | 1 +
.../src/com/vaadin/tests/fonticon/FontIcons.java | 226 +++++++++++
.../com/vaadin/tests/fonticon/FontIconsTest.java | 36 ++
37 files changed, 1786 insertions(+), 248 deletions(-)
create mode 100644 WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.eot
create mode 100644 WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.svg
create mode 100644 WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.ttf
create mode 100644 WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.woff
create mode 100644 WebContent/VAADIN/themes/base/fonts/fonts.scss
create mode 100644 WebContent/licenses/OFL.txt
create mode 100644 client/src/com/vaadin/client/ui/FontIcon.java
create mode 100644 client/src/com/vaadin/client/ui/ImageIcon.java
create mode 100644 server/src/com/vaadin/server/FontAwesome.java
create mode 100644 server/src/com/vaadin/server/FontIcon.java
create mode 100644 uitest/src/com/vaadin/tests/fonticon/FontIcons.java
create mode 100644 uitest/src/com/vaadin/tests/fonticon/FontIconsTest.java
(limited to 'WebContent')
diff --git a/WebContent/VAADIN/themes/base/base.scss b/WebContent/VAADIN/themes/base/base.scss
index aa1e778d6f..fd3c5d067d 100644
--- a/WebContent/VAADIN/themes/base/base.scss
+++ b/WebContent/VAADIN/themes/base/base.scss
@@ -15,6 +15,7 @@
@import "inlinedatefield/inlinedatefield.scss";
@import "dragwrapper/dragwrapper.scss";
@import "embedded/embedded.scss";
+@import "fonts/fonts.scss";
@import "formlayout/formlayout.scss";
@import "gridlayout/gridlayout.scss";
@import "label/label.scss";
@@ -119,3 +120,4 @@ $line-height: normal;
// always include, don't wrap in .themename{}
@include debug-globals;
+@include fonts;
diff --git a/WebContent/VAADIN/themes/base/common/common.scss b/WebContent/VAADIN/themes/base/common/common.scss
index 5cae1b26ce..6ec85e3c6d 100644
--- a/WebContent/VAADIN/themes/base/common/common.scss
+++ b/WebContent/VAADIN/themes/base/common/common.scss
@@ -243,6 +243,7 @@ input::-ms-clear {
width: 0;
height: 0;
}
+
}
/* Outside the base mixin because elements might be added directly to the body */
diff --git a/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.eot b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.eot
new file mode 100644
index 0000000000..7c79c6a6bc
Binary files /dev/null and b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.eot differ
diff --git a/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.svg b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.svg
new file mode 100644
index 0000000000..45fdf33830
--- /dev/null
+++ b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.svg
@@ -0,0 +1,414 @@
+
+
+
\ No newline at end of file
diff --git a/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.ttf b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.ttf
new file mode 100644
index 0000000000..e89738de5e
Binary files /dev/null and b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.ttf differ
diff --git a/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.woff b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.woff
new file mode 100644
index 0000000000..8c1748aab7
Binary files /dev/null and b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.woff differ
diff --git a/WebContent/VAADIN/themes/base/fonts/fonts.scss b/WebContent/VAADIN/themes/base/fonts/fonts.scss
new file mode 100644
index 0000000000..2a882ab53d
--- /dev/null
+++ b/WebContent/VAADIN/themes/base/fonts/fonts.scss
@@ -0,0 +1,25 @@
+@mixin fonts {
+ @include fonticons;
+}
+
+@mixin fonticons {
+ @include font(FontAwesome, fontawesome-webfont);
+}
+
+@mixin font($font-family, $file-name) {
+ @font-face {
+ font-family: '#{$font-family}';
+ src: url('#{$file-name}.eot');
+ src: url('#{$file-name}.eot?#iefix') format('embedded-opentype'), url('#{$file-name}.woff') format('woff'), url('#{$file-name}.ttf') format('truetype'), url('#{$file-name}.svg') format('svg');
+ font-weight: normal;
+ font-style: normal;
+ }
+ .#{$font-family} {
+ font-family: '#{$font-family}';
+ font-style: normal;
+ font-weight: normal;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ display: inline-block;
+ }
+}
diff --git a/WebContent/license.html b/WebContent/license.html
index 5e9bfe4dc5..0f9a573041 100644
--- a/WebContent/license.html
+++ b/WebContent/license.html
@@ -130,7 +130,11 @@
diff --git a/WebContent/licenses/OFL.txt b/WebContent/licenses/OFL.txt
new file mode 100644
index 0000000000..f1a20ac1a8
--- /dev/null
+++ b/WebContent/licenses/OFL.txt
@@ -0,0 +1,97 @@
+Copyright (c) , (),
+with Reserved Font Name .
+Copyright (c) , (),
+with Reserved Font Name .
+Copyright (c) , ().
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java
index b84d8a376f..3d00141aae 100644
--- a/client/src/com/vaadin/client/ApplicationConnection.java
+++ b/client/src/com/vaadin/client/ApplicationConnection.java
@@ -65,6 +65,7 @@ import com.google.gwt.user.client.Window.ClosingHandler;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ApplicationConfiguration.ErrorMessage;
+import com.vaadin.client.ApplicationConnection.ApplicationStoppedEvent;
import com.vaadin.client.ResourceLoader.ResourceLoadEvent;
import com.vaadin.client.ResourceLoader.ResourceLoadListener;
import com.vaadin.client.communication.HasJavaScriptConnectorHelper;
@@ -85,6 +86,9 @@ import com.vaadin.client.metadata.Type;
import com.vaadin.client.metadata.TypeData;
import com.vaadin.client.ui.AbstractComponentConnector;
import com.vaadin.client.ui.AbstractConnector;
+import com.vaadin.client.ui.FontIcon;
+import com.vaadin.client.ui.Icon;
+import com.vaadin.client.ui.ImageIcon;
import com.vaadin.client.ui.VContextMenu;
import com.vaadin.client.ui.VNotification;
import com.vaadin.client.ui.VNotification.HideEvent;
@@ -3030,6 +3034,26 @@ public class ApplicationConnection {
return contextMenu;
}
+ /**
+ * Gets an {@link Icon} instance corresponding to a URI.
+ *
+ * @since 7.2
+ * @param uri
+ * @return Icon object
+ */
+ public Icon getIcon(String uri) {
+ Icon icon;
+ if (uri == null) {
+ return null;
+ } else if (FontIcon.isFontIconUri(uri)) {
+ icon = GWT.create(FontIcon.class);
+ } else {
+ icon = GWT.create(ImageIcon.class);
+ }
+ icon.setUri(translateVaadinUri(uri));
+ return icon;
+ }
+
/**
* Translates custom protocols in UIDL URI's to be recognizable by browser.
* All uri's from UIDL should be routed via this method before giving them
diff --git a/client/src/com/vaadin/client/VCaption.java b/client/src/com/vaadin/client/VCaption.java
index d96e6ed653..e11082cf47 100644
--- a/client/src/com/vaadin/client/VCaption.java
+++ b/client/src/com/vaadin/client/VCaption.java
@@ -24,6 +24,7 @@ import com.google.gwt.user.client.ui.HTML;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.ui.AbstractFieldConnector;
import com.vaadin.client.ui.Icon;
+import com.vaadin.client.ui.ImageIcon;
import com.vaadin.client.ui.aria.AriaHelper;
import com.vaadin.shared.AbstractComponentState;
import com.vaadin.shared.AbstractFieldState;
@@ -106,6 +107,7 @@ public class VCaption extends HTML {
if (null != owner) {
AriaHelper.bindCaption(owner.getWidget(), getElement());
}
+
}
@Override
@@ -159,25 +161,27 @@ public class VCaption extends HTML {
showRequired = ((AbstractFieldConnector) owner).isRequired();
}
+ if (icon != null) {
+ getElement().removeChild(icon.getElement());
+ icon = null;
+ }
if (hasIcon) {
- if (icon == null) {
- icon = new Icon(client);
+ String uri = owner.getState().resources.get(
+ ComponentConstants.ICON_RESOURCE).getURL();
+
+ icon = client.getIcon(uri);
+
+ if (icon instanceof ImageIcon) {
+ // onload will set appropriate size later
icon.setWidth("0");
icon.setHeight("0");
-
- DOM.insertChild(getElement(), icon.getElement(),
- getInsertPosition(InsertPosition.ICON));
}
- // Icon forces the caption to be above the component
- placedAfterComponent = false;
- icon.setUri(owner.getState().resources.get(
- ComponentConstants.ICON_RESOURCE).getURL());
+ DOM.insertChild(getElement(), icon.getElement(),
+ getInsertPosition(InsertPosition.ICON));
- } else if (icon != null) {
- // Remove existing
- DOM.removeChild(getElement(), icon.getElement());
- icon = null;
+ // Icon forces the caption to be above the component
+ placedAfterComponent = false;
}
if (owner.getState().caption != null) {
@@ -332,24 +336,24 @@ public class VCaption extends HTML {
}
boolean hasIcon = iconURL != null;
+ if (icon != null) {
+ getElement().removeChild(icon.getElement());
+ icon = null;
+ }
if (hasIcon) {
- if (icon == null) {
- icon = new Icon(client);
+ icon = client.getIcon(iconURL);
+ if (icon instanceof ImageIcon) {
+ // onload sets appropriate size later
icon.setWidth("0");
icon.setHeight("0");
-
- DOM.insertChild(getElement(), icon.getElement(),
- getInsertPosition(InsertPosition.ICON));
}
+ icon.setAlternateText(iconAltText);
+ DOM.insertChild(getElement(), icon.getElement(),
+ getInsertPosition(InsertPosition.ICON));
+
// Icon forces the caption to be above the component
placedAfterComponent = false;
- icon.setUri(iconURL, iconAltText);
-
- } else if (icon != null) {
- // Remove existing
- DOM.removeChild(getElement(), icon.getElement());
- icon = null;
}
if (caption != null) {
diff --git a/client/src/com/vaadin/client/ui/AbstractComponentConnector.java b/client/src/com/vaadin/client/ui/AbstractComponentConnector.java
index 8fdaf0a5be..5933441e0a 100644
--- a/client/src/com/vaadin/client/ui/AbstractComponentConnector.java
+++ b/client/src/com/vaadin/client/ui/AbstractComponentConnector.java
@@ -462,15 +462,24 @@ public abstract class AbstractComponentConnector extends AbstractConnector
}
/**
- * Gets the icon set for this component.
+ * Gets the URI of the icon set for this component.
*
- * @return the URL of the icon, or null if no icon has been
+ * @return the URI of the icon, or null if no icon has been
* defined.
*/
- protected String getIcon() {
+ protected String getIconUri() {
return getResourceUrl(ComponentConstants.ICON_RESOURCE);
}
+ /**
+ * Gets the icon set for this component.
+ *
+ * @return the icon, or null if no icon has been defined.
+ */
+ protected Icon getIcon() {
+ return getConnection().getIcon(getIconUri());
+ }
+
/*
* (non-Javadoc)
*
diff --git a/client/src/com/vaadin/client/ui/FontIcon.java b/client/src/com/vaadin/client/ui/FontIcon.java
new file mode 100644
index 0000000000..04640fab06
--- /dev/null
+++ b/client/src/com/vaadin/client/ui/FontIcon.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2000-2013 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.client.ui;
+
+import com.google.gwt.http.client.URL;
+import com.google.gwt.user.client.DOM;
+import com.vaadin.shared.ApplicationConstants;
+
+/**
+ * A font-based icon implementation.
+ *
+ * The icon represents a specific character (identified by codepoint,
+ * {@link #getCodepoint()}, {@link #setCodepoint(int)}) within a specific font
+ * (identified by font-family, {@link #getFontFamily()},
+ * {@link #setFontFamily(String)}).
+ *
+ *
+ * @since 7.2
+ * @author Vaadin Ltd
+ */
+public class FontIcon extends Icon {
+
+ private int codepoint;
+ private String fontFamily;
+
+ public FontIcon() {
+ setElement(DOM.createSpan());
+ setStyleName(CLASSNAME);
+ }
+
+ @Override
+ public void setUri(String uri) {
+ String[] parts = uri.substring(
+ ApplicationConstants.FONTICON_PROTOCOL_PREFIX.length()).split(
+ "/");
+ setFontFamily(URL.decode(parts[0]));
+ setCodepoint(Integer.parseInt(parts[1], 16));
+ }
+
+ /**
+ * Not implemeted for {@link FontIcon} yet.
+ *
+ * @see com.vaadin.client.ui.Icon#setAlternateText(java.lang.String)
+ */
+ @Override
+ public void setAlternateText(String alternateText) {
+ // TODO this is mostly for WAI-ARIA and should be implemented in an
+ // appropriate way.
+
+ }
+
+ /**
+ * Sets the font-family from which this icon comes. Use
+ * {@link #setCodepoint(int)} to specify a particular icon (character)
+ * within the font.
+ *
+ * @param fontFamily
+ * font-family name
+ */
+ protected void setFontFamily(String fontFamily) {
+ if (this.fontFamily != null) {
+ removeStyleName(getFontStylename());
+ }
+ this.fontFamily = fontFamily;
+ if (fontFamily != null) {
+ addStyleName(getFontStylename());
+ }
+ }
+
+ /**
+ * Gets the font-family from which this icon comes. Use
+ * {@link #getCodepoint()} to find out which particular icon (character)
+ * within the font this is.
+ *
+ * @return font-family name
+ */
+ public String getFontFamily() {
+ return fontFamily;
+ }
+
+ /**
+ * Sets the codepoint indicating which particular icon (character) within
+ * the font-family this is.
+ *
+ * @param codepoint
+ */
+ protected void setCodepoint(int codepoint) {
+ this.codepoint = codepoint;
+ getElement().setInnerText(new String(Character.toChars(codepoint)));
+ }
+
+ /**
+ * Gets the codepoint indicating which particular icon (character) within
+ * the font-family this is.
+ *
+ * @return
+ */
+ public int getCodepoint() {
+ return codepoint;
+ }
+
+ /**
+ * Get the font-family based stylename used to apply the font-family.
+ *
+ * @since 7.2
+ * @return stylename used to apply font-family
+ */
+ protected String getFontStylename() {
+ if (fontFamily == null) {
+ return null;
+ }
+ return fontFamily.replace(' ', '-');
+ }
+
+ /**
+ * Checks whether or not the given uri is a font icon uri. Does not check
+ * whether or not the font icon is available and can be rendered.
+ *
+ * @since 7.2
+ * @param uri
+ * @return true if it's a fonticon uri
+ */
+ public static boolean isFontIconUri(String uri) {
+ return uri != null
+ && uri.startsWith(ApplicationConstants.FONTICON_PROTOCOL_PREFIX);
+ }
+
+ @Override
+ public String getUri() {
+ if (fontFamily == null) {
+ return null;
+ }
+ return ApplicationConstants.FONTICON_PROTOCOL_PREFIX + fontFamily + "/"
+ + codepoint;
+ }
+}
diff --git a/client/src/com/vaadin/client/ui/Icon.java b/client/src/com/vaadin/client/ui/Icon.java
index 4a0e858798..219692161e 100644
--- a/client/src/com/vaadin/client/ui/Icon.java
+++ b/client/src/com/vaadin/client/ui/Icon.java
@@ -13,55 +13,40 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
-
package com.vaadin.client.ui;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.UIObject;
import com.vaadin.client.ApplicationConnection;
-public class Icon extends UIObject {
- public static final String CLASSNAME = "v-icon";
- private final ApplicationConnection client;
- private String myUri;
-
- public Icon(ApplicationConnection client) {
- setElement(DOM.createImg());
- DOM.setElementProperty(getElement(), "alt", "");
- setStyleName(CLASSNAME);
- this.client = client;
- }
-
- public Icon(ApplicationConnection client, String uidlUri) {
- this(client, uidlUri, "");
- }
-
- public Icon(ApplicationConnection client, String uidlUri, String iconAltText) {
- this(client);
- setUri(uidlUri, iconAltText);
- }
-
- public void setUri(String uidlUri) {
- setUri(uidlUri, "");
- }
+/**
+ * An abstract representation of an icon.
+ *
+ * @since 7.2
+ * @author Vaadin Ltd
+ */
+public abstract class Icon extends UIObject {
- public void setUri(String uidlUri, String uidlAlt) {
- if (!uidlUri.equals(myUri)) {
- /*
- * Start sinking onload events, widgets responsibility to react. We
- * must do this BEFORE we set src as IE fires the event immediately
- * if the image is found in cache (#2592).
- */
- sinkEvents(Event.ONLOAD);
+ public static final String CLASSNAME = "v-icon";
- String uri = client.translateVaadinUri(uidlUri);
- DOM.setElementProperty(getElement(), "src", uri);
- myUri = uidlUri;
- }
+ /**
+ * Sets the URI for the icon. The URI should be run trough
+ * {@link ApplicationConnection#translateVaadinUri(String)} before setting.
+ *
+ * This might be a URL referencing a image (e.g {@link ImageIcon}) or a
+ * custom URI (e.g {@link FontIcon}).
+ *
+ *
+ * @param uri
+ * the URI for this icon
+ */
+ public abstract void setUri(String uri);
- setAlternateText(uidlAlt);
- }
+ /**
+ * Gets the current URI for this icon.
+ *
+ * @return URI in use
+ */
+ public abstract String getUri();
/**
* Sets the alternate text for the icon.
@@ -69,8 +54,6 @@ public class Icon extends UIObject {
* @param alternateText
* with the alternate text.
*/
- public void setAlternateText(String alternateText) {
- getElement().setAttribute("alt",
- alternateText == null ? "" : alternateText);
- }
+ public abstract void setAlternateText(String alternateText);
+
}
diff --git a/client/src/com/vaadin/client/ui/ImageIcon.java b/client/src/com/vaadin/client/ui/ImageIcon.java
new file mode 100644
index 0000000000..787b0175aa
--- /dev/null
+++ b/client/src/com/vaadin/client/ui/ImageIcon.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2000-2013 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.client.ui;
+
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Event;
+import com.vaadin.client.BrowserInfo;
+
+/**
+ * A image based implementation of {@link Icon}.
+ *
+ * The image is loaded from the given URL ( {@link #setUri(String)}) and
+ * displayed in full.
+ *
+ *
+ * @author Vaadin Ltd
+ */
+public class ImageIcon extends Icon {
+ public static final String CLASSNAME = "v-icon";
+
+ public ImageIcon() {
+ setElement(DOM.createImg());
+ setStyleName(CLASSNAME);
+ }
+
+ @Override
+ public void setUri(final String imageUrl) {
+ /*
+ * Start sinking onload events, widgets responsibility to react. We must
+ * do this BEFORE we set src as IE fires the event immediately if the
+ * image is found in cache (#2592).
+ */
+ sinkEvents(Event.ONLOAD);
+
+ if (BrowserInfo.get().isIE()) {
+ // apply src later for IE, to ensure onload is fired
+ Scheduler.get().scheduleDeferred(new ScheduledCommand() {
+ @Override
+ public void execute() {
+ DOM.setElementProperty(getElement(), "src", imageUrl);
+ }
+ });
+ }
+
+ DOM.setElementProperty(getElement(), "src", imageUrl);
+
+ }
+
+ @Override
+ public void setAlternateText(String alternateText) {
+ getElement().setAttribute("alt",
+ alternateText == null ? "" : alternateText);
+ }
+
+ @Override
+ public String getUri() {
+ return DOM.getElementProperty(getElement(), "src");
+ }
+
+}
diff --git a/client/src/com/vaadin/client/ui/VFormLayout.java b/client/src/com/vaadin/client/ui/VFormLayout.java
index 6c2661d1d8..56870e5e41 100644
--- a/client/src/com/vaadin/client/ui/VFormLayout.java
+++ b/client/src/com/vaadin/client/ui/VFormLayout.java
@@ -260,21 +260,17 @@ public class VFormLayout extends SimplePanel {
boolean isEmpty = true;
+ if (icon != null) {
+ getElement().removeChild(icon.getElement());
+ icon = null;
+ }
if (state.resources.containsKey(ComponentConstants.ICON_RESOURCE)) {
- if (icon == null) {
- icon = new Icon(owner.getConnection());
+ icon = owner.getConnection().getIcon(
+ state.resources.get(ComponentConstants.ICON_RESOURCE)
+ .getURL());
+ DOM.insertChild(getElement(), icon.getElement(), 0);
- DOM.insertChild(getElement(), icon.getElement(), 0);
- }
- icon.setUri(state.resources.get(
- ComponentConstants.ICON_RESOURCE).getURL());
isEmpty = false;
- } else {
- if (icon != null) {
- DOM.removeChild(getElement(), icon.getElement());
- icon = null;
- }
-
}
if (state.caption != null) {
diff --git a/client/src/com/vaadin/client/ui/VMenuBar.java b/client/src/com/vaadin/client/ui/VMenuBar.java
index 0aa26e4999..6c994777a7 100644
--- a/client/src/com/vaadin/client/ui/VMenuBar.java
+++ b/client/src/com/vaadin/client/ui/VMenuBar.java
@@ -230,7 +230,7 @@ public class VMenuBar extends SimpleFocusablePanel implements
itemHTML.append("");
+ + ImageIcon.CLASSNAME + "\" alt=\"\" />");
}
String itemText = item.getStringAttribute("text");
if (!htmlContentAllowed) {
diff --git a/client/src/com/vaadin/client/ui/VOptionGroup.java b/client/src/com/vaadin/client/ui/VOptionGroup.java
index fe4ef214cb..3e4b357be3 100644
--- a/client/src/com/vaadin/client/ui/VOptionGroup.java
+++ b/client/src/com/vaadin/client/ui/VOptionGroup.java
@@ -139,12 +139,10 @@ public class VOptionGroup extends VOptionGroupBase implements FocusHandler,
itemHtml = Util.escapeHTML(itemHtml);
}
- String icon = opUidl.getStringAttribute("icon");
- if (icon != null && icon.length() != 0) {
- String iconUrl = client.translateVaadinUri(icon);
- itemHtml = ""
- + itemHtml;
+ String iconUrl = opUidl.getStringAttribute("icon");
+ if (iconUrl != null && iconUrl.length() != 0) {
+ Icon icon = client.getIcon(iconUrl);
+ itemHtml = icon.getElement().getString() + itemHtml;
}
String key = opUidl.getStringAttribute("key");
@@ -161,7 +159,7 @@ public class VOptionGroup extends VOptionGroupBase implements FocusHandler,
op = new RadioButton(paintableId);
op.setStyleName("v-radiobutton");
}
- if (icon != null && icon.length() != 0) {
+ if (iconUrl != null && iconUrl.length() != 0) {
Util.sinkOnloadForImages(op.getElement());
op.addHandler(iconLoadHandler, LoadEvent.getType());
}
diff --git a/client/src/com/vaadin/client/ui/VPanel.java b/client/src/com/vaadin/client/ui/VPanel.java
index ffeacade46..32d99e7ca9 100644
--- a/client/src/com/vaadin/client/ui/VPanel.java
+++ b/client/src/com/vaadin/client/ui/VPanel.java
@@ -152,17 +152,12 @@ public class VPanel extends SimplePanel implements ShortcutActionHandlerOwner,
/** For internal use only. May be removed or replaced in the future. */
public void setIconUri(String iconUri, ApplicationConnection client) {
- if (iconUri == null) {
- if (icon != null) {
- DOM.removeChild(captionNode, icon.getElement());
- icon = null;
- }
- } else {
- if (icon == null) {
- icon = new Icon(client);
- DOM.insertChild(captionNode, icon.getElement(), 0);
- }
- icon.setUri(iconUri);
+ if (icon != null) {
+ captionNode.removeChild(icon.getElement());
+ }
+ icon = client.getIcon(iconUri);
+ if (icon != null) {
+ DOM.insertChild(captionNode, icon.getElement(), 0);
}
}
diff --git a/client/src/com/vaadin/client/ui/VScrollTable.java b/client/src/com/vaadin/client/ui/VScrollTable.java
index bbf06bfec1..1b0dd646d1 100644
--- a/client/src/com/vaadin/client/ui/VScrollTable.java
+++ b/client/src/com/vaadin/client/ui/VScrollTable.java
@@ -6924,10 +6924,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
String s = uidl.hasAttribute("caption") ? uidl
.getStringAttribute("caption") : "";
if (uidl.hasAttribute("icon")) {
- s = "" + s;
+ Icon icon = client.getIcon(uidl.getStringAttribute("icon"));
+ s = icon.getElement().getString() + s;
}
return s;
}
diff --git a/client/src/com/vaadin/client/ui/VTree.java b/client/src/com/vaadin/client/ui/VTree.java
index 1acd4bd05f..86c724a3e0 100644
--- a/client/src/com/vaadin/client/ui/VTree.java
+++ b/client/src/com/vaadin/client/ui/VTree.java
@@ -1124,23 +1124,15 @@ public class VTree extends FocusElementPanel implements VHasDropHandler,
}
public void setIcon(String iconUrl, String altText) {
- if (iconUrl != null) {
- // Add icon if not present
- if (icon == null) {
- icon = new Icon(client);
- Roles.getImgRole().set(icon.getElement());
- DOM.insertBefore(DOM.getFirstChild(nodeCaptionDiv),
- icon.getElement(), nodeCaptionSpan);
- }
- icon.setUri(iconUrl);
- icon.getElement().setAttribute("alt", altText);
- } else {
- // Remove icon if present
- if (icon != null) {
- DOM.removeChild(DOM.getFirstChild(nodeCaptionDiv),
- icon.getElement());
- icon = null;
- }
+ if (icon != null) {
+ DOM.getFirstChild(nodeCaptionDiv)
+ .removeChild(icon.getElement());
+ }
+ icon = client.getIcon(iconUrl);
+ if (icon != null) {
+ DOM.insertBefore(DOM.getFirstChild(nodeCaptionDiv),
+ icon.getElement(), nodeCaptionSpan);
+ icon.setAlternateText(altText);
}
}
diff --git a/client/src/com/vaadin/client/ui/button/ButtonConnector.java b/client/src/com/vaadin/client/ui/button/ButtonConnector.java
index 9a63808742..94c2841c3c 100644
--- a/client/src/com/vaadin/client/ui/button/ButtonConnector.java
+++ b/client/src/com/vaadin/client/ui/button/ButtonConnector.java
@@ -80,20 +80,17 @@ public class ButtonConnector extends AbstractComponentConnector implements
addStateChangeHandler("resources", new StateChangeHandler() {
@Override
public void onStateChanged(StateChangeEvent stateChangeEvent) {
- if (getIcon() != null) {
- if (getWidget().icon == null) {
- getWidget().icon = new Icon(getConnection());
- getWidget().wrapper.insertBefore(
- getWidget().icon.getElement(),
- getWidget().captionElement);
- }
- getWidget().icon.setUri(getIcon(), getState().iconAltText);
- } else {
- if (getWidget().icon != null) {
- getWidget().wrapper.removeChild(getWidget().icon
- .getElement());
- getWidget().icon = null;
- }
+ if (getWidget().icon != null) {
+ getWidget().wrapper.removeChild(getWidget().icon
+ .getElement());
+ getWidget().icon = null;
+ }
+ Icon icon = getIcon();
+ if (icon != null) {
+ getWidget().icon = icon;
+ icon.setAlternateText(getState().iconAltText);
+ getWidget().wrapper.insertBefore(icon.getElement(),
+ getWidget().captionElement);
}
}
});
diff --git a/client/src/com/vaadin/client/ui/checkbox/CheckBoxConnector.java b/client/src/com/vaadin/client/ui/checkbox/CheckBoxConnector.java
index 85e4e5ee8b..b40e96ff95 100644
--- a/client/src/com/vaadin/client/ui/checkbox/CheckBoxConnector.java
+++ b/client/src/com/vaadin/client/ui/checkbox/CheckBoxConnector.java
@@ -30,6 +30,7 @@ import com.vaadin.client.VTooltip;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.ui.AbstractFieldConnector;
import com.vaadin.client.ui.Icon;
+import com.vaadin.client.ui.ImageIcon;
import com.vaadin.client.ui.VCheckBox;
import com.vaadin.shared.MouseEventDetails;
import com.vaadin.shared.communication.FieldRpc.FocusAndBlurServerRpc;
@@ -96,21 +97,17 @@ public class CheckBoxConnector extends AbstractFieldConnector implements
getWidget().setEnabled(false);
}
- if (getIcon() != null) {
- if (getWidget().icon == null) {
- getWidget().icon = new Icon(getConnection());
- DOM.insertChild(getWidget().getElement(),
- getWidget().icon.getElement(), 1);
- getWidget().icon.sinkEvents(VTooltip.TOOLTIP_EVENTS);
- getWidget().icon.sinkEvents(Event.ONCLICK);
- }
- getWidget().icon.setUri(getIcon());
- } else if (getWidget().icon != null) {
- // detach icon
- DOM.removeChild(getWidget().getElement(),
- getWidget().icon.getElement());
+ if (getWidget().icon != null) {
+ getWidget().getElement().removeChild(getWidget().icon.getElement());
getWidget().icon = null;
}
+ Icon icon = getIcon();
+ if (icon != null) {
+ getWidget().icon = icon;
+ DOM.insertChild(getWidget().getElement(), icon.getElement(), 1);
+ icon.sinkEvents(VTooltip.TOOLTIP_EVENTS);
+ icon.sinkEvents(Event.ONCLICK);
+ }
// Set text
getWidget().setText(getState().caption);
diff --git a/client/src/com/vaadin/client/ui/form/FormConnector.java b/client/src/com/vaadin/client/ui/form/FormConnector.java
index acd0e917fc..a6015170c2 100644
--- a/client/src/com/vaadin/client/ui/form/FormConnector.java
+++ b/client/src/com/vaadin/client/ui/form/FormConnector.java
@@ -27,7 +27,6 @@ import com.vaadin.client.Paintable;
import com.vaadin.client.TooltipInfo;
import com.vaadin.client.UIDL;
import com.vaadin.client.ui.AbstractComponentContainerConnector;
-import com.vaadin.client.ui.Icon;
import com.vaadin.client.ui.ShortcutActionHandler;
import com.vaadin.client.ui.VForm;
import com.vaadin.client.ui.layout.ElementResizeEvent;
@@ -108,17 +107,14 @@ public class FormConnector extends AbstractComponentContainerConnector
} else {
getWidget().caption.setInnerText("");
}
- if (getIcon() != null) {
- if (getWidget().icon == null) {
- getWidget().icon = new Icon(client);
- getWidget().legend.insertFirst(getWidget().icon.getElement());
- }
- getWidget().icon.setUri(getIcon());
+ if (getWidget().icon != null) {
+ getWidget().legend.removeChild(getWidget().icon.getElement());
+ }
+ if (getIconUri() != null) {
+ getWidget().icon = client.getIcon(getIconUri());
+ getWidget().legend.insertFirst(getWidget().icon.getElement());
+
legendEmpty = false;
- } else {
- if (getWidget().icon != null) {
- getWidget().legend.removeChild(getWidget().icon.getElement());
- }
}
if (legendEmpty) {
getWidget().addStyleDependentName("nocaption");
diff --git a/client/src/com/vaadin/client/ui/link/LinkConnector.java b/client/src/com/vaadin/client/ui/link/LinkConnector.java
index d2c41e9f38..c8bbc426e9 100644
--- a/client/src/com/vaadin/client/ui/link/LinkConnector.java
+++ b/client/src/com/vaadin/client/ui/link/LinkConnector.java
@@ -87,13 +87,15 @@ public class LinkConnector extends AbstractComponentConnector {
"none");
}
- if (getIcon() != null) {
- if (getWidget().icon == null) {
- getWidget().icon = new Icon(getConnection());
- getWidget().anchor.insertBefore(getWidget().icon.getElement(),
- getWidget().captionElement);
- }
- getWidget().icon.setUri(getIcon());
+ if (getWidget().icon != null) {
+ getWidget().anchor.removeChild(getWidget().icon.getElement());
+ getWidget().icon = null;
+ }
+ Icon icon = getIcon();
+ if (icon != null) {
+ getWidget().icon = icon;
+ getWidget().anchor.insertBefore(icon.getElement(),
+ getWidget().captionElement);
}
}
diff --git a/client/src/com/vaadin/client/ui/menubar/MenuBarConnector.java b/client/src/com/vaadin/client/ui/menubar/MenuBarConnector.java
index 3e22ebb05b..9ce418c358 100644
--- a/client/src/com/vaadin/client/ui/menubar/MenuBarConnector.java
+++ b/client/src/com/vaadin/client/ui/menubar/MenuBarConnector.java
@@ -27,7 +27,7 @@ import com.vaadin.client.TooltipInfo;
import com.vaadin.client.UIDL;
import com.vaadin.client.Util;
import com.vaadin.client.ui.AbstractComponentConnector;
-import com.vaadin.client.ui.Icon;
+import com.vaadin.client.ui.ImageIcon;
import com.vaadin.client.ui.SimpleManagedLayout;
import com.vaadin.client.ui.VMenuBar;
import com.vaadin.shared.ui.ComponentStateUtil;
@@ -81,7 +81,7 @@ public class MenuBarConnector extends AbstractComponentConnector implements
+ Util.escapeAttribute(client
.translateVaadinUri(moreItemUIDL
.getStringAttribute("icon")))
- + "\" class=\"" + Icon.CLASSNAME + "\" alt=\"\" />");
+ + "\" class=\"" + ImageIcon.CLASSNAME + "\" alt=\"\" />");
}
String moreItemText = moreItemUIDL.getStringAttribute("text");
diff --git a/client/src/com/vaadin/client/ui/nativebutton/NativeButtonConnector.java b/client/src/com/vaadin/client/ui/nativebutton/NativeButtonConnector.java
index 2253397b16..e4e88899eb 100644
--- a/client/src/com/vaadin/client/ui/nativebutton/NativeButtonConnector.java
+++ b/client/src/com/vaadin/client/ui/nativebutton/NativeButtonConnector.java
@@ -87,20 +87,16 @@ public class NativeButtonConnector extends AbstractComponentConnector implements
getWidget().errorIndicatorElement = null;
}
- if (getIcon() != null) {
- if (getWidget().icon == null) {
- getWidget().icon = new Icon(getConnection());
- getWidget().getElement().insertBefore(
- getWidget().icon.getElement(),
- getWidget().captionElement);
- }
- getWidget().icon.setUri(getIcon(), getState().iconAltText);
- } else {
- if (getWidget().icon != null) {
- getWidget().getElement().removeChild(
- getWidget().icon.getElement());
- getWidget().icon = null;
- }
+ if (getWidget().icon != null) {
+ getWidget().getElement().removeChild(getWidget().icon.getElement());
+ getWidget().icon = null;
+ }
+ Icon icon = getIcon();
+ if (icon != null) {
+ getWidget().icon = icon;
+ getWidget().getElement().insertBefore(icon.getElement(),
+ getWidget().captionElement);
+ icon.setAlternateText(getState().iconAltText);
}
}
diff --git a/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java b/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java
index ec4307e50b..166e4b7530 100644
--- a/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java
+++ b/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java
@@ -32,6 +32,7 @@ import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.communication.StateChangeEvent.StateChangeHandler;
import com.vaadin.client.ui.AbstractFieldConnector;
import com.vaadin.client.ui.AbstractLayoutConnector;
+import com.vaadin.client.ui.Icon;
import com.vaadin.client.ui.LayoutClickEventHandler;
import com.vaadin.client.ui.aria.AriaHelper;
import com.vaadin.client.ui.layout.ElementResizeEvent;
@@ -244,6 +245,8 @@ public abstract class AbstractOrderedLayoutConnector extends
URLReference iconUrl = child.getState().resources
.get(ComponentConstants.ICON_RESOURCE);
String iconUrlString = iconUrl != null ? iconUrl.getURL() : null;
+ Icon icon = child.getConnection().getIcon(iconUrlString);
+
List styles = child.getState().styles;
String error = child.getState().errorMessage;
boolean showError = error != null;
@@ -258,8 +261,8 @@ public abstract class AbstractOrderedLayoutConnector extends
}
boolean enabled = child.isEnabled();
- slot.setCaption(caption, iconUrlString, styles, error, showError,
- required, enabled);
+ slot.setCaption(caption, icon, styles, error, showError, required,
+ enabled);
AriaHelper.handleInputRequired(child.getWidget(), required);
AriaHelper.handleInputInvalid(child.getWidget(), showError);
diff --git a/client/src/com/vaadin/client/ui/orderedlayout/Slot.java b/client/src/com/vaadin/client/ui/orderedlayout/Slot.java
index efa19895a8..6e1e8d28eb 100644
--- a/client/src/com/vaadin/client/ui/orderedlayout/Slot.java
+++ b/client/src/com/vaadin/client/ui/orderedlayout/Slot.java
@@ -19,18 +19,21 @@ package com.vaadin.client.ui.orderedlayout;
import java.util.List;
import com.google.gwt.aria.client.Roles;
+import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.SimplePanel;
-import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.BrowserInfo;
import com.vaadin.client.LayoutManager;
import com.vaadin.client.StyleConstants;
import com.vaadin.client.Util;
+import com.vaadin.client.ui.FontIcon;
+import com.vaadin.client.ui.Icon;
+import com.vaadin.client.ui.ImageIcon;
import com.vaadin.client.ui.layout.ElementResizeEvent;
import com.vaadin.client.ui.layout.ElementResizeListener;
import com.vaadin.shared.ui.AlignmentInfo;
@@ -39,44 +42,6 @@ import com.vaadin.shared.ui.AlignmentInfo;
* Represents a slot which contains the actual widget in the layout.
*/
public final class Slot extends SimplePanel {
- /**
- * The icon for each widget. Located in the caption of the slot.
- */
- private static class Icon extends UIObject {
-
- public static final String CLASSNAME = "v-icon";
-
- private String myUrl;
-
- /**
- * Constructor
- */
- public Icon() {
- setElement(DOM.createImg());
- DOM.setElementProperty(getElement(), "alt", "");
- setStyleName(CLASSNAME);
- }
-
- /**
- * Set the URL where the icon is located
- *
- * @param url
- * A fully qualified URL
- */
- public void setUri(String url) {
- if (!url.equals(myUrl)) {
- /*
- * Start sinking onload events, widgets responsibility to react.
- * We must do this BEFORE we set src as IE fires the event
- * immediately if the image is found in cache (#2592).
- */
- sinkEvents(Event.ONLOAD);
-
- DOM.setElementProperty(getElement(), "src", url);
- myUrl = url;
- }
- }
- }
private static final String ALIGN_CLASS_PREFIX = "v-align-";
@@ -123,15 +88,12 @@ public final class Slot extends SimplePanel {
private double expandRatio = -1;
/**
- * Constructor
+ * Constructs a slot.
*
+ * @param layout
+ * The layout to which this slot belongs
* @param widget
* The widget to put in the slot
- * @param layout
- * TODO
- *
- * @param layoutManager
- * The layout manager used by the layout
*/
public Slot(VAbstractOrderedLayout layout, Widget widget) {
this.layout = layout;
@@ -437,7 +399,7 @@ public final class Slot extends SimplePanel {
* @param captionText
* The text of the caption
* @param iconUrl
- * The icon URL
+ * The icon URL, must already be run trough translateVaadinUri()
* @param styles
* The style names
* @param error
@@ -448,10 +410,47 @@ public final class Slot extends SimplePanel {
* Is the (field) required
* @param enabled
* Is the component enabled
+ *
+ * @deprecated Use
+ * {@link #setCaption(String, Icon, List, String, boolean, boolean, boolean)}
+ * instead
*/
+ @Deprecated
public void setCaption(String captionText, String iconUrl,
List styles, String error, boolean showError,
boolean required, boolean enabled) {
+ Icon icon;
+ if (FontIcon.isFontIconUri(iconUrl)) {
+ icon = GWT.create(FontIcon.class);
+ } else {
+ icon = GWT.create(ImageIcon.class);
+ }
+ icon.setUri(iconUrl);
+
+ setCaption(captionText, icon, styles, error, showError, required,
+ enabled);
+ }
+
+ /**
+ * Set the caption of the slot
+ *
+ * @param captionText
+ * The text of the caption
+ * @param icon
+ * The icon
+ * @param styles
+ * The style names
+ * @param error
+ * The error message
+ * @param showError
+ * Should the error message be shown
+ * @param required
+ * Is the (field) required
+ * @param enabled
+ * Is the component enabled
+ */
+ public void setCaption(String captionText, Icon icon, List styles,
+ String error, boolean showError, boolean required, boolean enabled) {
// TODO place for optimization: check if any of these have changed
// since last time, and only run those changes
@@ -461,7 +460,7 @@ public final class Slot extends SimplePanel {
final Element focusedElement = Util.getFocusedElement();
// By default focus will not be lost
boolean focusLost = false;
- if (captionText != null || iconUrl != null || error != null || required) {
+ if (captionText != null || icon != null || error != null || required) {
if (caption == null) {
caption = DOM.createDiv();
captionWrap = DOM.createDiv();
@@ -508,16 +507,13 @@ public final class Slot extends SimplePanel {
}
// Icon
- if (iconUrl != null) {
- if (icon == null) {
- icon = new Icon();
- caption.insertFirst(icon.getElement());
- }
- icon.setUri(iconUrl);
- } else if (icon != null) {
+ if (this.icon != null) {
icon.getElement().removeFromParent();
- icon = null;
}
+ if (icon != null) {
+ caption.insertFirst(icon.getElement());
+ }
+ this.icon = icon;
// Required
if (required) {
@@ -568,7 +564,7 @@ public final class Slot extends SimplePanel {
}
// Caption position
- if (captionText != null || iconUrl != null) {
+ if (captionText != null || icon != null) {
setCaptionPosition(CaptionPosition.TOP);
} else {
setCaptionPosition(CaptionPosition.RIGHT);
diff --git a/client/src/com/vaadin/client/ui/panel/PanelConnector.java b/client/src/com/vaadin/client/ui/panel/PanelConnector.java
index 4011f86c76..f2e73bae80 100644
--- a/client/src/com/vaadin/client/ui/panel/PanelConnector.java
+++ b/client/src/com/vaadin/client/ui/panel/PanelConnector.java
@@ -137,8 +137,8 @@ public class PanelConnector extends AbstractSingleComponentContainerConnector
getWidget().client = client;
getWidget().id = uidl.getId();
- if (getIcon() != null) {
- getWidget().setIconUri(getIcon(), client);
+ if (getIconUri() != null) {
+ getWidget().setIconUri(getIconUri(), client);
} else {
getWidget().setIconUri(null, client);
}
diff --git a/client/src/com/vaadin/client/ui/window/WindowConnector.java b/client/src/com/vaadin/client/ui/window/WindowConnector.java
index 788799d81c..b6fe541c00 100644
--- a/client/src/com/vaadin/client/ui/window/WindowConnector.java
+++ b/client/src/com/vaadin/client/ui/window/WindowConnector.java
@@ -295,8 +295,8 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector
// Caption must be set before required header size is measured. If
// the caption attribute is missing the caption should be cleared.
String iconURL = null;
- if (getIcon() != null) {
- iconURL = getIcon();
+ if (getIconUri() != null) {
+ iconURL = getIconUri();
}
window.setAssistivePrefix(state.assistivePrefix);
diff --git a/server/src/com/vaadin/server/FontAwesome.java b/server/src/com/vaadin/server/FontAwesome.java
new file mode 100644
index 0000000000..a7f4c7b342
--- /dev/null
+++ b/server/src/com/vaadin/server/FontAwesome.java
@@ -0,0 +1,447 @@
+/*
+ * 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.server;
+
+/**
+ * FontAwesome set of font icons.
+ *
+ * Each {@link FontIcon} comes from the FontAwesome font family, which is
+ * included in the theme.
+ * Consider this a starting point: it is unlikely an application needs exactly
+ * these icons, and all of them, so you might want to consider making a custom
+ * icon font - either to get other icons, or to minimize the size of the font.
+ *
+ * {@link FontIcon} is a custom resource type which uses the URI scheme
+ * fonticon://<fontfamily>/<codepoint> to reference a
+ * specific icon from a specific icon font.
+ *
+ *
+ * @since 7.2
+ * @author Vaadin Ltd
+ */
+public interface FontIcon extends Resource {
+ /**
+ * Returns the name (font family) of the font from which this icon comes.
+ * The name is used to apply the correct font where the icon is used.
+ *
+ * @since 7.2
+ * @return
+ */
+ public String getFontFamily();
+
+ /**
+ * Returns the unicode codepoint (character location) for this icon within
+ * the font given in {@link #getFontFamily()}.
+ *
+ * For example, 0x0021 would in a regular font be the codepoint for the
+ * exclamation-point character.
+ * When constructing icon fonts, it might be a good idea to use the
+ * codepoints in the "Private use area", from 0xE000 0xF8FF.
+ *
+ *
+ * @since 7.2
+ * @return
+ */
+ public int getCodepoint();
+
+ /**
+ * Returns HTML that can be used to display the icon in places where HTML
+ * can be used, such as a {@link Label} with {@link ContentMode#HTML}.
+ *
+ *
+ * @since 7.2
+ * @return HTML needed to display icon
+ */
+ public String getHtml();
+}
diff --git a/server/src/com/vaadin/server/ResourceReference.java b/server/src/com/vaadin/server/ResourceReference.java
index 6747dd2b74..4bc8febd72 100644
--- a/server/src/com/vaadin/server/ResourceReference.java
+++ b/server/src/com/vaadin/server/ResourceReference.java
@@ -67,6 +67,13 @@ public class ResourceReference extends URLReference {
final String uri = "theme://"
+ ((ThemeResource) resource).getResourceId();
return uri;
+ } else if (resource instanceof FontIcon) {
+ // fonticon://[font-family]/[codepoint]
+ final FontIcon icon = (FontIcon) resource;
+ final String uri = ApplicationConstants.FONTICON_PROTOCOL_PREFIX
+ + urlEncode(icon.getFontFamily()) + "/"
+ + Integer.toHexString(icon.getCodepoint());
+ return uri;
} else {
throw new RuntimeException(getClass().getSimpleName()
+ " does not support resources of type: "
diff --git a/shared/src/com/vaadin/shared/ApplicationConstants.java b/shared/src/com/vaadin/shared/ApplicationConstants.java
index a81f29b77c..d54823ee60 100644
--- a/shared/src/com/vaadin/shared/ApplicationConstants.java
+++ b/shared/src/com/vaadin/shared/ApplicationConstants.java
@@ -35,6 +35,7 @@ public class ApplicationConstants implements Serializable {
public static final String APP_PROTOCOL_PREFIX = "app://";
public static final String VAADIN_PROTOCOL_PREFIX = "vaadin://";
+ public static final String FONTICON_PROTOCOL_PREFIX = "fonticon://";
public static final String PUBLISHED_PROTOCOL_NAME = "published";
public static final String PUBLISHED_PROTOCOL_PREFIX = PUBLISHED_PROTOCOL_NAME
+ "://";
diff --git a/uitest/src/com/vaadin/tests/fonticon/FontIcons.java b/uitest/src/com/vaadin/tests/fonticon/FontIcons.java
new file mode 100644
index 0000000000..5511acf3bf
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/fonticon/FontIcons.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2000-2013 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.fonticon;
+
+import com.vaadin.event.Action;
+import com.vaadin.event.Action.Handler;
+import com.vaadin.server.FontAwesome;
+import com.vaadin.server.FontIcon;
+import com.vaadin.server.Page;
+import com.vaadin.server.Resource;
+import com.vaadin.server.ThemeResource;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.Position;
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.AbstractSelect;
+import com.vaadin.ui.Accordion;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.DateField;
+import com.vaadin.ui.GridLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Link;
+import com.vaadin.ui.ListSelect;
+import com.vaadin.ui.MenuBar;
+import com.vaadin.ui.MenuBar.MenuItem;
+import com.vaadin.ui.NativeButton;
+import com.vaadin.ui.NativeSelect;
+import com.vaadin.ui.Notification;
+import com.vaadin.ui.OptionGroup;
+import com.vaadin.ui.Panel;
+import com.vaadin.ui.Slider;
+import com.vaadin.ui.TabSheet;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.Table.Align;
+import com.vaadin.ui.Table.RowHeaderMode;
+import com.vaadin.ui.TextArea;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.Tree;
+import com.vaadin.ui.TwinColSelect;
+import com.vaadin.ui.Upload;
+import com.vaadin.ui.VerticalLayout;
+
+/**
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class FontIcons extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ buildUI(FontAwesome.ANDROID);
+ }
+
+ private void buildUI(final Resource icon) {
+ VerticalLayout layout = new VerticalLayout();
+ setContent(layout);
+ layout.setMargin(true);
+
+ layout.setIcon(icon);
+
+ layout.addComponent(new Button("Switch icon type",
+ new Button.ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ buildUI(icon instanceof FontIcon ? new ThemeResource(
+ "../runo/icons/16/user.png")
+ : FontAwesome.ANDROID);
+ }
+ }));
+
+ Handler actionHandler = new Handler() {
+ Action[] actions = { new Action("Do it!", icon) };
+
+ @Override
+ public void handleAction(Action action, Object sender, Object target) {
+
+ }
+
+ @Override
+ public Action[] getActions(Object target, Object sender) {
+ return actions;
+ }
+ };
+
+ // Notification
+ Notification n = new Notification("Hey there!");
+ n.setIcon(icon);
+ n.setPosition(Position.BOTTOM_CENTER);
+ n.setDelayMsec(-1);
+ n.show(Page.getCurrent());
+
+ // grid of compoents
+ GridLayout gl = new GridLayout(4, 5);
+ gl.setSpacing(true);
+ layout.addComponent(gl);
+
+ // Basic components, caption icon only
+ Class>[] components = { Button.class, CheckBox.class,
+ DateField.class, NativeButton.class, Link.class, Label.class,
+ Panel.class, Slider.class, TextArea.class, TextField.class,
+ Upload.class };
+ for (Class> clazz : components) {
+ Component c;
+ try {
+ c = (Component) clazz.newInstance();
+ } catch (Exception e) {
+ e.printStackTrace();
+ continue;
+ }
+ c.setCaption(clazz.getSimpleName());
+ c.setIcon(icon);
+ gl.addComponent(c);
+ }
+
+ // TabSheet, caption + tab icons
+ TabSheet tabs = new TabSheet();
+ tabs.setCaption("TabSheet");
+ tabs.setIcon(icon);
+ tabs.addStyleName("myTabs");
+ tabs.addTab(new Label("Content 1"), "Tab 1", icon);
+ tabs.addTab(new Label("Content 2"), "Tab 2", icon);
+ tabs.setWidth("150px");
+ gl.addComponent(tabs);
+
+ // Accordion, caption + tab icons
+ Accordion acc = new Accordion();
+ acc.setCaption("Accordion");
+ acc.setIcon(icon);
+ acc.addTab(new Label(), "Section 1", icon);
+ acc.addTab(new Label(), "Section 2", icon);
+ gl.addComponent(acc);
+
+ // Table, caption + column + row + action icons
+ Table tbl = new Table("Table");
+ tbl.setRowHeaderMode(RowHeaderMode.ICON_ONLY);
+ tbl.setIcon(icon);
+ tbl.addContainerProperty("Column 1", String.class, "Row", "Column 1",
+ icon, Align.LEFT);
+ tbl.addContainerProperty("Column 2", String.class, "Row", "Column 2",
+ icon, Align.LEFT);
+ tbl.setItemIcon(tbl.addItem(), icon);
+ tbl.setItemIcon(tbl.addItem(), icon);
+ tbl.setItemIcon(tbl.addItem(), icon);
+ tbl.setPageLength(3);
+ gl.addComponent(tbl);
+ tbl.addActionHandler(actionHandler);
+
+ // Selects, caption + item icons
+ Class>[] selects = { ComboBox.class, NativeSelect.class,
+ ListSelect.class, TwinColSelect.class, OptionGroup.class };
+ for (Class> clazz : selects) {
+ AbstractSelect sel;
+ try {
+ sel = (AbstractSelect) clazz.newInstance();
+ } catch (Exception e) {
+ e.printStackTrace();
+ continue;
+ }
+ sel.setCaption(clazz.getSimpleName());
+ sel.setIcon(icon);
+ sel.addItem("One");
+ sel.setItemIcon("One", icon);
+ sel.addItem("Two");
+ sel.setItemIcon("Two", icon);
+ gl.addComponent(sel);
+ }
+
+ // MenuBar, caption + item + sub-item icons
+ MenuBar menu = new MenuBar();
+ menu.setIcon(icon);
+ menu.setCaption("MenuBar");
+ MenuItem mi = menu.addItem("File", icon, null);
+ MenuItem smi = mi.addItem("Item", icon, null);
+ smi = mi.addItem("Item", icon, null);
+ smi = smi.addItem("Item", icon, null);
+ gl.addComponent(menu);
+
+ // Tree, caption + item + subitem + action icons
+ Tree tree = new Tree("Tree");
+ tree.addItem("Root");
+ tree.setItemIcon("Root", icon);
+ tree.addItem("Leaf");
+ tree.setItemIcon("Leaf", icon);
+ tree.setParent("Leaf", "Root");
+ tree.expandItemsRecursively("Root");
+ tree.addActionHandler(actionHandler);
+ gl.addComponent(tree);
+
+ // All of FontAwesome
+ String allIcons = "";
+ for (FontIcon ic : FontAwesome.values()) {
+ allIcons += ic.getHtml() + " ";
+ }
+ layout.addComponent(new Label(allIcons, ContentMode.HTML));
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Font icons should show up in all the right places";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 13152;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/fonticon/FontIconsTest.java b/uitest/src/com/vaadin/tests/fonticon/FontIconsTest.java
new file mode 100644
index 0000000000..af54b73ae3
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/fonticon/FontIconsTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2013 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.fonticon;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class FontIconsTest extends MultiBrowserTest {
+
+ @Test
+ public void checkScreenshot() throws IOException {
+ openTestURL();
+ compareScreen("all");
+ }
+}
--
cgit v1.2.3
From 4188c706e2a0de6216cf258339552d9f6abcb7c6 Mon Sep 17 00:00:00 2001
From: Artur Signell
Date: Tue, 25 Feb 2014 14:31:01 +0200
Subject: Fixed invalid HTML/XML
Change-Id: Icd9e30e54e5353277e4c5406269613cbb8a37414
---
WebContent/statictestfiles/EmbedSizeHostPage.html | 3 +-
.../componentlocator/TestDetachedNotPresent.html | 1 -
.../optiongroup/OptionGroupParentDisabled.html | 2 +-
.../tests/fieldgroup/CommitHandlerFailures.html | 431 ++++++++++-----------
.../CommitWithValidationOrConversionError.html | 296 +++++++-------
5 files changed, 362 insertions(+), 371 deletions(-)
(limited to 'WebContent')
diff --git a/WebContent/statictestfiles/EmbedSizeHostPage.html b/WebContent/statictestfiles/EmbedSizeHostPage.html
index 2576a200db..3ef6c5d0cd 100644
--- a/WebContent/statictestfiles/EmbedSizeHostPage.html
+++ b/WebContent/statictestfiles/EmbedSizeHostPage.html
@@ -37,7 +37,6 @@ setTimeout('if (typeof com_vaadin_DefaultWidgetSet == "undefined") {alert("Faile
Test page for resize events with embedded applications