Bug 361501, use 'anonid' attribute inside anonymous content as ID attribute, p=surkov, r=aaronr+me

This commit is contained in:
Olli.Pettay%helsinki.fi 2006-12-11 10:54:09 +00:00
Родитель 56b41da8f7
Коммит 7465f6fb99
10 изменённых файлов: 120 добавлений и 69 удалений

Просмотреть файл

@ -363,35 +363,30 @@ nsXFormsControlStub::ProcessNodeBinding(const nsString &aBindingAttr,
if (aModel)
NS_ADDREF(*aModel = mModel);
mUsesModelBinding = usesModelBinding;
nsCOMPtr<nsIContent> content(do_QueryInterface(mElement));
NS_ENSURE_STATE(content);
nsCOMPtr<nsIDocument> doc = content->GetCurrentDoc();
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(doc));
NS_ENSURE_STATE(domDoc);
if (NS_SUCCEEDED(rv) && indexesUsed.Count()) {
if (indexesUsed.Count()) {
// add index listeners on repeat elements
for (PRInt32 i = 0; i < indexesUsed.Count(); ++i) {
// Find the repeat element and add |this| as a listener
nsCOMPtr<nsIDOMElement> repElem;
domDoc->GetElementById(*(indexesUsed[i]), getter_AddRefs(repElem));
nsXFormsUtils::GetElementByContextId(mElement, *(indexesUsed[i]),
getter_AddRefs(repElem));
nsCOMPtr<nsIXFormsRepeatElement> rep(do_QueryInterface(repElem));
if (!rep)
continue;
rv = rep->AddIndexUser(this);
if (NS_FAILED(rv)) {
return rv;
}
NS_ENSURE_SUCCESS(rv, rv);
rv = mIndexesUsed.AppendObject(rep);
NS_ENSURE_SUCCESS(rv, rv);
}
}
return rv;
return NS_OK;
}
NS_IMETHODIMP

Просмотреть файл

@ -95,18 +95,17 @@ nsXFormsDispatchElement::HandleAction(nsIDOMEvent* aEvent,
nsXFormsUtils::GetEventDefaults(name, tmp, bubbles);
}
nsCOMPtr<nsIDOMDocument> doc;
mElement->GetOwnerDocument(getter_AddRefs(doc));
if (!doc)
return NS_OK;
nsCOMPtr<nsIDOMElement> el;
nsXFormsUtils::GetElementById(doc, target, PR_FALSE, mElement,
getter_AddRefs(el));
nsXFormsUtils::GetElementById(target, PR_FALSE, mElement, getter_AddRefs(el));
if (!el)
return NS_OK;
nsCOMPtr<nsIDOMDocument> doc;
mElement->GetOwnerDocument(getter_AddRefs(doc));
nsCOMPtr<nsIDOMDocumentEvent> docEvent = do_QueryInterface(doc);
if (!docEvent)
return NS_OK;
nsCOMPtr<nsIDOMEvent> event;
docEvent->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));
event->InitEvent(name, bubbles, cancelable);

Просмотреть файл

