XUL:Trees View vs Controller

From MozillaWiki
Jump to: navigation, search

nsITreeView contains methods that require the implementor to handle both the viewing of data from a model but also actions performed on that view - methods that are better held in a controller.

In bug 317904 I write:

nsITreeView makes it very difficult to have proper separation of model and controller sections of code because it requires the implementor interested in feeding the view model information also implement a bunch of methods that belong in the controller.

For example, you might have a data model and tree view implementation in C++, e.g. browser/components/places/src/nsNavHistoryResult.cpp,h ... it's all well and good for the result object to supply the tree widget with row text values and the structure of the data, but it has no business implementing things like canDrop, drop, etc which belong in the controller.

nsIXULTreeBuilder ran into this problem long ago when it discovered that UI components needed say in implementing some of these methods (since the XUL tree builder was completely generic there was no way it could answer some of these questions appropriately) and an approach was taken implementing nsIXULTreeBuilderObserver, a pass through that the stub methods in the builder used to call fe methods. This is clumsy though and sadly the tree API was not redeveloped at that time when it would have been easier to do so without breaking people. Now we're having to implement the same kind of interface in places.

Here's what I propose:

  1. make nsITreeView contain only view specific interface methods
  2. make nsITreeController that contains the non-view related methods
  3. provide hooks to attach a controller object separately to the view object,

so that it may be implemented in a different place/language

  1. for nsITreeView methods that still need to be handled in some way by the

front end, e.g. when folders are opened or closed, synthesize and fire a DOM event for such things, since they're pretty much fire-and-forget anyway.

Jan Varga has been implementing this in bug 120071