Markup Mixing Nexaweb IBM 20060712

From MemberWiki

Jump to: navigation, search


About the current version of this wiki page

The current version of the wiki page consists of a proposal from James Margaris of Nexaweb in its original form, annotated with comments by Jon Ferraiolo of IBM. Future versions of this document might resolve the issues raised in the annotated comments such that the wiki page is updated to contain those resolutions. [JF] This sentence is an example of such an annotation.[/JF]


This proposal builds on both the Alternate Hub Proposal Using XML Namespaces as well as the Tibco Dojo Proposal Toolkit Loading, Markup Mixing. This proposal is a refinement of the XML Namespaces proposal that goes into more algorithmic and technical details. For purposes of this discussion "namespace" refers to a proper namespace as well as to an oa:type attribute value that denotes ownership of the element by some identified toolkit. Proper XML namespaces are the preferred mechanism but oa:type is supported for browser compatibility reasons as well as markup validation reasons. This proposal assumes the existence of some shared OA code that is a part of the page that all toolkits know about and can use. This proposal should be detailed enough to allow for creation of a prototype implementation.

[JF] Two issues:

  1. At a previous teleconference, we discussed the requirement to support both the "Single DOM" approach and the "Dual DOM" approach for Ajax toolkits. With the Single DOM approach, the original source markup is intermixed smack dab with other HTML, where the generated HTML for advanced UI controls is co-mingled with original HTML and/or replaces the original HTML. Dojo is one example of Simple DOM among many existing toolkits. With the Dual DOM approach, the source markup and generated HTML are separate DOM trees. XAP is one example of a Dual DOM approach. I have added a requirement below that we must support both the Single DOM and Dual DOM approaches.
  2. At a previous teleconference, we discussed how today's browsers provide only imperfect support for XML namespaces. (In fact, with IE6, it is arguable that its only support for XML namespaces done in a broken manner.) Given the requirement to support both Single DOM and Dual DOM, and the fact that browsers have major bugs with namespaces, we probably will have to compromise on how much leverage we can make of XML namespaces. In particular, there is not reliable cross-browser support for custom namespaced elements (<MyNs:MyCustomControl>) when using the Single DOM approach, which means we have to support at least one other alternate *first-class* syntax approach, such as <div some-open-ajax-attribute="value">.


Markup Requirements recap

  • 1: Allow existing toolkits to re-use existing syntax
  • 2: Allow the mixing/intermingling of widgets from different toolkits - multiple levels of mixed containment
  • 3: Optimize page scanning and widget creation
  • 4: Simple from an end-user perspective
  • [JF] 5: Must support both the Single DOM and Dual DOM approaches for Ajax toolkits.[/JF]
  • [JF] 6: Must take into account the realities about limitations in today's browsers, such as poor XML namespace support in IE6.[/JF]

Page scanning by shared OA code

Each toolkit when loaded performs the following operations:

  1. Registers a namespace that the toolkit will handle. [JF] ISSUE: I believe we need to genericize this to allow registering of a namespace but also other means for identifying elements which should be handed off to toolkits. Two obvious things would be to key off of custom elements, such as all elements in the "foo:" namespace or particular QNames such a <foo:bar1> and <foo:bar2>, and key off of well-known attributes, such as the standard "oa:type" attribute that was proposed in Alternate Hub Proposal Using XML Namespaces[/JF]
  2. Registers a method that will be called back when elements with that namespace [JF] those elements[/JF] are encountered.

From there, some shared OA code will scan the page for element subtrees with registered namespaces [JF](may need rewording)[/JF]. When a subtree is encountered, the contents of that subtree are passed to the registered method that handles elements of that namespace [JF](may need rewording)[/JF]. Alternately the page creator can specify element IDs to look for, rather than require a full page scan.[JF] ISSUE: What is search order: do a top-down traversal looking for element/attribute matches first, then do various calls to getElementById, or vice versa, or will IDs get checked as part of the top-down traversal?[/JF]

Namespaced subtrees nested in other namespaced subtrees are not handled during this initial scan. For example in the following snippet, the subtree rooted at <foo:ButtonBar> will be passed to the method registered for that namespace, but the <bar:FancyButton> will not be passed to a handler method.

  <bar:FancyButton>Button label</bar:FancyButton>

It will be up to the individual toolkit handler method to recursively handle other-namespaced imbedded subtrees by calling some helper OA methods. This code should be simple boilerplate code in most cases.

