I will try that out. 


On Aug 19, 2011, at 10:34 PM, Robert Zeigler <robert.zeig...@roxanemy.com> 
wrote:

> Yes, you can do that.  The document tree that gets rendered is separate from 
> the component tree. 
> MarkupRenderer (the service that you configure with MarkupRenderFilters) is a 
> pipeline, so it gives you a chance to manipulate the document tree before it 
> is converted to text and streamed to the client. So it's exactly the same 
> idea as "option #2", except that you're basically deferring the addition of 
> the script until after document link has added the other script elements. 
> Note that even though you're going to manipulate the dom after 
> DocumentLinker, when you contribute your custom MarkupRenderFilter, you'll 
> need to contribute it /before/ DocumentLinker because DocumentLinker does 
> it's manipulations after the contributions ordered after it. That is, it 
> executes something like:
> 
>  push the DocumentLinker onto the environment
>  pass control to the next MarkupRenderFilter (ie: everything ordered /after/ 
> DocumentLinker)
>  Control returns to the "DocumentLinker" MarkupRenderFilter. It now adds the 
> scripts to the document.
> 
> So you want your filter ordered before MarkupRenderFilter, so the chain of 
> events would be:
>  Your Filter is called by the previous filter int the pipeline
>  You pass control to the next MarkrupRenderFilter (ie: DocumentLinker)
>  Control returns to your filter /after/ "DocumentLinker" has added the 
> scripts to head
>  You manipulate the DOM to add in your script before the GWT-including script
>  Control returns to the previous filter in the pipeline
>  Document eventually streamed to client
> 
> Robert
> 
> On Aug 19, 2011, at 8/199:30 PM , Lenny Primak wrote:
> 
>> The component itself knows it's the variable's value at compile time. The 
>> problem is that there are many components each has a different value. Or 
>> none at all. Basically the first one that gets instantiated has to put it's 
>> value into the variable and has to be on the page before the components 
>> injected JS library. 
>> 
>> I I go with the MarkupRenderFilter approach, it's not a problem to put the 
>> value of the variable in there but will it be able to put the variable in 
>> front of the imported JS library? _after_ the component has been 
>> instantiated?
>> 
>> 
>> On Aug 19, 2011, at 12:26 AM, Robert Zeigler <robert.zeig...@roxanemy.com> 
>> wrote:
>> 
>>> Hm... when does this component render with respect to the rest of the page? 
>>> Must be early on... the dom document will contain everything in the page 
>>> that has rendered to this point.  Thinking about this a bit more... the 
>>> script elements from the library imports are added by the document linker, 
>>> and they are added as part of a MarkupRenderFilter, after the page render.  
>>> You could still add the script element to the head, but then all of the 
>>> imported scripts will be placed before it.  You could fix that with a 
>>> MarkupRenderFilter... as long as it comes after "DocumentLinker".  
>>> Basically, then you would add the script in afterRender, as before 
>>> (assuming you have an html > head element to add the element to) and then 
>>> use your markup renderer to re-order the elements after documentLinker adds 
>>> the <script src="..."> elements. 
>>> 
>>> At what point in the rendering process do you know the variable value? Put 
>>> another way, how is your component calculating the directory?  If that 
>>> logic can be separate from the component rendering, then you could move 
>>> /all/ of the logic to the MarkupRendererFilter.  If the logic for 
>>> calculating the value needs to be inside the component, then you'll need 
>>> some way to stash the value.  You could stick it in the Request service as 
>>> a request attribute.  Or you could push it onto the environment (but if you 
>>> do that, make sure that you're not pushing a "raw" type... you'll want a 
>>> custom class, such as "GWTRenderInfo" or some such.  That way, you know 
>>> what you're pushing onto and popping off the environment, since it works 
>>> entirely by type). The environment idea is kind of fun... you could then 
>>> check to see if GWTRenderInfo is in the environment 
>>> (environment.peek(GWTRenderInfo.class)) and only add the necessary script 
>>> value if it is.  
>>> 
>>> HTH
>>> 
>>> Robert
>>> 
>>> On Aug 18, 2011, at 8/1811:41 PM , lpri...@hope.nyc.ny.us wrote:
>>> 
>>>> I tried Option #2, but it didn't work. †The DOM document only contained 
>>>> the DOM of the current component,
>>>> not the whole page, there were no <script> entries in the DOM. †Is it 
>>>> worth trying MarkupRenderFilter?
>>>> Or do you have any other ideas?
>>>> 
>>>> On Aug 18, 2011, at 4:22 PM, Robert Zeigler wrote:
>>>> 
>>>>> If GWT is generating the scripts directory, why doesn't it know the 
>>>>> directory? Or are you telling it the directory to use?
>>>>> 
>>>>> In any event, I can think of a couple of possibilities. †Basically, the 
>>>>> problem is that you don't know the value of the directory until render 
>>>>> time, but Tapestry puts all libraries to be imported into the document 
>>>>> head, and all code to be executed (such as a variable declaration) occurs 
>>>>> after page load (which is after loading the gwtSupport.js script).
>>>>> 
>>>>> Option #1 (gross, btw, but it would get the job done): 
>>>>> †* Remove the @Import
>>>>> †* @Inject JavaScriptSupport jsSupport;
>>>>> †* In one of the render phase methods, generate the required value and 
>>>>> write it to a file (eg: in the context).
>>>>> †* jsSupport.includeJavaScriptLibrary("your generated file");
>>>>> †* jsSupport.includeJavaScriptLibrary("context:js/gwtSupport.js");
>>>>> 
>>>>> Option #2 (not as gross; still smells, but should work):
>>>>> †* Leave the import in place
>>>>> †* After render:
>>>>> ††††void afterRender(MarkupWriter writer) {
>>>>> ††††††††//find the gwt script:
>>>>> ††††††††Element gwtScript;
>>>>> ††††††††for(Node n : 
>>>>> writer.getDocument().find("html/head").getChildren()) {
>>>>> ††††††††††††if (!(n instanceof Element)) continue;
>>>>> ††††††††††††Element el = (Element) n;
>>>>> ††††††††††††if ("script".equals(el.getName()) && el.getAttribute("src") 
>>>>> != null && el.getAttribute("src").contains("gwtSupport.js")) {
>>>>> ††††††††††††††††gwtScript = el;
>>>>> ††††††††††††††††break;
>>>>> ††††††††††††}
>>>>> ††††††††}
>>>>> ††††††††if (gwtScript == null)
>>>>> ††††††††††††throw new RuntimeException("Couldn't find gwtSupport 
>>>>> script!");
>>>>> 
>>>>> ††††††††Element myScript = 
>>>>> getDocument().find("html/head").element("script","type","text/javascript");
>>>>> ††††††††myScript.text("var myvar=" + myGeneratedValue);
>>>>> ††††††††myScript.moveBefore(gwtScript);
>>>>> ††††}
>>>>> 
>>>>> In option 2, you're leveraging the fact that Tapestry renders a DOM tree 
>>>>> on the server to find the gwtScript element in the document head and 
>>>>> insert your custom script (with variable declaration) before it.
>>>>> 
>>>>> Neither option is very pretty, but both should work. 
>>>>> 
>>>>> 
>>>>> Robert
>>>>> 
>>>>> On Aug 18, 2011, at 8/183:37 PM , Lenny Primak wrote:
>>>>> 
>>>>>> Its a path to the GWT-generated scripts directory. †Basically, there can 
>>>>>> be many GWT modules, but supporting scripts are the same,
>>>>>> even though they are duplicated in different paths, so any path will do, 
>>>>>> but there has to be one, just dynamically generated from
>>>>>> any of the available components.
>>>>>> 
>>>>>> Thanks for your help!
>>>>>> 
>>>>>> On Aug 18, 2011, at 3:34 PM, Robert Zeigler wrote:
>>>>>> 
>>>>>>> Hm. Can you speak more to what the generated value is supposed to 
>>>>>>> be/do? †It appears that it doesn't matter /too/ much what it is since 
>>>>>>> it doesn't matter if multiple component instances overwrite the value?
>>>>>>> 
>>>>>>> Robert
>>>>>>> 
>>>>>>> On Aug 18, 2011, at 8/183:24 PM , Lenny Primak wrote:
>>>>>>> 
>>>>>>>> The variable's value is dynamically generated by the component that is 
>>>>>>>> importing the library.
>>>>>>>> If there are multiple component, any component instance should win, 
>>>>>>>> and that's ok.
>>>>>>>> 
>>>>>>>> 
>>>>>>>> On Aug 18, 2011, at 3:22 PM, Robert Zeigler wrote:
>>>>>>>> 
>>>>>>>>> What if you include a bit of custom js in a separate file that 
>>>>>>>>> defines the variable?
>>>>>>>>> 
>>>>>>>>> component.js:
>>>>>>>>> var somevar="someval";
>>>>>>>>> 
>>>>>>>>> Then:
>>>>>>>>> 
>>>>>>>>> @Import(library={"component.js","context:js/gwtSupport.js"})
>>>>>>>>> public class GwtSupport{...}
>>>>>>>>> 
>>>>>>>>> Pretty sure that the order of the libraries in your @Import will be 
>>>>>>>>> honored in the import declarations on the page (but I don't remember 
>>>>>>>>> offhand).
>>>>>>>>> 
>>>>>>>>> Robert
>>>>>>>>> 
>>>>>>>>> On Aug 18, 2011, at 8/183:14 PM , Lenny Primak wrote:
>>>>>>>>> 
>>>>>>>>>> I have a component like this:
>>>>>>>>>> 
>>>>>>>>>> @Import(library="context:js/gwtSupport.js")
>>>>>>>>>> public class GwtSupport
>>>>>>>>>> {
>>>>>>>>>> // intentionally left blank
>>>>>>>>>> }
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> gwtSupport.js (actually the GWT component itself which I have no 
>>>>>>>>>> control over)
>>>>>>>>>> is trying to read a variable.
>>>>>>>>>> 
>>>>>>>>>> I wasn't able to figure out a way to set it before gwtSupport.js 
>>>>>>>>>> gets included.
>>>>>>>>>> 
>>>>>>>>>> I tried addInitializerCall, addScript, etc. but they all come after 
>>>>>>>>>> gwtSupport.js is included.
>>>>>>>>>> 
>>>>>>>>>> What am I missing?
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> ---------------------------------------------------------------------
>>>>>>>>>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
>>>>>>>>>> For additional commands, e-mail: users-h...@tapestry.apache.org
>>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> ---------------------------------------------------------------------
>>>>>>>>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
>>>>>>>>> For additional commands, e-mail: users-h...@tapestry.apache.org
>>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> ---------------------------------------------------------------------
>>>>>>>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
>>>>>>>> For additional commands, e-mail: users-h...@tapestry.apache.org
>>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> ---------------------------------------------------------------------
>>>>>>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
>>>>>>> For additional commands, e-mail: users-h...@tapestry.apache.org
>>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> ---------------------------------------------------------------------
>>>>>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
>>>>>> For additional commands, e-mail: users-h...@tapestry.apache.org
>>>>>> 
>>>>> 
>>>>> 
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
>>>>> For additional commands, e-mail: users-h...@tapestry.apache.org
>>>>> 
>>>> 
>>>> 
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
>>>> For additional commands, e-mail: users-h...@tapestry.apache.org
>>> 
>>> 
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
>>> For additional commands, e-mail: users-h...@tapestry.apache.org
>>> 
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
>> For additional commands, e-mail: users-h...@tapestry.apache.org
>> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org

Reply via email to