Updated Branches:
  refs/heads/WICKET-5297-ajax-repaint-with-animation 00cbf54d8 -> 881f1a9b7


WICKET-5297 Animate ajax DOM manipulation smoothly

Re-order automatically any Effect JavaScript so the one with the longest 
duration is executed last and has notify=true, so any following JavaScripts 
should wait for it.


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

Branch: refs/heads/WICKET-5297-ajax-repaint-with-animation
Commit: 881f1a9b7e0ece194cb23f4b945773effbe56f4e
Parents: 00cbf54
Author: Martin Tzvetanov Grigorov <mgrigo...@apache.org>
Authored: Tue Oct 1 16:58:19 2013 +0200
Committer: Martin Tzvetanov Grigorov <mgrigo...@apache.org>
Committed: Tue Oct 1 16:58:19 2013 +0200

----------------------------------------------------------------------
 .../apache/wicket/ajax/AjaxRequestHandler.java  | 59 +++++++++++++++++-
 .../org/apache/wicket/ajax/XmlAjaxResponse.java | 24 +++++++-
 .../ajax/effects/DisplayNoneBehavior.java       | 16 +++++
 .../org/apache/wicket/ajax/effects/Effect.java  | 65 +++++++++++++++++---
 .../org/apache/wicket/ajax/effects/Effects.java | 21 ++++++-
 5 files changed, 171 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/881f1a9b/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestHandler.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestHandler.java 
b/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestHandler.java
index 3c6faf1..ba67bb8 100644
--- a/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestHandler.java
+++ b/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestHandler.java
@@ -18,6 +18,7 @@ package org.apache.wicket.ajax;
 
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
@@ -28,6 +29,7 @@ import org.apache.wicket.Application;
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.Page;
+import org.apache.wicket.ajax.effects.Effect;
 import org.apache.wicket.core.request.handler.PageProvider;
 import org.apache.wicket.core.request.handler.RenderPageRequestHandler;
 import org.apache.wicket.core.request.handler.logger.PageLogData;
@@ -169,11 +171,66 @@ public class AjaxRequestHandler implements 
AjaxRequestTarget
 
                                listenersFrozen = false;
                        }
-
                };
+
+               addListener(new EffectsListener());
+       }
+
+       /**
+        * A listener that reorders any Effect prepend/append JavaScripts.
+        * It also sets notify = true to the last effect. This way any other 
JavaScripts
+        * should wait the effect to finish to be executed.
+        */
+       private class EffectsListener extends AbstractListener
+       {
+               @Override
+               public void onBeforeRespond(Map<String, Component> map, 
AjaxRequestTarget target)
+               {
+                       super.onBeforeRespond(map, target);
+
+                       Collections.sort(responseObject.prependJavaScripts, new 
EffectComparator());
+                       notifyLast(responseObject.prependJavaScripts);
+
+                       Collections.sort(responseObject.appendJavaScripts, new 
EffectComparator());
+                       notifyLast(responseObject.appendJavaScripts);
+               }
+
+               private void notifyLast(List<CharSequence> effects)
+               {
+                       if (effects != null && effects.isEmpty() == false)
+                       {
+                               for (int i = effects.size() - 1; i >= 0; i--)
+                               {
+                                       CharSequence sequence = effects.get(i);
+                                       if (sequence instanceof Effect)
+                                       {
+                                               ((Effect) 
sequence).setNotify(true);
+                                               break;
+                                       }
+                               }
+                       }
+               }
        }
 
        /**
+        * Used to re-order the Effect append/prepend JavaScripts
+        */
+       private static class EffectComparator implements 
Comparator<CharSequence>
+       {
+               @Override
+               public int compare(CharSequence o1, CharSequence o2)
+               {
+                       if (o1 instanceof Effect && o2 instanceof Effect)
+                       {
+                               Effect e1 = (Effect) o1;
+                               Effect e2 = (Effect) o2;
+                               return 
e1.getDuration().compareTo(e2.getDuration());
+                       }
+                       return 0;
+               }
+       };
+
+       /**
         * @see 
org.apache.wicket.core.request.handler.IPageRequestHandler#getPage()
         */
        @Override

http://git-wip-us.apache.org/repos/asf/wicket/blob/881f1a9b/wicket-core/src/main/java/org/apache/wicket/ajax/XmlAjaxResponse.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/ajax/XmlAjaxResponse.java 
b/wicket-core/src/main/java/org/apache/wicket/ajax/XmlAjaxResponse.java
index 80c056e..b59e4e9 100644
--- a/wicket-core/src/main/java/org/apache/wicket/ajax/XmlAjaxResponse.java
+++ b/wicket-core/src/main/java/org/apache/wicket/ajax/XmlAjaxResponse.java
@@ -17,6 +17,7 @@
 package org.apache.wicket.ajax;
 
 import java.util.Collection;
+import java.util.regex.Pattern;
 
 import org.apache.wicket.Component;
 import org.apache.wicket.Page;
