W3C home > Mailing lists > Public > www-forms-editor@w3.org > January 2003

RE: 7.2 XForms DOM interfaces are specified strangely

From: Mark Birbeck <Mark.Birbeck@x-port.net>
Date: Fri, 3 Jan 2003 09:55:25 -0000
Message-ID: <E3ED00A7C285EE408679DE2A26D1C7818FFD48@S007.x-port.net>
To: "'Micah Dubinko'" <mdubinko@yahoo.com>, www-forms-editor@w3.org

Dear all,

Micah wrote:
> Upon review of the DOM interfaces defined in 7.2, there are some
> seeming inconsistencies, or at least oddities.

I think Micah is right to point out some oddities.

Let's assume the following is in some document:

    <model id="mdlA">
       <instance id="instA" src="http://example.com/A.xml" />
       <instance id="instB" src="http://example.com/B.xml" />
       <instance id="instC" src="http://example.com/C.xml" />
       <instance id="instD" src="http://example.com/D.xml" />
    </model>

You would expect to be able to navigate to any of these elements from within
the containing document, using any DOM functions you fancy. This means that
to get to the definition of the instance data for 'instC' you *should* be
able to:

    Call getElementById with 'instC' as the ID parameter

Or:

    Call getElementById with 'mdlA' as the ID parameter,
    then get the childNodes property, and then retrieve
    the third item

Or:

    any other route you can think of

and then call some function to get the DOM document.

The problem with the spec as it stands is that if we were to navigate to
this element, we wouldn't find anything of use when we got there, other than
a dom::Element with @src as an attribute. Whilst there is nothing to say
that the hierarchical nature of a DOM representation must somehow reflect
the logical representation of an application, the current spec does seem
particularly counter-intuitive. I think Micah is therefore right that we
should have a get function on the instance data element so that once we
navigate to it we can retrieve the connected instance data.

Micah's proposed solution is as follows:

> Request: If the implementers agree, I request that the interface be
> specified as part of the instance element instead, removing the need
> for a parameter on getInstanceData. The previous code would then look
> like:
>
> var instElem = document.getElementById("id_of_instance_element");
> var instDoc = modelElem.getInstanceDocument();

[There's a small typo here - for 'modelElem' read 'instElem'.]

If we are going to make this change, I would suggest that we also consider a
name change for the function, to getDocument(). The rationale for this is
that the object returned is a dom::Document, and not an InstanceDocument.
This is along the lines of the approach used for functions in DOM 2, where
the name of the object being returned features in the function name (for
example, getElementById or getAttribute).

We would therefore have something along the lines of the following, for the
interface definition:

    interface XFormsInstanceElement : Element {
        Document getDocument();
    }

Note also that if we don't adopt Micah's proposal then there is currently no
way to access the instance data in the scenario where no ID is present on
the instance data:

    <model id="mdlA">
       <instance src="http://example.com/A.xml" />
    </model>

None of this is to say that when you navigate to a model element you
shouldn't still be able to find the associated instance data in an XForms
way (as presently), rather than a DOM way. However, since there is nothing
in the XForms spec to stop us doing this:

    <model id="mdlA">
       <instance src="http://example.com/A.xml" />
       <instance src="http://example.com/B.xml" />
       <instance src="http://example.com/C.xml" />
       <instance src="http://example.com/D.xml" />
    </model>

it seems to me that we can't rely on there being an ID attribute present,
and therefore we can't use 'get' functions that refer to the instance by
name (as the spec currently does).

One possibility would be for a model to hold a list of XFormsInstanceElement
objects, that uses (or derives from) dom::NodeList:

    interface XFormsModelElement : Element {
        readonly attribute NodeList instances;
    };

I am aware that this gets into the area of defining a DOM for XForms, which
although is much needed, I know will open a big can of worms and is probably
best kept away from the discussion on 1.0.

REBUILD, ETC.
If I understand Micah correctly, he then goes on to suggest that the r*
functions are also moved to this new instance element interface:

> // Perform operations on instDoc
> 
> instElem.rebuild();
> instElem.recalculate();
> instElem.revalidate();
> instElem.refresh();

I would disagree with this. We have not been privy to the discussions
surrounding the change from models with one set of instance data, to models
with multiple instances, so we have had to read between the lines, but we
assumed that the introduction of multiple instances in the same model was
made so that the dependency trees were easier to manage, whilst still
allowing different sets of instance data. Since XPath statements can only
refer to multiples instances in the same model, it means that you know that
in any particular statement you only have to worry about dependencies within
one model, and not across models, which makes refresh and so on easier to
implement.

As far as I can see, you lose this if you move the r* functions down to the
instance data level. In particular, if an XPath statement contains
references to two or more different instances you have no easy way of
ensuring that a control bound to that statement is only refreshed once
(rather than never or twice or even more). The same principle applies to the
other r* functions.

I would therefore suggest that the r* functions are left where they are, on
the model element.

SUMMARY
I suggest the following:

1. A new interface is created, with one method:

    interface XFormsInstanceElement : Element {
        Document getDocument();
    }

2. The existing model element interface becomes as follows:

    interface XFormsModelElement : Element {
        readonly attribute NodeList instances;
        void                        rebuild();
        void                        recalculate();
        void                        revalidate();
        void                        refresh();
    };

with 'instances' being a list of XFormsInstanceElement objects, either of
type XFormsInstanceElementList, or of type NodeList.

3. Leave the r* functions where they are.

Regards,

Mark


Mark Birbeck
Co-author Professional XML and
Professional XML Meta Data,
both by Wrox Press

Managing Director
x-port.net Ltd.
4 Pear Tree Court
London
EC1R 0DS

E: Mark.Birbeck@x-port.net
W: www.x-port.net
T: +44 (20) 7689 9232
Received on Friday, 3 January 2003 04:56:27 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Wednesday, 10 June 2009 18:12:12 GMT