From 21c4ae46b3293029ac3eecf3a06eb1f8127a0899 Mon Sep 17 00:00:00 2001 From: "waterson%netscape.com" Date: Wed, 16 Feb 2000 07:36:35 +0000 Subject: [PATCH] Bugs 27947, 27271. Re-order content-model-to-layout notification to avoid an incremental reflow. This ensures that 1) all menus will be completely created before they are displayed, and 2) the 'oncreate' handler runs after RDF content has been generated. r=hyatt --- content/xul/document/src/nsXULDocument.cpp | 31 ++++++++++--------- .../templates/src/nsXULTemplateBuilder.cpp | 25 +++++---------- rdf/content/src/nsRDFGenericBuilder.cpp | 25 +++++---------- rdf/content/src/nsXULDocument.cpp | 31 ++++++++++--------- rdf/content/src/nsXULTemplateBuilder.cpp | 25 +++++---------- 5 files changed, 58 insertions(+), 79 deletions(-) diff --git a/content/xul/document/src/nsXULDocument.cpp b/content/xul/document/src/nsXULDocument.cpp index d1eaabc5e9dd..0cbc85cbacea 100644 --- a/content/xul/document/src/nsXULDocument.cpp +++ b/content/xul/document/src/nsXULDocument.cpp @@ -1416,19 +1416,9 @@ nsXULDocument::AttributeChanged(nsIContent* aElement, if (NS_FAILED(rv)) return rv; } - // Now notify external observers - for (PRInt32 i = 0; i < mObservers.Count(); i++) { - nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; - observer->AttributeChanged(this, aElement, aNameSpaceID, aAttribute, aHint); - if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) { - i--; - } - } - - // Handle "special" cases. We do this handling _after_ we've - // notified the observer to ensure that any frames that are - // caching information (e.g., the tree widget and the 'open' - // attribute) will notice things properly. + // Handle "open" and "close" cases. We do this handling before + // we've notified the observer, so that content is already created + // for the frame system to walk. if ((nameSpaceID == kNameSpaceID_XUL) && (aAttribute == kOpenAtom)) { nsAutoString open; rv = aElement->GetAttribute(kNameSpaceID_None, kOpenAtom, open); @@ -1441,7 +1431,20 @@ nsXULDocument::AttributeChanged(nsIContent* aElement, CloseWidgetItem(aElement); } } - else if (aAttribute == kRefAtom) { + + // Now notify external observers + for (PRInt32 i = 0; i < mObservers.Count(); i++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; + observer->AttributeChanged(this, aElement, aNameSpaceID, aAttribute, aHint); + if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) { + i--; + } + } + + // Check for a change to the 'ref' attribute on an atom, in which + // case we may need to nuke and rebuild the entire content model + // beneath the element. + if (aAttribute == kRefAtom) { RebuildWidgetItem(aElement); } diff --git a/content/xul/templates/src/nsXULTemplateBuilder.cpp b/content/xul/templates/src/nsXULTemplateBuilder.cpp index 946b7a636ae8..a9aa2bf9d8ee 100644 --- a/content/xul/templates/src/nsXULTemplateBuilder.cpp +++ b/content/xul/templates/src/nsXULTemplateBuilder.cpp @@ -771,7 +771,9 @@ RDFGenericBuilderImpl::OpenContainer(nsIContent* aElement) rv = CreateContainerContents(aElement, resource, PR_FALSE, getter_AddRefs(container), &newIndex); if (NS_FAILED(rv)) return rv; - if (container) { + if (container && IsTreeWidgetItem(aElement)) { + // The tree widget is special, and has to be spanked every + // time we add content to a container. nsCOMPtr doc = do_QueryInterface(mDocument); if (! doc) return NS_ERROR_UNEXPECTED; @@ -2462,22 +2464,11 @@ RDFGenericBuilderImpl::CreateContainerContents(nsIContent* aElement, *aNewIndexInContainer = -1; } - // If it's XUL, then see if the item is even "open" (HTML content - // must be generated eagerly). If not, then just pretend it - // doesn't have _any_ contents. We check this _before_ checking - // the contents-generated attribute so that we don't eagerly set - // contents-generated on a closed node. - { - PRInt32 nameSpaceID; - rv = aElement->GetNameSpaceID(nameSpaceID); - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get namespace ID"); - if (NS_FAILED(rv)) return rv; - - if (nameSpaceID == kNameSpaceID_XUL) { - if (! IsOpen(aElement)) - return NS_OK; - } - } + // The tree widget is special. If the item isn't open, then just + // "pretend" that there aren't any contents here. We'll create + // them when OpenContainer() gets called. + if (IsTreeWidgetItem(aElement) && !IsOpen(aElement)) + return NS_OK; // See if the element's templates contents have been generated: // this prevents a re-entrant call from triggering another diff --git a/rdf/content/src/nsRDFGenericBuilder.cpp b/rdf/content/src/nsRDFGenericBuilder.cpp index 946b7a636ae8..a9aa2bf9d8ee 100644 --- a/rdf/content/src/nsRDFGenericBuilder.cpp +++ b/rdf/content/src/nsRDFGenericBuilder.cpp @@ -771,7 +771,9 @@ RDFGenericBuilderImpl::OpenContainer(nsIContent* aElement) rv = CreateContainerContents(aElement, resource, PR_FALSE, getter_AddRefs(container), &newIndex); if (NS_FAILED(rv)) return rv; - if (container) { + if (container && IsTreeWidgetItem(aElement)) { + // The tree widget is special, and has to be spanked every + // time we add content to a container. nsCOMPtr doc = do_QueryInterface(mDocument); if (! doc) return NS_ERROR_UNEXPECTED; @@ -2462,22 +2464,11 @@ RDFGenericBuilderImpl::CreateContainerContents(nsIContent* aElement, *aNewIndexInContainer = -1; } - // If it's XUL, then see if the item is even "open" (HTML content - // must be generated eagerly). If not, then just pretend it - // doesn't have _any_ contents. We check this _before_ checking - // the contents-generated attribute so that we don't eagerly set - // contents-generated on a closed node. - { - PRInt32 nameSpaceID; - rv = aElement->GetNameSpaceID(nameSpaceID); - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get namespace ID"); - if (NS_FAILED(rv)) return rv; - - if (nameSpaceID == kNameSpaceID_XUL) { - if (! IsOpen(aElement)) - return NS_OK; - } - } + // The tree widget is special. If the item isn't open, then just + // "pretend" that there aren't any contents here. We'll create + // them when OpenContainer() gets called. + if (IsTreeWidgetItem(aElement) && !IsOpen(aElement)) + return NS_OK; // See if the element's templates contents have been generated: // this prevents a re-entrant call from triggering another diff --git a/rdf/content/src/nsXULDocument.cpp b/rdf/content/src/nsXULDocument.cpp index d1eaabc5e9dd..0cbc85cbacea 100644 --- a/rdf/content/src/nsXULDocument.cpp +++ b/rdf/content/src/nsXULDocument.cpp @@ -1416,19 +1416,9 @@ nsXULDocument::AttributeChanged(nsIContent* aElement, if (NS_FAILED(rv)) return rv; } - // Now notify external observers - for (PRInt32 i = 0; i < mObservers.Count(); i++) { - nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; - observer->AttributeChanged(this, aElement, aNameSpaceID, aAttribute, aHint); - if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) { - i--; - } - } - - // Handle "special" cases. We do this handling _after_ we've - // notified the observer to ensure that any frames that are - // caching information (e.g., the tree widget and the 'open' - // attribute) will notice things properly. + // Handle "open" and "close" cases. We do this handling before + // we've notified the observer, so that content is already created + // for the frame system to walk. if ((nameSpaceID == kNameSpaceID_XUL) && (aAttribute == kOpenAtom)) { nsAutoString open; rv = aElement->GetAttribute(kNameSpaceID_None, kOpenAtom, open); @@ -1441,7 +1431,20 @@ nsXULDocument::AttributeChanged(nsIContent* aElement, CloseWidgetItem(aElement); } } - else if (aAttribute == kRefAtom) { + + // Now notify external observers + for (PRInt32 i = 0; i < mObservers.Count(); i++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; + observer->AttributeChanged(this, aElement, aNameSpaceID, aAttribute, aHint); + if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) { + i--; + } + } + + // Check for a change to the 'ref' attribute on an atom, in which + // case we may need to nuke and rebuild the entire content model + // beneath the element. + if (aAttribute == kRefAtom) { RebuildWidgetItem(aElement); } diff --git a/rdf/content/src/nsXULTemplateBuilder.cpp b/rdf/content/src/nsXULTemplateBuilder.cpp index 946b7a636ae8..a9aa2bf9d8ee 100644 --- a/rdf/content/src/nsXULTemplateBuilder.cpp +++ b/rdf/content/src/nsXULTemplateBuilder.cpp @@ -771,7 +771,9 @@ RDFGenericBuilderImpl::OpenContainer(nsIContent* aElement) rv = CreateContainerContents(aElement, resource, PR_FALSE, getter_AddRefs(container), &newIndex); if (NS_FAILED(rv)) return rv; - if (container) { + if (container && IsTreeWidgetItem(aElement)) { + // The tree widget is special, and has to be spanked every + // time we add content to a container. nsCOMPtr doc = do_QueryInterface(mDocument); if (! doc) return NS_ERROR_UNEXPECTED; @@ -2462,22 +2464,11 @@ RDFGenericBuilderImpl::CreateContainerContents(nsIContent* aElement, *aNewIndexInContainer = -1; } - // If it's XUL, then see if the item is even "open" (HTML content - // must be generated eagerly). If not, then just pretend it - // doesn't have _any_ contents. We check this _before_ checking - // the contents-generated attribute so that we don't eagerly set - // contents-generated on a closed node. - { - PRInt32 nameSpaceID; - rv = aElement->GetNameSpaceID(nameSpaceID); - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get namespace ID"); - if (NS_FAILED(rv)) return rv; - - if (nameSpaceID == kNameSpaceID_XUL) { - if (! IsOpen(aElement)) - return NS_OK; - } - } + // The tree widget is special. If the item isn't open, then just + // "pretend" that there aren't any contents here. We'll create + // them when OpenContainer() gets called. + if (IsTreeWidgetItem(aElement) && !IsOpen(aElement)) + return NS_OK; // See if the element's templates contents have been generated: // this prevents a re-entrant call from triggering another