@@ -43,6 +44,8 @@ public abstract class XmlAjaxResponse extends 
AbstractAjaxResponse
 {
        private static final Logger LOG = 
LoggerFactory.getLogger(XmlAjaxResponse.class);
 
+       private static final Pattern EVALUATION_WITH_NOTIFY = 
Pattern.compile("^[a-zA-Z_]\\w*\\|(.|\\n)*;$");
+
        /**
         * The name of the root element in the produced XML document.
         */
@@ -190,7 +193,6 @@ public abstract class XmlAjaxResponse extends 
AbstractAjaxResponse
        protected void writeNormalEvaluations(final Response response, final 
Collection<CharSequence> scripts)
        {
                writeEvaluations(response, "evaluate", scripts);
-
        }
 
        @Override
@@ -206,9 +208,25 @@ public abstract class XmlAjaxResponse extends 
AbstractAjaxResponse
                        StringBuilder combinedScript = new StringBuilder(1024);
                        for (CharSequence script : scripts)
                        {
-                               
combinedScript.append("(function(){").append(script).append("})();");
+                               String s = script.toString();
+                               if (EVALUATION_WITH_NOTIFY.matcher(s).matches())
+                               {
+                                       if (combinedScript.length() > 0)
+                                       {
+                                               writeEvaluation(elementName, 
response, combinedScript);
+                                               combinedScript.setLength(0);
+                                               writeEvaluation(elementName, 
response, "(function(){" + s + "})();");
+                                       }
+                               }
+                               else
+                               {
+                                       
combinedScript.append("(function(){").append(s).append("})();");
+                               }
+                       }
+                       if (combinedScript.length() > 0)
+                       {
+                               writeEvaluation(elementName, response, 
combinedScript);
                        }
-                       writeEvaluation(elementName, response, combinedScript);
                }
        }
 

http://git-wip-us.apache.org/repos/asf/wicket/blob/881f1a9b/wicket-core/src/main/java/org/apache/wicket/ajax/effects/DisplayNoneBehavior.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/ajax/effects/DisplayNoneBehavior.java
 
b/wicket-core/src/main/java/org/apache/wicket/ajax/effects/DisplayNoneBehavior.java
index d62e8c1..33fa552 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/ajax/effects/DisplayNoneBehavior.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/ajax/effects/DisplayNoneBehavior.java
@@ -1,3 +1,19 @@
+/*
+ * 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.ajax.effects;
 
 import org.apache.wicket.Component;

http://git-wip-us.apache.org/repos/asf/wicket/blob/881f1a9b/wicket-core/src/main/java/org/apache/wicket/ajax/effects/Effect.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/ajax/effects/Effect.java 
b/wicket-core/src/main/java/org/apache/wicket/ajax/effects/Effect.java
index 2110631..2f179c2 100644
--- a/wicket-core/src/main/java/org/apache/wicket/ajax/effects/Effect.java
+++ b/wicket-core/src/main/java/org/apache/wicket/ajax/effects/Effect.java
@@ -1,6 +1,21 @@
+/*
+ * 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.ajax.effects;
 
-import org.apache.wicket.Component;
 import org.apache.wicket.util.lang.Args;
 import org.apache.wicket.util.time.Duration;
 
@@ -8,7 +23,7 @@ import org.apache.wicket.util.time.Duration;
  * An effect is responsible to render the JavaScript that should be
  * used to show the animation effect.
  */
-public class Effect
+public class Effect implements CharSequence
 {
        /**
         * The default duration of all effects which do not specify
@@ -28,13 +43,15 @@ public class Effect
         */
        private Duration duration;
 
+       private String componentMarkupId;
+
        /**
         * A flag indicating whether the animation should suspend
         * the execution of other Ajax response evaluations.
         * By default effects notify when they are finished and other
         * evaluations can be executed.
         */
-       private boolean notify = true;
+       private boolean notify = false;
 
        /**
         * Constructor.
@@ -88,23 +105,31 @@ public class Effect
                return this;
        }
 
+       public String getComponentMarkupId()
+       {
+               return componentMarkupId;
+       }
+
+       public Effect setComponentMarkupId(String componentMarkupId)
+       {
+               this.componentMarkupId = componentMarkupId;
+               return this;
+       }
+
        /**
         * Constructs JavaScript like: 
Wicket.Effect['name']('componentMarkupId', duration)
         *
-        * @param component
         * @return the JavaScript used to execute the effect
         */
-       public CharSequence toJavaScript(Component component)
+       private CharSequence toJavaScript()
        {
-               Args.notNull(component, "component");
-
                StringBuilder js = new StringBuilder();
                if (isNotify())
                {
                        js.append("notify|");
                }
                js.append("Wicket.Effect['").append(name).append("']");
-               js.append("('").append(component.getMarkupId()).append("', ")
+               js.append("('").append(getComponentMarkupId()).append("', ")
                                .append(getDuration().getMilliseconds());
                if (isNotify())
                {
@@ -114,4 +139,28 @@ public class Effect
 
                return js;
        }
+
+       @Override
+       public int length()
+       {
+               return toJavaScript().length();
+       }
+
+       @Override
+       public char charAt(int index)
+       {
+               return toJavaScript().charAt(index);
+       }
+
+       @Override
+       public CharSequence subSequence(int start, int end)
+       {
+               return toJavaScript().subSequence(start, end);
+       }
+
+       @Override
+       public String toString()
+       {
+               return toJavaScript().toString();
+       }
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/881f1a9b/wicket-core/src/main/java/org/apache/wicket/ajax/effects/Effects.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/ajax/effects/Effects.java 
b/wicket-core/src/main/java/org/apache/wicket/ajax/effects/Effects.java
index c40ffad..a45a98a 100644
--- a/wicket-core/src/main/java/org/apache/wicket/ajax/effects/Effects.java
+++ b/wicket-core/src/main/java/org/apache/wicket/ajax/effects/Effects.java
@@ -1,3 +1,19 @@
+/*
+ * 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.ajax.effects;
 
 import org.apache.wicket.Component;
@@ -45,11 +61,12 @@ public class Effects
 
                component.add(new DisplayNoneBehavior());
 
-               target.prependJavaScript(hide.toJavaScript(component));
+               String markupId = component.getMarkupId();
+               target.prependJavaScript(hide.setComponentMarkupId(markupId));
 
                target.add(component);
 
-               target.appendJavaScript(show.toJavaScript(component));
+               target.appendJavaScript(show.setComponentMarkupId(markupId));
        }
 
        /*

Reply via email to