If you do not use Cell Widgets, you can ignore this email.

*
We recently introduced a new ElementBuilder
API<http://code.google.com/p/google-web-toolkit/source/detail?r=10412>
for
building elements using either DOM manipulation or string concatenation with
innerHTML.  It allows us to optimize for different browsers, and it even
opens the door for server side rendering.  We've found that on some
browsers, DOM manipulation is getting faster than innerHTML (due to the cost
of actually building the HTML string).
*

So, we want to integrate ElementBuilder into CellTable/DataGrid/CellList.
 The problem is that Cell Widgets currently assume that their contents will
be built using a SafeHtmlBuilder, which isn't compatible with the
ElementBuilder API.  In the current flow, we call *renderRowValues()* to
build a SafeHtml string, then call one of *
replaceAllChildren/replaceChildren()* to render the SafeHtml string into the
CellTable.  I plan to replace *renderRowValues()* with a new
CellTableBuilder (name to be determined) interface that lets you build zero
or more rows for each row value using the ElementBuilder API, allowing the
use of colspans and rowspans.  This provides a lot of flexibility to create
customized CellTables.

Below is my proposal, which reduces this to a a couple of breaking changes
that should not affect many people:

   - renderRowValues() will be deprecated and will throw an
   UnsupportedOperationException if called.  However, CellTable will still call
   the code and catch the UnsupportedOperationException.  If we DO NOT catch
   the UnsupportedOperationException, then we proceed through the legacy stack,
   calling replaceAllChildren/replaceChildren with the generated HTML string.
    This handles the case where user code overrides renderRowValues() and DOES
   NOT call super.renderRowValues().
   - replaceAllChildren/replaceChildren(List<R> values, SafeHtml html) will
   be repurposed to mean "build and replace".  By default, we pass null as the
   value of the SafeHtml string and note in the JavaDoc that it is a dead
   variable, and only there for legacy reasons to prevent API changes.
    replaceAllChildren/replaceChildren will use the CellTableBuilder to build
   the table rows, then it will replace the rows.
   - However, if renderRowValues() does not throw an
   UnsupportedOperationException, then the HTML is passed in and we use the
   existing implementation.  This allows existing subclasses of AbstractHasData
   to continue working normally.  In fact, CellList will use this exact
   process.

This leaves two potential breaking situations.  First, if you currently
override renderRowValues() and call super.renderRowValues(), you'll trigger
an UnsupportedOperationException, which is ignored.  As a temporary
workaround, we'll introduce a deprecated final protected method
renderRowValuesLegacy().  Subclasses can override renderRowValues() and call
super.renderRowValues().  I expect that this is a very rare usecase, but
renderRowValuesLegacy will be dead-code eliminated by the compiler anyway.

The other breaking situation is if you override
replaceAllChildren/replaceChildren and try to operate on the SafeHtml
argument, which is now null.  In this case, you will have to update your
code accordingly (or override renderRowValues).

This is a bit hacky, but I prefer it over other options it because it does
not require any actual API changes, and the affected methods are protected
and I don't think a lot of people will override them.

John LaBanca | GWT Software Engineer | jlaba...@google.com

-- 
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to