Tapestry
  1. Tapestry
  2. TAPESTRY-1012

PageRenderSupportImpl.writeInitializationScript(IMarkupWriter) does not use the "writer" parameter

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 4.1
    • Fix Version/s: 4.1.1
    • Component/s: Framework
    • Labels:
      None

      Description

      Is it purposeful?
      One of my Tap4.0 components does not work correctly because of this...

        Issue Links

          Activity

          Hide
          Jesse Kuhnert added a comment -

          Is there anymore stack trace to this? I have to admit that I'm not familiar with any errors containing "does not use <x> parameter" .

          Show
          Jesse Kuhnert added a comment - Is there anymore stack trace to this? I have to admit that I'm not familiar with any errors containing "does not use <x> parameter" .
          Hide
          Jesse Kuhnert added a comment -

          Ohhhh...I get it now. You were manually circumventing something and using the Impl version directly.

          You can just call cycle.getResponseBuilder() and do what you want with the initialization scripts in there now.

          Show
          Jesse Kuhnert added a comment - Ohhhh...I get it now. You were manually circumventing something and using the Impl version directly. You can just call cycle.getResponseBuilder() and do what you want with the initialization scripts in there now.
          Hide
          Norbert Sándor added a comment -

          The problem is the following in details. I tried to implement a CSS style component named @Style, similar to the one in TAPESTRY-199.

          It uses a nested writer in the Shell component to allow wrapped @Style components to contribute CSS files. The Shell and a wrapped Body are rendered in the following order:
          1. a nested writer is created
          2. the Shell's body (including the Body component) is rendered to the nested writer
          3. <html>, <head>, </head> written
          4. the nested writer is closed, so its content is committed to the "real" writer (the "real" writer is the one which was passed to Shell.renderComponent() when the Shell component has begun to render)
          5. </hml> is written

          At (2), in Body.java at line 187

          _pageRenderSupport.writeInitializationScript(writer);

          is called, so PageRenderSupportImpl.writeInitializationScript(IMarkupWriter) is called. The problem is here because in PageRenderSupportImpl.java at line 252:

          _builder.writeInitializationScript(_initializationScript.toString());

          This means that the method PageRenderSupportImpl.writeInitializationScript() does not use its "writer" parameter, so the initialization scripts are written to the "real" writer instead of the nested one created at (1). This results in pages rendered incorrectly like

          <script>
          ... some initialization scripts like Form registration...
          </script>
          <html>
          <head>
          ...

          I hope this helps.

          Show
          Norbert Sándor added a comment - The problem is the following in details. I tried to implement a CSS style component named @Style, similar to the one in TAPESTRY-199 . It uses a nested writer in the Shell component to allow wrapped @Style components to contribute CSS files. The Shell and a wrapped Body are rendered in the following order: 1. a nested writer is created 2. the Shell's body (including the Body component) is rendered to the nested writer 3. <html>, <head>, </head> written 4. the nested writer is closed, so its content is committed to the "real" writer (the "real" writer is the one which was passed to Shell.renderComponent() when the Shell component has begun to render) 5. </hml> is written At (2), in Body.java at line 187 _pageRenderSupport.writeInitializationScript(writer); is called, so PageRenderSupportImpl.writeInitializationScript(IMarkupWriter) is called. The problem is here because in PageRenderSupportImpl.java at line 252: _builder.writeInitializationScript(_initializationScript.toString()); This means that the method PageRenderSupportImpl.writeInitializationScript() does not use its "writer" parameter, so the initialization scripts are written to the "real" writer instead of the nested one created at (1). This results in pages rendered incorrectly like <script> ... some initialization scripts like Form registration... </script> <html> <head> ... I hope this helps.
          Hide
          Jesse Kuhnert added a comment -

          Yeah, not sure what to say. The "new" way of doing this would be to override the DefaultResponseContributor service to provide your own IMarkupWriter output manager. (contributor)

          http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/tapestry.services.xml?view=markup

          Show
          Jesse Kuhnert added a comment - Yeah, not sure what to say. The "new" way of doing this would be to override the DefaultResponseContributor service to provide your own IMarkupWriter output manager. (contributor) http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/tapestry.services.xml?view=markup
          Hide
          Norbert Sándor added a comment -

          Please provide some more info on how it should be done.
          If you do then I will modify the patch of TAPESTRY-199 to work with 4.1 (and contribute it).

          Show
          Norbert Sándor added a comment - Please provide some more info on how it should be done. If you do then I will modify the patch of TAPESTRY-199 to work with 4.1 (and contribute it).
          Hide
          Andreas Andreou added a comment -

          I propose changing interface ResponseBuilder and adding a new parameter (IMarkupWriter) to
          methods: beginBodyScript, writeImageInitializations, writeBodyScript, endBodyScript, writeInitializationScript.

          All calls to this interface are from PageRenderSupportImpl.writeBodyScript which already holds
          a reference to the IMarkupWriter, so changes will be minimal.

          Only DefaultResponseBuilder will make use of this writer.

          This change fixes issues when one wraps @Body with a custom component and
          renders it (the @Body) with a custom writer, i.e. a nested writer.

          Objections?

          Show
          Andreas Andreou added a comment - I propose changing interface ResponseBuilder and adding a new parameter (IMarkupWriter) to methods: beginBodyScript, writeImageInitializations, writeBodyScript, endBodyScript, writeInitializationScript. All calls to this interface are from PageRenderSupportImpl.writeBodyScript which already holds a reference to the IMarkupWriter, so changes will be minimal. Only DefaultResponseBuilder will make use of this writer. This change fixes issues when one wraps @Body with a custom component and renders it (the @Body) with a custom writer, i.e. a nested writer. Objections?

            People

            • Assignee:
              Andreas Andreou
              Reporter:
              Norbert Sándor
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development