void nsReferencedElement::ResetWithID(nsIContent* aFromContent, const nsString& aID, bool aWatch) { nsIDocument *doc = aFromContent->GetCurrentDoc(); if (!doc) return; // XXX Need to take care of XBL/XBL2 if (aWatch) { nsCOMPtr<nsIAtom> atom = do_GetAtom(aID); if (!atom) return; atom.swap(mWatchID); } mReferencingImage = false; HaveNewDocument(doc, aWatch, aID); }
void nsReferencedElement::Reset(nsIContent* aFromContent, nsIURI* aURI, bool aWatch, bool aReferenceImage) { NS_ABORT_IF_FALSE(aFromContent, "Reset() expects non-null content pointer"); Unlink(); if (!aURI) return; nsCAutoString refPart; aURI->GetRef(refPart); // Unescape %-escapes in the reference. The result will be in the // origin charset of the URL, hopefully... NS_UnescapeURL(refPart); nsCAutoString charset; aURI->GetOriginCharset(charset); nsAutoString ref; nsresult rv = nsContentUtils::ConvertStringFromCharset(charset, refPart, ref); if (NS_FAILED(rv)) { CopyUTF8toUTF16(refPart, ref); } if (ref.IsEmpty()) return; // Get the current document nsIDocument *doc = aFromContent->GetCurrentDoc(); if (!doc) return; nsIContent* bindingParent = aFromContent->GetBindingParent(); if (bindingParent) { nsXBLBinding* binding = doc->BindingManager()->GetBinding(bindingParent); if (binding) { bool isEqualExceptRef; rv = aURI->EqualsExceptRef(binding->PrototypeBinding()->DocURI(), &isEqualExceptRef); if (NS_SUCCEEDED(rv) && isEqualExceptRef) { // XXX sXBL/XBL2 issue // Our content is an anonymous XBL element from a binding inside the // same document that the referenced URI points to. In order to avoid // the risk of ID collisions we restrict ourselves to anonymous // elements from this binding; specifically, URIs that are relative to // the binding document should resolve to the copy of the target // element that has been inserted into the bound document. // If the URI points to a different document we don't need this // restriction. nsINodeList* anonymousChildren = doc->BindingManager()->GetAnonymousNodesFor(bindingParent); if (anonymousChildren) { PRUint32 length; anonymousChildren->GetLength(&length); for (PRUint32 i = 0; i < length && !mElement; ++i) { mElement = nsContentUtils::MatchElementId(anonymousChildren->GetNodeAt(i), ref); } } // We don't have watching working yet for XBL, so bail out here. return; } } } bool isEqualExceptRef; rv = aURI->EqualsExceptRef(doc->GetDocumentURI(), &isEqualExceptRef); if (NS_FAILED(rv) || !isEqualExceptRef) { nsRefPtr<nsIDocument::ExternalResourceLoad> load; doc = doc->RequestExternalResource(aURI, aFromContent, getter_AddRefs(load)); if (!doc) { if (!load || !aWatch) { // Nothing will ever happen here return; } DocumentLoadNotification* observer = new DocumentLoadNotification(this, ref); mPendingNotification = observer; if (observer) { load->AddObserver(observer); } // Keep going so we set up our watching stuff a bit } } if (aWatch) { nsCOMPtr<nsIAtom> atom = do_GetAtom(ref); if (!atom) return; atom.swap(mWatchID); } mReferencingImage = aReferenceImage; HaveNewDocument(doc, aWatch, ref); }
void nsReferencedElement::Reset(nsIContent* aFromContent, nsIURI* aURI, PRBool aWatch) { Unlink(); nsCOMPtr<nsIURL> url = do_QueryInterface(aURI); if (!url) return; nsCAutoString refPart; url->GetRef(refPart); // Unescape %-escapes in the reference. The result will be in the // origin charset of the URL, hopefully... NS_UnescapeURL(refPart); nsCAutoString charset; url->GetOriginCharset(charset); nsAutoString ref; nsresult rv = nsContentUtils::ConvertStringFromCharset(charset, refPart, ref); if (NS_FAILED(rv)) { CopyUTF8toUTF16(refPart, ref); } if (ref.IsEmpty()) return; // Get the current document nsIDocument *doc = aFromContent->GetCurrentDoc(); if (!doc) return; // This will be the URI of the document the content belongs to // (the URI of the XBL document if the content is anonymous // XBL content) nsCOMPtr<nsIURL> documentURL = do_QueryInterface(doc->GetDocumentURI()); nsIContent* bindingParent = aFromContent->GetBindingParent(); PRBool isXBL = PR_FALSE; if (bindingParent) { nsXBLBinding* binding = doc->BindingManager()->GetBinding(bindingParent); if (binding) { // XXX sXBL/XBL2 issue // If this is an anonymous XBL element then the URI is // relative to the binding document. A full fix requires a // proper XBL2 implementation but for now URIs that are // relative to the binding document should be resolve to the // copy of the target element that has been inserted into the // bound document. documentURL = do_QueryInterface(binding->PrototypeBinding()->DocURI()); isXBL = PR_TRUE; } } if (!documentURL) return; if (!EqualExceptRef(url, documentURL)) { // Don't take the XBL codepath here, since we'll want to just // normally set up our external resource document and then watch // it as needed. isXBL = PR_FALSE; nsRefPtr<nsIDocument::ExternalResourceLoad> load; doc = doc->RequestExternalResource(url, aFromContent, getter_AddRefs(load)); if (!doc) { if (!load || !aWatch) { // Nothing will ever happen here return; } DocumentLoadNotification* observer = new DocumentLoadNotification(this, ref); mPendingNotification = observer; if (observer) { load->AddObserver(observer); } // Keep going so we set up our watching stuff a bit } } // Get the element if (isXBL) { nsCOMPtr<nsIDOMNodeList> anonymousChildren; doc->BindingManager()-> GetAnonymousNodesFor(bindingParent, getter_AddRefs(anonymousChildren)); if (anonymousChildren) { PRUint32 length; anonymousChildren->GetLength(&length); for (PRUint32 i = 0; i < length && !mContent; ++i) { nsCOMPtr<nsIDOMNode> node; anonymousChildren->Item(i, getter_AddRefs(node)); nsCOMPtr<nsIContent> c = do_QueryInterface(node); if (c) { mContent = nsContentUtils::MatchElementId(c, ref); } } } // We don't have watching working yet for XBL, so bail out here. return; } if (aWatch) { nsCOMPtr<nsIAtom> atom = do_GetAtom(ref); if (!atom) return; atom.swap(mWatchID); } HaveNewDocument(doc, aWatch, ref); }