Updated Branches:
  refs/heads/master 71c8e8402 -> 43237280a

WICKET-5142 Generating invalid JavaScript for ajax update


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

Branch: refs/heads/master
Commit: 43237280ae58c4094508aa11cdb295f8a8fdcb4e
Parents: 71c8e84
Author: Martin Tzvetanov Grigorov <[email protected]>
Authored: Mon Apr 22 13:46:54 2013 +0200
Committer: Martin Tzvetanov Grigorov <[email protected]>
Committed: Mon Apr 22 13:46:54 2013 +0200

----------------------------------------------------------------------
 .../wicket/ajax/res/js/wicket-ajax-jquery.js       |   99 +++++++++++----
 wicket-core/src/test/js/ajax.js                    |   23 ++++
 wicket-core/src/test/js/all.html                   |    1 +
 .../js/data/ajax/twoEvaluationsWithIdentifier.xml  |   18 +++
 4 files changed, 115 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/43237280/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js
----------------------------------------------------------------------
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 4db6061..4ebf4ed 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
@@ -1044,53 +1044,100 @@
                        // used to match evaluation scripts which manually call 
FunctionsExecuter's notify() when ready
                        var scriptWithIdentifierR = new 
RegExp("^\\(function\\(\\)\\{([a-zA-Z_]\\w*)\\|((.|\\n)*)?\\}\\)\\(\\);$");
 
