зеркало из https://github.com/mozilla/gecko-dev.git
Bug 361501, use 'anonid' attribute inside anonymous content as ID attribute, p=surkov, r=aaronr+me
This commit is contained in:
Родитель
95bbd41e92
Коммит
7e546f415b
|
@ -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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче