Wicket-5801 Responsive Images

Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/0880713f
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/0880713f
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/0880713f

Branch: refs/heads/master
Commit: 0880713fa15ee8ce67c8005759312964609f5e7c
Parents: 1c1bb4d
Author: klopfdreh <klopfdreh@tobiass-mbp>
Authored: Tue Jan 20 00:21:34 2015 +0100
Committer: Martin Tzvetanov Grigorov <mgrigo...@apache.org>
Committed: Wed Jan 28 18:53:33 2015 +0200

----------------------------------------------------------------------
 .../apache/wicket/markup/html/image/Image.java  | 277 ++++++++++++++++---
 .../wicket/markup/html/image/Picture.java       |  67 +++++
 .../apache/wicket/markup/html/image/Source.java | 123 ++++++++
 .../markup/html/image/ImagePictureTestPage.html |  13 +
 .../markup/html/image/ImagePictureTestPage.java |  45 +++
 .../image/ImageResourceReferenceTestPage.html   |   9 +
 .../image/ImageResourceReferenceTestPage.java   |  46 +++
 .../markup/html/image/ImageSrcSetTestPage.html  |   9 +
 .../markup/html/image/ImageSrcSetTestPage.java  |  37 +++
 .../markup/html/image/ResponsiveImageTest.java  |  90 ++++++
 .../org/apache/wicket/examples/images/Home.html |   6 +
 .../org/apache/wicket/examples/images/Home.java |  32 +++
 .../wicket/examples/images/Image2_large.gif     | Bin 0 -> 1562 bytes
 .../wicket/examples/images/Image2_medium.gif    | Bin 0 -> 1276 bytes
 .../wicket/examples/images/Image2_small.gif     | Bin 0 -> 1092 bytes
 15 files changed, 718 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/0880713f/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Image.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Image.java 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Image.java
index 93d4475..74b6512 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Image.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Image.java
@@ -17,6 +17,9 @@
 package org.apache.wicket.markup.html.image;
 
 import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 import org.apache.wicket.Component;
 import org.apache.wicket.IResourceListener;
@@ -32,22 +35,37 @@ import org.apache.wicket.request.resource.IResource;
 import org.apache.wicket.request.resource.ResourceReference;
 
 /**
- * An Image component displays a localizable image resource.
+ * An Image component displays localizable image resources.
  * <p>
  * For details of how Images load, generate and manage images, see {@link 
LocalizedImageResource}.
  * 
+ * The first ResourceReference / ImageResource is used for the src attribute 
within the img tag, all
+ * following are applied to the srcset. If setXValues(String... values) is 
used the values are set
+ * behind the srcset elements in the order they are given to the 
setXValues(String... valus) method.
+ * The separated values in the sizes attribute are set with setSizes(String... 
sizes)
+ *
  * @see NonCachingImage
  * 
  * @author Jonathan Locke
+ * @author Tobias Soloschenko
  * 
  */
 public class Image extends WebComponent implements IResourceListener
 {
        private static final long serialVersionUID = 1L;
 
-       /** The image resource this image component references */
+       /** The image resource this image component references (src attribute) 
*/
        private final LocalizedImageResource localizedImageResource = new 
LocalizedImageResource(this);
 
+       /** The image resources this image component references (srcset 
attribute) */
+       private final List<LocalizedImageResource> localizedImageResources = 
new ArrayList<LocalizedImageResource>();
+
+       /** The x values to be used within the srcset */
+       private List<String> xValues = null;
+
+       /** The sizes of the responsive images */
+       private List<String> sizes = null;
+
        /**
         * This constructor can be used if you override {@link 
#getImageResourceReference()} or
         * {@link #getImageResource()}
@@ -72,11 +90,14 @@ public class Image extends WebComponent implements 
IResourceListener
         * @param id
         *            See Component
         * @param resourceReference
-        *            The shared image resource
+        *            The shared image resource used in the src attribute
+        * @param resourceReferences
+        *            The shared image resources used in the srcset attribute
         */
-       public Image(final String id, final ResourceReference resourceReference)
+       public Image(final String id, final ResourceReference resourceReference,
+               final ResourceReference... resourceReferences)
        {
-               this(id, resourceReference, null);
+               this(id, resourceReference, null, resourceReferences);
        }
 
        /**
@@ -92,15 +113,18 @@ public class Image extends WebComponent implements 
IResourceListener
         * @param id
         *            See Component
         * @param resourceReference
-        *            The shared image resource
+        *            The shared image resource used in the src attribute
         * @param resourceParameters
         *            The resource parameters
+        * @param resourceReferences
+        *            The shared image resources used in the srcset attribute
         */
        public Image(final String id, final ResourceReference resourceReference,
-               PageParameters resourceParameters)
+               PageParameters resourceParameters, final ResourceReference... 
resourceReferences)
        {
                super(id);
-               setImageResourceReference(resourceReference, 
resourceParameters);
+               this.setImageResourceReference(resourceParameters, 
resourceReference);
+               this.setImageResourceReferences(resourceParameters, 
resourceReferences);
        }
 
        /**
@@ -114,12 +138,15 @@ public class Image extends WebComponent implements 
IResourceListener
         *            See Component
         * 
         * @param imageResource
-        *            The image resource
+        *            The image resource used in the src attribute
+        * @param imageResources
+        *            The image resource used in the srcset attribute
         */
