diff --git a/mozilla/content/xul/content/src/nsXULElement.cpp b/mozilla/content/xul/content/src/nsXULElement.cpp index 1d3960ab4bc..4b3ddb7ba48 100644 --- a/mozilla/content/xul/content/src/nsXULElement.cpp +++ b/mozilla/content/xul/content/src/nsXULElement.cpp @@ -1646,7 +1646,7 @@ nsXULElement::EnsureContentsGenerated(void) const return NS_OK; } - return builder->CreateContents(unconstThis); + return builder->CreateContents(unconstThis, PR_FALSE); } } diff --git a/mozilla/content/xul/document/src/nsXULDocument.cpp b/mozilla/content/xul/document/src/nsXULDocument.cpp index dc0d3bed5f4..279f53ee57e 100644 --- a/mozilla/content/xul/document/src/nsXULDocument.cpp +++ b/mozilla/content/xul/document/src/nsXULDocument.cpp @@ -3659,7 +3659,7 @@ nsXULDocument::CreateTemplateBuilder(nsIContent* aElement) } else { // Force construction of immediate template sub-content _now_. - builder->CreateContents(aElement); + builder->CreateContents(aElement, PR_FALSE); } } diff --git a/mozilla/content/xul/templates/public/nsIXULTemplateBuilder.idl b/mozilla/content/xul/templates/public/nsIXULTemplateBuilder.idl index a9635d1f2ae..8e4773eb6f3 100644 --- a/mozilla/content/xul/templates/public/nsIXULTemplateBuilder.idl +++ b/mozilla/content/xul/templates/public/nsIXULTemplateBuilder.idl @@ -42,8 +42,6 @@ #include "domstubs.idl" #include "nsISupports.idl" -#include "nsIRDFCompositeDataSource.idl" -#include "nsIRDFResource.idl" interface nsIAtom; interface nsIContent; @@ -51,6 +49,8 @@ interface nsIXULBuilderListener; interface nsIXULTemplateResult; interface nsIXULTemplateRuleFilter; interface nsIXULTemplateQueryProcessor; +interface nsIRDFResource; +interface nsIRDFCompositeDataSource; /** * A template builder, given an input source of data, a template, and a @@ -158,7 +158,7 @@ interface nsIXULTemplateQueryProcessor; * * See http://wiki.mozilla.org/XUL:Templates_Plan for details about templates. */ -[scriptable, uuid(1762801E-1147-4197-BF0D-D749C903AF74)] +[scriptable, uuid(A583B676-5B02-4F9C-A0C9-CB850CB99818)] interface nsIXULTemplateBuilder : nsISupports { /** @@ -328,10 +328,13 @@ interface nsIXULTemplateBuilder : nsISupports [noscript] void init(in nsIContent aElement); /** - * Invoked lazily by a XUL element that needs its child content - * built. + * Invoked lazily by a XUL element that needs its child content built. + * If aForceCreation is true, then the contents of an element will be + * generated even if it is closed. If false, the element will only + * generate its contents if it is open. This behaviour is used with menus. */ - [noscript] void createContents(in nsIContent aElement); + [noscript] void createContents(in nsIContent aElement, + in boolean aForceCreation); /** * Add a listener to this template builder. The template builder diff --git a/mozilla/content/xul/templates/src/nsXULContentBuilder.cpp b/mozilla/content/xul/templates/src/nsXULContentBuilder.cpp index 32978bed279..15b4f52d351 100644 --- a/mozilla/content/xul/templates/src/nsXULContentBuilder.cpp +++ b/mozilla/content/xul/templates/src/nsXULContentBuilder.cpp @@ -128,7 +128,7 @@ class nsXULContentBuilder : public nsXULTemplateBuilder { public: // nsIXULTemplateBuilder interface - NS_IMETHOD CreateContents(nsIContent* aElement); + NS_IMETHOD CreateContents(nsIContent* aElement, PRBool aForceCreation); NS_IMETHOD HasGeneratedContent(nsIRDFResource* aResource, nsIAtom* aTag, @@ -261,11 +261,13 @@ protected: * was generated. * * @param aElement element to generate content inside + * @param aForceCreation true to force creation for closed items such as menus * @param aContainer container content was added inside * @param aNewIndexInContainer index with container in which content was added */ nsresult CreateTemplateAndContainerContents(nsIContent* aElement, + PRBool aForceCreation, nsIContent** aContainer, PRInt32* aNewIndexInContainer); @@ -275,6 +277,7 @@ protected: * * @param aElement element to generate content inside * @param aResult reference point for query + * @param aForceCreation true to force creation for closed items such as menus * @param aNotify true to notify of DOM changes * @param aContainer container content was added inside * @param aNewIndexInContainer index with container in which content was added @@ -282,6 +285,7 @@ protected: nsresult CreateContainerContents(nsIContent* aElement, nsIXULTemplateResult* aResult, + PRBool aForceCreation, PRBool aNotify, nsIContent** aContainer, PRInt32* aNewIndexInContainer); @@ -853,7 +857,7 @@ nsXULContentBuilder::BuildContentFromTemplate(nsIContent *aTemplateNode, if (NS_FAILED(rv)) return rv; if (isGenerationElement) { - rv = CreateContainerContents(realKid, aChild, PR_FALSE, + rv = CreateContainerContents(realKid, aChild, PR_FALSE, PR_FALSE, nsnull /* don't care */, nsnull /* don't care */); if (NS_FAILED(rv)) return rv; @@ -1099,6 +1103,7 @@ nsXULContentBuilder::RemoveMember(nsIContent* aContent) nsresult nsXULContentBuilder::CreateTemplateAndContainerContents(nsIContent* aElement, + PRBool aForceCreation, nsIContent** aContainer, PRInt32* aNewIndexInContainer) { @@ -1143,8 +1148,8 @@ nsXULContentBuilder::CreateTemplateAndContainerContents(nsIContent* aElement, } if (mRootResult) { - CreateContainerContents(aElement, mRootResult, PR_FALSE, - aContainer, aNewIndexInContainer); + CreateContainerContents(aElement, mRootResult, aForceCreation, + PR_FALSE, aContainer, aNewIndexInContainer); } } else if (!(mFlags & eDontRecurse)) { @@ -1159,8 +1164,8 @@ nsXULContentBuilder::CreateTemplateAndContainerContents(nsIContent* aElement, if (NS_FAILED(rv) || !mayProcessChildren) return rv; - CreateContainerContents(aElement, match->mResult, PR_FALSE, - aContainer, aNewIndexInContainer); + CreateContainerContents(aElement, match->mResult, aForceCreation, + PR_FALSE, aContainer, aNewIndexInContainer); } } @@ -1173,6 +1178,7 @@ nsXULContentBuilder::CreateTemplateAndContainerContents(nsIContent* aElement, nsresult nsXULContentBuilder::CreateContainerContents(nsIContent* aElement, nsIXULTemplateResult* aResult, + PRBool aForceCreation, PRBool aNotify, nsIContent** aContainer, PRInt32* aNewIndexInContainer) @@ -1210,7 +1216,7 @@ nsXULContentBuilder::CreateContainerContents(nsIContent* aElement, // 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 (IsLazyWidgetItem(aElement) && !IsOpen(aElement)) + if (!aForceCreation && IsLazyWidgetItem(aElement) && !IsOpen(aElement)) return NS_OK; // See if the element's templates contents have been generated: @@ -1670,13 +1676,26 @@ nsXULContentBuilder::SetContainerAttrs(nsIContent *aElement, // NS_IMETHODIMP -nsXULContentBuilder::CreateContents(nsIContent* aElement) +nsXULContentBuilder::CreateContents(nsIContent* aElement, PRBool aForceCreation) { NS_PRECONDITION(aElement != nsnull, "null ptr"); if (! aElement) return NS_ERROR_NULL_POINTER; - return CreateTemplateAndContainerContents(aElement, nsnull /* don't care */, nsnull /* don't care */); + nsCOMPtr container; + PRInt32 newIndex; + nsresult rv = CreateTemplateAndContainerContents(aElement, aForceCreation, + getter_AddRefs(container), &newIndex); + NS_ENSURE_SUCCESS(rv, rv); + + // if forcing an element to be created, make sure to notify + if (aForceCreation && container) { + MOZ_AUTO_DOC_UPDATE(container->GetCurrentDoc(), UPDATE_CONTENT_MODEL, + PR_TRUE); + nsNodeUtils::ContentAppended(container, newIndex); + } + + return NS_OK; } NS_IMETHODIMP @@ -2017,7 +2036,8 @@ nsXULContentBuilder::OpenContainer(nsIContent* aElement) // notify layout where content got created. nsCOMPtr container; PRInt32 newIndex; - CreateContainerContents(aElement, result, PR_FALSE, getter_AddRefs(container), &newIndex); + CreateContainerContents(aElement, result, PR_FALSE, + PR_FALSE, getter_AddRefs(container), &newIndex); if (container && IsLazyWidgetItem(aElement)) { // The tree widget is special, and has to be spanked every @@ -2090,7 +2110,7 @@ nsXULContentBuilder::RebuildAll() // contents for the current element... nsCOMPtr container; PRInt32 newIndex; - CreateTemplateAndContainerContents(mRoot, getter_AddRefs(container), &newIndex); + CreateTemplateAndContainerContents(mRoot, PR_FALSE, getter_AddRefs(container), &newIndex); if (container) { MOZ_AUTO_DOC_UPDATE(container->GetCurrentDoc(), UPDATE_CONTENT_MODEL, diff --git a/mozilla/content/xul/templates/src/nsXULTemplateBuilder.cpp b/mozilla/content/xul/templates/src/nsXULTemplateBuilder.cpp index 28afe0132e9..6a8b3ef8773 100644 --- a/mozilla/content/xul/templates/src/nsXULTemplateBuilder.cpp +++ b/mozilla/content/xul/templates/src/nsXULTemplateBuilder.cpp @@ -457,7 +457,7 @@ nsXULTemplateBuilder::Init(nsIContent* aElement) } NS_IMETHODIMP -nsXULTemplateBuilder::CreateContents(nsIContent* aElement) +nsXULTemplateBuilder::CreateContents(nsIContent* aElement, PRBool aForceCreation) { return NS_OK; } diff --git a/mozilla/layout/xul/base/src/Makefile.in b/mozilla/layout/xul/base/src/Makefile.in index 2fe5e770752..4f1c6e900b0 100644 --- a/mozilla/layout/xul/base/src/Makefile.in +++ b/mozilla/layout/xul/base/src/Makefile.in @@ -64,6 +64,7 @@ REQUIRES = xpcom \ unicharutil \ xpconnect \ js \ + xultmpl \ $(NULL) ifdef MOZ_ENABLE_CANVAS diff --git a/mozilla/layout/xul/base/src/nsXULPopupManager.cpp b/mozilla/layout/xul/base/src/nsXULPopupManager.cpp index 4b6aae8bb14..216df6732e7 100644 --- a/mozilla/layout/xul/base/src/nsXULPopupManager.cpp +++ b/mozilla/layout/xul/base/src/nsXULPopupManager.cpp @@ -45,6 +45,8 @@ #include "nsIDOMDocument.h" #include "nsIDOMNSEvent.h" #include "nsIDOMNSUIEvent.h" +#include "nsIDOMXULElement.h" +#include "nsIXULTemplateBuilder.h" #include "nsIPrivateDOMEvent.h" #include "nsEventDispatcher.h" #include "nsEventStateManager.h" @@ -366,6 +368,24 @@ nsXULPopupManager::ShowMenu(nsIContent *aMenu, PRBool aSelectFirstItem, PRBool aAsynchronous) { + // generate any template content first. Otherwise, the menupopup may not + // have been created yet. + if (aMenu) { + nsIContent* element = aMenu; + do { + nsCOMPtr xulelem = do_QueryInterface(element); + if (xulelem) { + nsCOMPtr builder; + xulelem->GetBuilder(getter_AddRefs(builder)); + if (builder) { + builder->CreateContents(aMenu, PR_TRUE); + break; + } + } + element = element->GetParent(); + } while (element); + } + nsMenuFrame* menuFrame = GetMenuFrameForContent(aMenu); if (!menuFrame || !menuFrame->IsMenu()) return; @@ -914,12 +934,6 @@ nsXULPopupManager::FirePopupShowingEvent(nsIContent* aPopup, { nsCOMPtr presShell = aPresContext->PresShell(); - // set the open attribute on the menu first so that templates will generate - // their content before the popupshowing event fires. - if (aMenu) - aMenu->SetAttr(kNameSpaceID_None, nsGkAtoms::open, - NS_LITERAL_STRING("true"), PR_TRUE); - // XXXndeakin (bug 383930) // eventually, the popup events will be a different event type with // additional fields for the anchor node and position and so forth. This diff --git a/mozilla/toolkit/content/xul.css b/mozilla/toolkit/content/xul.css index 610c301a8e4..8e7c043d0b6 100644 --- a/mozilla/toolkit/content/xul.css +++ b/mozilla/toolkit/content/xul.css @@ -277,7 +277,7 @@ menu.menu-iconic { -moz-binding: url("chrome://global/content/bindings/menu.xml#menu-iconic"); } -menu:empty { +menubar > menu:empty { visibility: collapse; }