gwt /
gwt /
7127d08a23bd05996fd4d49bb0039227ba352f58 Adding a new ElementBuilder API to build DOM Elements using the builder pattern. There are two implementations: one that builds using DOM manipulation, and another that builds using String concatenation and innerHtml. The latter can be user in a regular JVM to create an HTML string, which will hopefully help with server side rendering in the future. Both can be used on the client, which allows an app to optimize depending on which is faster. Once I incorporate this into Cell Widgets, I'll do performance metrics on real apps to compare the difference.
There are a lot of classes here, so I'll explain what they are. At the core, we have the ElementBuilderBase interface and its subclasses, one for each element type (ex. DivBuilder, SelectBuilder). These interfaces mirror the Element JSO types, with short method names to reduce the verbosity of the builder. You can build an element by doing something like divBuilder.id("myDiv").title("my title").end(). If you start a sub element, you get a builder with methods specific to the new element. For example, selectBuilder.startOption() returns an OptionBuilder, with methods like disabled() and defaultSelected(). Note that currently, the only builder subclasses are Div, Select, and Option. There is also a StylesBuilder for building the style attribute (similar to SafeStylesBuilder, but generic enough to work for DOM or HTML). I'll add the rest once we've finalized the design. The return value of the end() method can be paraneterized with the builder class of the containing element, so you can continue chaining with the parent builder.
Next, we have the two implementations of these interfaces: one for DOM and one for HTML. For example, DomDivBuilder is a concrete class to build a div using DOM manipulation, while HtmlDivBuilder is a concrete class to build a div using HTML manipulation. The HTML versions expose asSafeHtml(), which allows users to access the string (useful for server side rendering).
Then, there are two impl clases: DomBuilderImpl and HtmlBuilderImpl. In practice, the concrete implementations of the ElementBuilder interfaces actually just delegate to a shared instance of one of these impl classes. That has the benefit that we don't create an object for every single element that is created (just one object for every element type). The impl classes are responsible for builder the Element/String, and they maintain state to ensure that they fire IllegalStateExceptions in similar circumstances. For example, technically DomBuilderImpl can set an attribute after setting innerHtml, but that wouldn't work in HtmlBuilderImpl, so both fire an exception in this case.
Finally, there are the ElementFactory classes, which return a new top level element builder. ElementFactory#get() will return either DomBuilderFactory or HtmlBuilderFactory, depending on which is optimal for the platform. Alternatively, user can access the DomBuilderFactory or HtmlBuilderFactory directly. The factory has createXXXBuilder() methods to create a builder for each element.
Review at http://gwt-code-reviews.appspot.com/1455802
Review by: skybrian@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10412 8db76d5a-ed1c-0410-87a9-c151d255dfc7
52 files changed