-       public Image(final String id, final IResource imageResource)
+       public Image(final String id, final IResource imageResource, final 
IResource... imageResources)
        {
                super(id);
-               setImageResource(imageResource);
+               this.setImageResource(imageResource);
+               this.setImageResources(imageResources);
        }
 
        /**
@@ -139,7 +166,7 @@ public class Image extends WebComponent implements 
IResourceListener
         */
        public Image(final String id, final String string)
        {
-               this(id, new Model<>(string));
+               this(id, new Model<String>(string));
        }
 
        /**
@@ -149,6 +176,10 @@ public class Image extends WebComponent implements 
IResourceListener
        public void onResourceRequested()
        {
                localizedImageResource.onResourceRequested(null);
+               for (LocalizedImageResource localizedImageResource : 
this.localizedImageResources)
+               {
+                       localizedImageResource.onResourceRequested(null);
+               }
        }
 
        /**
@@ -157,28 +188,99 @@ public class Image extends WebComponent implements 
IResourceListener
         */
        public void setImageResource(final IResource imageResource)
        {
-               localizedImageResource.setResource(imageResource);
+               if (imageResource != null)
+               {
+                       this.localizedImageResource.setResource(imageResource);
+               }
        }
 
        /**
-        * @param resourceReference
-        *            The shared ImageResource to set.
+        *
+        * @param imageResources
+        *            the new ImageResource to set.
         */
-       public void setImageResourceReference(final ResourceReference 
resourceReference)
+       public void setImageResources(final IResource... imageResources)
        {
-               localizedImageResource.setResourceReference(resourceReference);
+               this.localizedImageResources.clear();
+               for (IResource imageResource : imageResources)
+               {
+                       LocalizedImageResource localizedImageResource = new 
LocalizedImageResource(this);
+                       localizedImageResource.setResource(imageResource);
+                       
this.localizedImageResources.add(localizedImageResource);
+               }
        }
 
        /**
         * @param resourceReference
-        *            The shared ImageResource to set.
+        *            The resource reference to set.
+        */
+       public void setImageResourceReference(final PageParameters parameters,
+               final ResourceReference resourceReference)
+       {
+               if (localizedImageResource != null)
+               {
+                       if (parameters != null)
+                       {
+                               
this.localizedImageResource.setResourceReference(resourceReference, parameters);
+                       }
+                       else
+                       {
+                               
this.localizedImageResource.setResourceReference(resourceReference);
+                       }
+               }
+       }
+
+       /**
         * @param parameters
         *            Set the resource parameters for the resource.
+        * @param resourceReferences
+        *            The resource references to set.
         */