@ -64,13 +64,9 @@ nsXFormsSendElement::HandleAction(nsIDOMEvent* aEvent,
if (submissionID.IsEmpty())
return NS_OK;
nsCOMPtr<nsIDOMDocument> doc;
mElement->GetOwnerDocument(getter_AddRefs(doc));
if (!doc)
return NS_OK;
nsCOMPtr<nsIDOMElement> el;
doc->GetElementById(submissionID, getter_AddRefs(el));
nsXFormsUtils::GetElementByContextId(mElement, submissionID,
getter_AddRefs(el));
if (!el || !nsXFormsUtils::IsXFormsElement(el, submission)) {
const PRUnichar *strings[] = { submissionID.get(), submission.get() };

Просмотреть файл

@ -65,14 +65,8 @@ nsXFormsSetFocusElement::HandleAction(nsIDOMEvent* aEvent,
if (control.IsEmpty())
return NS_OK;
nsCOMPtr<nsIDOMDocument> doc;
mElement->GetOwnerDocument(getter_AddRefs(doc));
if (!doc)
return NS_OK;
nsCOMPtr<nsIDOMElement> el;
nsXFormsUtils::GetElementById(doc, control, PR_TRUE, mElement,
getter_AddRefs(el));
nsXFormsUtils::GetElementById(control, PR_TRUE, mElement, getter_AddRefs(el));
if (!el)
return NS_OK;

Просмотреть файл

@ -111,18 +111,17 @@ nsXFormsSetIndexElement::HandleAction(nsIDOMEvent *aEvent,
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 indexInt = indexDoub < 1 ? 0 : (PRUint32) floor(indexDoub);
// Find the \<repeat\> with @id == |id|
nsCOMPtr<nsIDOMDocument> domDoc;
rv = mElement->GetOwnerDocument(getter_AddRefs(domDoc));
NS_ENSURE_SUCCESS(rv, rv);
#ifdef DEBUG_XF_SETINDEX
printf("<setindex>: Setting index '%s' to '%d'\n",
NS_ConvertUTF16toUTF8(id).get(),
indexInt);
#endif
#endif
// Find the \<repeat\> with @id == |id|
nsCOMPtr<nsIDOMElement> repeatElem;
rv = domDoc->GetElementById(id, getter_AddRefs(repeatElem));
nsXFormsUtils::GetElementByContextId(mElement, id,
getter_AddRefs(repeatElem));
nsCOMPtr<nsIXFormsRepeatElement> repeat = do_QueryInterface(repeatElem);
if (!repeat) {
const PRUnichar *strings[] = { id.get(), repeatStr.get() };

Просмотреть файл

@ -66,14 +66,9 @@ nsXFormsToggleElement::HandleAction(nsIDOMEvent* aEvent,
mElement->GetAttribute(caseStr, caseAttr);
if (caseAttr.IsEmpty())
return NS_OK;
nsCOMPtr<nsIDOMDocument> doc;
mElement->GetOwnerDocument(getter_AddRefs(doc));
if (!doc)
return NS_OK;
nsCOMPtr<nsIDOMElement> caseEl;
nsXFormsUtils::GetElementById(doc, caseAttr, PR_TRUE, mElement,
nsXFormsUtils::GetElementById(caseAttr, PR_TRUE, mElement,
getter_AddRefs(caseEl));
if (!caseEl)
return NS_OK;

Просмотреть файл

@ -113,14 +113,12 @@ nsXFormsSubmitElement::HandleDefault(nsIDOMEvent *aEvent, PRBool *aHandled)
nsAutoString submissionID;
mElement->GetAttribute(submission, submissionID);
nsCOMPtr<nsIDOMDocument> ownerDoc;
mElement->GetOwnerDocument(getter_AddRefs(ownerDoc));
NS_ENSURE_STATE(ownerDoc);
nsCOMPtr<nsIDOMElement> submissionElement;
ownerDoc->GetElementById(submissionID, getter_AddRefs(submissionElement));
nsXFormsUtils::GetElementByContextId(mElement, submissionID,
getter_AddRefs(submissionElement));
nsCOMPtr<nsIXFormsSubmissionElement> xfSubmission(do_QueryInterface(submissionElement));
if (!xfSubmission) {
const PRUnichar *strings[] = { submissionID.get(), submission.get() };
nsXFormsUtils::ReportError(NS_LITERAL_STRING("idRefError"),

Просмотреть файл

@ -43,6 +43,7 @@
#include "nsIDOMElement.h"
#include "nsIDOMNSHTMLElement.h"
#include "nsIDocument.h"
#include "nsIDOMDocumentXBL.h"
#include "nsINameSpaceManager.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMXPathEvaluator.h"
@ -312,16 +313,13 @@ nsXFormsUtils::GetNodeContext(nsIDOMElement *aElement,
*aContextPosition = 1;
// Find correct model element
nsCOMPtr<nsIDOMDocument> domDoc;
aElement->GetOwnerDocument(getter_AddRefs(domDoc));
NS_ENSURE_TRUE(domDoc, NS_ERROR_FAILURE);
nsAutoString bindId;
NS_NAMED_LITERAL_STRING(bindStr, "bind");
aElement->GetAttribute(bindStr, bindId);
if (!bindId.IsEmpty()) {
// CASE 1: Use @bind
domDoc->GetElementById(bindId, aBindElement);
GetElementByContextId(aElement, bindId, aBindElement);
if (!IsXFormsElement(*aBindElement, bindStr)) {
const PRUnichar *strings[] = { bindId.get(), bindStr.get() };
nsXFormsUtils::ReportError(NS_LITERAL_STRING("idRefError"),
@ -342,9 +340,9 @@ nsXFormsUtils::GetNodeContext(nsIDOMElement *aElement,
if (!modelId.IsEmpty()) {
nsCOMPtr<nsIDOMElement> modelElement;
domDoc->GetElementById(modelId, getter_AddRefs(modelElement));
GetElementByContextId(aElement, modelId, getter_AddRefs(modelElement));
nsCOMPtr<nsIModelElementPrivate> model = do_QueryInterface(modelElement);
// No element found, or element not a \<model\> element
if (!model) {
const PRUnichar *strings[] = { modelId.get(), modelStr.get() };
@ -1798,19 +1796,17 @@ FindRepeatContext(nsIDOMElement *aElement, PRBool aFindContainer)
/* static */
nsresult
nsXFormsUtils::GetElementById(nsIDOMDocument *aDoc,
const nsAString &aId,
nsXFormsUtils::GetElementById(const nsAString &aId,
const PRBool aOnlyXForms,
nsIDOMElement *aCaller,
nsIDOMElement **aElement)
{
NS_ENSURE_TRUE(!aId.IsEmpty(), NS_ERROR_INVALID_ARG);
NS_ENSURE_ARG_POINTER(aDoc);
NS_ENSURE_ARG_POINTER(aElement);
*aElement = nsnull;
nsCOMPtr<nsIDOMElement> element;
aDoc->GetElementById(aId, getter_AddRefs(element));
GetElementByContextId(aCaller, aId, getter_AddRefs(element));
if (!element)
return NS_OK;
@ -1894,6 +1890,53 @@ nsXFormsUtils::GetElementById(nsIDOMDocument *aDoc,
return NS_OK;
}
/* static */
nsresult
nsXFormsUtils::GetElementByContextId(nsIDOMElement *aRefNode,
const nsAString &aId,
nsIDOMElement **aElement)
{
NS_ENSURE_ARG(aRefNode);
NS_ENSURE_ARG_POINTER(aElement);
*aElement = nsnull;
nsCOMPtr<nsIDOMDocument> document;
aRefNode->GetOwnerDocument(getter_AddRefs(document));
// Even if given element is anonymous node then search element by ID attribute
// of document because anonymous node can inherit attribute from bound node
// that is refID of document.
nsresult rv = document->GetElementById(aId, aElement);
NS_ENSURE_SUCCESS(rv, rv);
if (*aElement)
return NS_OK;
nsCOMPtr<nsIDOMDocumentXBL> xblDoc(do_QueryInterface(document));
if (!xblDoc)
return NS_OK;
nsCOMPtr<nsIContent> content(do_QueryInterface(aRefNode));
if (!content)
return NS_OK;
// Search for the element with the given value in its 'anonid' attribute
// throughout the complete bindings chain. We must ensure that the binding
// parent of currently traversed element is not element itself to avoid an
// infinite loop.
nsIContent *boundContent;
for (boundContent = content->GetBindingParent(); boundContent != nsnull &&
boundContent != boundContent->GetBindingParent() && !*aElement;
boundContent = boundContent->GetBindingParent()) {
nsCOMPtr<nsIDOMElement> boundElm(do_QueryInterface(boundContent));
xblDoc->GetAnonymousElementByAttribute(boundElm, NS_LITERAL_STRING("anonid"),
aId, aElement);
}
return NS_OK;
}
/* static */
PRBool

Просмотреть файл

@ -549,21 +549,50 @@ public:
static NS_HIDDEN_(PRBool) IsDocumentReadyForBind(nsIDOMElement *aElement);
/**
* Retrieve an element by id, handling (cloned) elements inside repeats.
* Search for an element by ID through repeat rows looking for controls in
* addition to looking through the regular DOM.
*
* For example, xf:dispatch dispatches an event to an element with the given
* ID. If the element is in a repeat, you don't want to dispatch the event to
* the element in the DOM since we just end up hiding it and treating it as
* part of the repeat template. So we use nsXFormsUtils::GetElementById to
* dispatch the event to the contol with that id that is in the repeat row
* that has the current focus (well, the repeat row that corresponds to the
* repeat's index). If the element with that ID isn't in a repeat, then it
* picks the element with that ID from the DOM. But you wouldn't want to use
* this call for items that you know can't be inside repeats (like instance or
* submission elements). So for those you should use
* nsXFormsUtils::GetElementByContextId.
*
* @param aDoc The document to get element from
* @param aId The id of the element
* @param aOnlyXForms Only search for XForms elements
* @param aCaller The caller (or rather the caller's DOM element),
ignored if nsnull
* @param aElement The element (or nsnull if not found)
*/
static NS_HIDDEN_(nsresult) GetElementById(nsIDOMDocument *aDoc,
const nsAString &aId,
static NS_HIDDEN_(nsresult) GetElementById(const nsAString &aId,
const PRBool aOnlyXForms,
nsIDOMElement *aCaller,
nsIDOMElement **aElement);
/**
* Search for an element with the given ID value. First
* nsIDOMDocument::getElementById() is used. If it successful then found
* element is returned. Second, if the given node is inside anonymous content
* then search is performed throughout the complete bindings chain by @anonid
* attribute.
*
* @param aRefNode The node relatively of which search is performed in
* anonymous content
* @param aId The @id/@anonid value to search for
*
* @return aElement The element we found that has its ID/anonid value
* equal to aId
*/
static NS_HIDDEN_(nsresult) GetElementByContextId(nsIDOMElement *aRefNode,
const nsAString &aId,
nsIDOMElement **aElement);
/**
* Shows an error dialog for fatal errors.
*

Просмотреть файл

@ -166,7 +166,10 @@ nsXFormsXPathFunctions::Index(txIFunctionEvaluationContext *aContext,
// aID should be the id of a nsIXFormsRepeatElement
nsCOMPtr<nsIDOMElement> repeatEle;
nsresult rv = document->GetElementById(aID, getter_AddRefs(repeatEle));
nsCOMPtr<nsIDOMElement> resolverEle(do_QueryInterface(resolverNode));
nsresult rv =
nsXFormsUtils::GetElementByContextId(resolverEle, aID,
getter_AddRefs(repeatEle));
NS_ENSURE_SUCCESS(rv, rv);
// now get the index value from the xforms:repeat.