Wicket
  1. Wicket
  2. WICKET-5142

Generating invalid JavaScript for ajax update

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 6.8.0
    • Component/s: wicket
    • Labels:
      None

      Description

      Suppose I have BlinkBehaviour

      public static class BlinkBehaviour extends Behavior {
      @Override
      public void renderHead(Component component, IHeaderResponse response) {
      AjaxRequestTarget target = component.getRequestCycle().find(AjaxRequestTarget.class);
      if (target != null)

      { target.prependJavaScript("notify|jQuery('#" + component.getMarkupId() + "').fadeOut(400, notify);"); target.appendJavaScript("jQuery('#"+component.getMarkupId()+"').fadeIn(400);"); }


      }
      }

      If I add it twice to a control and update the control via ajax 6.7.0-SNAPSHOT will yield error:

      ERROR: Wicket.Ajax.Call.processEvaluation: Exception evaluating javascript: SyntaxError: Unexpected token ), text: f = function(notify)

      {jQuery('#version2').fadeOut(400, notify);}

      )();(function()

      {notify|jQuery('#version2').fadeOut(400, notify);}

      ;

      1. myproject.zip
        34 kB
        Alexey Mukas

        Activity

        Hide
        Martin Grigorov added a comment -

        This is more trickier than it seems.
        The problem at the moment is the Regex that we use to detect that a manual execution of 'notify' is needed. But the deeper problem is that the user code has two executions of 'notify', i.e. the first execution will release FunctionsExecutor to proceed with the following steps.

        The solution that I see is to split the combined JavaScript into parts again. For example:

        combined: (function()

        {notify|jQuery('#version4').fadeOut(400, notify);})();(function(){notify|jQuery('#version4').fadeOut(400, notify);}

        )();
        to:
        1) (function()

        {notify|jQuery('#version4').fadeOut(400, notify);})();
        2) (function(){notify|jQuery('#version4').fadeOut(400, notify);}

        )();

        and then execute them one by one, so they wait for each other.

        Show
        Martin Grigorov added a comment - This is more trickier than it seems. The problem at the moment is the Regex that we use to detect that a manual execution of 'notify' is needed. But the deeper problem is that the user code has two executions of 'notify', i.e. the first execution will release FunctionsExecutor to proceed with the following steps. The solution that I see is to split the combined JavaScript into parts again. For example: combined: (function() {notify|jQuery('#version4').fadeOut(400, notify);})();(function(){notify|jQuery('#version4').fadeOut(400, notify);} )(); to: 1) (function() {notify|jQuery('#version4').fadeOut(400, notify);})(); 2) (function(){notify|jQuery('#version4').fadeOut(400, notify);} )(); and then execute them one by one, so they wait for each other.
        Hide
        Alexey Mukas added a comment -

        Looks good

        Show
        Alexey Mukas added a comment - Looks good
        Hide
        Martin Grigorov added a comment - - edited

        I'm not quite sure.
        Splitting will lead to bad performance, especially on IE.
        The best is to chain the JS snippets and call Wicket's notify() (the callback passed by Wicket) at the end.
        For example the perfect JS should look like:

        (function(){notify|jQuery('#version4').fadeOut(400, function()

        { jQuery('#version4').fadeOut(400, notify); }

        )})();

        But it will be hard to compose this at the client side.

        Show
        Martin Grigorov added a comment - - edited I'm not quite sure. Splitting will lead to bad performance, especially on IE. The best is to chain the JS snippets and call Wicket's notify() (the callback passed by Wicket) at the end. For example the perfect JS should look like: (function(){notify|jQuery('#version4').fadeOut(400, function() { jQuery('#version4').fadeOut(400, notify); } )})(); But it will be hard to compose this at the client side.
        Hide
        Martin Grigorov added a comment -

        Improved the code by splitting the text with all-functions-in-one in <evaluate> element to separate functions which are executed one by one and each of them can execute 'notify' manually.

        Show
        Martin Grigorov added a comment - Improved the code by splitting the text with all-functions-in-one in <evaluate> element to separate functions which are executed one by one and each of them can execute 'notify' manually.

          People

          • Assignee:
            Martin Grigorov
            Reporter:
            Alexey Mukas
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development