[gwt-contrib] Re: Initial implementation of layout system, along with the first two layout widgets.
I did a very-very simplified layout system based on top,bottom,left,right,width and height CSS attributes: http://69.20.122.77:8880/gwt-layout/ So far SimpleLayout, HBoxLayout VBoxLayout are implemented. Source files: http://69.20.122.77:8880/gwt-layout/org.gwt20.mosaic.demo.tbz2 The EntryPoint class for the demo is: http://pastebin.com/m27e7a4e7 Nice work as always George, But why use a widget wrapper to define alignments for a child of the container? I must say I like the idea of passing layout-data to the add() method better. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Inlining nocache.js
I'd like to save first time visitors that roundtrip to fetch nocache.js. Instead I've declared the module HTML page as non- cacheable (works nice thanks to E-Tag) and moved images and GWT- compiler output to a fully cacheable directory. After inlining nocache.js into the module HTML I had to change the paths to the XYZ.cache.html permutations, but couldn't get RPC to work reliably across all browsers. Is there a way to do this cleanly? --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Better support of IE6 for ImageResourceGenerator
Hi, As for the question on adding another permutations... I think that adding an ie7 permutation might be not necesarry. I posted a small example on how I handle ie6/7(or 8 in ie7 mode) in my application... it just means a small extra indirection but the cost is very low. It's not like we are creating ImageBundles in a tight loop in our applications (that is a bit against the whole idea of using them in the first place). Your remark just made me think to something. The problem with extra permutations is mainly compile time. When 2 permutations are very close to one another (a lot of deferred binding will lead to the same implementation for the 2 permutations), dynamic selection through indirection might not be that costly in performance. There is also a loss because of some optimization that will not take place, but one will have to accept that. Then GWT could have an option to say that such and such permutation must be separated at runtime instead of compile time. That will allow the compilation to be as quick as now, but the designers will still be able to use the deferred binding mechanism to handle ie6/ie7 (for example). Moreover, one can imagine an option to have all permutations separated at runtime for speeding up the compilation in development mode. Did I miss something obvious? -- Benjamin Lerman --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Better support of IE6 for ImageResourceGenerator
On Fri, Aug 7, 2009 at 9:57 AM, Benjamin Lermangoogle+goo...@ambre.net wrote: Hi, As for the question on adding another permutations... I think that adding an ie7 permutation might be not necesarry. I posted a small example on how I handle ie6/7(or 8 in ie7 mode) in my application... it just means a small extra indirection but the cost is very low. It's not like we are creating ImageBundles in a tight loop in our applications (that is a bit against the whole idea of using them in the first place). Your remark just made me think to something. The problem with extra permutations is mainly compile time. When 2 permutations are very close to one another (a lot of deferred binding will lead to the same implementation for the 2 permutations), dynamic selection through indirection might not be that costly in performance. There is also a loss because of some optimization that will not take place, but one will have to accept that. Then GWT could have an option to say that such and such permutation must be separated at runtime instead of compile time. That will allow the compilation to be as quick as now, but the designers will still be able to use the deferred binding mechanism to handle ie6/ie7 (for example). Moreover, one can imagine an option to have all permutations separated at runtime for speeding up the compilation in development mode. Did I miss something obvious? Sounds like an interesting proposition, but is it really needed: I tend to limit the number of permutations in development. I'm not running multiple browsers at the same time. David --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Initial implementation of layout system, along with the first two layout widgets.
Just to keep LayoutPanel class simple with only the required methods added to AbsolutePanel widget: http://pastebin.com/m7fc7deb0 I agree, LayoutData should for that purpose. Something like: LayoutPanel.add(Widget w, LayoutData data) should replace AbsolutePanel.add(). On Aug 7, 10:42 am, Johan Rydberg johan.rydb...@edgeware.tv wrote: I did a very-very simplified layout system based on top,bottom,left,right,width and height CSS attributes: http://69.20.122.77:8880/gwt-layout/ So far SimpleLayout, HBoxLayout VBoxLayout are implemented. Source files:http://69.20.122.77:8880/gwt-layout/org.gwt20.mosaic.demo.tbz2 The EntryPoint class for the demo is:http://pastebin.com/m27e7a4e7 Nice work as always George, But why use a widget wrapper to define alignments for a child of the container? I must say I like the idea of passing layout-data to the add() method better. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Inlining nocache.js
On Fri, Aug 7, 2009 at 3:51 AM, George Georgovassilis g.georgovassi...@gmail.com wrote: I'd like to save first time visitors that roundtrip to fetch nocache.js. Instead I've declared the module HTML page as non- cacheable (works nice thanks to E-Tag) and moved images and GWT- compiler output to a fully cacheable directory. After inlining nocache.js into the module HTML I had to change the paths to the XYZ.cache.html permutations, but couldn't get RPC to work reliably across all browsers. Is there a way to do this cleanly? There is a Google-internal linker that does this, and will be cleaned up and moved to GWT itself in the near future. I don't know an exact timeframe for this however. -- John A. Tamplin Software Engineer (GWT), Google --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] [google-web-toolkit] r5912 committed - Left out part of r5911....
Revision: 5912 Author: j...@google.com Date: Fri Aug 7 04:32:01 2009 Log: Left out part of r5911. Patch by: jat Review by: amitmanjhi (TBR) http://code.google.com/p/google-web-toolkit/source/detail?r=5912 Modified: /trunk/dev/core/src/com/google/gwt/dev/shell/BrowserWidget.java === --- /trunk/dev/core/src/com/google/gwt/dev/shell/BrowserWidget.java Wed Mar 11 16:11:41 2009 +++ /trunk/dev/core/src/com/google/gwt/dev/shell/BrowserWidget.java Fri Aug 7 04:32:01 2009 @@ -172,7 +172,7 @@ * The version number that should be passed into gwtOnLoad. Must match the * version in hosted.html. */ - private static final String EXPECTED_GWT_ONLOAD_VERSION = 1.6; + private static final String EXPECTED_GWT_ONLOAD_VERSION = 2.0; public static void launchExternalBrowser(TreeLogger logger, String location) { String browserCmd = System.getenv(GWT_EXTERNAL_BROWSER); --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Better support of IE6 for ImageResourceGenerator
On Fri, Aug 7, 2009 at 3:57 AM, Benjamin Lerman google+goo...@ambre.netgoogle%2bgoo...@ambre.net wrote: When 2 permutations are very close to one another (a lot of deferred binding will lead to the same implementation for the 2 permutations), dynamic selection through indirection might not be that costly in performance. There is also a loss because of some optimization that will not take place, but one will have to accept that. We already do this for runtime locales. For example, look at the Showcase sample in trunk. It only has 5 compile time locales for 25 permutations, but you get country-specific number/date/time formats and currency information for far more locales than that. The generated code is smart about which locales are equivalent for pieces of this and produces code to choose between only the individual implementations that are possible in a given permutation at runtime. Note that this is only viable where you don't have different translations for the different runtime locales, though you could imagine extending this concept to handle a small number of differences efficiently, the same way the currency data/etc is handled now (if you had most of the translations different it wouldn't be useful because the strings can wind up taking a significant portion of the compiled output). Then GWT could have an option to say that such and such permutation must be separated at runtime instead of compile time. That will allow the compilation to be as quick as now, but the designers will still be able to use the deferred binding mechanism to handle ie6/ie7 (for example). Doing it in a general way is much more complicated, because it isn't just in the compiler but to get efficient results each generator has to do the work. Moreover, one can imagine an option to have all permutations separated at runtime for speeding up the compilation in development mode. For development, you should consider having a separate .gwt.xml file which limits the web compile to a single permutation. Also, most of your development should be done in hosted mode rather than doing web-mode compiles. -- John A. Tamplin Software Engineer (GWT), Google --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] [google-web-toolkit] r5913 committed - Disabling showOutput for the junit ant target because its too spammy f...
Revision: 5913 Author: jlaba...@google.com Date: Fri Aug 7 04:58:23 2009 Log: Disabling showOutput for the junit ant target because its too spammy for now. Patch by: jlabanca Review by: rjrjr (TBR) http://code.google.com/p/google-web-toolkit/source/detail?r=5913 Modified: /trunk/common.ant.xml === --- /trunk/common.ant.xml Thu Aug 6 14:05:34 2009 +++ /trunk/common.ant.xml Fri Aug 7 04:58:23 2009 @@ -199,8 +199,7 @@ echo message=${javac.out} ${javac.junit.out} / junit dir=@{test.out} fork=yes printsummary=yes - failureproperty=junit.failure tempdir=@{test.out} - showoutput=yes + failureproperty=junit.failure tempdir=@{test.out} jvmarg line=${junit.platform.args} / jvmarg line=-Xmx768m / jvmarg value=-demma.coverage.out.fi...@{test.emma.coverage}/coverage.emma / --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Inlining nocache.js
I'd be keen to see this land in trunk ! Cam 2009/8/7 John Tamplin j...@google.com On Fri, Aug 7, 2009 at 3:51 AM, George Georgovassilis g.georgovassi...@gmail.com wrote: I'd like to save first time visitors that roundtrip to fetch nocache.js. Instead I've declared the module HTML page as non- cacheable (works nice thanks to E-Tag) and moved images and GWT- compiler output to a fully cacheable directory. After inlining nocache.js into the module HTML I had to change the paths to the XYZ.cache.html permutations, but couldn't get RPC to work reliably across all browsers. Is there a way to do this cleanly? There is a Google-internal linker that does this, and will be cleaned up and moved to GWT itself in the near future. I don't know an exact timeframe for this however. -- John A. Tamplin Software Engineer (GWT), Google --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Inlining nocache.js
I'd love to see this in the trunk too. We have only 2 round trips on start up now, thanks to ClientBundle. Getting it down to one will be very slick! -- Arthur Kalmenson On Fri, Aug 7, 2009 at 8:41 AM, Cameron Braidcame...@braid.com.au wrote: I'd be keen to see this land in trunk ! Cam 2009/8/7 John Tamplin j...@google.com On Fri, Aug 7, 2009 at 3:51 AM, George Georgovassilis g.georgovassi...@gmail.com wrote: I'd like to save first time visitors that roundtrip to fetch nocache.js. Instead I've declared the module HTML page as non- cacheable (works nice thanks to E-Tag) and moved images and GWT- compiler output to a fully cacheable directory. After inlining nocache.js into the module HTML I had to change the paths to the XYZ.cache.html permutations, but couldn't get RPC to work reliably across all browsers. Is there a way to do this cleanly? There is a Google-internal linker that does this, and will be cleaned up and moved to GWT itself in the near future. I don't know an exact timeframe for this however. -- John A. Tamplin Software Engineer (GWT), Google --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Add GWT#getUserAgentProperty()
On 2009/08/07 13:56:08, jlabanca wrote: So there's one problem here: The GWT class is in the Core module, which doesn't (and shouldn't) depend upon the UserAgent module. I think that to get this right, we'll need to do one of the following things: - Add this code to some class in User. Not my favorite option. - Add a new UserAgent module that lives in its own package, so that we can add UserAgent-related stuff to a class there. Perhaps com.google.gwt.ua.UserAgent? - I kind of like this option, because (a) it gets UserAgent out of the user packgage, where it never should have been in the first place, and (b) it gives me a place to put other UserAgent-related methods I need to add. What say you? http://gwt-code-reviews.appspot.com/57804 --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Add GWT#getUserAgentProperty()
Reviewers: jgw, Description: Sometimes its nice to now the user agent property at runtime to do runtime checks. This patch adds a method to GWT to get the user agent property. I verified that the return value is correct on all browsers. Please review this at http://gwt-code-reviews.appspot.com/57804 Affected files: user/src/com/google/gwt/core/client/GWT.java user/src/com/google/gwt/core/client/impl/Impl.java user/src/com/google/gwt/user/UserAgent.gwt.xml Index: user/src/com/google/gwt/core/client/GWT.java === --- user/src/com/google/gwt/core/client/GWT.java(revision 5913) +++ user/src/com/google/gwt/core/client/GWT.java(working copy) @@ -164,6 +164,15 @@ return sUncaughtExceptionHandler; } + /** + * Get the user agent property value as defined by GWT (eg. ie6, safari). + * + * @return the user.agent GWT property + */ + public static String getUserAgentProperty() { +return Impl.getUserAgentProperty(); + }; + public static String getVersion() { if (sGWTBridge == null) { return getVersion0(); Index: user/src/com/google/gwt/core/client/impl/Impl.java === --- user/src/com/google/gwt/core/client/impl/Impl.java (revision 5913) +++ user/src/com/google/gwt/core/client/impl/Impl.java (working copy) @@ -95,6 +95,10 @@ return $strongName; }-*/; + public static native String getUserAgentProperty() /*-{ +return $wnd.__gwt_userAgent; + }-*/; + /** * Called from JSNI. Do not change this implementation without updating: * ul Index: user/src/com/google/gwt/user/UserAgent.gwt.xml === --- user/src/com/google/gwt/user/UserAgent.gwt.xml (revision 5913) +++ user/src/com/google/gwt/user/UserAgent.gwt.xml (working copy) @@ -26,20 +26,23 @@ var makeVersion = function(result) { return (parseInt(result[1]) * 1000) + parseInt(result[2]); }; + var setUserAgent = function(userAgent) { +return $wnd.__gwt_userAgent = userAgent; + } if (ua.indexOf(opera) != -1) { -return opera; +return setUserAgent(opera); } else if (ua.indexOf(webkit) != -1) { -return safari; +return setUserAgent(safari); } else if (ua.indexOf(msie) != -1) { if (document.documentMode = 8) { - return ie8; + return setUserAgent(ie8); } else { var result = /msie ([0-9]+)\.([0-9]+)/.exec(ua); if (result result.length == 3) { var v = makeVersion(result); if (v = 6000) { - return ie6; + return setUserAgent(ie6); } } } @@ -47,11 +50,11 @@ var result = /rv:([0-9]+)\.([0-9]+)/.exec(ua); if (result result.length == 3) { if (makeVersion(result) = 1008) -return gecko1_8; +return setUserAgent(gecko1_8); } -return gecko; +return setUserAgent(gecko); } - return unknown; + return setUserAgent(unknown); ]]/property-provider !-- Deferred binding to optimize JRE classes based on user agent. -- --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Add GWT#getUserAgentProperty()
I say where's the unit test? On Fri, Aug 7, 2009 at 7:14 AM, j...@google.com wrote: On 2009/08/07 13:56:08, jlabanca wrote: So there's one problem here: The GWT class is in the Core module, which doesn't (and shouldn't) depend upon the UserAgent module. I think that to get this right, we'll need to do one of the following things: - Add this code to some class in User. Not my favorite option. - Add a new UserAgent module that lives in its own package, so that we can add UserAgent-related stuff to a class there. Perhaps com.google.gwt.ua.UserAgent? - I kind of like this option, because (a) it gets UserAgent out of the user packgage, where it never should have been in the first place, and (b) it gives me a place to put other UserAgent-related methods I need to add. What say you? http://gwt-code-reviews.appspot.com/57804 --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Add GWT#getUserAgentProperty()
Let me play devil's advocate, at least against the idea of returning the string directly. I fear that making this value easily accessible will encourage people to write conditional tests all over the place, which is brittle (i.e. because we're very subtly locked into particular user.agent values) and less optimal (because it isn't clear that the resulting patterns will optimize well). I guarantee you people will create maps of (user agent string key) = (functor), which will thoroughly default compiler optimizations. Can you talk a bit more about the motivation, so we could consider alternatives? On Fri, Aug 7, 2009 at 10:50 AM, Ray Ryan rj...@google.com wrote: I say where's the unit test? On Fri, Aug 7, 2009 at 7:14 AM, j...@google.com wrote: On 2009/08/07 13:56:08, jlabanca wrote: So there's one problem here: The GWT class is in the Core module, which doesn't (and shouldn't) depend upon the UserAgent module. I think that to get this right, we'll need to do one of the following things: - Add this code to some class in User. Not my favorite option. - Add a new UserAgent module that lives in its own package, so that we can add UserAgent-related stuff to a class there. Perhaps com.google.gwt.ua.UserAgent? - I kind of like this option, because (a) it gets UserAgent out of the user packgage, where it never should have been in the first place, and (b) it gives me a place to put other UserAgent-related methods I need to add. What say you? http://gwt-code-reviews.appspot.com/57804 --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Inlining nocache.js
2 requests is very impressive, Arthur! This is the sort of conscientiousness (i.e. for optimizing user experience) I hope all GWT developers would strive for. Nice work. And yes, we'd like to help you get that down to 1, too. On Fri, Aug 7, 2009 at 9:43 AM, Arthur Kalmenson arthur.k...@gmail.comwrote: I'd love to see this in the trunk too. We have only 2 round trips on start up now, thanks to ClientBundle. Getting it down to one will be very slick! -- Arthur Kalmenson On Fri, Aug 7, 2009 at 8:41 AM, Cameron Braidcame...@braid.com.au wrote: I'd be keen to see this land in trunk ! Cam 2009/8/7 John Tamplin j...@google.com On Fri, Aug 7, 2009 at 3:51 AM, George Georgovassilis g.georgovassi...@gmail.com wrote: I'd like to save first time visitors that roundtrip to fetch nocache.js. Instead I've declared the module HTML page as non- cacheable (works nice thanks to E-Tag) and moved images and GWT- compiler output to a fully cacheable directory. After inlining nocache.js into the module HTML I had to change the paths to the XYZ.cache.html permutations, but couldn't get RPC to work reliably across all browsers. Is there a way to do this cleanly? There is a Google-internal linker that does this, and will be cleaned up and moved to GWT itself in the near future. I don't know an exact timeframe for this however. -- John A. Tamplin Software Engineer (GWT), Google --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] lightweight events for runAsync in draft mode
Okay, I recently wrote a test for runAsync lightweight metrics, but -- oops -- that test fails in draft mode. In draft mode, no code splitting happens, so no events are generated, and so the test rightfully complains. So, what should be done? I'm thinking to have draft mode generate some different events, and am wondering what people think. My first thought was to leave the events alone, because after all there are no actual downloads in draft mode. However, there are several problems with that approach: 1. The test really should fail if no events are generated in regular compilation modes. So it wouldn't be good to simply change the test to tolerate a complete lack of events. 2. It's awkward to have a test that only runs in certain compilation modes. The list of exceptions would have to live somewhere, and where would that be? 3. It's also awkward to have the test disable itself, because it needs to query some API to figure out whether code splitting really happened. What API would that be? Am I in draft compile mode? Did code splitting happen for real? I can't think of an API that wouldn't be fragile. It's fully intended that the compiler is flexible in the kinds of optimization it does, and it should be possible for the code splitter to have its own decision making as well. It would be better if this test were robust against such changes. Further, the API would be hard to keep private to the test; application code might start using it, thus locking GWT into supporting it for some amount of time. So, instead of enabling the test selectively, how about generating a different event when in draft compile mode? The current event sequence for calling a single runAsync is as follows: - leftoversDownload -- download of the leftovers fragment - download1 --- download of code for split point 1 - runCallbacks1 -- run the callbacks for split point 1 In draft compile mode, maybe the events could be like this: - codeAlreadyLoaded1 -- code for split point 1 requested but already present - runCallbacks1 -- run the callbacks for split point 1 I could then update the test to tolerate either sequence. Thoughts? Lex --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Add GWT#getUserAgentProperty()
It seems like there are a lot of issues with this, and a lot of complementary methods and classes to consider. I only wanted this to modify as part of a junit patch I'm working on, so I'll just modify the existing GWTRunnerGenerator to put the user.agent property into the generated GWTRunner class, and we can save this design/debate for another day. Thanks, John LaBanca jlaba...@google.com On Fri, Aug 7, 2009 at 11:07 AM, Bruce Johnson br...@google.com wrote: Let me play devil's advocate, at least against the idea of returning the string directly. I fear that making this value easily accessible will encourage people to write conditional tests all over the place, which is brittle (i.e. because we're very subtly locked into particular user.agent values) and less optimal (because it isn't clear that the resulting patterns will optimize well). I guarantee you people will create maps of (user agent string key) = (functor), which will thoroughly default compiler optimizations. Can you talk a bit more about the motivation, so we could consider alternatives? On Fri, Aug 7, 2009 at 10:50 AM, Ray Ryan rj...@google.com wrote: I say where's the unit test? On Fri, Aug 7, 2009 at 7:14 AM, j...@google.com wrote: On 2009/08/07 13:56:08, jlabanca wrote: So there's one problem here: The GWT class is in the Core module, which doesn't (and shouldn't) depend upon the UserAgent module. I think that to get this right, we'll need to do one of the following things: - Add this code to some class in User. Not my favorite option. - Add a new UserAgent module that lives in its own package, so that we can add UserAgent-related stuff to a class there. Perhaps com.google.gwt.ua.UserAgent? - I kind of like this option, because (a) it gets UserAgent out of the user packgage, where it never should have been in the first place, and (b) it gives me a place to put other UserAgent-related methods I need to add. What say you? http://gwt-code-reviews.appspot.com/57804 --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: lightweight events for runAsync in draft mode
On Fri, Aug 7, 2009 at 11:11 AM, Lex Spoonsp...@google.com wrote: Okay, I recently wrote a test for runAsync lightweight metrics, but -- oops -- that test fails in draft mode. In draft mode, no code splitting happens, so no events are generated, and so the test rightfully complains. So, what should be done? I'm thinking to have draft mode generate some different events, and am wondering what people think. My first thought was to leave the events alone, because after all there are no actual downloads in draft mode. However, there are several problems with that approach: 1. The test really should fail if no events are generated in regular compilation modes. So it wouldn't be good to simply change the test to tolerate a complete lack of events. 2. It's awkward to have a test that only runs in certain compilation modes. The list of exceptions would have to live somewhere, and where would that be? 3. It's also awkward to have the test disable itself, because it needs to query some API to figure out whether code splitting really happened. What API would that be? Am I in draft compile mode? Did code splitting happen for real? I can't think of an API that wouldn't be fragile. I don't think its terribly yucky to add a GWT.isRunAsync() (pick your favorite name) method the way we have GWT.isScript() and a host of other little similar static methods in the GWT class. It's fully intended that the compiler is flexible in the kinds of optimization it does, and it should be possible for the code splitter to have its own decision making as well. It would be better if this test were robust against such changes. Further, the API would be hard to keep private to the test; application code might start using it, thus locking GWT into supporting it for some amount of time. So, instead of enabling the test selectively, how about generating a different event when in draft compile mode? The current event sequence for calling a single runAsync is as follows: - leftoversDownload -- download of the leftovers fragment - download1 --- download of code for split point 1 - runCallbacks1 -- run the callbacks for split point 1 In draft compile mode, maybe the events could be like this: - codeAlreadyLoaded1 -- code for split point 1 requested but already present - runCallbacks1 -- run the callbacks for split point 1 I could then update the test to tolerate either sequence. Thoughts? Lex -- Eric Z. Ayers - GWT Team - Atlanta, GA USA http://code.google.com/webtoolkit/ --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: lightweight events for runAsync in draft mode
There's a related issue for ClassObjectTest. It is sensitive to whether or not the compiler is in -XdisableClassMetadata mode. I've wanted to add some kind of build information to the GeneratorContext that would allow Generators to get the command-line flags so generators can be sensitive to pretty vs obfuscated mode. When you have tests that are sensitive to flags, you could use a class similar in spirit to LocaleInfo. Even if all you could get is a string containing the compiler's command-line, that should be sufficient. -- Bob Vawter Google Web Toolkit Team --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Inlining nocache.js
+1 On Aug 8, 8:43 am, Arthur Kalmenson arthur.k...@gmail.com wrote: I'd love to see this in the trunk too. We have only 2 round trips on start up now, thanks to ClientBundle. Getting it down to one will be very slick! -- Arthur Kalmenson On Fri, Aug 7, 2009 at 8:41 AM, Cameron Braidcame...@braid.com.au wrote: I'd be keen to see this land in trunk ! Cam 2009/8/7 John Tamplin j...@google.com On Fri, Aug 7, 2009 at 3:51 AM, George Georgovassilis g.georgovassi...@gmail.com wrote: I'd like to save first time visitors that roundtrip to fetch nocache.js. Instead I've declared the module HTML page as non- cacheable (works nice thanks to E-Tag) and moved images and GWT- compiler output to a fully cacheable directory. After inlining nocache.js into the module HTML I had to change the paths to the XYZ.cache.html permutations, but couldn't get RPC to work reliably across all browsers. Is there a way to do this cleanly? There is a Google-internal linker that does this, and will be cleaned up and moved to GWT itself in the near future. I don't know an exact timeframe for this however. -- John A. Tamplin Software Engineer (GWT), Google --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Add GWT#getUserAgentProperty()
This thread seems related to the one that Lex just started, that you have user code which depends upon how the module was built. -- Bob Vawter Google Web Toolkit Team --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Inlining nocache.js
Are you counting fetching the host HTML page? With this approach, the selection script is done away with but you still have a fetch for the compiled script so that it can remain permanently cacheable. You could theoretically inline it into the host page, but since none of that is cacheable that would only make sense for very tiny compiled outputs. I don't think firebug counts the initial request to fetch the host page, so two requests. One for the nocache.js and another for the cachable HTML. With the inlining of the nocache.js file, you could get it down to 0 requests if the retrieved page is cached forever. Are you saying to inline the generated JS in the host page too? How could you do that? Don't you need the selector script to pick the correct compiled version? Maybe I'm just not understanding what you mean. 2 requests is very impressive, Arthur! This is the sort of conscientiousness (i.e. for optimizing user experience) I hope all GWT developers would strive for. Nice work. And yes, we'd like to help you get that down to 1, too. Thanks Bruce! But it's really all thanks to Bob's ClientBundle :) -- Arthur Kalmenson On Fri, Aug 7, 2009 at 9:57 AM, John Tamplinj...@google.com wrote: On Fri, Aug 7, 2009 at 9:43 AM, Arthur Kalmenson arthur.k...@gmail.com wrote: I'd love to see this in the trunk too. We have only 2 round trips on start up now, thanks to ClientBundle. Getting it down to one will be very slick! Are you counting fetching the host HTML page? With this approach, the selection script is done away with but you still have a fetch for the compiled script so that it can remain permanently cacheable. You could theoretically inline it into the host page, but since none of that is cacheable that would only make sense for very tiny compiled outputs. Note that there is a cost, as your host HTML page now can't be cached (since the selection script essentially runs in the server). If your host page is complex, this may be a net loss. You could try leaving it cacheable but setting Vary headers for the pieces that you use to make the decision, but my understanding is that many caches do not handle this properly. Also, you cannot use any deferred binding properties that can't be determined by the HTTP fetch of your host page. -- John A. Tamplin Software Engineer (GWT), Google --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] [google-web-toolkit] r5914 committed - Removing extraneous file....
Revision: 5914 Author: fabb...@google.com Date: Fri Aug 7 08:50:02 2009 Log: Removing extraneous file. TBR: rjrjr http://code.google.com/p/google-web-toolkit/source/detail?r=5914 Deleted: /trunk/user/src/com/google/gwt/uibinder/testing/BUILD === --- /trunk/user/src/com/google/gwt/uibinder/testing/BUILD Wed Aug 5 20:27:52 2009 +++ /dev/null @@ -1,11 +0,0 @@ -# -*- mode: python; -*- - -# Description: -# testing things - -gwt_module( - name = testing, - srcs = glob([ -*.java, - ]), -) --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Inlining nocache.js
The best you can do for a cold cache is 2 round-trips (including the host page) if you inline the selection script (.nocache.js) in the host page. You definitely do want the compiled script (.cache.html) *not* embedded in the host page, so that it can have cache forever semantics. Then, when users have a warm cache, it's literally exactly 1 round-trip for the module to start. BTW, once you do inline the selection script, it will be more important to get the HTTP semantics just right. Although it says nocache, the proper semantics are must-revalidate, so typically, the host page won't have changed on the server, and thus it becomes an If-Modified-Since (IMS) request with a Not-Modified (NM) response. In other words, the best case for a warm cache is this 1 round-trip: IMS = NM, which is very cheap because there's no response payload. Your code can start essentially instantly on a decent network. On Fri, Aug 7, 2009 at 11:39 AM, Arthur Kalmenson arthur.k...@gmail.comwrote: Are you counting fetching the host HTML page? With this approach, the selection script is done away with but you still have a fetch for the compiled script so that it can remain permanently cacheable. You could theoretically inline it into the host page, but since none of that is cacheable that would only make sense for very tiny compiled outputs. I don't think firebug counts the initial request to fetch the host page, so two requests. One for the nocache.js and another for the cachable HTML. With the inlining of the nocache.js file, you could get it down to 0 requests if the retrieved page is cached forever. Are you saying to inline the generated JS in the host page too? How could you do that? Don't you need the selector script to pick the correct compiled version? Maybe I'm just not understanding what you mean. 2 requests is very impressive, Arthur! This is the sort of conscientiousness (i.e. for optimizing user experience) I hope all GWT developers would strive for. Nice work. And yes, we'd like to help you get that down to 1, too. Thanks Bruce! But it's really all thanks to Bob's ClientBundle :) -- Arthur Kalmenson On Fri, Aug 7, 2009 at 9:57 AM, John Tamplinj...@google.com wrote: On Fri, Aug 7, 2009 at 9:43 AM, Arthur Kalmenson arthur.k...@gmail.com wrote: I'd love to see this in the trunk too. We have only 2 round trips on start up now, thanks to ClientBundle. Getting it down to one will be very slick! Are you counting fetching the host HTML page? With this approach, the selection script is done away with but you still have a fetch for the compiled script so that it can remain permanently cacheable. You could theoretically inline it into the host page, but since none of that is cacheable that would only make sense for very tiny compiled outputs. Note that there is a cost, as your host HTML page now can't be cached (since the selection script essentially runs in the server). If your host page is complex, this may be a net loss. You could try leaving it cacheable but setting Vary headers for the pieces that you use to make the decision, but my understanding is that many caches do not handle this properly. Also, you cannot use any deferred binding properties that can't be determined by the HTTP fetch of your host page. -- John A. Tamplin Software Engineer (GWT), Google --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: lightweight events for runAsync in draft mode
JUnit 4 has @Theory and @Assumption annotations that might help here. I forget which does what, but one of them (probably @Assumption) can say I believe X is true and it needs to be for my tests to pass, so ignore these if it's false. If there was some way to expose a predicate that was true when you expect code splitting and false otherwise, you might be able to let JUnit manage the conditional quality of your tests. As for how to expose that predicate, I have no brilliant ideas. Ian --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: NOTICE - removing all @deprecated code for GWT 2.0
I've always been meaning to use it myself, so I just tried it and here's what appears to be the most useful thing you can do as an API or GWT developer: 1. Refactor your library using Eclipse 2. Review your history at any time with Refactor - History 3. Package your refactorings - I did this via File - Export - Jar file (and then check the box 'Export refactorings for checked projects'), which produced a META-INF/REFACTORINGS.XML in the jar - I bet you could instead more simply use Refactor - Create Script 4. Ship a jar with the new APIs and include the refactoring history in META-INF/REFACTORINGS.XML Your users then simply: 1. Open their project while they still have your old jar in their classpath 2. They select Refactor - Migrate JAR file - specify the location of the new jar file which contains the META-INF/REFACTORINGS.XML - specify the old jar already in their project classpath - Click, Next, then Next again - review the refactorings they want to apply - Click Finish The rest is magic. Pretty cool. It wouldn't handle listener-handler migrations, but simple method name changes would be trivial. I tried it with an 'encapsulate field' refactoring. Works beautifully. You might even be able to trigger the user.Element - dom.Element migration in user code. Most excellent would be integration with the Eclipse Plugin whereby an update from GWT 1.7 - 2.0 causes the Refactor-Migrate JAR file wizard to be invoked for you. Fred 2009/8/3 Joel Webber j...@google.com I haven't actually tried any of this stuff. I'll definitely have a look when I hunker down to do this refactoring. Of course, if anyone wants to look into it before I get to it, that would be even cooler... :) On Mon, Aug 3, 2009 at 12:13 PM, Fred Sauer fre...@google.com wrote: I wonder how much work we could make Eclipse do for us. Under the 'Refactor' menu there are a few useful optional to record / playback refactorings: Migrate JAR File Migrates a JAR File on the build path of a project in your workspace to a newer version, possibly using refactoring information stored in the new JAR File to avoid breaking changes. Available: JAR Files on build path Create Script Creates a script of the refactorings that have been applied in the workspace. Refactoring scripts can either be saved to a file or copied to the clipboard. See *Apply Script*. Available: Always Apply Script Applies a refactoring script to projects in your workspace. Refactoring scripts can either be loaded from a file or from the clipboard. See *Create Script*. Available: Always History Browses the workspace refactoring history and offers the option to delete refactorings from the refactoring history. Available: Always What if you recorded all the refactorings you wanted to make and then let developers simply replay them on their own projects? In fact, the Eclipse plugin could potentially prompt to auto upgrade projects to the new API. Fred On Mon, Aug 3, 2009 at 7:10 AM, Joel Webber j...@google.com wrote: I'd be a lot more comfortable if our own code didn't have reams of deprecation warnings. The good news is that it's actually pretty easy to do -- it's damned near rote, though not quite enough to automate. I did it for a few large classes in 1.5 (though I didn't commit the changes), just to make sure I didn't miss anything too important. On Mon, Aug 3, 2009 at 10:06 AM, John Tamplin j...@google.com wrote: On Mon, Aug 3, 2009 at 8:30 AM, Joel Webber j...@google.com wrote: I've been wanting to do this since we first introduced the dom package in 1.5. The plan is to remove all extant references to user.Element and friends, as well as the DOM.* static methods, at which point they can be deprecated. I'd like to do this as part of 2.0, so that we can go ahead and get them deprecated, but it remains to be seen if there's enough time in the schedule. Do we have to remove internal references to it before marking it deprecated? Obviously, those would have to be cleaned up before we actually remove it, but it doesn't seem necessary to require it earlier. -- John A. Tamplin Software Engineer (GWT), Google -- Fred Sauer Developer Advocate Google Inc. 1600 Amphitheatre Parkway Mountain View, CA 94043 fre...@google.com -- Fred Sauer Developer Advocate Google Inc.1600 Amphitheatre Parkway Mountain View, CA 94043 fre...@google.com --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Inlining nocache.js
On Fri, Aug 7, 2009 at 11:39 AM, Arthur Kalmenson arthur.k...@gmail.comwrote: I don't think firebug counts the initial request to fetch the host page, so two requests. One for the nocache.js and another for the cachable HTML. With the inlining of the nocache.js file, you could get it down to 0 requests if the retrieved page is cached forever. Well, since it can't be strongly named (if it was then the page with the link would have to be weakly cached for when it changed), the host page can't be cached forever but it can be cached based on the frequency you might need to update it. Note that you need to keep the old compiled script around for as long as the host page might be cached (and any server resources it might need, which makes server RPC changes difficult), since caches with the old host page will be referring to the old compiled output. Are you saying to inline the generated JS in the host page too? How could you do that? Don't you need the selector script to pick the correct compiled version? Maybe I'm just not understanding what you mean. See the example below for how it currently works and the change usign server-side selection. The problem is that the browser will fetch foo.html and get the proper compiled output for their browser/locale/etc. An intervening cache, say at an ISP, will then return that foo.html response to a different user with different parameters. As I mentioned in the other message, you have to either make the host page uncacheable (which is only feasible with small compiled scripts) or rely on caches honoring the Vary headers, which is problematic on the Internet in general though might be feasible if you control the network your users use to access it. Currently you have a host page, say Showcase.html, that is cached based on the frequency you expect to update it and contains a reference to the selection script. ... script language='javascript' src='showcase/showcase.nocache.js'/script That then fetches the selection script, which is cached based on the frequency you expect to update the app but with must-validate set and executes in the browser, and chooses a strong-named JS file for the compiled output, say XYZ.cache.html. That file is then cached for 1 year (forever according to the HTTP spec). In the new scheme, you have a host page that is generated by the server from a template. That is mark cacheable for the shorter of the time you expect to update the host page template or recompile your app, with must-revalidate set. It directly includes a script tag referencing XYZ.cache.html, where the server made the deferred binding decision based on the information available in the request. In the typical case, it will use the User-Agent header and perhaps the Accept-Language header and the locale query parameter in the URL. Since the results of the request for Showcase.html now depend on those parameters of the HTTP request, you have to make sure that a cache doesn't return a previous copy served to someone with Firefox to the next guy to ask for it who might be using Safari. One way to do that is to make sure it isn't cached at all (or at least with must-validate), and the other is to rely on the caches to correctly interpret Vary headers so they know that the response you returned may be different if those headers are different. As a side note, it doesn't know that you don't care about the difference between IE 7.0 and IE 7.0.1 (making these up so you get the point), or even the screen resolution that some user agents send in the request, so even caches that accept the Vary header will be less effective. There are other ways around it with newer standards, but even fewer of the caches out there will make use of those features so it will be a while before they are actually useful. -- John A. Tamplin Software Engineer (GWT), Google --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Questions and concerns with HandlerManager
All, There has been a fair amount of discussion about the 1.6 HandlerManager and related code, along with a few issues submitted (primarily by Ed), and I'm starting this thread to try and reach some kind of consensus on what, if anything, needs to be changed about it. Please note that we need to find the simplest things we can do to enable everyone's use cases, without creating a new event system from whole cloth, or adding a lot of complexity to simple use cases. Please help me to reach convergence so that we can get this taken care of reasonably soon. The following are the three issues I'm aware of. I'll work backwards, from simplest to most complex. 1. Switching the 'source' of an event object, primarily for composite events. We actually did consider this in the original design. This is the normal pattern for re-firing an event from a composite (the composite has a field called 'button' that represents a wrapped widget): HandlerRegistration addClickHandler(ClickHandler h) { return button.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { fireEvent(event); } }); } This does require the instantiation of an extra inner class, but the design allows the HandlerManager to re-use event objects, even when they're fired through multiple layers of widgets and composites. 2. Making the source of a HandlerManager generic (issue 3636). Mark Renouf's comment in this issue was spot on: Doing so would break the delegation described above. I don't see any way around this. Please let me know if I've missed something (but please no proposals that would involve redesigning the whole event system). 3. Adding an interceptor to the HandlerManager (issue 3628). I'll be honest. I've spent all morning trying to figure out what's being requested here, and I just don't quite get it. I'm sure there's a real problem being described here, but I think I need a very concrete use-case that can't be easily implemented the way things are to fully understand it. Thanks for your help, joel. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: lightweight events for runAsync in draft mode
On Fri, Aug 7, 2009 at 11:35 AM, Bruce Johnsonbr...@google.com wrote: I would go back and push on your dismissal of option #2: tests that really do only run in certain modes. I think we're going to have to embrace that on many different levels, and perhaps we simply need to come up with better infrastructure for managing it. That's a great list of examples you give! I'm now convinced we need selective enabling of tests in at least some cases. Your list is just too long and varied to rule them all out. One place I would quibble about is compiler transforms that we consider to be optimizations, because an optimization should preserve behavior. Thus, a test case should not have any easy way to be sensitive to the choice. Going back to the code splitting example, it would be within spec for the code splitter *not* to generate a download event for a particular split point, even though it's not that clever right now. That flexibility makes it very hard to think up an API for querying the code splitter's settings. Certainly on and off isn't enough information, at least going forward. Would anyone see anything bad, for the narrow code splitting example, with adding a LWM event saying split point requested, but code already present? This approach would mean I can finish up the runAsync LWM patch on Monday or Tuesday. So, would it be too much of a digression to brainstorm about a uniform way to handle all these variations? We have @DoNotRunWith() right now. Could we generalize that to: @DoNotRunWhen(from=deferred-bound-type, to=chosen-replacement-class) such as @DoNotRunWhen(from=DOMImpl.class, to=DOMImplOpera.class) We'd have to figure out how to compose these using a decent syntax, but something like this seems like it might work. It would also mean that we'd have to introduce potentially artificial classes to represent optional modes that are just flags right now, including classes such as AggressiveCompilerOptimizationsDisabled or CodeSplittingEnabled, etc. Looks good to me. For the short term, how does it strike you to also have a way to query config and binding properties? While it might not be what we want in the long run, it looks very practical right now. For example, disable this test when user.agent=opera. Another example would be, disable this test if class metadata is off. Given the near-term state of module specifications, querying the property looks more direct than needing to define a class that corresponds to them. Also, while thinking about how to set up the annotations, or and and would seem helpful in some cases. Run this test if the agent is iphone *or* the agent is android. Run this test if the agent is iphone *and* class metadata is on. So it would be good to include them, or something equally powerful, in the supported annotations. At Ian's suggestion, I just took a quick look at the JUnit 4 documentation, and they support an assumeThat() method that we could mimic. The way it's used is that a test method or class can run assumeThat(someExpression) as the first thing it does. If the assumption fails, then the rest of the test simply doesn't run. Large benefits of this approach are that it is very general, and that we don't have to spec up and implement and ||. Instead, the built-in Java versions could be used: // test a deferred binding result assumeThat(!(GWT.create(com.google.gwt.user.DOMImpl) instanceof DOMImplOpera)); // test a property assumeThat(GWT.bindingPropertyIs(user.agent, safari)); // test two properties assumeThat( GWT.bindingPropertyIs(user.agent, safari) GWT.configurationPropertyIs(gwt.metadata.disabled, false)); On the downside, using assumeThat() means that the test runner still has to run the tests. With annotations, the test runner can know ahead of time which tests are relevant on which platforms. Would our test runners make good use of that information? Enough to merit the implementation time and the larger GWT user manual? -Lex --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Better support of IE6 for ImageResourceGenerator
I just updated issue 3588 with the results of this discussion. Thanks, everyone. On Thu, Aug 6, 2009 at 2:53 PM, Matt Mastracci matt...@mastracci.comwrote: On 6-Aug-09, at 12:04 PM, Joel Webber wrote: On Thu, Aug 6, 2009 at 1:47 PM, Joel Webber j...@google.com wrote: Side note: God, I thought I would never have to think about this problem again after everybody finally dropped their old VGA cards, and we could at least just deal with 5-5-5 vs. 5-6-5 16-bit color modes in all our assembly code. Wait, did I just date myself pretty badly? Side side note: Holy crap, I just realized that NeuQuant uses a Kohonen network to iteratively converge on a palette. No wonder it works so much better. But does it end up taking a really long time to converge? I'd hate to make the build take forever because it's waiting on a neural network to converge :) NeuQuant was pretty fast in all of my experiements. For our build pipeline I actually ended up using pngquant instead of NeuQuant because of the difficulty getting NeuQuant to process transparency. I haven't tested the JAI version of it, but the NeuQuant version linked on that website completely ignores transparency. On top of that, I was having trouble getting Java to output IE-transparency-compatible PNG files. It also seemed like I had to construct PNG files by hand with a very specific set of chunks to get IE to recognize them, meaning I had to skip the convenience of ImageIO PNG output . The output quality is great, but the hoops I had to jump through to hook it into the pipeline forced me to drop it. Dither like it's 1999! --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: lightweight events for runAsync in draft mode
On Fri, Aug 7, 2009 at 12:20 PM, Lex Spoon sp...@google.com wrote: One place I would quibble about is compiler transforms that we consider to be optimizations, because an optimization should preserve behavior. Thus, a test case should not have any easy way to be sensitive to the choice. Going back to the code splitting example, it would be within spec for the code splitter *not* to generate a download event for a particular split point, even though it's not that clever right now. That flexibility makes it very hard to think up an API for querying the code splitter's settings. Certainly on and off isn't enough information, at least going forward. The sorts of compiler optimizations tests I was referring to were to-be-written tests of complex optimizations where the whole point of the test is to ensure the compiler is doing exactly the transform we intend it to. IOW, the sort of stuff Scott is working on testing infrastructure for. I mostly see your point about the splitter, and in cases like that where you aren't trying to test the exact decisions/implementation, then it seems reasonable to have something that's a bit looser. OTOH, one could argue that it's good to have tests that verify specific behavior that is intended for the current implementation rather than adherence to the spec. Would anyone see anything bad, for the narrow code splitting example, with adding a LWM event saying split point requested, but code already present? This approach would mean I can finish up the runAsync LWM patch on Monday or Tuesday. No objections here, especially if the code already present event is meaningful for web mode where indeed the needed code has already been downloaded. That could be useful thing to know at runtime in production. Looks good to me. For the short term, how does it strike you to also have a way to query config and binding properties? While it might not be what we want in the long run, it looks very practical right now. For example, disable this test when user.agent=opera. Another example would be, disable this test if class metadata is off. Given the near-term state of module specifications, querying the property looks more direct than needing to define a class that corresponds to them. I like the pragmatism, but I fear the repercussions of a intermediate generalized solution that would encouraged the string literal names of properties and flags all over client code. I'd rather we switched things over to The Right Way (whatever we deem that to be) rather than have a half-done waypoint. However, The Right Thing could be something very different than what I proposed -- see the JUnit discussion below. Also, while thinking about how to set up the annotations, or and and would seem helpful in some cases. Run this test if the agent is iphone *or* the agent is android. Run this test if the agent is iphone *and* class metadata is on. So it would be good to include them, or something equally powerful, in the supported annotations. My idea here might be considered a hack. I was thinking that and could be represented as pairs of (to, from) tuples, and that or could be represented as separate test cases that simply delegate, such as @RunWhen(Browser.class, Browser_IPhone.class) public void testIPhone() { doTestIPhoneOrAndroid(); } @RunWhen(Browser.class, Browser_Android.class) public void testAndroid() { doTestIPhoneOrAndroid(); } private void doTestIPhoneOrAndroid() { ... } Now that I look at it, it's kinda hacky, but then again it may not be very common. Hopefully not, or we're not doing a good job of creating portable APIs. On the downside, using assumeThat() means that the test runner still has to run the tests. With annotations, the test runner can know ahead of time which tests are relevant on which platforms. Would our test runners make good use of that information? Enough to merit the implementation time and the larger GWT user manual? I think assumeThat() might indeed be a good general solution, along the lines of your examples. It subsumes the annotations I proposed, and it's nice that it could be generalized easily to any sort of tests. Also, it *might* be possible for the compiler to optimize it statically somewhat such that if a test contained assumeThat(X) where X was statically know to be false, the whole method could go away. (Of course, we'd need that behavior to be generalized somehow -- I'm not proposing JUnit-specific compiler behavior, which would be way too hacky). --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Questions and concerns with HandlerManager
It costs me a bit to go back in time as these issues are already from some time back.. Let me try to give some input on these points. 2) I don't fully understand what the problem is here. Could you give an example that shows that it breaks? Anyway, let me explain a bit how my handlermanager works as I don't seem to have this problem yet... but neither do I think it solves it (I did this somewhere on the forum already... I think but but can't find it 123) In my implementation I can specify the source through generics as I found it important due to experience in the past. It makes it more clear and tight about what to expect in the listener event (the element of least-suprise). The steps for firing an event are almost the same, except: - I bought myself some extra freedom by introducing an extra eventbuilder object that contains the event (kind of intermediate object). The event is a stupid value object without any extra logic like the GWT event. This is takes away the need for the gwt package protected event methods btw. I moved the logica that GWT put in the gwt event in my eventbuilder, such that they al have their simple and clear responsibility. I think the current gwt event contains/does too much. I experience this when trying to extend/use it, this is difficult/not possible... The event builder will call the listener and pass in the contained event. I use the builders as flyweight object and reuse them. The event builder is passed to the fireEvent(..) method of the HandlerManager. This is an interface of which if have several sub interfaces to add extra functionality like the interceptor construction. The HandlerManager will ask the event builder to fire the event passing in the register that holds all the listeners. The event builder will then ask the register to fire the event, passing in himself. The register will retrieve all interested listeners through the type that is contained in the event builder, and will then ask the event builder to dispatch the event to the listener, passing in the listener (one by one) I might sound a bit cumberslume.. al these forward calls (visitor pattern) (at least I think it is).. but I needed it to keep it tight and use my generics correctly... If you want a the dirty details I really have to dig in to it again... Anyway: the above construction I needed to win extra freedom to add extra functionality like the interceptor, stop delegation, etc.. and to work with different implementations againts common interfaces (which currently isn't possible with the GWT implementation as the gwt event contains too many things: logica and data. Ofcourse this is desired looking from a rich object perspective, but you don't want to expose all the delegation to the subscribers... I mean: they can stop the delegation, but that's about it... Maybe the above will give some idea's. 3) Ok, let me give an example and hope I have some luck here... ;) I remember we had this same discussion about primitive-simple Widget interfaces, you asked me the same thing (together with Bruce), I gave some concrete interfaces.. and never heard anyting :(... My app is very simple in layout: a menu on the left and the content on the right. You can navigate to another piece of content by clicking on the next/prev button in the content screen part or by clicking in the menu. If the user navigates away from the current content screen (by clicking next/previous... or the menu), and the current shown content isn't valid, he will be asked for a confirmation. If yes, the action (=going to the new content and saving the current shown content) will be performed, if no, the action is canceled and he stays on the same content screen. I implement this through an interceptor (aynchrone in this case) that will take care of the confirmation and some other side-actions. It makes it clean and transparent. What I do roughly: I inject the interceptor in the presenter. When the select value in the model changes it will first inform the interceptor with a callback. The call back contains different methods that are called by the HandlerManager implementation to indicate success/ cancelation. In case of success (the user clicks Ok), it will inform the callback about this such that the property change can be made permanent. The handlermanager will then inform the listeners and after that call the callback to indicate that they are all informed If you need more details, let me know ? After describing the above, you might understand that it's desirable to open up the GWT Handlermanager to add these functionality directly to it, instead of making a copy and changing it.. Probably this is need in my case anyway... but still... Hope this helps... --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: lightweight events for runAsync in draft mode
On Fri, Aug 7, 2009 at 1:30 PM, Bruce Johnson br...@google.com wrote: The sorts of compiler optimizations tests I was referring to were to-be-written tests of complex optimizations where the whole point of the test is to ensure the compiler is doing exactly the transform we intend it to. IOW, the sort of stuff Scott is working on testing infrastructure for. This is a non-issue.. those tests are working at a lower level that tests our optimizers directly. Things like compiler options won't come into play. (If we needed to test them, we'd set them to specific values directly to run certain tests.) --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: lightweight events for runAsync in draft mode
On Fri, Aug 7, 2009 at 10:30 AM, Bruce Johnsonbr...@google.com wrote: I think assumeThat() might indeed be a good general solution, along the lines of your examples. It subsumes the annotations I proposed, and it's nice that it could be generalized easily to any sort of tests. Also, it *might* be possible for the compiler to optimize it statically somewhat such that if a test contained assumeThat(X) where X was statically know to be false, the whole method could go away. (Of course, we'd need that behavior to be generalized somehow -- I'm not proposing JUnit-specific compiler behavior, which would be way too hacky). I *think* that assumeThat(X) functions by throwing some sort of IgnoreThisTestException when X is false. In the case that X is statically false, the compiler might be able to determine that all the code after assumeThat(false) would not execute because an uncaught exception would be thrown. Perhaps the test method would be optimized to @Test public void testSomething() { throw new IgnoreThisTestException(); } Ian --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Inlining nocache.js
This occurred to me also when I started cutting down the requests: you cannot do the initial selection on the server as HTTP proxies will then see only one permutation: the first one that is ever retrieved by them. I've reduced the total number of HTTP requests required to load to just 2 (1 for the initial module html and 1 for the .cache.html), but as stated earlier, inlining does not work as smoothly as Bruce (and for that matter, me also) wants it to. First you have to (manually/ant task) change the strings in nocache.js to prepend the actual path to XYZ.cache.html, and then RPC will get back to you because the .cache.html scripts disagree with the serialization policy about the service entry points. So, is there a clean way? On Aug 7, 6:03 pm, John Tamplin j...@google.com wrote: On Fri, Aug 7, 2009 at 11:39 AM, Arthur Kalmenson arthur.k...@gmail.comwrote: I don't think firebug counts the initial request to fetch the host page, so two requests. One for the nocache.js and another for the cachable HTML. With the inlining of the nocache.js file, you could get it down to 0 requests if the retrieved page is cached forever. Well, since it can't be strongly named (if it was then the page with the link would have to be weakly cached for when it changed), the host page can't be cached forever but it can be cached based on the frequency you might need to update it. Note that you need to keep the old compiled script around for as long as the host page might be cached (and any server resources it might need, which makes server RPC changes difficult), since caches with the old host page will be referring to the old compiled output. Are you saying to inline the generated JS in the host page too? How could you do that? Don't you need the selector script to pick the correct compiled version? Maybe I'm just not understanding what you mean. See the example below for how it currently works and the change usign server-side selection. The problem is that the browser will fetch foo.html and get the proper compiled output for their browser/locale/etc. An intervening cache, say at an ISP, will then return that foo.html response to a different user with different parameters. As I mentioned in the other message, you have to either make the host page uncacheable (which is only feasible with small compiled scripts) or rely on caches honoring the Vary headers, which is problematic on the Internet in general though might be feasible if you control the network your users use to access it. Currently you have a host page, say Showcase.html, that is cached based on the frequency you expect to update it and contains a reference to the selection script. ... script language='javascript' src='showcase/showcase.nocache.js'/script That then fetches the selection script, which is cached based on the frequency you expect to update the app but with must-validate set and executes in the browser, and chooses a strong-named JS file for the compiled output, say XYZ.cache.html. That file is then cached for 1 year (forever according to the HTTP spec). In the new scheme, you have a host page that is generated by the server from a template. That is mark cacheable for the shorter of the time you expect to update the host page template or recompile your app, with must-revalidate set. It directly includes a script tag referencing XYZ.cache.html, where the server made the deferred binding decision based on the information available in the request. In the typical case, it will use the User-Agent header and perhaps the Accept-Language header and the locale query parameter in the URL. Since the results of the request for Showcase.html now depend on those parameters of the HTTP request, you have to make sure that a cache doesn't return a previous copy served to someone with Firefox to the next guy to ask for it who might be using Safari. One way to do that is to make sure it isn't cached at all (or at least with must-validate), and the other is to rely on the caches to correctly interpret Vary headers so they know that the response you returned may be different if those headers are different. As a side note, it doesn't know that you don't care about the difference between IE 7.0 and IE 7.0.1 (making these up so you get the point), or even the screen resolution that some user agents send in the request, so even caches that accept the Vary header will be less effective. There are other ways around it with newer standards, but even fewer of the caches out there will make use of those features so it will be a while before they are actually useful. -- John A. Tamplin Software Engineer (GWT), Google --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Initial implementation of layout system, along with the first two layout widgets.
George, This is nice, and I can't think of any reason why it couldn't use the Layout class I just checked in. In particular, this code won't work on IE6 because its left/right/top/bottom CSS implementation is hopelessly broken. Looking over this, it does remind me why I'm a little uncomfortable with the idea of decoupling Panels from LayoutManagers: - It works well for cases like the ones you've implemented here, but it could become rather more awkward for cases like SplitLayout, TabbedLayout, StackLayout, and others that require extra structure. - You have to deal with the case when a LayoutManager is changed on an already-existing panel. Depending upon the manager, this could require a lot of cleanup, which would be easy to get wrong (you'd probably have to allow the previous manager to clean up after itself to make this work in general. - You might be able to mitigate this somewhat by making the LayoutPanel's manager a construction-time invariant. Cheers, joel. On Fri, Aug 7, 2009 at 5:41 AM, ggeorg georgopoulos.georg...@gmail.comwrote: Just to keep LayoutPanel class simple with only the required methods added to AbsolutePanel widget: http://pastebin.com/m7fc7deb0 I agree, LayoutData should for that purpose. Something like: LayoutPanel.add(Widget w, LayoutData data) should replace AbsolutePanel.add(). On Aug 7, 10:42 am, Johan Rydberg johan.rydb...@edgeware.tv wrote: I did a very-very simplified layout system based on top,bottom,left,right,width and height CSS attributes: http://69.20.122.77:8880/gwt-layout/ So far SimpleLayout, HBoxLayout VBoxLayout are implemented. Source files: http://69.20.122.77:8880/gwt-layout/org.gwt20.mosaic.demo.tbz2 The EntryPoint class for the demo is:http://pastebin.com/m27e7a4e7 Nice work as always George, But why use a widget wrapper to define alignments for a child of the container? I must say I like the idea of passing layout-data to the add() method better. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Inlining nocache.js
Nevermind, solved my RPC-woes by copying the policy file to the web- app root. Ugly, but down to 2 requests. On Aug 7, 8:50 pm, George Georgovassilis g.georgovassi...@gmail.com wrote: This occurred to me also when I started cutting down the requests: you cannot do the initial selection on the server as HTTP proxies will then see only one permutation: the first one that is ever retrieved by them. I've reduced the total number of HTTP requests required to load to just 2 (1 for the initial module html and 1 for the .cache.html), but as stated earlier, inlining does not work as smoothly as Bruce (and for that matter, me also) wants it to. First you have to (manually/ant task) change the strings in nocache.js to prepend the actual path to XYZ.cache.html, and then RPC will get back to you because the .cache.html scripts disagree with the serialization policy about the service entry points. So, is there a clean way? On Aug 7, 6:03 pm, John Tamplin j...@google.com wrote: On Fri, Aug 7, 2009 at 11:39 AM, Arthur Kalmenson arthur.k...@gmail.comwrote: I don't think firebug counts the initial request to fetch the host page, so two requests. One for the nocache.js and another for the cachable HTML. With the inlining of the nocache.js file, you could get it down to 0 requests if the retrieved page is cached forever. Well, since it can't be strongly named (if it was then the page with the link would have to be weakly cached for when it changed), the host page can't be cached forever but it can be cached based on the frequency you might need to update it. Note that you need to keep the old compiled script around for as long as the host page might be cached (and any server resources it might need, which makes server RPC changes difficult), since caches with the old host page will be referring to the old compiled output. Are you saying to inline the generated JS in the host page too? How could you do that? Don't you need the selector script to pick the correct compiled version? Maybe I'm just not understanding what you mean. See the example below for how it currently works and the change usign server-side selection. The problem is that the browser will fetch foo.html and get the proper compiled output for their browser/locale/etc. An intervening cache, say at an ISP, will then return that foo.html response to a different user with different parameters. As I mentioned in the other message, you have to either make the host page uncacheable (which is only feasible with small compiled scripts) or rely on caches honoring the Vary headers, which is problematic on the Internet in general though might be feasible if you control the network your users use to access it. Currently you have a host page, say Showcase.html, that is cached based on the frequency you expect to update it and contains a reference to the selection script. ... script language='javascript' src='showcase/showcase.nocache.js'/script That then fetches the selection script, which is cached based on the frequency you expect to update the app but with must-validate set and executes in the browser, and chooses a strong-named JS file for the compiled output, say XYZ.cache.html. That file is then cached for 1 year (forever according to the HTTP spec). In the new scheme, you have a host page that is generated by the server from a template. That is mark cacheable for the shorter of the time you expect to update the host page template or recompile your app, with must-revalidate set. It directly includes a script tag referencing XYZ.cache.html, where the server made the deferred binding decision based on the information available in the request. In the typical case, it will use the User-Agent header and perhaps the Accept-Language header and the locale query parameter in the URL. Since the results of the request for Showcase.html now depend on those parameters of the HTTP request, you have to make sure that a cache doesn't return a previous copy served to someone with Firefox to the next guy to ask for it who might be using Safari. One way to do that is to make sure it isn't cached at all (or at least with must-validate), and the other is to rely on the caches to correctly interpret Vary headers so they know that the response you returned may be different if those headers are different. As a side note, it doesn't know that you don't care about the difference between IE 7.0 and IE 7.0.1 (making these up so you get the point), or even the screen resolution that some user agents send in the request, so even caches that accept the Vary header will be less effective. There are other ways around it with newer standards, but even fewer of the caches out there will make use of those features so it will be a while before they are actually useful. -- John A. Tamplin Software Engineer (GWT), Google
[gwt-contrib] [google-web-toolkit] r5915 committed - Reverting c5897, which itself was reverting c5889. In short, re-introd...
Revision: 5915 Author: amitman...@google.com Date: Fri Aug 7 12:30:40 2009 Log: Reverting c5897, which itself was reverting c5889. In short, re-introducing c5889. http://code.google.com/p/google-web-toolkit/source/detail?r=5915 Deleted: /tools/lib/xerces/serializer-2.7.1.jar /tools/lib/xerces/xercesImpl-2.8.1.jar /tools/lib/xerces/xml-apis-1.3.04.jar === --- /tools/lib/xerces/serializer-2.7.1.jar Wed Aug 5 20:57:41 2009 +++ /dev/null Binary file, no diff available. === --- /tools/lib/xerces/xercesImpl-2.8.1.jar Wed Aug 5 20:57:41 2009 +++ /dev/null File is too large to display a diff. === --- /tools/lib/xerces/xml-apis-1.3.04.jar Wed Aug 5 20:57:41 2009 +++ /dev/null Binary file, no diff available. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Inlining nocache.js
On Fri, Aug 7, 2009 at 2:50 PM, George Georgovassilis g.georgovassi...@gmail.com wrote: This occurred to me also when I started cutting down the requests: you cannot do the initial selection on the server as HTTP proxies will then see only one permutation: the first one that is ever retrieved by them. I've reduced the total number of HTTP requests required to load to just 2 (1 for the initial module html and 1 for the .cache.html), but as stated earlier, inlining does not work as smoothly as Bruce (and for that matter, me also) wants it to. First you have to (manually/ant task) change the strings in nocache.js to prepend the actual path to XYZ.cache.html, and then RPC will get back to you because the .cache.html scripts disagree with the serialization policy about the service entry points. So, is there a clean way? With server-side selection, it just works. All you have to do is create the host page template so it can fill in the compile output name, write server equivalents for any custom property providers you have, configure your servlet container properly so the server components can intercept the request for the host page (if you aren't using Java on the server you will have to recreate that functionality) and inherit the right .gwt.xml file to pull in the server-side selection linker. -- John A. Tamplin Software Engineer (GWT), Google --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: changes to OOPHM plugins to support protocol changes
Reviewed the common, ie, and webkit code. LGTM http://gwt-code-reviews.appspot.com/51834/diff/1/11 File plugins/common/ChooseTransportMessage.cpp (right): http://gwt-code-reviews.appspot.com/51834/diff/1/11#newcode31 Line 31: * Receive an FatalError message from the channel (note that the message Copy-and-paste? http://gwt-code-reviews.appspot.com/51834/diff/1/13 File plugins/common/FatalErrorMessage.h (right): http://gwt-code-reviews.appspot.com/51834/diff/1/13#newcode27 Line 27: * Class representing an InvokeMessage received from the server, and a way Copy-and-paste? http://gwt-code-reviews.appspot.com/51834/diff/1/26 File plugins/common/ProtocolVersionMessage.h (right): http://gwt-code-reviews.appspot.com/51834/diff/1/26#newcode27 Line 27: * Class representing an InvokeMessage received from the server, and a way Copy-and-paste http://gwt-code-reviews.appspot.com/51834/diff/1/17 File plugins/common/SwitchTransportMessage.cpp (right): http://gwt-code-reviews.appspot.com/51834/diff/1/17#newcode29 Line 29: * Receive a SwitchTransport message from the server. What is this message type used for? http://gwt-code-reviews.appspot.com/51834/diff/1/27 File plugins/common/SwitchTransportMessage.h (right): http://gwt-code-reviews.appspot.com/51834/diff/1/27#newcode27 Line 27: * Class representing an InvokeMessage received from the server, and a way Copy-and-paste. http://gwt-code-reviews.appspot.com/51834/diff/1/2 File plugins/webkit/Core/WebScriptSessionHandler.cpp (right): http://gwt-code-reviews.appspot.com/51834/diff/1/2#newcode97 Line 97: Debug::log(Debug::Error) Fatal error: message Debug::flush; There's a CrashHandler mechanism already built into the plugin, you can call that to initiate an orderly shutdown. http://gwt-code-reviews.appspot.com/51834/diff/1/5 File plugins/webkit/Plugin/OophmWebScriptObject.mm (right): http://gwt-code-reviews.appspot.com/51834/diff/1/5#newcode98 Line 98: - (BOOL)initForWebScriptWithJsniContext: (WebScriptObject*) jsniContext { Just to confirm that this is intended to be a no-op? http://gwt-code-reviews.appspot.com/51834 --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Reserve globalTemp, 3-6% reduction in code size
Reviewers: Lex, scottb, Description: The globalTemp used for prototype setup ends up being assigned a large identifier in some obfuscated programs. In Showcase, it is atleast 3 characters. Reserving the _ for this variable leads to a 3% compressed savings, and 6% uncompressed savings. Please review this at http://gwt-code-reviews.appspot.com/57805 Affected files: dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java Index: dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java === --- dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java (revision 5895) +++ dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java (working copy) @@ -500,8 +500,8 @@ private final JsName prototype = objectScope.declareName(prototype); { + prototype.setObfuscatable(false); globalTemp.setObfuscatable(false); - prototype.setObfuscatable(false); } public GenerateJavaScriptVisitor() { --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Questions and concerns with HandlerManager
On Fri, Aug 7, 2009 at 1:34 PM, Ed post2edb...@hotmail.com wrote: It costs me a bit to go back in time as these issues are already from some time back.. Let me try to give some input on these points. 2) I don't fully understand what the problem is here. Could you give an example that shows that it breaks? It's actually worse than I thought. If I add a type parameter to HandlerManager, I get something like class HandlerManagerSource { ... } But I have no way to specify the source type when it's declared in Widget: class Widget { HandlerManager??? handlerManager; } The Source type parameter would force me to declare a separate HandlerManager field in each subclass of Widget. But then I can't subclass a widget and get the source type correct -- I'd need *another* handlerManager field. 3) Ok, let me give an example and hope I have some luck here... ;) I remember we had this same discussion about primitive-simple Widget interfaces, you asked me the same thing (together with Bruce), I gave some concrete interfaces.. and never heard anyting :(... My app is very simple in layout: a menu on the left and the content on the right. You can navigate to another piece of content by clicking on the next/prev button in the content screen part or by clicking in the menu. If the user navigates away from the current content screen (by clicking next/previous... or the menu), and the current shown content isn't valid, he will be asked for a confirmation. If yes, the action (=going to the new content and saving the current shown content) will be performed, if no, the action is canceled and he stays on the same content screen. I implement this through an interceptor (aynchrone in this case) that will take care of the confirmation and some other side-actions. It makes it clean and transparent. What I do roughly: I inject the interceptor in the presenter. When the select value in the model changes it will first inform the interceptor with a callback. The call back contains different methods that are called by the HandlerManager implementation to indicate success/ cancelation. In case of success (the user clicks Ok), it will inform the callback about this such that the property change can be made permanent. The handlermanager will then inform the listeners and after that call the callback to indicate that they are all informed If you need more details, let me know ? To be honest, I'm having a really hard time understanding the structure you're describing. Maybe a bit of (heavily elided) code would help clarify it? After describing the above, you might understand that it's desirable to open up the GWT Handlermanager to add these functionality directly to it, instead of making a copy and changing it.. Probably this is need in my case anyway... but still... If you could describe *precisely* what you think should be opened up in HandlerManager, it would help me to make a reasonable judgment. As it stands, it all seems very vague to me. Thanks, joel. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Initial implementation of layout system, along with the first two layout widgets.
Joel, this is a very simplified layout system based on: top,bottom,left,right and size CCS attributes. It mimics somehow the existing layout system in gwt-mosaic except of the LayoutData class (layout constraints) which is missing from this implementation. And as you already know it works only on standard mode and not with IE6. --- Your Layout class is like a wrapper for the widgets and a LayoutData object put together. I am going to use it in the next implementation, just getting familiar with your code (but I have some problems with that class since the wrapper requires border=0px for the child widgets, I did not check for margins so far). About TabbedLayout, SplitLayout and StackLayout this design works very good, see gwt-mosaic demos: http://69.20.122.77/gwt-mosaic/Showcase.html#CwTabLayoutPanel http://69.20.122.77/gwt-mosaic/Showcase.html#CwStackLayoutPanel and for split panel: http://69.20.122.77/gwt-mosaic/Showcase.html#CwBorderLayout In most of the cases they do not require extra code since they rely on the SimpleLayout implementation that renders only the first visible widget. This makes SimpleLayout (or FillLayout in gwt-mosaic) very useful for widgets like DeckLayoutPanel. About switching LayoutManagers the only objects that have to be changed are the LayoutData on each widget (LayoutData = Layers without the wrapper) and a call to layout() to render with the new LayoutManager. The LayoutManagers should not keep a list of widgets, they should get the widget list from the LayoutPanel. About the last point, I don't understand you very good :-) I keep trying, is there a demo for the classes you have? Kind Regards, George. On Aug 7, 10:05 pm, Joel Webber j...@google.com wrote: George, This is nice, and I can't think of any reason why it couldn't use the Layout class I just checked in. In particular, this code won't work on IE6 because its left/right/top/bottom CSS implementation is hopelessly broken. Looking over this, it does remind me why I'm a little uncomfortable with the idea of decoupling Panels from LayoutManagers: - It works well for cases like the ones you've implemented here, but it could become rather more awkward for cases like SplitLayout, TabbedLayout, StackLayout, and others that require extra structure. - You have to deal with the case when a LayoutManager is changed on an already-existing panel. Depending upon the manager, this could require a lot of cleanup, which would be easy to get wrong (you'd probably have to allow the previous manager to clean up after itself to make this work in general. - You might be able to mitigate this somewhat by making the LayoutPanel's manager a construction-time invariant. Cheers, joel. On Fri, Aug 7, 2009 at 5:41 AM, ggeorg georgopoulos.georg...@gmail.comwrote: Just to keep LayoutPanel class simple with only the required methods added to AbsolutePanel widget: http://pastebin.com/m7fc7deb0 I agree, LayoutData should for that purpose. Something like: LayoutPanel.add(Widget w, LayoutData data) should replace AbsolutePanel.add(). On Aug 7, 10:42 am, Johan Rydberg johan.rydb...@edgeware.tv wrote: I did a very-very simplified layout system based on top,bottom,left,right,width and height CSS attributes: http://69.20.122.77:8880/gwt-layout/ So far SimpleLayout, HBoxLayout VBoxLayout are implemented. Source files: http://69.20.122.77:8880/gwt-layout/org.gwt20.mosaic.demo.tbz2 The EntryPoint class for the demo is:http://pastebin.com/m27e7a4e7 Nice work as always George, But why use a widget wrapper to define alignments for a child of the container? I must say I like the idea of passing layout-data to the add() method better. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Set cache headers properly in embedded Jetty for hosted mode
Reviewers: scottb, Description: This patch sets the cache-related headers properly, similarly to how the embedded Tomcat did. This is derived from code in my production Jetty server (the default case is different of course) at home that has been running for a couple of years. Please review this at http://gwt-code-reviews.appspot.com/56807 Affected files: dev/core/src/com/google/gwt/dev/shell/jetty/JettyLauncher.java Index: dev/core/src/com/google/gwt/dev/shell/jetty/JettyLauncher.java === --- dev/core/src/com/google/gwt/dev/shell/jetty/JettyLauncher.java (revision 5915) +++ dev/core/src/com/google/gwt/dev/shell/jetty/JettyLauncher.java (working copy) @@ -19,6 +19,7 @@ import com.google.gwt.core.ext.ServletContainerLauncher; import com.google.gwt.core.ext.TreeLogger; import com.google.gwt.core.ext.UnableToCompleteException; +import com.google.gwt.dev.util.HttpHeaders; import com.google.gwt.dev.util.InstalledHelpInfo; import org.mortbay.component.AbstractLifeCycle; @@ -40,6 +41,10 @@ import java.net.URL; import java.util.Iterator; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + /** * A {...@link ServletContainerLauncher} for an embedded Jetty server. */ @@ -425,6 +430,53 @@ } @Override +public void handle(String target, HttpServletRequest request, +HttpServletResponse response, int dispatch) throws IOException, +ServletException { + super.handle(target, request, response, dispatch); + + // If the cache-control header has already been set, assume it + // has been set properly by the servlet/etc. + if (response.containsHeader(HttpHeaders.CACHE_CONTROL)) { +return; + } + + // Set headers for caching -- unfortunately we can't get the status + // code from the response, but setting the extra headers on 304s/etc + // doesn't appear to cause any problems. + long now = System.currentTimeMillis(); + response.setDateHeader(HttpHeaders.DATE, now); + if (!request.getMethod().equals(GET)) { +// to be safe, mark all non-GETs as non-cacheable +response.setHeader(HttpHeaders.CACHE_CONTROL, +HttpHeaders.CACHE_CONTROL_NO_CACHE); +// for older caches +response.setHeader(Pragma, no-cache); +response.setDateHeader(HttpHeaders.EXPIRES, now); + } else if (target.contains(.nocache.)) { +// nocache is used for the selection script, and should be only +// privately cached, since it may vary on user-specific data, and must be +// revalidated for each use +response.setHeader(HttpHeaders.CACHE_CONTROL, +HttpHeaders.CACHE_CONTROL_PRIVATE + , ++ HttpHeaders.CACHE_CONTROL_MAXAGE + 0, ++ HttpHeaders.CACHE_CONTROL_MUST_REVALIDATE); +// Set expires to the same as Date to disable old proxy caches +response.setDateHeader(HttpHeaders.EXPIRES, now); + } else if (target.contains(.cache.)) { +// cache files should be cached for anyone forever (ie, 1 year) +response.setHeader(Cache-Control, public, max-age=31536000); +response.setDateHeader(HttpHeaders.EXPIRES, now + 3153600L); + } else { +// everything else gets public caching for 60 seconds +response.setHeader(HttpHeaders.CACHE_CONTROL, +HttpHeaders.CACHE_CONTROL_PUBLIC + , ++ HttpHeaders.CACHE_CONTROL_MAXAGE + 60); +response.setDateHeader(HttpHeaders.EXPIRES, now + 6000); + } +} + +@Override protected void doStart() throws Exception { setClassLoader(new WebAppClassLoaderExtension()); super.doStart(); --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Questions and concerns with HandlerManager
class HandlerManagerSource { ... } Interesting how you put Generics in the HandlerManager Of course this is a no go area as you explained. Try my HandlerManager scenario like I described above; only the event contains the actual source generics, and of course not he HandlerManager... Let me know if you want some code of this ? So I can grep something together... I might need a bit of time for that... and let me know where to send it to? To be honest, I'm having a really hard time understanding the structure you're describing. Maybe a bit of (heavily elided) code would help clarify it? H... I could give some code, but I think in words the need for the interceptor is clear: The user selects something and the interceptor will indicate if the selection is allowed to be committed (like a 2-phase db transaction) or not.. Can you give me more details about what you not understand here please? I am afraid that the code only make it less understandable as it's complex.. due to the asynchrone behavior. If you could describe *precisely* what you think should be opened up in HandlerManager, it would help me to make a reasonable judgment. As it stands, it all seems very vague to me. H... can't remember the *precise* details anymore... it was already some time ago... :( One thing I remember was that I wanted to change the source in the HandlerManager, which wasn't possible as it can only be set through the constructor.. On Aug 7, 10:07 pm, Joel Webber j...@google.com wrote: On Fri, Aug 7, 2009 at 1:34 PM, Ed post2edb...@hotmail.com wrote: It costs me a bit to go back in time as these issues are already from some time back.. Let me try to give some input on these points. 2) I don't fully understand what the problem is here. Could you give an example that shows that it breaks? It's actually worse than I thought. If I add a type parameter to HandlerManager, I get something like class HandlerManagerSource { ... } But I have no way to specify the source type when it's declared in Widget: class Widget { HandlerManager??? handlerManager; } The Source type parameter would force me to declare a separate HandlerManager field in each subclass of Widget. But then I can't subclass a widget and get the source type correct -- I'd need *another* handlerManager field. 3) Ok, let me give an example and hope I have some luck here... ;) I remember we had this same discussion about primitive-simple Widget interfaces, you asked me the same thing (together with Bruce), I gave some concrete interfaces.. and never heard anyting :(... My app is very simple in layout: a menu on the left and the content on the right. You can navigate to another piece of content by clicking on the next/prev button in the content screen part or by clicking in the menu. If the user navigates away from the current content screen (by clicking next/previous... or the menu), and the current shown content isn't valid, he will be asked for a confirmation. If yes, the action (=going to the new content and saving the current shown content) will be performed, if no, the action is canceled and he stays on the same content screen. I implement this through an interceptor (aynchrone in this case) that will take care of the confirmation and some other side-actions. It makes it clean and transparent. What I do roughly: I inject the interceptor in the presenter. When the select value in the model changes it will first inform the interceptor with a callback. The call back contains different methods that are called by the HandlerManager implementation to indicate success/ cancelation. In case of success (the user clicks Ok), it will inform the callback about this such that the property change can be made permanent. The handlermanager will then inform the listeners and after that call the callback to indicate that they are all informed If you need more details, let me know ? To be honest, I'm having a really hard time understanding the structure you're describing. Maybe a bit of (heavily elided) code would help clarify it? After describing the above, you might understand that it's desirable to open up the GWT Handlermanager to add these functionality directly to it, instead of making a copy and changing it.. Probably this is need in my case anyway... but still... If you could describe *precisely* what you think should be opened up in HandlerManager, it would help me to make a reasonable judgment. As it stands, it all seems very vague to me. Thanks, joel. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Set cache headers properly in embedded Jetty for hosted mode
LGTM, but we should probably get a thumbs-up from at least one other interested person. http://gwt-code-reviews.appspot.com/56807 --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: changes to OOPHM plugins to support protocol changes
Thanks for the review. Are there instructions somewhere for building the IE and WebKit plugins? I have MSVC setup in VMWare, but I don't have Xcode setup on my MBP. http://gwt-code-reviews.appspot.com/51834/diff/1/11 File plugins/common/ChooseTransportMessage.cpp (right): http://gwt-code-reviews.appspot.com/51834/diff/1/11#newcode31 Line 31: * Receive an FatalError message from the channel (note that the message On 2009/08/07 19:46:49, bobv wrote: Copy-and-paste? Will fix. http://gwt-code-reviews.appspot.com/51834/diff/1/13 File plugins/common/FatalErrorMessage.h (right): http://gwt-code-reviews.appspot.com/51834/diff/1/13#newcode27 Line 27: * Class representing an InvokeMessage received from the server, and a way On 2009/08/07 19:46:49, bobv wrote: Copy-and-paste? Will Fix. http://gwt-code-reviews.appspot.com/51834/diff/1/26 File plugins/common/ProtocolVersionMessage.h (right): http://gwt-code-reviews.appspot.com/51834/diff/1/26#newcode27 Line 27: * Class representing an InvokeMessage received from the server, and a way On 2009/08/07 19:46:49, bobv wrote: Copy-and-paste Will fix. http://gwt-code-reviews.appspot.com/51834/diff/1/17 File plugins/common/SwitchTransportMessage.cpp (right): http://gwt-code-reviews.appspot.com/51834/diff/1/17#newcode29 Line 29: * Receive a SwitchTransport message from the server. On 2009/08/07 19:46:49, bobv wrote: What is this message type used for? The intent is to allow a plugin to advertise a list of alternate transports it supports, and allow the server to choose an acceptable one considering what it supports and the address of the connection. An obvious example would be shared memory, using the work that Sam did last year. http://gwt-code-reviews.appspot.com/51834/diff/1/27 File plugins/common/SwitchTransportMessage.h (right): http://gwt-code-reviews.appspot.com/51834/diff/1/27#newcode27 Line 27: * Class representing an InvokeMessage received from the server, and a way On 2009/08/07 19:46:49, bobv wrote: Copy-and-paste. Will fix. http://gwt-code-reviews.appspot.com/51834/diff/1/2 File plugins/webkit/Core/WebScriptSessionHandler.cpp (right): http://gwt-code-reviews.appspot.com/51834/diff/1/2#newcode97 Line 97: Debug::log(Debug::Error) Fatal error: message Debug::flush; On 2009/08/07 19:46:49, bobv wrote: There's a CrashHandler mechanism already built into the plugin, you can call that to initiate an orderly shutdown. Ok thanks, I will use that. http://gwt-code-reviews.appspot.com/51834/diff/1/5 File plugins/webkit/Plugin/OophmWebScriptObject.mm (right): http://gwt-code-reviews.appspot.com/51834/diff/1/5#newcode98 Line 98: - (BOOL)initForWebScriptWithJsniContext: (WebScriptObject*) jsniContext { On 2009/08/07 19:46:49, bobv wrote: Just to confirm that this is intended to be a no-op? Well, it should return true if the plugin is properly initialized and reachable from the hot page. A plugin that needed the hosted.html window object would stash or use it, and if there were any other i'm ok checks they would be performed here. Mostly, this is so that a failure to call plugin.init can be detected as an error getting the plugin running, separate from plugin.connect failing meaning it couldn't get the connection to the server running. http://gwt-code-reviews.appspot.com/51834 --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Questions and concerns with HandlerManager
Are there lots of folks on the list that have the same sorts of feedback on HandlerManager? I ask because, as a fly on the wall here, this conversation doesn't sound like it's converging, and I'd like to declare this thread dead for now so that we can move onto other things. We have a lot of other things to be giving attention to so that we can get GWT 2.0 out. If we need to revisit these issues in the future, we certainly can. -- Bruce On Fri, Aug 7, 2009 at 4:43 PM, Ed post2edb...@hotmail.com wrote: class HandlerManagerSource { ... } Interesting how you put Generics in the HandlerManager Of course this is a no go area as you explained. Try my HandlerManager scenario like I described above; only the event contains the actual source generics, and of course not he HandlerManager... Let me know if you want some code of this ? So I can grep something together... I might need a bit of time for that... and let me know where to send it to? To be honest, I'm having a really hard time understanding the structure you're describing. Maybe a bit of (heavily elided) code would help clarify it? H... I could give some code, but I think in words the need for the interceptor is clear: The user selects something and the interceptor will indicate if the selection is allowed to be committed (like a 2-phase db transaction) or not.. Can you give me more details about what you not understand here please? I am afraid that the code only make it less understandable as it's complex.. due to the asynchrone behavior. If you could describe *precisely* what you think should be opened up in HandlerManager, it would help me to make a reasonable judgment. As it stands, it all seems very vague to me. H... can't remember the *precise* details anymore... it was already some time ago... :( One thing I remember was that I wanted to change the source in the HandlerManager, which wasn't possible as it can only be set through the constructor.. On Aug 7, 10:07 pm, Joel Webber j...@google.com wrote: On Fri, Aug 7, 2009 at 1:34 PM, Ed post2edb...@hotmail.com wrote: It costs me a bit to go back in time as these issues are already from some time back.. Let me try to give some input on these points. 2) I don't fully understand what the problem is here. Could you give an example that shows that it breaks? It's actually worse than I thought. If I add a type parameter to HandlerManager, I get something like class HandlerManagerSource { ... } But I have no way to specify the source type when it's declared in Widget: class Widget { HandlerManager??? handlerManager; } The Source type parameter would force me to declare a separate HandlerManager field in each subclass of Widget. But then I can't subclass a widget and get the source type correct -- I'd need *another* handlerManager field. 3) Ok, let me give an example and hope I have some luck here... ;) I remember we had this same discussion about primitive-simple Widget interfaces, you asked me the same thing (together with Bruce), I gave some concrete interfaces.. and never heard anyting :(... My app is very simple in layout: a menu on the left and the content on the right. You can navigate to another piece of content by clicking on the next/prev button in the content screen part or by clicking in the menu. If the user navigates away from the current content screen (by clicking next/previous... or the menu), and the current shown content isn't valid, he will be asked for a confirmation. If yes, the action (=going to the new content and saving the current shown content) will be performed, if no, the action is canceled and he stays on the same content screen. I implement this through an interceptor (aynchrone in this case) that will take care of the confirmation and some other side-actions. It makes it clean and transparent. What I do roughly: I inject the interceptor in the presenter. When the select value in the model changes it will first inform the interceptor with a callback. The call back contains different methods that are called by the HandlerManager implementation to indicate success/ cancelation. In case of success (the user clicks Ok), it will inform the callback about this such that the property change can be made permanent. The handlermanager will then inform the listeners and after that call the callback to indicate that they are all informed If you need more details, let me know ? To be honest, I'm having a really hard time understanding the structure you're describing. Maybe a bit of (heavily elided) code would help clarify it? After describing the above, you might understand that it's desirable to open up the GWT Handlermanager to add these functionality directly to it, instead of making a copy and changing it.. Probably this is need in
[gwt-contrib] Re: Set cache headers properly in embedded Jetty for hosted mode
On Fri, Aug 7, 2009 at 4:46 PM, sco...@google.com wrote: LGTM, but we should probably get a thumbs-up from at least one other interested person. http://gwt-code-reviews.appspot.com/56807 Suggestion of that person? -- John A. Tamplin Software Engineer (GWT), Google --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Questions and concerns with HandlerManager
Then I would declare it dead Bruce! With all do respect: I do very complex things with GWT and do walk on his boundaries... And to my experience - I am a bit lonely out here... (yes I know it sounds a bit arrogant...) And yes, I agree that you guys have better things to do to make GWT first more mature before they support these complex things... Buttt... it would be nice if these things aren't forgotten and put on the nice-to-have list... and not on the forget-list. I think that adding (more) primitive (characteristic) widget/panel interfaces, like we discussed before has an higher priority, so I hope you guys add this to gwt 2.0. I am still suprised about the few people complain about this. But I have pointed out concrete clear cases that show the need for this...(like you asked before) Just my thoughts... BTW: Joe if you want some code about my HandlerManager to be able to define the source through generics, let me know... On Aug 7, 10:55 pm, Bruce Johnson br...@google.com wrote: Are there lots of folks on the list that have the same sorts of feedback on HandlerManager? I ask because, as a fly on the wall here, this conversation doesn't sound like it's converging, and I'd like to declare this thread dead for now so that we can move onto other things. We have a lot of other things to be giving attention to so that we can get GWT 2.0 out. If we need to revisit these issues in the future, we certainly can. -- Bruce On Fri, Aug 7, 2009 at 4:43 PM, Ed post2edb...@hotmail.com wrote: class HandlerManagerSource { ... } Interesting how you put Generics in the HandlerManager Of course this is a no go area as you explained. Try my HandlerManager scenario like I described above; only the event contains the actual source generics, and of course not he HandlerManager... Let me know if you want some code of this ? So I can grep something together... I might need a bit of time for that... and let me know where to send it to? To be honest, I'm having a really hard time understanding the structure you're describing. Maybe a bit of (heavily elided) code would help clarify it? H... I could give some code, but I think in words the need for the interceptor is clear: The user selects something and the interceptor will indicate if the selection is allowed to be committed (like a 2-phase db transaction) or not.. Can you give me more details about what you not understand here please? I am afraid that the code only make it less understandable as it's complex.. due to the asynchrone behavior. If you could describe *precisely* what you think should be opened up in HandlerManager, it would help me to make a reasonable judgment. As it stands, it all seems very vague to me. H... can't remember the *precise* details anymore... it was already some time ago... :( One thing I remember was that I wanted to change the source in the HandlerManager, which wasn't possible as it can only be set through the constructor.. On Aug 7, 10:07 pm, Joel Webber j...@google.com wrote: On Fri, Aug 7, 2009 at 1:34 PM, Ed post2edb...@hotmail.com wrote: It costs me a bit to go back in time as these issues are already from some time back.. Let me try to give some input on these points. 2) I don't fully understand what the problem is here. Could you give an example that shows that it breaks? It's actually worse than I thought. If I add a type parameter to HandlerManager, I get something like class HandlerManagerSource { ... } But I have no way to specify the source type when it's declared in Widget: class Widget { HandlerManager??? handlerManager; } The Source type parameter would force me to declare a separate HandlerManager field in each subclass of Widget. But then I can't subclass a widget and get the source type correct -- I'd need *another* handlerManager field. 3) Ok, let me give an example and hope I have some luck here... ;) I remember we had this same discussion about primitive-simple Widget interfaces, you asked me the same thing (together with Bruce), I gave some concrete interfaces.. and never heard anyting :(... My app is very simple in layout: a menu on the left and the content on the right. You can navigate to another piece of content by clicking on the next/prev button in the content screen part or by clicking in the menu. If the user navigates away from the current content screen (by clicking next/previous... or the menu), and the current shown content isn't valid, he will be asked for a confirmation. If yes, the action (=going to the new content and saving the current shown content) will be performed, if no, the action is canceled and he stays on the same content screen. I implement this through an interceptor (aynchrone in this case) that will take care of the confirmation and some other
[gwt-contrib] Re: Questions and concerns with HandlerManager
Dead! (for now) On Fri, Aug 7, 2009 at 5:10 PM, Ed post2edb...@hotmail.com wrote: Then I would declare it dead Bruce! With all do respect: I do very complex things with GWT and do walk on his boundaries... And to my experience - I am a bit lonely out here... (yes I know it sounds a bit arrogant...) And yes, I agree that you guys have better things to do to make GWT first more mature before they support these complex things... Buttt... it would be nice if these things aren't forgotten and put on the nice-to-have list... and not on the forget-list. I think that adding (more) primitive (characteristic) widget/panel interfaces, like we discussed before has an higher priority, so I hope you guys add this to gwt 2.0. I am still suprised about the few people complain about this. But I have pointed out concrete clear cases that show the need for this...(like you asked before) Just my thoughts... BTW: Joe if you want some code about my HandlerManager to be able to define the source through generics, let me know... On Aug 7, 10:55 pm, Bruce Johnson br...@google.com wrote: Are there lots of folks on the list that have the same sorts of feedback on HandlerManager? I ask because, as a fly on the wall here, this conversation doesn't sound like it's converging, and I'd like to declare this thread dead for now so that we can move onto other things. We have a lot of other things to be giving attention to so that we can get GWT 2.0 out. If we need to revisit these issues in the future, we certainly can. -- Bruce On Fri, Aug 7, 2009 at 4:43 PM, Ed post2edb...@hotmail.com wrote: class HandlerManagerSource { ... } Interesting how you put Generics in the HandlerManager Of course this is a no go area as you explained. Try my HandlerManager scenario like I described above; only the event contains the actual source generics, and of course not he HandlerManager... Let me know if you want some code of this ? So I can grep something together... I might need a bit of time for that... and let me know where to send it to? To be honest, I'm having a really hard time understanding the structure you're describing. Maybe a bit of (heavily elided) code would help clarify it? H... I could give some code, but I think in words the need for the interceptor is clear: The user selects something and the interceptor will indicate if the selection is allowed to be committed (like a 2-phase db transaction) or not.. Can you give me more details about what you not understand here please? I am afraid that the code only make it less understandable as it's complex.. due to the asynchrone behavior. If you could describe *precisely* what you think should be opened up in HandlerManager, it would help me to make a reasonable judgment. As it stands, it all seems very vague to me. H... can't remember the *precise* details anymore... it was already some time ago... :( One thing I remember was that I wanted to change the source in the HandlerManager, which wasn't possible as it can only be set through the constructor.. On Aug 7, 10:07 pm, Joel Webber j...@google.com wrote: On Fri, Aug 7, 2009 at 1:34 PM, Ed post2edb...@hotmail.com wrote: It costs me a bit to go back in time as these issues are already from some time back.. Let me try to give some input on these points. 2) I don't fully understand what the problem is here. Could you give an example that shows that it breaks? It's actually worse than I thought. If I add a type parameter to HandlerManager, I get something like class HandlerManagerSource { ... } But I have no way to specify the source type when it's declared in Widget: class Widget { HandlerManager??? handlerManager; } The Source type parameter would force me to declare a separate HandlerManager field in each subclass of Widget. But then I can't subclass a widget and get the source type correct -- I'd need *another* handlerManager field. 3) Ok, let me give an example and hope I have some luck here... ;) I remember we had this same discussion about primitive-simple Widget interfaces, you asked me the same thing (together with Bruce), I gave some concrete interfaces.. and never heard anyting :(... My app is very simple in layout: a menu on the left and the content on the right. You can navigate to another piece of content by clicking on the next/prev button in the content screen part or by clicking in the menu. If the user navigates away from the current content screen (by clicking next/previous... or the menu), and the current shown content isn't valid, he will be asked for a confirmation. If yes, the action (=going to the new content and saving the current shown content) will be
[gwt-contrib] [google-web-toolkit] r5918 committed - Creating special snapshot branch for introduction of instant hosted mo...
Revision: 5918 Author: rj...@google.com Date: Fri Aug 7 14:28:38 2009 Log: Creating special snapshot branch for introduction of instant hosted mode. Note that this is a branch off of snapshot-2009.08.04-r5888, not trunk svn copy \ https://google-web-toolkit.googlecode.com/svn/branches/snapshot-2009.08.04-r5888 \ https://google-web-toolkit.googlecode.com/svn/branches/snapshot-2009.08.04-ihm-r5888 http://code.google.com/p/google-web-toolkit/source/detail?r=5918 Added: /branches/snapshot-2009.08.04-ihm-r5888 --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] [google-web-toolkit] r5920 committed - Adjust branchinfo.txt for this new branch
Revision: 5920 Author: rj...@google.com Date: Fri Aug 7 14:47:13 2009 Log: Adjust branchinfo.txt for this new branch http://code.google.com/p/google-web-toolkit/source/detail?r=5920 Modified: /branches/snapshot-2009.08.04-ihm-r5888/branch-info.txt === --- /branches/snapshot-2009.08.04-ihm-r5888/branch-info.txt Thu Aug 6 15:39:10 2009 +++ /branches/snapshot-2009.08.04-ihm-r5888/branch-info.txt Fri Aug 7 14:47:13 2009 @@ -3,9 +3,7 @@ See: http://code.google.com/p/google-web-toolkit/wiki/ManagingMerges Copies: -/branches/snapshot-2009.08.04-r5888 was created (r5899) as a straight copy from /trunk/@5888 +/branches/snapshot-2009.08.04-ihm-r5888 was created (r5918) as a straight copy from +/branches/snapshot-2009.08.04-r5888 Merges: -/trunk c5896 was merged into this branch - UiBinder - svn merge -c5896 https://google-web-toolkit.googlecode.com/svn/trunk . --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] [google-web-toolkit] r5921 committed - Merging in OOPHM wire protocol change (http://gwt-code-reviews.appspot...
Revision: 5921 Author: rj...@google.com Date: Fri Aug 7 15:17:40 2009 Log: Merging in OOPHM wire protocol change (http://gwt-code-reviews.appspot.com/51835), c5911 and followup c5912 svn merge -r5910:5912 https://google-web-toolkit.googlecode.com/svn/trunk . http://code.google.com/p/google-web-toolkit/source/detail?r=5921 Added: /branches/snapshot-2009.08.04-ihm-r5888/dev/core/src/com/google/gwt/dev/util/TemporaryBufferStream.java /branches/snapshot-2009.08.04-ihm-r5888/dev/oophm/test Modified: /branches/snapshot-2009.08.04-ihm-r5888/branch-info.txt /branches/snapshot-2009.08.04-ihm-r5888/dev/core/src/com/google/gwt/core/ext/linker/impl/hosted.html /branches/snapshot-2009.08.04-ihm-r5888/dev/core/src/com/google/gwt/dev/SwtHostedModeBase.java /branches/snapshot-2009.08.04-ihm-r5888/dev/core/src/com/google/gwt/dev/shell/BrowserWidget.java /branches/snapshot-2009.08.04-ihm-r5888/dev/core/src/com/google/gwt/dev/shell/BrowserWidgetHost.java /branches/snapshot-2009.08.04-ihm-r5888/dev/oophm/build.xml /branches/snapshot-2009.08.04-ihm-r5888/dev/oophm/src/com/google/gwt/dev/OophmHostedModeBase.java /branches/snapshot-2009.08.04-ihm-r5888/dev/oophm/src/com/google/gwt/dev/shell/BrowserChannel.java /branches/snapshot-2009.08.04-ihm-r5888/dev/oophm/src/com/google/gwt/dev/shell/BrowserChannelServer.java /branches/snapshot-2009.08.04-ihm-r5888/dev/oophm/src/com/google/gwt/dev/shell/OophmSessionHandler.java Replaced: /branches/snapshot-2009.08.04-ihm-r5888/dev/oophm/test/com /branches/snapshot-2009.08.04-ihm-r5888/dev/oophm/test/com/google /branches/snapshot-2009.08.04-ihm-r5888/dev/oophm/test/com/google/gwt /branches/snapshot-2009.08.04-ihm-r5888/dev/oophm/test/com/google/gwt/dev /branches/snapshot-2009.08.04-ihm-r5888/dev/oophm/test/com/google/gwt/dev/shell /branches/snapshot-2009.08.04-ihm-r5888/dev/oophm/test/com/google/gwt/dev/shell/BrowserChannelTest.java === --- /dev/null +++ /branches/snapshot-2009.08.04-ihm-r5888/dev/core/src/com/google/gwt/dev/util/TemporaryBufferStream.java Fri Aug 7 15:17:40 2009 @@ -0,0 +1,56 @@ +/* + * Copyright 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the License); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.google.gwt.dev.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; + +/** + * A utility for tests that allow writing to a temporary buffer and reading + * from the same buffer to verify that serialization/deserialization works. + */ +public class TemporaryBufferStream { + + private ArrayListByte buf = new ArrayListByte(); + + private InputStream inputStream = new InputStream() { +@Override +public int read() throws IOException { + try { +return buf.remove(0) 255; + } catch (IndexOutOfBoundsException e) { +return -1; + } +} + }; + + private OutputStream outputStream = new OutputStream() { +@Override +public void write(int b) throws IOException { + buf.add(Byte.valueOf((byte) b)); +} + }; + + public InputStream getInputStream() { +return inputStream; + } + + public OutputStream getOutputStream() { +return outputStream; + } +} === --- /branches/snapshot-2009.08.04-ihm-r5888/branch-info.txt Fri Aug 7 14:47:13 2009 +++ /branches/snapshot-2009.08.04-ihm-r5888/branch-info.txt Fri Aug 7 15:17:40 2009 @@ -1,4 +1,4 @@ -branch-info.txt for the snapshot-2009.08.04-r5888 branch. +branch-info.txt for the snapshot-2009.08.04-ihm-r5888 branch. Tracks interactions between this branch and other branches. See: http://code.google.com/p/google-web-toolkit/wiki/ManagingMerges @@ -7,3 +7,6 @@ /branches/snapshot-2009.08.04-r5888 Merges: +/trunk r5910:5912 was merged into this branch + OOPHM wire protocol change (http://gwt-code-reviews.appspot.com/51835) + svn merge -r5910:5912 https://google-web-toolkit.googlecode.com/svn/trunk . === --- /branches/snapshot-2009.08.04-ihm-r5888/dev/core/src/com/google/gwt/core/ext/linker/impl/hosted.html Wed Jul 8 14:29:31 2009 +++ /branches/snapshot-2009.08.04-ihm-r5888/dev/core/src/com/google/gwt/core/ext/linker/impl/hosted.html Fri Aug 7 15:17:40 2009 @@ -11,6 +11,7 @@ var moduleName = moduleFunc ? moduleFunc.moduleName : unknown;
[gwt-contrib] Re: Set cache headers properly in embedded Jetty for hosted mode
Bob? Kelly? On Fri, Aug 7, 2009 at 4:56 PM, John Tamplin j...@google.com wrote: On Fri, Aug 7, 2009 at 4:46 PM, sco...@google.com wrote: LGTM, but we should probably get a thumbs-up from at least one other interested person. http://gwt-code-reviews.appspot.com/56807 Suggestion of that person? -- John A. Tamplin Software Engineer (GWT), Google --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Optimizer test framework
Reviewers: cromwellian_google.com, Lex, bruce, Description: Creates some test infrastructure to easily test individual compiler passes. Also started some very basic tests for ControlFlowAnalyzer, ExpressionAnalyzer, and DeadCodeElimination. Hopefully this will start the process of fixing broken windows and result in more test coverage in the future. :) Please review this at http://gwt-code-reviews.appspot.com/57806 Affected files: dev/core/src/com/google/gwt/dev/jdt/BasicWebModeCompiler.java dev/core/src/com/google/gwt/dev/jdt/WebModeCompilerFrontEnd.java dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java dev/core/test/com/google/gwt/dev/javac/impl/JavaResourceBase.java dev/core/test/com/google/gwt/dev/javac/impl/MockJavaResource.java dev/core/test/com/google/gwt/dev/javac/impl/MockResourceOracle.java dev/core/test/com/google/gwt/dev/jjs/JavaAstConstructor.java dev/core/test/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzerTest.java dev/core/test/com/google/gwt/dev/jjs/impl/DeadCodeEliminationTest.java dev/core/test/com/google/gwt/dev/jjs/impl/ExpressionAnalyzerTest.java dev/core/test/com/google/gwt/dev/jjs/impl/OptimizerTestBase.java --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] [google-web-toolkit] r5922 committed - Re-introduces c5892 that rolled htmlunit dependencies in gwt_dev_jar a...
Revision: 5922 Author: amitman...@google.com Date: Fri Aug 7 15:52:15 2009 Log: Re-introduces c5892 that rolled htmlunit dependencies in gwt_dev_jar and updated user/build.xml accordingly Patch by: amitmanjhi http://code.google.com/p/google-web-toolkit/source/detail?r=5922 Modified: /trunk/dev/core/build.xml /trunk/user/build.xml === --- /trunk/dev/core/build.xml Wed Aug 5 21:01:59 2009 +++ /trunk/dev/core/build.xml Fri Aug 7 15:52:15 2009 @@ -54,6 +54,21 @@ include name=tomcat/tomcat-http11-1.0.jar / include name=tomcat/tomcat-jk2-2.1.jar / include name=tomcat/tomcat-util-5.1.jar / + !-- htmlunit dependencies not already included: BEGIN -- + include name=apache/commons/commons-codec-1.3.jar / + include name=apache/commons/commons-httpclient-3.1.jar / + include name=apache/commons/commons-io-1.4.jar / + include name=apache/commons/commons-lang-2.4.jar / + include name=cssparser/cssparser-0.9.5.jar / + include name=htmlunit/htmlunit-2.5.jar / + include name=htmlunit/htmlunit-core-js-2.5.jar / + include name=nekohtml/nekohtml-1.9.12.jar / + include name=xalan/xalan-2.7.1.jar / + include name=xerces/xerces-2_9_1/serializer.jar / + include name=xerces/xerces-2_9_1/xercesImpl.jar / + include name=xerces/xerces-2_9_1/xml-apis.jar / + include name=w3c/sac/sac-1.3.jar / + !-- htmlunit dependencies not already included: END -- /fileset fileset file=build.xml/ /sourcefiles @@ -93,6 +108,21 @@ zipfileset src=${gwt.tools.lib}/tomcat/tomcat-http11-1.0.jar / zipfileset src=${gwt.tools.lib}/tomcat/tomcat-jk2-2.1.jar / zipfileset src=${gwt.tools.lib}/tomcat/tomcat-util-5.1.jar / + !-- htmlunit dependencies not already included: BEGIN -- + zipfileset src=${gwt.tools.lib}/apache/commons/commons-codec-1.3.jar / + zipfileset src=${gwt.tools.lib}/apache/commons/commons-httpclient-3.1.jar / + zipfileset src=${gwt.tools.lib}/apache/commons/commons-io-1.4.jar / + zipfileset src=${gwt.tools.lib}/apache/commons/commons-lang-2.4.jar / + zipfileset src=${gwt.tools.lib}/cssparser/cssparser-0.9.5.jar / + zipfileset src=${gwt.tools.lib}/htmlunit/htmlunit-2.5.jar / + zipfileset src=${gwt.tools.lib}/htmlunit/htmlunit-core-js-2.5.jar / + zipfileset src=${gwt.tools.lib}/nekohtml/nekohtml-1.9.12.jar / + zipfileset src=${gwt.tools.lib}/xalan/xalan-2.7.1.jar / + zipfileset src=${gwt.tools.lib}/xerces/xerces-2_9_1/serializer.jar / + zipfileset src=${gwt.tools.lib}/xerces/xerces-2_9_1/xercesImpl.jar / + zipfileset src=${gwt.tools.lib}/xerces/xerces-2_9_1/xml-apis.jar / + zipfileset src=${gwt.tools.lib}/w3c/sac/sac-1.3.jar / + !-- htmlunit dependencies not already included: END -- /gwt.jar /sequential /outofdate === --- /trunk/user/build.xml Fri Aug 7 13:08:28 2009 +++ /trunk/user/build.xml Fri Aug 7 15:52:15 2009 @@ -36,26 +36,6 @@ pathelement location=test_i18n_${gwt.i18n.test.InnerClassChar} / /path - !-- -Classpaths added for htmlunit libs - -- - path id=htmlunit.libs -pathelement location=${gwt.tools.lib}/apache/commons/commons-codec-1.3.jar / -pathelement location=${gwt.tools.lib}/tomcat/commons-collections-3.1.jar / -pathelement location=${gwt.tools.lib}/apache/commons/commons-httpclient-3.1.jar / -pathelement location=${gwt.tools.lib}/apache/commons/commons-io-1.4.jar / -pathelement location=${gwt.tools.lib}/apache/commons/commons-lang-2.4.jar / -pathelement location=${gwt.tools.lib}/tomcat/commons-logging-1.0.jar / -pathelement location=${gwt.tools.lib}/cssparser/cssparser-0.9.5.jar / -pathelement location=${gwt.tools.lib}/htmlunit/htmlunit-2.5.jar / -pathelement location=${gwt.tools.lib}/htmlunit/htmlunit-core-js-2.5.jar / -pathelement location=${gwt.tools.lib}/nekohtml/nekohtml-1.9.12.jar / -pathelement location=${gwt.tools.lib}/xalan/xalan-2.7.1.jar / -pathelement location=${gwt.tools.lib}/xerces/xerces-2_9_1/serializer.jar / -pathelement location=${gwt.tools.lib}/xerces/xerces-2_9_1/xercesImpl.jar / -pathelement location=${gwt.tools.lib}/xerces/xerces-2_9_1/xml-apis.jar / -pathelement location=${gwt.tools.lib}/w3c/sac/sac-1.3.jar / - /path !-- Platform shouldn't matter here, just picking one -- property.ensure name=gwt.dev.jar location=${gwt.build.lib}/gwt-dev-${build.host.platform}.jar / @@ -70,7 +50,6 @@ pathelement location=${gwt.tools.lib}/w3c/sac/sac-1.3.jar / pathelement location=${gwt.tools.lib}/w3c/flute/flute-1.3.jar / pathelement location=${gwt.dev.jar} / -path
[gwt-contrib] [google-web-toolkit] r5923 committed - Merging in HTMLUnit changes from trunk, c5916, c5917, c5919,...
Revision: 5923 Author: rj...@google.com Date: Fri Aug 7 16:05:37 2009 Log: Merging in HTMLUnit changes from trunk, c5916, c5917, c5919, c5922. These are all the trunk changes in this range, so a single merge command sufficed: svn merge -r5915:5922 https://google-web-toolkit.googlecode.com/svn/trunk . Reviewed by amitmanjhi http://code.google.com/p/google-web-toolkit/source/detail?r=5923 Modified: /branches/snapshot-2009.08.04-ihm-r5888/branch-info.txt /branches/snapshot-2009.08.04-ihm-r5888/dev/core/build.xml /branches/snapshot-2009.08.04-ihm-r5888/dev/core/src/com/google/gwt/dev/shell/tomcat/EmbeddedTomcatServer.java /branches/snapshot-2009.08.04-ihm-r5888/eclipse/user/.classpath /branches/snapshot-2009.08.04-ihm-r5888/user/build.xml /branches/snapshot-2009.08.04-ihm-r5888/user/test/com/google/gwt/uibinder/client/UiBinderTest.java === --- /branches/snapshot-2009.08.04-ihm-r5888/branch-info.txt Fri Aug 7 15:17:40 2009 +++ /branches/snapshot-2009.08.04-ihm-r5888/branch-info.txt Fri Aug 7 16:05:37 2009 @@ -10,3 +10,7 @@ /trunk r5910:5912 was merged into this branch OOPHM wire protocol change (http://gwt-code-reviews.appspot.com/51835) svn merge -r5910:5912 https://google-web-toolkit.googlecode.com/svn/trunk . + +/trunk r5915:5922 was merged into this branch + HTLMUnit changes + svn merge -r5915:5922 https://google-web-toolkit.googlecode.com/svn/trunk . === --- /branches/snapshot-2009.08.04-ihm-r5888/dev/core/build.xml Wed Aug 5 12:55:36 2009 +++ /branches/snapshot-2009.08.04-ihm-r5888/dev/core/build.xml Fri Aug 7 16:05:37 2009 @@ -54,6 +54,21 @@ include name=tomcat/tomcat-http11-1.0.jar / include name=tomcat/tomcat-jk2-2.1.jar / include name=tomcat/tomcat-util-5.1.jar / + !-- htmlunit dependencies not already included: BEGIN -- + include name=apache/commons/commons-codec-1.3.jar / + include name=apache/commons/commons-httpclient-3.1.jar / + include name=apache/commons/commons-io-1.4.jar / + include name=apache/commons/commons-lang-2.4.jar / + include name=cssparser/cssparser-0.9.5.jar / + include name=htmlunit/htmlunit-2.5.jar / + include name=htmlunit/htmlunit-core-js-2.5.jar / + include name=nekohtml/nekohtml-1.9.12.jar / + include name=xalan/xalan-2.7.1.jar / + include name=xerces/xerces-2_9_1/serializer.jar / + include name=xerces/xerces-2_9_1/xercesImpl.jar / + include name=xerces/xerces-2_9_1/xml-apis.jar / + include name=w3c/sac/sac-1.3.jar / + !-- htmlunit dependencies not already included: END -- /fileset fileset file=build.xml/ /sourcefiles @@ -93,6 +108,21 @@ zipfileset src=${gwt.tools.lib}/tomcat/tomcat-http11-1.0.jar / zipfileset src=${gwt.tools.lib}/tomcat/tomcat-jk2-2.1.jar / zipfileset src=${gwt.tools.lib}/tomcat/tomcat-util-5.1.jar / + !-- htmlunit dependencies not already included: BEGIN -- + zipfileset src=${gwt.tools.lib}/apache/commons/commons-codec-1.3.jar / + zipfileset src=${gwt.tools.lib}/apache/commons/commons-httpclient-3.1.jar / + zipfileset src=${gwt.tools.lib}/apache/commons/commons-io-1.4.jar / + zipfileset src=${gwt.tools.lib}/apache/commons/commons-lang-2.4.jar / + zipfileset src=${gwt.tools.lib}/cssparser/cssparser-0.9.5.jar / + zipfileset src=${gwt.tools.lib}/htmlunit/htmlunit-2.5.jar / + zipfileset src=${gwt.tools.lib}/htmlunit/htmlunit-core-js-2.5.jar / + zipfileset src=${gwt.tools.lib}/nekohtml/nekohtml-1.9.12.jar / + zipfileset src=${gwt.tools.lib}/xalan/xalan-2.7.1.jar / + zipfileset src=${gwt.tools.lib}/xerces/xerces-2_9_1/serializer.jar / + zipfileset src=${gwt.tools.lib}/xerces/xerces-2_9_1/xercesImpl.jar / + zipfileset src=${gwt.tools.lib}/xerces/xerces-2_9_1/xml-apis.jar / + zipfileset src=${gwt.tools.lib}/w3c/sac/sac-1.3.jar / + !-- htmlunit dependencies not already included: END -- /gwt.jar /sequential /outofdate === --- /branches/snapshot-2009.08.04-ihm-r5888/dev/core/src/com/google/gwt/dev/shell/tomcat/EmbeddedTomcatServer.java Fri Mar 27 08:09:11 2009 +++ /branches/snapshot-2009.08.04-ihm-r5888/dev/core/src/com/google/gwt/dev/shell/tomcat/EmbeddedTomcatServer.java Fri Aug 7 16:05:37 2009 @@ -177,6 +177,15 @@ // File topWorkDir = new File(System.getProperty(user.dir)); +/* + * set property explicitly so that addition of the xercesImpl lib, when java + * 1.5 is used, does not affect tomcat. + */ +if (1.5.equals(System.getProperty(java.specification.version))) { + System.setProperty(javax.xml.parsers.DocumentBuilderFactory, +
[gwt-contrib] New GWT RPC project: gwt-rpc-plus
Hey all, We've been working on a number of RPC enhancements locally and thought that it might be helpful to open-source some of them (prompted by a recent suggestion from Ray Cromwell). I've created a new Google Code project that encapsulates them here: http://code.google.com/p/gwt-rpc-plus/ It's an umbrella project for a number of RPC enhancements that we're using. It includes a set of building blocks and some higher-level code that builds on them to enhance the current GWT RPC functionality: 1. A set of 'bare-metal', strongly-typed JS collections optimized for both RPC and client-side use. These collections are designed to mimic (but not fully support) the interfaces of the standard Java List, Map and Set. They are code-generated and based on JavaScriptObject (see here: http://code.google.com/p/gwt-rpc-plus/source/browse/#svn/trunk/ gwt-rpc-plus/gwt/com/dotspots/rpcplus/client/jscollections). They are essential to the Thrift RPC system (mentioned below), but are useful as their own standalone collections. 2. Alternative JSON and text transports, including a cross-domain transport using window.name and standard XMLHttpRequest communication. 3. A set of fast utility classes to parse and emit JSON using browser- native code where possible (ie: JSON.parse/stringify, eval/uneval). 4. A way to plug alternative transports into GWT RPC (based on a technique similar to this: http://timepedia.blogspot.com/2009/04/gwt-rpc-over-arbitrary-transports-uber.html) . It currently includes a way to easily replace the RPC transport with any text transport (including the window.name transport mentioned above). 5. A Thrift-based, versioned RPC framework that can replace GWT RPC entirely (built on top of the above-mentioned pieces). The code in the library was extracted from a bunch of code scattered throughout our project. I'm still working on refactoring and cleaning up parts of it, so it's likely to change over the next few weeks. None of the architecture is set in stone, so anyone interested in helping contribute/architect is welcome to join in. Thanks! Matt. --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---