1 Reply Latest reply on Feb 3, 2011 8:36 AM by Stan Silvert

    Scripts re-rendered by ajax not executed - critical

    Bernard Labno Master

      There is a bug in HtmlUnit which prevents re-rendered scripts from being executed. I've reported it at htmlunit mailing list:

      http://sourceforge.net/mailarchive/forum.php?thread_name=AANLkTin_tNYEVEKsxGLZ4_AMmpUoaRBHa1A%2B-wap0iqn%40mail.gmail.com&forum_name=htmlunit-user

       

      This is a pain if you have i.e. table with datascroller in second tab of your tab panel that works in ajax mode. To display the table you need to click on a tab, which re-renders part of page with the tabe and script that initializes datascroller. Now, the script doesn't get executed and you may wonder for a long time why clicking on datascroller doesn't trigger another ajax request.

       

      As a temporary workaround call this method after ajax request:

      public static void executeAjaxReRenderedScripts(HtmlPage page) {

              final DomNodeList<HtmlElement> scripts = page.getElementsByTagName("script");

              /**

               * We cannot iterate over html DomNodeList cause it depends on sibling relationship which we will modify.

               */

              final List<HtmlElement> scriptsList = new ArrayList<HtmlElement>();

              for (HtmlElement element : scripts) {

                  scriptsList.add(element);

              }

              for (HtmlElement element : scriptsList) {

                  if (element.getChildNodes().size() > 1) {

                      element.removeChild(element.getFirstChild());

                      final DomNode sibling = element.getNextSibling();

                      final DomNode parentNode = element.getParentNode();

                      /**

                       * Script will be executed upon inserting into DOM tree, so we removed and add it again.

                       */

                      if (sibling != null) {

                          parentNode.removeChild(element);

                          sibling.insertBefore(element);

                      } else {

                          parentNode.removeChild(element);

                          parentNode.appendChild(element);

                      }

                  }

              }

          }

       

      A visible sign that the script has not beed executed is such output when you call scriptElement.asXml():

      <script type="text/javascript">

      //<![CDATA[

      //

      //]]>

      </script>