-                       context.steps.push(function (notify) {
-                               // get the javascript body
-                               var text;
+                       /**
+                        * 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\\(\\)\\{.*?}\\)\\(\\);)");
 
-                               try {
-                                       text = node.firstChild.nodeValue;
-                               } catch (e) {
-                                       // TODO remove this fallback in 6.11.0+
-                                       text = jQuery(node).text();
+                       /**
+                        * Removes all empty items from an Array of String's
+                        * @param original The array is empty string elements
+                        * @returns {Array[String]} An array that has no empty 
elements
+                        */
+                       // Needed because String.split(scriptSplitterR) returns 
something like ["", "script1", "", "script2", ""]
+                       var cleanArray = function (original) {
+                               var result = [];
+                               for(var i = 0; i < original.length; i++){
+                                       if (original[i]) {
+                                               result.push(original[i]);
+                                       }
                                }
+                               return result;
+                       };
 
-                               // unescape it if necessary
-                               var encoding = node.getAttribute("encoding");
-                               if (encoding) {
-                                       text = 
Wicket.Head.Contributor.decode(encoding, text);
-                               }
+                       // get the javascript body
+                       var text;
 
-                               // 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
-                               var res = text.match(scriptWithIdentifierR);
+                       try {
+                               text = node.firstChild.nodeValue;
+                       } catch (e) {
+                               // TODO remove this fallback in 6.11.0+
+                               text = jQuery(node).text();
+                       }
 
-                               if (res !== null) {
+                       // unescape it if necessary
+                       var encoding = node.getAttribute("encoding");
+                       if (encoding) {
+                               text = Wicket.Head.Contributor.decode(encoding, 
text);
+                       }
+
+                       // aliases to improve performance
+                       var steps = context.steps;
+                       var log = Wicket.Log;
+
+                       var evaluateWithManualNotify = function (parameters, 
body) {
+                               return function(notify) {
                                        var f = jQuery.noop;
-                                       text = "f = function(" + res[1] + ") {" 
+ res[2] + "};";
+                                       var toExecute = "f = function(" + 
parameters + ") {" + body + "};";
 
                                        try {
                                                // do the evaluation
-                                               eval(text);
+                                               eval(toExecute);
                                                f(notify);
                                        } catch (exception) {
-                                               
Wicket.Log.error("Wicket.Ajax.Call.processEvaluation: Exception evaluating 
javascript: " + exception + ", text: " + text);
+                                               
log.error("Wicket.Ajax.Call.processEvaluation: Exception evaluating javascript: 
" + exception + ", text: " + text);
                                        }
+                               };
+                       };
 
-                               } else {
+                       var evaluate = function (script) {
+                               return function(notify) {
                                        // just evaluate the javascript
                                        try {
                                                // do the evaluation
-                                               eval(text);
+                                               eval(script);
                                        } catch (exception) {
-                                               
Wicket.Log.error("Wicket.Ajax.Call.processEvaluation: Exception evaluating 
javascript: " + exception + ", text: " + text);
+                                               
log.error("Wicket.Ajax.Call.processEvaluation: Exception evaluating javascript: 
" + exception + ", text: " + text);
                                        }
                                        // continue to next step
                                        notify();
+                               };
+                       };
+
+                       // 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 = 
cleanArray(text.split(scriptSplitterR));
+
+                               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));
+                       }
                },
 
                // Adds a closure that processes a header contribution

http://git-wip-us.apache.org/repos/asf/wicket/blob/43237280/wicket-core/src/test/js/ajax.js
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/js/ajax.js b/wicket-core/src/test/js/ajax.js
index 2086d73..0117f1b 100644
--- a/wicket-core/src/test/js/ajax.js
+++ b/wicket-core/src/test/js/ajax.js
@@ -109,6 +109,29 @@ jQuery(document).ready(function() {
                        execute(attrs);
                });
 
+               /**
+                * Executes the second part of 'something|functionBody' by 
passing 'notify' function as parameter.
+                * There are two functions with passed 'notify' function which 
leads to splitting the text in
+                * <(priority-)evaluate> elements to eval one function at a 
time to be able to call notify manually.
+                */
+               asyncTest('processEvaluation*s* with identifier|code.', 
function () {
+
+                       expect(7);
+
+                       var attrs = {
+                               u: 'data/ajax/twoEvaluationsWithIdentifier.xml',
+                               c: 'twoEvaluationsWithIdentifier',
+                               counter: 0,
+                               coh: [
+                                       function(attrs) {
+                                               start();
+                                               equal(attrs.counter, 3, "The 
counter is incremented in both evaluations with and without manual notifying");
+                                       }
+                               ]
+                       };
+                       execute(attrs);
+               });
+
                asyncTest('processComponent, normal case.', function () {
 
                        expect(2);

http://git-wip-us.apache.org/repos/asf/wicket/blob/43237280/wicket-core/src/test/js/all.html
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/js/all.html b/wicket-core/src/test/js/all.html
index a6f4d52..aa27ad1 100644
--- a/wicket-core/src/test/js/all.html
+++ b/wicket-core/src/test/js/all.html
@@ -46,6 +46,7 @@
                <div id="evaluationId"></div>
                <div id="priorityEvaluationId"></div>
                <div id="evaluationIdentifierAndCodeId"></div>
+               <div id="twoEvaluationsWithIdentifier"></div>
 
                <div id="componentToReplace">old body</div>
 

http://git-wip-us.apache.org/repos/asf/wicket/blob/43237280/wicket-core/src/test/js/data/ajax/twoEvaluationsWithIdentifier.xml
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/js/data/ajax/twoEvaluationsWithIdentifier.xml 
b/wicket-core/src/test/js/data/ajax/twoEvaluationsWithIdentifier.xml
new file mode 100644
index 0000000..12706d9
--- /dev/null
+++ b/wicket-core/src/test/js/data/ajax/twoEvaluationsWithIdentifier.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   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.
+-->
+<ajax-response><evaluate>(function(){notify|context.attrs.counter++; ok(true, 
'Evaluation1 with identifier must be executed!'); equal(typeof(notify), 
'function', 'The passed identifier1 must be a function'); 
notify();})();(function(){context.attrs.counter++;ok(true, 'Evaluation2 without 
identifier must be 
executed!');})();(function(){notify|context.attrs.counter++;ok(true, 
'Evaluation3 with identifier must be executed!'); equal(typeof(notify), 
'function', 'The passed identifier3 must be a function'); 
notify();})();</evaluate></ajax-response>
\ No newline at end of file

Reply via email to