Rationale
This page lists core XForms engine improvements we would like to see happen.
Orbeon Forms is open source and your help is appreciated. Post to ops-users or tweet us at @orbeon if you hare interested!
XBL
Automatic aggregation of JS and CSS resources for XBL
Currently, this is simply not done for XBL components (it is done for other XForms resources).
Proposal: XForms engine incl. XForms resource server handles this.
Use XBL to represent appearances and types
Current:
- Appearances and types are handled in an ad-hoc way
- custom Java code in handlers
- custom JS code on client
- custom, incomplete switching code on client
- issues
- complex
- error-prone
- inflexible
- requires compilation of Java code for even simple changes
Proposal:
- Higher-level appearances and types implemented in XBL
- XForms engine changes
- new CSS bindings
- appearance
- xforms|select1[appearance = "xxforms:tree"]
- type
- xforms|input[xxforms|type = "xs:dateTime"] (here using a virtual attribute)
- OR xforms|input[class ~= "xforms-type-dateTime"] (here using a class)
- hook up XBL based on those matches instead of using built-in appearances
- detect switch of appearance and type
- Ajax mode: run controls through XBL template and send markup template update to client
- Current controls which can benefit
- date, time, dateTime, boolean types for xforms:input
- xxforms:tree, xxforms:menu appearances for xforms:select/xforms:select1
- autcomplete input
- Later
- even native XForms controls cah be implemented this way
- xforms:switch/xforms:case optimization where hidden cases are sent to client using same update mechanism as for appearance/type change
Flow of events over XBL scopes
Currently, events ignore xxbl:scope.
Plan:
Automatic detection of noscript-enabled controlsCurrently, the xxforms:noscript-supported property must be set by hand. Plan is to determine the value automatically based on: - built-in controls which don't support noscript
- xbl:binding/xxbl:noscript-support="true" (or maybe something in xbl:template production)
Performance
Improvement to client-side/server-side repeat handling
When repeat iterations are moved, the client is not made aware of this and instead considers that iterations are updated.
This means that the client might take a long time to execute those updates, especially with older browsers.
The proposed solution is that the server can apply the regular repeat nodeset diff mechanism at Ajax diff time to detect and notify the client of:
- iterations removed
- iterations created
- iterations moved
This is similar to the current repeat nodeset diff taking place upon insert/delete/refresh, but applies between the state of the tree at the start and end of an Ajax request.
The server must also assign new unique ids to iterations, so that the client can keep references from id to JavaScript structure.
Steps: - define how handling of new unique ids will work
- implement diff in ControlsComparator
- define format to send to client
- implement client-side
[TODO: more details]
Improved XPath dependencies
See also:
Implement alternate disk-based persistent XForms state managerCurrently: - also support writing to a plain disk-based database
Handling of non-relevant control subtrees
Plan:
- As per XForms 1.1, no evaluation takes place and event handlers are not activated
- Extension option for xf:switch/case to retain relevance
- Within repeats, do not output initial HTML markup within non-relevant objects (see also Form Builder - Performance Enhancements)
Optimization of event dispatches
Rationale:
- server: reduce number of events dispatched for "nothing"
- client: prevent sending of focus events
- improve efficiency of event dispatch
Later, when dependencies: "not dispatching value-changed for controls for which nothing depends on their value or catches a value-changed event".
Client-side:
- client doesn't need to send DOMFocusIn/Out if there is no handler
- EXCEPT if changing repeat iterations!
- EXCEPT if we can determine that the index() function is not used in binds (?) (harder)
- Q: how does the server tell the client
Server-side:
- analysis
- Q: exact algorithm
- Q: should we do static or dynamic analysis or a combination?
- need to handle XBL as well
- data structures
- Q: what exactly needs to be stored? must be as small+efficient as possible
- idea: for each control, for each event name, create ordered list of listeners (might be empty)
- this would allow more efficient event dispatch
Static analysis:
- starting from controls
- issues
- XBL components: need recursive analysis of tree of XBL containers?
- for each native control: list of possible events dispatched
- for each XBL control: build list of possible events dispatched
- xf:dispatch w/ dynamic @targetid or @name
- starting from listeners
- determine which controls (and model objects?) can dispatch events caught by given listener
- for each object, store list of events worth dispatching
- during event dispatch, use this information to determine whether event must be even dispatched
Dynamic analysis:
- catpure information at runtime and store it into static state, instead of computing it ahead of time
Better xforms-enabled/disabled integration between client and server
Currently:
- we use xf-enabled/disabled to run script
- in some cases, there can be a discrepancy between client/server
- iterations added on server -> ids change
- controls become relevant/non-relevant/relevant again
[TODO: Brainstorm about this, e.g. see issue with inserting currency fields]
Static analysis of namespace information
Goal: improve XPathCache lookups performance.
- XFormsStaticState must keep an element id -> key mapping, computed statically or dynamically
- whenever XPath evaluation, must ask XFStSt for namespace "key"
- key is stored into static state
- we should make the key smaller to make lookups faster
- instead of passing a Map of namespace mappings to XPathCache, we probably need to wrap this in a containing object, so the API must be slightly changed
- does it make sense to intern the strings for the key/cache entry id?
Shortening of XForms class names in generated HTML
Currently, classes start with "xforms-*".
Plan:
- Make the client-side markup and DOM smaller.
- change to "xf-*"
- possibly: shorten suffixes as well, e.g.:
- Q: how to manage the transition, given the existing CSS? use a property to switch?
Features
Support for click/focus/blur/focusin/focusout DOM events
Rationale:
- DOM 3 might deprecate DOMActivate/DOMFocusIn/DOMFocusOut
- Not sure as of February 2010 whether new versions of XForms will deprecate those events
- But it might still be a good idea to support the closely matching click/focus/etc. DOM 3 events
Questions:
- How can the engine avoid dispatching too many events?
Scoped models
XBL components support nested models and instances. The notion could (and should) be extended outside components, as really the same code should handle that:
<xforms:repeat nodeset="...">
<xforms:model id="my-scoped-model">
<xforms:instance>
<foobar/>
</xforms:instance>
</xforms:model>
<xforms:input model="my-scoped-model" ref="."/>
</xforms:repeat>
[TODO: more brainstorming on this]
Architecture
Upgrade to Saxon 9.1/9.2
Currently, Orbeon Forms still uses Saxon 8.8.
Plan:
- Upgrade to Saxon 9.1 first
- Then try upgrade to Saxon 9.2 HE and backport missing features
- saxon:*, exslt:* functions
- dom4j support
Representation of variables within controls
Currently, variables are only represented on the XFormsContextStack. As for outer action handlers (below), they should be represented like controls.
Proposal:
- XXFormsVariableControl
- variables do not have client-side representation
- can receive MIP events
- can receive xforms-value-changed
- need different algorithm for value change i.e. not change in string value only
- BindingContext evaluated at tree update time
- value evaluated at tree evaluation time
- must be ignored by diff algo
This would allow improved syntax for XBL components, since listening on dummy groups wouldn't be needed anymore.
Representation of outer action handlers within controls
Currently, those are entirely static, which has benefits. However, when dispatching events to actions that have scoped variables, we currently reevaluate the variables, which is wasteful.
Proposal:
- Have a representation of actions in the controls tree
- XFormsActionControl?
- Main benefit is having a BindingContext
- Can then refer to static action information for running the action
- Limitation: nested actions, if executed directly, may not have the proper binding context
Streamline use of XFAnnotatorCH, XFExtractorCH
Proposal:
- SAXStore produced by XFACH should not contain models and actions, only HTML and XForms controls
- For XBL
- must do exactly the same thing as top-level => better code reuse
- output of XFACH must be SAXStore, not DOM
- ideally: SAX the XSLT/XBL transformation (even pipeline???)
- can XFACH and XFECH be refactored to produce the two outputs at the same time? probably!
Static representation of controls
Plan:
- Don't use dom4j to represent controls, instead use ad-hoc classes, e.g. XFormsElement + class hierarchy
- Benefit: less waste of space and construction time (dom4j is wasteful, and tree is immutable)
- Construct through SAX
- Could possibly be Java-serialized to state, possibly more compact
[TODO: elaborate]
Representation of XForms models
Plan:
- Like for controls, no longer use DOM
- Use sister class of XFormsControl
- Proper hierarchy, like for controls
- Better evaluation of variables
- Makes it easier to place models within controls with flexibility
[TODO: elaborate]
Allowing asynchronous updates to an XForms document
There
is a limitation right now which is that no async changes to the page
can happen: only one client (the web browser) can make updates, in
sequence. If you come in with an older dynamic state id, things won't
work. In other words:
- There is one live document...
- for which there is exactly one client able to interact with it, that is a single window in a web browser.
Changing this would allow:
- Fully asynchronous uploads able to update an instance directly
- Asynchronous submissions able to modify the document upon xforms-submit-done/xforms-submit-error
- Java or service APIs to perform async updates on XForms pages
Use cases:
- Getting status of autosave actions
- Chat system / twitter client polling asynchronously
- Asynchronous system to allow multiple users to edit the same data
NOTE:
An async update wouldn't be visible immediately to other clients of the
document. Clients need to regularly poll, e.g. with a dummy event, to
get the updates, (unless you have some comet style of connection open).
Ideas:
- Architecture changed so that one live document
- Idea of a "page generation id" which identifies the life of a particular page
- NOTE: XFormsStateManager
has an incomplete notion of currentPageGenerationId (incomplete because
not used in case static state is cached)
- P1 QUESTION: do we still need, in addition to page generation id, a dynamic
state id? Mabye not!
- Over the life of the page, the page generation id is passed alongside static state id and dynamic state id
- When request comes in
- sync on page gen id
- NOTE: This requires changes, as currently our syncing mechanism is not reliable (but then it is probably not used atm anyway)
- find latest dynamic state id for gen id
- if passed dynamic state id is latest, then client was up to date and proceeds
- if not, then
- perform incoming actions on latest document (matching latest dynamic state id)
- response must compute updates between passed dynamic state id and new
xf:dispatch/@delay: improve handling of delayed events queue
- order by expiration time
- check queue "once in a while" to see if delay has elapsed
- implement XForms 1.1 strategy of avoiding duplicate events
Implemented
2010-03-02: Recursive handling of XBL dependencies
Currently, xforms-widgets.xsl implements basic support for automatic inclusion of XBL files:
- it looks at all the elements of the document
- for each unique fr:* name(), it performs an include
This is problematic:
- it is not recursive, so hacks are in place to handle specific components like fr:alert-dialog
- it is not efficient
- oxf.epilogue.xforms.widgets.fr-elements-to-skip is a mess and not local
Proposal:
- handle natively in XForms engine, which must anyway know all XBL components used
- simple property can map prefix fr:* -> oxf:/xbl/orbeon/* and other mappings
- XFormsToXHTML can add all XBL dependencies so caching works properly
|