A full example

  xmlns:bar="" >
  <!-- All OpenAjax-compatible web pages would have to use a JavaScript
       library that implemented the feature set we define for our hub.
       The hub would have to be listed in the html:head before any
       references to any OpenAjax-compatible toolkits. -->
  <script src="...URL to JavaScript for OpenAjax hub..." />
  <!-- Each OpenAjax-compatible toolkit typically would load its 
       bootstrapping JavaScript logic within the html:head after the OpenAjax 
       hub were loaded. The initialization routines for the bootstrapping 
       JavaScript would register the same namespace prefix as was defined in 
       the root element (e.g., "foo" and "bar").-->
  <script src="...URL to bootstrap JavaScript for foo-toolkit" />
  <script src="...URL to bootstrap JavaScript for bar-toolkit" />

    <bar:FancyButton>Button label</bar:FancyButton>
  • 1: Toolkit A is loaded and registers a handler for the namespace identified by prefix foo
  • 2: Toolkit B is loaded and registers a handler for the namescape identified by prefix bar
  • 3: The OA page scanner detects the <foo:ButtonBar> namespaced subtree
  • 4: The OA page scanner hands this subtree off to the registered handler
  • 5: The toolkit-specific handler parses the subtree and alters the HTML DOM. Example result
      <bar:FancyButton>Button label</bar:FancyButton>
  • 6: When the alteration is complete tookit A asks the shared OA code to rescan some segment of the subtree. In this example the segment inside the <td> tag
  • 7: The OA page scanner detects <bar:FancyButton> and hands that subtree off to the handler method from toolkit B
  • 8: The toolkit B-specific handler parses the subtree and alters the HTML DOM. Example result:
      <div>Button label</div>

[JF] ISSUE: I believe that when we actually go public with our documents, we should show examples of non-destructive techniques where the original markup is preserved, versus the above example, where the original markup is clobbered by the generated HTML. We probably need multiple examples. Maybe there should be a Single DOM example that shows non-destructive techniques with a <div oa:type="..."> that is preserved after toolkit processing (although child HTML elements might be added to the <div>), and then a Dual DOM approach where the original XML is stored somewhere else. My guess is that we will reach consensus that best practice for Ajax toolkits is to preserve original markup somehow or other, in which case our examples should reflect these best practices.[/JF]
[LS] To what extent do most toolkits preserve the pre-processed xml now? Most offer the value of manipulating the DOM and offer APIs for scripting against new elements as opposed to the original ones. Maybe this is an issue we can debate in the meeting today? I don't see any great value in preserving the original xhtml in the case of widget containers for instance.[/LS]

Rationalization for lack of automated recursive scanning

The lack of automatic recursive scanning is the responsibility of the individual toolkits for a few reasons.

  1. Certain toolkits may not play nicely with widgets from other toolkits imbedded within them. These toolkits can simply not parse the imbedded namespaces or throw some error/warning/exception.
  2. There may be timing/ordering of operations issues.
  3. The toolkits know more than the OA shared code about how they manipulate the HTML DOM. For example in an extreme case they may alter parts of the DOM not related to the current subtree at all, which then may also need to be scanned for namespaced subtrees. They may also scope down the area that needs to be scanned, by for example tracking imbedded content during their own parsing routines.

Open issues

  1. The exact mechanism that toolkits register namespaces and handlers for them. (Some simple shared OA code)
  2. The exact details of the scanning algorithm. [JF] ISSUE: Just how flexible do we have to make the hub in how it scans the document? The simplest approach would be that the hub does a simple one-pass top/down traversal of the whole document, examining each element according to criteria (e.g., prefix/namespace of each element, QName of each element, and the value of a well-known OpenAjax special attribute. But there are infinite ways to complicate this, such as allowing toolkits to interpose just before or just after another toolkit processes an element, or scanning for a particular toolkit's elements before another toolkits elements.[/JF]
  3. Unified mechanism to deal with toolkits that do not imbed well in others, or that do not handle imbedded toolkits well.
  4. [JF] The exact set of XML namespace support we can use successfully across popular browsers today. It appears that custom elements such as <foo:bar> do not work reliably in IE6 -- see What about namespaced attributes, such as oa:type="..."? Or do we need to throw in the towel there, also, and use a naming convention such as openajaxType="..."[/JF]

These issues are probably best ironed out in prototype code creation.

Markup Requirements check

  • 1: Allow existing toolkits to re-use existing syntax
    • Yes other than that the root tag of a toolkit-specific subtree must have either a namespaced tag or an oa:type attribute on it. All other syntax remains the same.
  • 2: Allow the mixing/intermingling of widgets from different toolkits
    • Yes at the markup level. Work may still have to be done to ensure toolkits play nicely with event handling, layering, etc.
  • 3: Optimize page scanning and widget creation
    • Page should only be scanned once regardless of number of toolkits used. Page can be scanned only in part if page author specified specific element IDs to look for.
  • 4: Simple from an end-user perspective
    • Does not require much from user other than use of namespaces and/or oa:type attribute. Very little extra code or markup required
  • [JF] 5: Must support both the Single DOM and Dual DOM approaches for Ajax toolkits.
    • I believe there are adjustments that we need to make to this document to support Single DOM.[/JF]
  • [JF] 6: Must take into account the realities about limitations in today's browsers, such as poor XML namespace support in IE6.
    • I believe there are adjustments that we need to make to this document to support Single DOM and the deficiencies in current browsers regarding XML Namespace support.[/JF]