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