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:
parent
a7dcfefb9f
commit
8c4d394eda
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user