-       public void setImageResourceReference(final ResourceReference 
resourceReference,
-               final PageParameters parameters)
+       public void setImageResourceReferences(final PageParameters parameters,
+               final ResourceReference... resourceReferences)
        {
-               localizedImageResource.setResourceReference(resourceReference, 
parameters);
+               this.localizedImageResources.clear();
+               for (ResourceReference resourceReference : resourceReferences)
+               {
+                       LocalizedImageResource localizedImageResource = new 
LocalizedImageResource(this);
+                       if (parameters != null)
+                       {
+                               
localizedImageResource.setResourceReference(resourceReference, parameters);
+                       }
+                       else
+                       {
+                               
localizedImageResource.setResourceReference(resourceReference);
+                       }
+                       
this.localizedImageResources.add(localizedImageResource);
+               }
+       }
+
+       /**
+        * @param values
+        *            the x values to be used in the srcset
+        */
+       public void setXValues(String... values)
+       {
+               if (this.xValues == null)
+               {
+                       xValues = new ArrayList<String>();
+               }
+               this.xValues.clear();
+               this.xValues.addAll(Arrays.asList(values));
+       }
+
+       /**
+        * @param sizes
+        *            the sizes to be used in the size
+        */
+       public void setSizes(String... sizes)
+       {
+               if (this.sizes == null)
+               {
+                       this.sizes = new ArrayList<String>();
+               }
+               this.sizes.clear();
+               this.sizes.addAll(Arrays.asList(sizes));
        }
 
        /**
@@ -189,6 +291,11 @@ public class Image extends WebComponent implements 
IResourceListener
        {
                // Null out the image resource, so we reload it (otherwise 
we'll be
                // stuck with the old model.
+               for (LocalizedImageResource localizedImageResource : 
this.localizedImageResources)
+               {
+                       localizedImageResource.setResourceReference(null);
+                       localizedImageResource.setResource(null);
+               }
                localizedImageResource.setResourceReference(null);
                localizedImageResource.setResource(null);
                return super.setDefaultModel(model);
@@ -228,29 +335,116 @@ public class Image extends WebComponent implements 
IResourceListener
        @Override
        protected void onComponentTag(final ComponentTag tag)
        {
-               checkComponentTag(tag, "img");
                super.onComponentTag(tag);
-               final IResource resource = getImageResource();
+               if (tag.getName().equals("source"))
+               {
+                       this.buildSrcSetAttribute(tag);
+                       tag.remove("src");
+               }
+               else
+               {
+                       this.checkComponentTag(tag, "img");
+                       String srcAttribute = this.buildSrcAttribute(tag);
+                       this.buildSrcSetAttribute(tag);
+                       tag.put("src", srcAttribute);
+               }
+               this.buildSizesAttribute(tag);
+       }
+
+       /**
+        * Builds the srcset attribute if multiple localizedImageResources are 
found as varargs
+        *
+        * @param tag
+        *            the component tag
+        */
+       protected void buildSrcSetAttribute(final ComponentTag tag)
+       {
+               int srcSetPosition = 0;
+               for (LocalizedImageResource localizedImageResource : 
this.localizedImageResources)
+               {
+                       localizedImageResource.setSrcAttribute(tag);
+
+                       if (this.shouldAddAntiCacheParameter())
+                       {
+                               this.addAntiCacheParameter(tag);
+                       }
+
+                       String srcset = tag.getAttribute("srcset");
+                       String xValue = "";
+
+                       // If there are xValues set process them in the applied 
order to the srcset attribute.
+                       if (this.xValues != null)
+                       {
+                               xValue = this.xValues.size() > srcSetPosition &&
+                                       this.xValues.get(srcSetPosition) != 
null ? " " +
+                                       this.xValues.get(srcSetPosition) : "";
+                       }
+                       tag.put("srcset", (srcset != null ? srcset + ", " : "") 
+ tag.getAttribute("src") +
+                               xValue);
+                       srcSetPosition++;
+               }
+       }
+
+       /**
+        * Builds the src attribute
+        *
+        * @param tag
+        *            the component tag
+        * @return the value of the src attribute
+        */
+       protected String buildSrcAttribute(final ComponentTag tag)
+       {
+               final IResource resource = this.getImageResource();
                if (resource != null)
                {
-                       localizedImageResource.setResource(resource);
+                       this.localizedImageResource.setResource(resource);
                }
-               final ResourceReference resourceReference = 
getImageResourceReference();
+               final ResourceReference resourceReference = 
this.getImageResourceReference();
                if (resourceReference != null)
                {
-                       
localizedImageResource.setResourceReference(resourceReference);
+                       
this.localizedImageResource.setResourceReference(resourceReference);
                }
-               localizedImageResource.setSrcAttribute(tag);
+               this.localizedImageResource.setSrcAttribute(tag);
 
-               if (shouldAddAntiCacheParameter())
+               if (this.shouldAddAntiCacheParameter())
+               {
+                       this.addAntiCacheParameter(tag);
+               }
+               return tag.getAttribute("src");
+       }
+
+       /**
+        * builds the sizes attribute of the img tag
+        *
+        * @param tag
+        *            the component tag
+        */
+       protected void buildSizesAttribute(final ComponentTag tag)
+       {
+               // if no sizes have been set then don't build the attribute
+               if (this.sizes == null)
+               {
+                       return;
+               }
+               String sizes = "";
+               for (String size : this.sizes)
+               {
+                       sizes += size + ",";
+               }
+               int lastIndexOf = sizes.lastIndexOf(",");
+               if (lastIndexOf != -1)
                {
-                       addAntiCacheParameter(tag);
+                       sizes = sizes.substring(0, lastIndexOf);
+               }
+               if (!"".equals(sizes))
+               {
+                       tag.put("sizes", sizes);
                }
        }
 
        /**
-        * Adding an image to {@link org.apache.wicket.ajax.AjaxRequestTarget} 
most of the times mean that the image has
-        * changes and must be re-rendered.
+        * Adding an image to {@link org.apache.wicket.ajax.AjaxRequestTarget} 
most of the times mean
+        * that the image has changes and must be re-rendered.
         * <p>
         * With this method the user may change this default behavior for some 
of her images.
         * </p>
@@ -259,7 +453,7 @@ public class Image extends WebComponent implements 
IResourceListener
         */
        protected boolean shouldAddAntiCacheParameter()
        {
-               return getRequestCycle().find(AjaxRequestTarget.class) != null;
+               return this.getRequestCycle().find(AjaxRequestTarget.class) != 
null;
        }
 
        /**
@@ -282,8 +476,17 @@ public class Image extends WebComponent implements 
IResourceListener
        @Override
        protected boolean getStatelessHint()
        {
-               return (getImageResource() == null || getImageResource() == 
localizedImageResource.getResource()) &&
+               boolean stateless = (getImageResource() == null || 
getImageResource() == localizedImageResource.getResource()) &&
                        localizedImageResource.isStateless();
+               boolean statelessList = false;
+               for (LocalizedImageResource localizedImageResource : 
this.localizedImageResources)
+               {
+                       if (localizedImageResource.isStateless())
+                       {
+                               statelessList = true;
+                       }
+               }
+               return stateless || statelessList;
        }
 
        /**
@@ -297,10 +500,12 @@ public class Image extends WebComponent implements 
IResourceListener
        @Override
        public boolean canCallListenerInterface(Method method)
        {
-               boolean isResource = method != null && 
IResourceListener.class.isAssignableFrom(method.getDeclaringClass());
-               if (isResource && isVisibleInHierarchy())
+               boolean isResource = method != null &&
+                       
IResourceListener.class.isAssignableFrom(method.getDeclaringClass());
+               if (isResource && this.isVisibleInHierarchy())
                {
-                       // when the image data is requested we do not care if 
this component is enabled in
+                       // when the image data is requested we do not care if 
this component
+                       // is enabled in
                        // hierarchy or not, only that it is visible
                        return true;
                }

http://git-wip-us.apache.org/repos/asf/wicket/blob/0880713f/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Picture.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Picture.java 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Picture.java
new file mode 100644
index 0000000..5cf5fb5
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Picture.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.wicket.markup.html.image;
+
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.model.IModel;
+
+/**
+ * A component which displays localizable image resources within source and 
image elements as
+ * responsive image. Elements are added with addImage / addSource.
+ *
+ * @author Tobias Soloschenko
+ */
+public class Picture extends WebMarkupContainer
+{
+
+       private static final long serialVersionUID = 1L;
+
+       /**
+        * Creates a picture component
+        *
+        * @param id
+        *            the id of the picture component
+        */
+       public Picture(String id)
+       {
+               super(id);
+       }
+
+       /**
+        * Creates a picture component
+        *
+        * @param id
+        *            the id of the picture component
+        * @param model
+        *            the component's model
+        */
+       public Picture(String id, IModel<?> model)
+       {
+               super(id, model);
+       }
+
+       /**
+        * builds the component tag and checks the tag to be a picture
+        */
+       @Override
+       protected void onComponentTag(ComponentTag tag)
+       {
+               this.checkComponentTag(tag, "picture");
+               super.onComponentTag(tag);
+       }
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/0880713f/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Source.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Source.java 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Source.java
new file mode 100644
index 0000000..cb074e9
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Source.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.wicket.markup.html.image;
+
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.request.resource.IResource;
+import org.apache.wicket.request.resource.ResourceReference;
+
+/**
+ * A component which displays localizable image resources within a picture tag.
+ *
+ * The source tag is the same as the image element, but it is also possible to 
set the media
+ * attribute with setMedia(String media). The second difference is that there 
is no src attribute,
+ * so every ResourceReference and ImageResource is added directly to the 
srcset attribute.
+ *
+ * @see org.apache.wicket.markup.html.image.Image
+ * @author Tobias Soloschenko
+ *
+ */
+public class Source extends Image
+{
+
+       private static final long serialVersionUID = 1L;
+
+       private String media = null;
+
+       /**
+        * @see org.apache.wicket.markup.html.image.Image
+        */
+       protected Source(final String id)
+       {
+               super(id);
+       }
+
+       /**
+        * @see org.apache.wicket.markup.html.image.Image
+        */
+       public Source(final String id, final ResourceReference... 
resourceReferences)
+       {
+               super(id, null, resourceReferences);
+       }
+
+       /**
+        * @see org.apache.wicket.markup.html.image.Image
+        */
+       public Source(final String id, PageParameters resourceParameters,
+               final ResourceReference... resourceReferences)
+       {
+               super(id, null, resourceParameters, resourceReferences);
+       }
+
+       /**
+        * @see org.apache.wicket.markup.html.image.Image
+        */
+       public Source(final String id, final IResource... imageResources)
+       {
+               super(id, null, imageResources);
+       }
+
+       /**
+        * @see org.apache.wicket.Component#Component(String, IModel)
+        */
+       public Source(final String id, final IModel<?> model)
+       {
+               super(id, model);
+       }
+
+       /**
+        * @see org.apache.wicket.markup.html.image.Image
+        */
+       public Source(final String id, final String string)
+       {
+               super(id, string);
+       }
+
+       @Override
+       protected void onComponentTag(ComponentTag tag)
+       {
+               checkComponentTag(tag, "source");
+               super.onComponentTag(tag);
+               if (this.media != null)
+               {
+                       tag.put("media", getMedia());
+               }
+       }
+
+       /**
+        * Sets the media attribute information
+        *
+        * @param media
+        *            the media attribute information
+        */
+       public void setMedia(String media)
+       {
+               this.media = media;
+       }
+
+       /**
+        * Gets the media attribute information
+        *
+        * @return the media attribute information
+        */
+       public String getMedia()
+       {
+               return media;
+       }
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/0880713f/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImagePictureTestPage.html
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImagePictureTestPage.html
 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImagePictureTestPage.html
new file mode 100644
index 0000000..913da1e
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImagePictureTestPage.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+       <head>
+               <title>de.test.testimage</title>
+       </head>
+       <body>
+               <picture wicket:id="picture">
+                       <source wicket:id="sourcelarge" />
+                       <source wicket:id="sourcemedium" />
+                       <img wicket:id="image3"/>
+               </picture>
+       </body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/0880713f/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImagePictureTestPage.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImagePictureTestPage.java
 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImagePictureTestPage.java
new file mode 100644
index 0000000..9d96368
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImagePictureTestPage.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.wicket.markup.html.image;
+
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.request.resource.PackageResourceReference;
+
+public class ImagePictureTestPage extends WebPage
+{
+
+       private static final long serialVersionUID = 1L;
+
+       public ImagePictureTestPage()
+       {
+               Picture picture = new Picture("picture");
+               Source large = new Source("sourcelarge", new 
PackageResourceReference(this.getClass(),
+                       "large.jpg"));
+               large.setMedia("(min-width: 650px)");
+               large.setSizes("(min-width: 50em) 33vw");
+               picture.add(large);
+               large.setOutputMarkupId(true);
+               Source medium = new Source("sourcemedium", new 
PackageResourceReference(this.getClass(),
+                       "medium.jpg"));
+               medium.setMedia("(min-width: 465px)");
+               picture.add(medium);
+               Image image3 = new Image("image3", new 
PackageResourceReference(this.getClass(),
+                       "small.jpg"));
+               picture.add(image3);
+               this.add(picture);
+       }
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/0880713f/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageResourceReferenceTestPage.html
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageResourceReferenceTestPage.html
 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageResourceReferenceTestPage.html
new file mode 100644
index 0000000..a61db1d
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageResourceReferenceTestPage.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+       <head>
+               <title>de.test.testimage</title>
+       </head>
+       <body>
+               <img wicket:id="image1" class="image1"/>
+       </body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/0880713f/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageResourceReferenceTestPage.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageResourceReferenceTestPage.java
 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageResourceReferenceTestPage.java
new file mode 100644
index 0000000..cb96f67
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageResourceReferenceTestPage.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.wicket.markup.html.image;
+
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.image.Image;
+import org.apache.wicket.markup.html.image.Picture;
+import org.apache.wicket.markup.html.image.Source;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.request.resource.PackageResourceReference;
+import org.apache.wicket.request.resource.ResourceReference;
+
+public class ImageResourceReferenceTestPage extends WebPage
+{
+
+       private static final long serialVersionUID = 1L;
+
+       public ImageResourceReferenceTestPage()
+       {
+               Image image1 = new Image("image1", Model.of("Test"))
+               {
+                       private static final long serialVersionUID = 1L;
+
+                       @Override
+                       protected ResourceReference getImageResourceReference()
+                       {
+                               return new 
PackageResourceReference(this.getClass(), "small.jpg");
+                       }
+               };
+               this.add(image1);
+       }
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/0880713f/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageSrcSetTestPage.html
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageSrcSetTestPage.html
 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageSrcSetTestPage.html
new file mode 100644
index 0000000..b5e7e71
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageSrcSetTestPage.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+       <head>
+               <title>de.test.testimage</title>
+       </head>
+       <body>
+               <img wicket:id="image2" class="image2" />
+       </body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/0880713f/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageSrcSetTestPage.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageSrcSetTestPage.java
 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageSrcSetTestPage.java
new file mode 100644
index 0000000..cfa2326
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageSrcSetTestPage.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.wicket.markup.html.image;
+
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.request.resource.PackageResourceReference;
+
+public class ImageSrcSetTestPage extends WebPage
+{
+
+       private static final long serialVersionUID = 1L;
+
+       public ImageSrcSetTestPage()
+       {
+               Image image2 = new Image("image2", new 
PackageResourceReference(this.getClass(),
+                       "small.jpg"), new 
PackageResourceReference(this.getClass(), "small.jpg"),
+                       new PackageResourceReference(this.getClass(), 
"medium.jpg"),
+                       new PackageResourceReference(this.getClass(), 
"large.jpg"));
+               image2.setXValues("320w", "2x", "900w");
+               image2.setSizes("(min-width: 50em) 33vw", "(min-width: 28em) 
50vw", "100vw");
+               this.add(image2);
+       }
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/0880713f/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ResponsiveImageTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ResponsiveImageTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ResponsiveImageTest.java
new file mode 100644
index 0000000..49fad03
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ResponsiveImageTest.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.wicket.markup.html.image;
+
+import org.apache.wicket.util.tester.TagTester;
+import org.apache.wicket.util.tester.WicketTester;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ResponsiveImageTest
+{
+
+       private WicketTester wicketTester;
+
+       @Before
+       public void setup()
+       {
+               wicketTester = new WicketTester(new PubApplication());
+       }
+
+       @Test
+       public void testSrcSetIsNotAvailableOnDefaultUsage()
+       {
+               wicketTester.startPage(ImageResourceReferenceTestPage.class);
+               String lastResponseAsString = 
wicketTester.getLastResponse().getDocument();
+               TagTester createTagByAttribute = 
TagTester.createTagByAttribute(lastResponseAsString, "img");
+               Assert.assertFalse(createTagByAttribute.hasAttribute("srcset"));
+       }
+
+       @Test
+       public void testPictureTagIsRenderedRight()
+       {
+               wicketTester.startPage(ImagePictureTestPage.class);
+               String lastResponseAsString = 
wicketTester.getLastResponse().getDocument();
+               TagTester pictureTagTester = 
TagTester.createTagByAttribute(lastResponseAsString, "picture");
+               Assert.assertTrue(pictureTagTester.hasChildTag("img"));
+               Assert.assertTrue(pictureTagTester.hasChildTag("source"));
+               TagTester sourceTagTester = 
TagTester.createTagByAttribute(lastResponseAsString, "source");
+               Assert.assertTrue(sourceTagTester.hasAttribute("media"));
+               Assert.assertEquals("(min-width: 650px)", 
sourceTagTester.getAttribute("media"));
+               Assert.assertEquals("(min-width: 50em) 33vw", 
sourceTagTester.getAttribute("sizes"));
+       }
+
+       @Test
+       public void testImageTagIsRenderedWithXValuesAndSrcSet()
+       {
+               wicketTester.startPage(ImageSrcSetTestPage.class);
+               String lastResponseAsString = 
wicketTester.getLastResponse().getDocument();
+               TagTester imgTagTester = 
TagTester.createTagByAttribute(lastResponseAsString, "img");
+               Assert.assertTrue(imgTagTester.hasAttribute("src"));
+               Assert.assertTrue(imgTagTester.hasAttribute("srcset"));
+               String attribute = imgTagTester.getAttribute("srcset");
+               String[] srcSetElements = attribute.split(",");
+               int i = 0;
+               for (String srcSetElement : srcSetElements)
+               {
+                       if (i == 0)
+                       {
+                               
Assert.assertTrue(srcSetElement.endsWith("320w"));
+                       }
+                       if (i == 1)
+                       {
+                               Assert.assertTrue(srcSetElement.endsWith("2x"));
+                       }
+                       if (i == 2)
+                       {
+                               
Assert.assertTrue(srcSetElement.endsWith("900w"));
+                       }
+                       i++;
+               }
+               Assert.assertEquals("(min-width: 50em) 33vw,(min-width: 28em) 
50vw,100vw",
+                       imgTagTester.getAttribute("sizes"));
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/0880713f/wicket-examples/src/main/java/org/apache/wicket/examples/images/Home.html
----------------------------------------------------------------------
diff --git 
a/wicket-examples/src/main/java/org/apache/wicket/examples/images/Home.html 
b/wicket-examples/src/main/java/org/apache/wicket/examples/images/Home.html
index 7624089..39ca830 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/images/Home.html
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/images/Home.html
@@ -17,5 +17,11 @@
     <wicket:link>
       <img src="Image2.gif" />
     </wicket:link>
+    <img wicket:id="image6" class="image2" />
+       <picture wicket:id="picture">
+               <source wicket:id="sourcelarge" />
+               <source wicket:id="sourcemedium" />
+               <img wicket:id="image7"/>
+       </picture>
 </body>
 </html>

http://git-wip-us.apache.org/repos/asf/wicket/blob/0880713f/wicket-examples/src/main/java/org/apache/wicket/examples/images/Home.java
----------------------------------------------------------------------
diff --git 
a/wicket-examples/src/main/java/org/apache/wicket/examples/images/Home.java 
b/wicket-examples/src/main/java/org/apache/wicket/examples/images/Home.java
index d21f242..0744f6e 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/images/Home.java
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/images/Home.java
@@ -23,6 +23,8 @@ import java.util.Random;
 
 import org.apache.wicket.examples.WicketExamplePage;
 import org.apache.wicket.markup.html.image.Image;
+import org.apache.wicket.markup.html.image.Picture;
+import org.apache.wicket.markup.html.image.Source;
 import 
org.apache.wicket.markup.html.image.resource.BufferedDynamicImageResource;
 import org.apache.wicket.markup.html.image.resource.DefaultButtonImageResource;
 import 
org.apache.wicket.markup.html.image.resource.RenderedDynamicImageResource;
@@ -94,6 +96,36 @@ public final class Home extends WicketExamplePage
                add(new Image("imageModelResource", new 
Model<CircleDynamicImageResource>(
                        new CircleDynamicImageResource(100, 100))));
 
+               // responsive images (only for img tag)
+               // the first package resource reference is used for the src 
attribute all following for the
+               // srcset in the order they are given to the constructor
+               Image respImage = new Image("image6", new 
PackageResourceReference(this.getClass(),
+                       "Image2_small.gif"), new 
PackageResourceReference(this.getClass(), "Image2_small.gif"),
+                       new PackageResourceReference(this.getClass(), 
"Image2_medium.gif"),
+                       new PackageResourceReference(this.getClass(), 
"Image2_large.gif"));
+               // the x values are applied after each given package resource 
reference in the order they
+               // are applied to the setter in the srcset attribute
+               respImage.setXValues("320w", "2x", "900w");
+               // The sizes are applied comma separated to the sizes attribute
+               respImage.setSizes("(min-width: 50em) 33vw", "(min-width: 28em) 
50vw", "100vw");
+               this.add(respImage);
+
+               // responsive images (to demonstrate the same picture is used 
for sources and img)
+               Picture picture = new Picture("picture");
+               Source large = new Source("sourcelarge", new 
PackageResourceReference(this.getClass(),
+                       "Image2_large.gif"));
+               large.setMedia("(min-width: 650px)");
+               large.setSizes("(min-width: 50em) 33vw");
+               picture.add(large);
+               large.setOutputMarkupId(true);
+               Source medium = new Source("sourcemedium", new 
PackageResourceReference(this.getClass(),
+                       "image2_medium.gif"));
+               medium.setMedia("(min-width: 465px)");
+               picture.add(medium);
+               Image image3 = new Image("image7", new 
PackageResourceReference(this.getClass(),
+                       "image2_small.gif"));
+               picture.add(image3);
+               this.add(picture);
        }
 
        /**

http://git-wip-us.apache.org/repos/asf/wicket/blob/0880713f/wicket-examples/src/main/java/org/apache/wicket/examples/images/Image2_large.gif
----------------------------------------------------------------------
diff --git 
a/wicket-examples/src/main/java/org/apache/wicket/examples/images/Image2_large.gif
 
b/wicket-examples/src/main/java/org/apache/wicket/examples/images/Image2_large.gif
new file mode 100644
index 0000000..f15d4c6
Binary files /dev/null and 
b/wicket-examples/src/main/java/org/apache/wicket/examples/images/Image2_large.gif
 differ

http://git-wip-us.apache.org/repos/asf/wicket/blob/0880713f/wicket-examples/src/main/java/org/apache/wicket/examples/images/Image2_medium.gif
----------------------------------------------------------------------
diff --git 
a/wicket-examples/src/main/java/org/apache/wicket/examples/images/Image2_medium.gif
 
b/wicket-examples/src/main/java/org/apache/wicket/examples/images/Image2_medium.gif
new file mode 100644
index 0000000..62ffd72
Binary files /dev/null and 
b/wicket-examples/src/main/java/org/apache/wicket/examples/images/Image2_medium.gif
 differ

http://git-wip-us.apache.org/repos/asf/wicket/blob/0880713f/wicket-examples/src/main/java/org/apache/wicket/examples/images/Image2_small.gif
----------------------------------------------------------------------
diff --git 
a/wicket-examples/src/main/java/org/apache/wicket/examples/images/Image2_small.gif
 
b/wicket-examples/src/main/java/org/apache/wicket/examples/images/Image2_small.gif
new file mode 100644
index 0000000..7861807
Binary files /dev/null and 
b/wicket-examples/src/main/java/org/apache/wicket/examples/images/Image2_small.gif
 differ

Reply via email to