This is an automated email from the ASF dual-hosted git repository.

svenmeier pushed a commit to branch WICKET-6703-replace-eval-with-domEval
in repository https://gitbox.apache.org/repos/asf/wicket.git

commit e1bc21b957baedd059a0c257b2eee159a2092ca7
Author: Sven Meier <svenme...@apache.org>
AuthorDate: Thu Oct 24 14:53:08 2019 +0200

    WICKET-6703 Ajax suspension via suspendCall()
    
    instead of pipe | syntax
---
 .../wicket/ajax/res/js/wicket-ajax-jquery.js       | 110 +++++++++++----------
 .../wicket/examples/ajax/builtin/EffectsPage.html  |  29 ++++--
 .../wicket/examples/ajax/builtin/EffectsPage.java  |  46 ++++++++-
 3 files changed, 123 insertions(+), 62 deletions(-)

diff --git 
a/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js 
b/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js
index dd856cf..018fc4b 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js
+++ 
b/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js
@@ -350,6 +350,32 @@
         */
        Wicket.Ajax.Call = Wicket.Class.create();
 
+       Wicket.Ajax._currentSuspension = undefined;
+
+       /**
+        * Suspend the currently evaluated Ajax call, fails if no Ajax call is 
currently
+        * evaluated.
+        */
+       Wicket.Ajax.suspendCall = function () {
+               var suspension = Wicket.Ajax._currentSuspension;
+               
+               if (suspension === undefined) {
+                       Wicket.Log.error("Can't suspend: no Ajax call in 
process");
+                       return;
+               }
+               
+               // suspend
+               suspension.suspend();
+
+               return function () {
+                       // release only once
+                       if (suspension !== null) {
+                               suspension.release();
+                               suspension = null;
+                       }
+               }
+       };
+
        Wicket.Ajax.Call.prototype = {
 
                initialize: jQuery.noop,
@@ -933,16 +959,6 @@
                 */
                processEvaluation: function (context, node) {
 
-                       // used to match evaluation scripts which manually call 
FunctionsExecuter's notify() when ready
-                       var scriptWithIdentifierR = new 
RegExp("\\(function\\(\\)\\{([a-zA-Z_]\\w*)\\|((.|\\n)*)?\\}\\)\\(\\);$");
-
-                       /**
-                        * A regex used to split the text in 
(priority-)evaluate elements in the Ajax response
-                        * when there are scripts which require manual call of 
'FunctionExecutor#notify()'
-                        * @type {RegExp}
-                        */
-                       var scriptSplitterR = new 
RegExp("\\(function\\(\\)\\{[\\s\\S]*?}\\)\\(\\);", 'gi');
-
                        // get the javascript body
                        var text = Wicket.DOM.text(node);
 
@@ -950,61 +966,47 @@
                        var steps = context.steps;
                        var log = Wicket.Log;
 
-                       var evaluateWithManualNotify = function (parameters, 
body) {
-                               return function(notify) {
-                                       var toExecute = "(function(" + 
parameters + ") {" + body + "})";
-
-                                       try {
-                                               // do the evaluation in global 
scope
-                                               var f = window.eval(toExecute);
-                                               f(notify);
-                                       } catch (exception) {
-                                               
log.error("Wicket.Ajax.Call.processEvaluation: Exception evaluating javascript: 
%s", text, exception);
-                                       }
-                                       return FunctionsExecuter.ASYNC;
-                               };
-                       };
-
                        var evaluate = function (script) {
                                return function(notify) {
-                                       // just evaluate the javascript
+                                       
+                                       var suspension = {
+                                               suspended: 0,
+                                               
+                                               suspend: function() {
+                                                       suspension.suspended++;
+                                               },
+                                               
+                                               release: function() {
+                                                       suspension.suspended--;
+                                                       if 
(suspension.suspended == 0) {
+                                                               notify();
+                                                       }
+                                               }
+                                       };
+                                       
                                        try {
+                                               Wicket.Ajax._currentSuspension 
= suspension;
+                                               
                                                // do the evaluation in global 
scope
                                                window.eval(script);
                                        } catch (exception) {
                                                
log.error("Ajax.Call.processEvaluation: Exception evaluating javascript: %s", 
text, exception);
+                                       } finally {
+                                               Wicket.Ajax.currentSuspension = 
undefined;
                                        }
+                                       
                                        // continue to next step
-                                       return FunctionsExecuter.DONE;
+                                       if (suspension.suspended === 0) {
+                                               // execution finished without 
suspension, just continue to next step
+                                               return FunctionsExecuter.DONE;
+                                       } else {
+                                               // suspended, signal 
asynchronous execution of next step
+                                               return FunctionsExecuter.ASYNC;
+                                       }
                                };
                        };
-
-                       // test if the javascript is in form of identifier|code
-                       // if it is, we allow for letting the javascript decide 
when the rest of processing will continue
-                       // by invoking identifier();. This allows usage of some 
asynchronous/deferred logic before the next script
-                       // See WICKET-5039
-                       if (scriptWithIdentifierR.test(text)) {
-                               var scripts = [];
-                               var scr;
-                               while ( (scr = scriptSplitterR.exec(text) ) !== 
null ) {
-                                       scripts.push(scr[0]);
-                               }
-
-                               for (var s = 0; s < scripts.length; s++) {
-                                       var script = scripts[s];
-                                       if (script) {
-                                               var scriptWithIdentifier = 
script.match(scriptWithIdentifierR);
-                                               if (scriptWithIdentifier) {
-                                                       
steps.push(evaluateWithManualNotify(scriptWithIdentifier[1], 
scriptWithIdentifier[2]));
-                                               }
-                                               else {
-                                                       
steps.push(evaluate(script));
-                                               }
-                                       }
-                               }
-                       } else {
-                               steps.push(evaluate(text));
-                       }
+                       
+                       steps.push(evaluate(text));
                },
 
                // Adds a closure that processes a header contribution
diff --git 
a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/EffectsPage.html
 
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/EffectsPage.html
index 241c86e..d875cea 100644
--- 
a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/EffectsPage.html
+++ 
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/EffectsPage.html
@@ -15,13 +15,28 @@
     }
 </style>
 <div class="container">
-counter 1:<span wicket:id="c1"></span> 
-<br/>
-<br/>
-counter 2: <span wicket:id="c2"></span>
-<br/>
-<br/>
-<a href="#" wicket:id="c1-link">counter1++ and shake</a>&#160;&#160;<a 
href="#" wicket:id="c2-link">counter2++ and highlight</a>
+       <div>
+               <p>
+                       counter 1:<span wicket:id="c1"></span>
+               </p>
+               <p>
+                       counter 2: <span wicket:id="c2"></span>
+               </p>
+               <p>
+                       counter 3: <span wicket:id="c3"></span>
+               </p>
+       </div>
+       <div>
+               <p>
+                       <a href="#" wicket:id="c1-link">counter1++ and shake</a>
+               </p>
+               <p>
+                       <a href="#" wicket:id="c2-link">counter2++ and 
highlight</a>
+               </p>
+               <p>
+                       <a href="#" wicket:id="c3-link">counter3++, fade-out 
and fade-in</a>
+               </p>
+       </div>
 </div>
 </wicket:extend>
 </html>
\ No newline at end of file
diff --git 
a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/EffectsPage.java
 
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/EffectsPage.java
index e286584..b0749ff 100644
--- 
a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/EffectsPage.java
+++ 
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/EffectsPage.java
@@ -36,6 +36,7 @@ public class EffectsPage extends BasePage
 {
        private int counter1 = 0;
        private int counter2 = 0;
+       private int counter3 = 0;
 
        /**
         * @return Value of counter1
@@ -71,6 +72,24 @@ public class EffectsPage extends BasePage
                this.counter2 = counter2;
        }
 
+
+       /**
+        * @return Value for counter3
+        */
+       public int getCounter3()
+       {
+               return counter3;
+       }
+
+       /**
+        * @param counter3
+        *            New value for counter3
+        */
+       public void setCounter3(int counter3)
+       {
+               this.counter3 = counter3;
+       }
+
        /**
         * Constructor
         */
@@ -84,6 +103,10 @@ public class EffectsPage extends BasePage
                c2.setOutputMarkupId(true);
                add(c2);
 
+               final Label c3 = new Label("c3", new PropertyModel<>(this, 
"counter3"));
+               c3.setOutputMarkupId(true);
+               add(c3);
+
                add(new AjaxLink<Void>("c1-link")
                {
                        @Override
@@ -125,13 +148,34 @@ public class EffectsPage extends BasePage
                                super.updateAjaxAttributes(attributes);
                        }
                });
+
+               add(new AjaxFallbackLink<Void>("c3-link")
+               {
+                       @Override
+                       public void onClick(Optional<AjaxRequestTarget> 
targetOptional)
+                       {
+                               counter3++;
+                               targetOptional.ifPresent(target -> {
+                                       
target.prependJavaScript((String.format("jQuery('#%s').fadeOut(500, 
Wicket.Ajax.suspendCall());", c3.getMarkupId())));
+                                       target.add(c3);
+                                       
target.appendJavaScript((String.format("jQuery('#%s').hide().fadeIn(500);", 
c3.getMarkupId())));
+                               });
+                       }
+
+                       @Override
+                       protected void 
updateAjaxAttributes(AjaxRequestAttributes attributes)
+                       {
+                               attributes.setChannel(new 
AjaxChannel("effects", Type.DROP));
+
+                               super.updateAjaxAttributes(attributes);
+                       }
+               });
        }
 
        @Override
        public void renderHead(IHeaderResponse response)
        {
                super.renderHead(response);
-
                
response.render(OnDomReadyHeaderItem.forScript("jQuery.noConflict();"));
        }
 

Reply via email to