Bugs 27271, 27947. Re-order menu creation so that RDF-generated menus are created simultaneously with XUL content. Use style rather than content tree crawling to avoid over-eager creation of menu content. r=hyatt,danm a=jevering.

git-svn-id: svn://10.0.0.236/trunk@61333 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
waterson%netscape.com 2000-02-19 00:56:13 +00:00
parent a7dcfefb9f
commit 8c4d394eda
7 changed files with 119 additions and 149 deletions

View File

@ -1426,19 +1426,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);
@ -1451,7 +1441,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);
}

View File

@ -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<nsIDocument> 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

View File

@ -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<nsIDocument> 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

View File

@ -1426,19 +1426,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);
@ -1451,7 +1441,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);
}

View File

@ -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<nsIDocument> 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

View File

@ -430,84 +430,48 @@ NS_IMETHODIMP nsContentTreeOwner::ApplyChromeMask()
if(!mXULWindow->mChromeLoaded)
return NS_OK; // We'll do this later when chrome is loaded
nsCOMPtr<nsIDOMElement> domElement;
mXULWindow->GetDOMElementFromDocShell(mXULWindow->mDocShell,
getter_AddRefs(domElement));
NS_ENSURE_TRUE(domElement, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMElement> window;
mXULWindow->GetDOMElementFromDocShell(mXULWindow->mDocShell, getter_AddRefs(window));
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
mXULWindow->mWindow->ShowMenuBar(mChromeMask &
nsIWebBrowserChrome::menuBarOn ?
PR_TRUE : PR_FALSE);
// get a list of this document's elements with the chromeclass attribute specified
nsCOMPtr<nsIDOMXULElement> xulRoot(do_QueryInterface(domElement));
NS_ENSURE_TRUE(xulRoot, NS_ERROR_FAILURE);
// Construct the new value for the 'chromehidden' attribute that
// we'll whack onto the window. We've got style rules in
// navigator.css that trigger visibility based on the
// 'chromehidden' attribute of the <window> tag.
nsAutoString newvalue;
// todo (maybe) the longer, straight DOM (not RDF) version?
nsCOMPtr<nsIDOMNodeList> chromeNodes;
xulRoot->GetElementsByAttribute("chromeclass", "*",
getter_AddRefs(chromeNodes));
NS_ENSURE_TRUE(chromeNodes, NS_ERROR_FAILURE);
if (! (mChromeMask & nsIWebBrowserChrome::menuBarOn)) {
newvalue += "menubar ";
}
if (! (mChromeMask & nsIWebBrowserChrome::toolBarOn)) {
newvalue += "toolbar ";
}
if (! (mChromeMask & nsIWebBrowserChrome::locationBarOn)) {
newvalue += "location ";
}
if (! (mChromeMask & nsIWebBrowserChrome::personalToolBarOn)) {
newvalue += "directories ";
}
if (! (mChromeMask & nsIWebBrowserChrome::statusBarOn)) {
newvalue += "status ";
}
if (! (mChromeMask & nsIWebBrowserChrome::extraChromeOn)) {
newvalue += "extrachrome";
}
PRUint32 nodeCtr;
PRUint32 nodeCount;
// Get the old value, to avoid useless style reflows if we're just
// setting stuff to the exact same thing.
nsAutoString oldvalue;
window->GetAttribute("chromehidden", oldvalue);
chromeNodes->GetLength(&nodeCount);
if (oldvalue != newvalue) {
window->SetAttribute("chromehidden", newvalue);
}
for(nodeCtr = 0; nodeCtr < nodeCount; nodeCtr++)
{
nsCOMPtr<nsIDOMNode> domNode;
chromeNodes->Item(nodeCtr, getter_AddRefs(domNode));
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(domNode));
if(domElement)
{
nsAutoString chromeClass;
PRBool makeChange;
PRUint32 flag;
// show or hide the element according to its chromeclass and the chromemask
domElement->GetAttribute("chromeclass", chromeClass);
makeChange = PR_FALSE;
if(chromeClass == "menubar")
{
makeChange = PR_TRUE;
flag = mChromeMask & nsIWebBrowserChrome::menuBarOn;
}
else if(chromeClass == "toolbar")
{
makeChange = PR_TRUE;
flag = mChromeMask & nsIWebBrowserChrome::toolBarOn;
}
else if(chromeClass == "location")
{
makeChange = PR_TRUE;
flag = mChromeMask & nsIWebBrowserChrome::locationBarOn;
}
else if(chromeClass == "directories")
{
makeChange = PR_TRUE;
flag = mChromeMask & nsIWebBrowserChrome::personalToolBarOn;
}
else if(chromeClass == "status")
{
makeChange = PR_TRUE;
flag = mChromeMask & nsIWebBrowserChrome::statusBarOn;
}
else if(chromeClass == "extrachrome")
{
makeChange = PR_TRUE;
flag = mChromeMask & nsIWebBrowserChrome::extraChromeOn;
}
if(makeChange)
{
if(flag)
domElement->RemoveAttribute("chromehidden");
else
domElement->SetAttribute("chromehidden", "T");
}
}
}
return NS_OK;
}

View File

@ -7,10 +7,37 @@ box#sidebar-parent {
margin-right: 2px;
}
[chromehidden] { /* what to do if chrome requests you be invisible */
/*
* Rules for 'hiding' portions of the chrome for special
* kinds of browser windows.
*/
window[chromehidden~="menubar"] [chromeclass="menubar"] {
display: none;
}
window[chromehidden~="toolbar"] [chromeclass="toolbar"] {
display: none;
}
window[chromehidden~="location"] [chromeclass="location"] {
display: none;
}
window[chromehidden~="directories"] [chromeclass="directories"] {
display: none;
}
window[chromehidden~="status"] [chromeclass="status"] {
display: none;
}
window[chromehidden~="extrachrome"] [chromeclass="extrachrome"] {
display: none;
}
/*
* Images for the main buttons
*/
titledbutton#back-button {
list-style-image:url("chrome://navigator/skin/back.gif");
}