]> source.dussan.org Git - vaadin-framework.git/commitdiff
Ignore style resource that has already been added (#11667)
authorLeif Åstrand <leif@vaadin.com>
Fri, 31 May 2013 12:16:16 +0000 (15:16 +0300)
committerVaadin Code Review <review@vaadin.com>
Mon, 3 Jun 2013 10:12:01 +0000 (10:12 +0000)
Change-Id: I828166f69c3ad1ac7e24c00de640c8645d2f2153

server/src/com/vaadin/server/Page.java
uitest/src/com/vaadin/tests/themes/CSSInjectTest.html
uitest/src/com/vaadin/tests/themes/CSSInjectTest.java

index d4c16fe7f7f7a9136bc0912c056acdfc2890001d..11553527e07e8fb31e8a014c6e5e499ee6e1f1d8 100644 (file)
@@ -21,11 +21,10 @@ import java.lang.reflect.Method;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.EventObject;
-import java.util.HashMap;
 import java.util.Iterator;
+import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
 
 import com.vaadin.event.EventRouter;
 import com.vaadin.shared.ui.BorderStyle;
@@ -307,6 +306,61 @@ public class Page implements Serializable {
         }
     }
 
+    private static interface InjectedStyle {
+        public void paint(int id, PaintTarget target) throws PaintException;
+    }
+
+    private static class InjectedStyleString implements InjectedStyle {
+
+        private String css;
+
+        public InjectedStyleString(String css) {
+            this.css = css;
+        }
+
+        @Override
+        public void paint(int id, PaintTarget target) throws PaintException {
+            target.startTag("css-string");
+            target.addAttribute("id", id);
+            target.addText(css);
+            target.endTag("css-string");
+        }
+    }
+
+    private static class InjectedStyleResource implements InjectedStyle {
+
+        private final Resource resource;
+
+        public InjectedStyleResource(Resource resource) {
+            this.resource = resource;
+        }
+
+        @Override
+        public void paint(int id, PaintTarget target) throws PaintException {
+            target.startTag("css-resource");
+            target.addAttribute("id", id);
+            target.addAttribute("url", resource);
+            target.endTag("css-resource");
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == this) {
+                return true;
+            } else if (obj instanceof InjectedStyleResource) {
+                InjectedStyleResource that = (InjectedStyleResource) obj;
+                return resource.equals(that.resource);
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        public int hashCode() {
+            return resource.hashCode();
+        }
+    }
+
     /**
      * Contains dynamically injected styles injected in the HTML document at
      * runtime.
@@ -315,16 +369,9 @@ public class Page implements Serializable {
      */
     public static class Styles implements Serializable {
 
-        private final Map<Integer, String> stringInjections = new HashMap<Integer, String>();
-
-        private final Map<Integer, Resource> resourceInjections = new HashMap<Integer, Resource>();
+        private LinkedHashSet<InjectedStyle> injectedStyles = new LinkedHashSet<InjectedStyle>();
 
-        // The combined injection counter between both string and resource
-        // injections. Used as the key for the injection maps
-        private int injectionCounter = 0;
-
-        // Points to the next injection that has not yet been made into the Page
-        private int nextInjectionPosition = 0;
+        private LinkedHashSet<InjectedStyle> pendingInjections = new LinkedHashSet<InjectedStyle>();
 
         private final UI ui;
 
@@ -344,7 +391,7 @@ public class Page implements Serializable {
                         "Cannot inject null CSS string");
             }
 
-            stringInjections.put(injectionCounter++, css);
+            pendingInjections.add(new InjectedStyleString(css));
             ui.markAsDirty();
         }
 
@@ -360,43 +407,33 @@ public class Page implements Serializable {
                         "Cannot inject null resource");
             }
 
-            resourceInjections.put(injectionCounter++, resource);
-            ui.markAsDirty();
+            InjectedStyleResource injection = new InjectedStyleResource(
+                    resource);
+            if (!injectedStyles.contains(injection)
+                    && pendingInjections.add(injection)) {
+                ui.markAsDirty();
+            }
         }
 
         private void paint(PaintTarget target) throws PaintException {
 
             // If full repaint repaint all injections
             if (target.isFullRepaint()) {
-                nextInjectionPosition = 0;
+                injectedStyles.addAll(pendingInjections);
+                pendingInjections = injectedStyles;
+                injectedStyles = new LinkedHashSet<InjectedStyle>();
             }
 
-            if (injectionCounter > nextInjectionPosition) {
+            if (!pendingInjections.isEmpty()) {
 
                 target.startTag("css-injections");
 
-                while (injectionCounter > nextInjectionPosition) {
-
-                    String stringInjection = stringInjections
-                            .get(nextInjectionPosition);
-                    if (stringInjection != null) {
-                        target.startTag("css-string");
-                        target.addAttribute("id", nextInjectionPosition);
-                        target.addText(stringInjection);
-                        target.endTag("css-string");
-                    }
-
-                    Resource resourceInjection = resourceInjections
-                            .get(nextInjectionPosition);
-                    if (resourceInjection != null) {
-                        target.startTag("css-resource");
-                        target.addAttribute("id", nextInjectionPosition);
-                        target.addAttribute("url", resourceInjection);
-                        target.endTag("css-resource");
-                    }
-
-                    nextInjectionPosition++;
+                for (InjectedStyle pending : pendingInjections) {
+                    int id = injectedStyles.size();
+                    pending.paint(id, target);
+                    injectedStyles.add(pending);
                 }
+                pendingInjections.clear();
 
                 target.endTag("css-injections");
             }
index 05a0f256c2da1f14f02d599950b7459ac83b166e..0c70d6f711f3bf27105e5534b99732b12f7b3265 100644 (file)
        <td></td>
        <td>world-red</td>
 </tr>
-
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadinteststhemesCSSInjectTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[4]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>world-still-red</td>
+</tr>
 </tbody></table>
 </body>
 </html>
index f4448bf326ca8b92ca40f14d8c44c7bf7730e747..738d8fc6817b652fdd642a1297ee2944e5c6790e 100644 (file)
@@ -22,14 +22,16 @@ public class CSSInjectTest extends TestBase {
         final Styles stylesheet = Page.getCurrent().getStyles();
 
         // Inject some resources initially
-        stylesheet.add(new StreamResource(new StreamResource.StreamSource() {
+        final StreamResource initialResource = new StreamResource(
+                new StreamResource.StreamSource() {
 
-            @Override
-            public InputStream getStream() {
-                return new ByteArrayInputStream(
-                        ".hello, .world { color:silver; }".getBytes());
-            }
-        }, "mystyles-" + System.currentTimeMillis() + ".css"));
+                    @Override
+                    public InputStream getStream() {
+                        return new ByteArrayInputStream(
+                                ".hello, .world { color:silver; }".getBytes());
+                    }
+                }, "mystyles-" + System.currentTimeMillis() + ".css");
+        stylesheet.add(initialResource);
 
         Label hello = new Label(
                 "<span class='hello'>Hello</span> <span class='world'>world</span>",
@@ -72,6 +74,14 @@ public class CSSInjectTest extends TestBase {
                     }
                 });
         addComponent(injectRandom);
+
+        addComponent(new Button("Inject initial again!",
+                new Button.ClickListener() {
+                    @Override
+                    public void buttonClick(ClickEvent event) {
+                        stylesheet.add(initialResource);
+                    }
+                }));
     }
 
     @Override