diff --git a/mozilla/build/mac/build_scripts/MozillaBuildList.pm b/mozilla/build/mac/build_scripts/MozillaBuildList.pm index 73a04c6740c..028e37a4ddd 100644 --- a/mozilla/build/mac/build_scripts/MozillaBuildList.pm +++ b/mozilla/build/mac/build_scripts/MozillaBuildList.pm @@ -167,6 +167,7 @@ sub InstallNonChromeResources() #// my($resource_dir) = "$dist_dir" . "res:"; my($samples_dir) = "$resource_dir" . "samples:"; + my($builtin_dir) = "$resource_dir" . "builtin:"; #// #// Make aliases of resource files @@ -228,6 +229,10 @@ sub InstallNonChromeResources() # QA Menu InstallResources(":mozilla:intl:strres:tests:MANIFEST", "$resource_dir"); + # install builtin XBL bindings + MakeAlias(":mozilla:layout:xbl:builtin:htmlbindings.xml", "$builtin_dir"); + MakeAlias(":mozilla:layout:xbl:builtin:mac:platformHTMLBindings.xml", "$builtin_dir"); + print("--- End Resource copying ----\n"); } diff --git a/mozilla/content/xbl/Makefile.in b/mozilla/content/xbl/Makefile.in index 22edea02654..aa3a9844dec 100644 --- a/mozilla/content/xbl/Makefile.in +++ b/mozilla/content/xbl/Makefile.in @@ -26,7 +26,7 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk -DIRS = public src +DIRS = public src builtin include $(topsrcdir)/config/rules.mk diff --git a/mozilla/content/xbl/public/nsIXBLDocumentInfo.h b/mozilla/content/xbl/public/nsIXBLDocumentInfo.h index d70fdd711da..32f72799530 100644 --- a/mozilla/content/xbl/public/nsIXBLDocumentInfo.h +++ b/mozilla/content/xbl/public/nsIXBLDocumentInfo.h @@ -58,8 +58,8 @@ public: NS_IMETHOD GetDocumentURI(nsCString& aDocURI)=0; - NS_IMETHOD GetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding** aResult)=0; - NS_IMETHOD SetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding* aBinding)=0; + NS_IMETHOD GetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding** aResult)=0; + NS_IMETHOD SetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding* aBinding)=0; }; extern nsresult diff --git a/mozilla/content/xbl/public/nsIXBLPrototypeBinding.h b/mozilla/content/xbl/public/nsIXBLPrototypeBinding.h index 72bcaf7f46f..91c499b884f 100644 --- a/mozilla/content/xbl/public/nsIXBLPrototypeBinding.h +++ b/mozilla/content/xbl/public/nsIXBLPrototypeBinding.h @@ -87,7 +87,7 @@ public: }; extern nsresult -NS_NewXBLPrototypeBinding(const nsCString& aRef, +NS_NewXBLPrototypeBinding(const nsAReadableCString& aRef, nsIContent* aElement, nsIXBLDocumentInfo* aInfo, nsIXBLPrototypeBinding** aResult); diff --git a/mozilla/content/xbl/public/nsIXBLService.h b/mozilla/content/xbl/public/nsIXBLService.h index e169c40ff67..ae82854bfea 100644 --- a/mozilla/content/xbl/public/nsIXBLService.h +++ b/mozilla/content/xbl/public/nsIXBLService.h @@ -79,7 +79,9 @@ public: const nsCString& aURI, const nsCString& aRef, PRBool aForceSyncLoad, nsIXBLDocumentInfo** aResult) = 0; + // Hooks up the global key and DragDrop event handlers to the document root. NS_IMETHOD AttachGlobalKeyHandler(nsIDOMEventReceiver* aElement)=0; + NS_IMETHOD AttachGlobalDragHandler(nsIDOMEventReceiver* aElement)=0; }; #endif // nsIXBLService_h__ diff --git a/mozilla/content/xbl/src/Makefile.in b/mozilla/content/xbl/src/Makefile.in index f339e721ee4..f70f9865d04 100644 --- a/mozilla/content/xbl/src/Makefile.in +++ b/mozilla/content/xbl/src/Makefile.in @@ -34,7 +34,9 @@ CPPSRCS = \ nsXBLBinding.cpp \ nsXBLPrototypeBinding.cpp \ nsXBLEventHandler.cpp \ + nsXBLWindowHandler.cpp \ nsXBLWindowKeyHandler.cpp \ + nsXBLWindowDragHandler.cpp \ nsXBLPrototypeHandler.cpp \ nsXBLFocusHandler.cpp \ nsXBLDragHandler.cpp \ diff --git a/mozilla/content/xbl/src/makefile.win b/mozilla/content/xbl/src/makefile.win index 45b075e8010..23f1f164600 100644 --- a/mozilla/content/xbl/src/makefile.win +++ b/mozilla/content/xbl/src/makefile.win @@ -31,7 +31,9 @@ CPPSRCS= \ nsXBLPrototypeBinding.cpp \ nsXBLService.cpp \ nsXBLEventHandler.cpp \ + nsXBLWindowHandler.cpp \ nsXBLWindowKeyHandler.cpp \ + nsXBLWindowDragHandler.cpp \ nsXBLKeyHandler.cpp \ nsXBLMouseHandler.cpp \ nsXBLMouseMotionHandler.cpp \ @@ -50,7 +52,9 @@ CPP_OBJS= \ .\$(OBJDIR)\nsXBLBinding.obj \ .\$(OBJDIR)\nsXBLPrototypeBinding.obj \ .\$(OBJDIR)\nsXBLEventHandler.obj \ + .\$(OBJDIR)\nsXBLWindowHandler.obj \ .\$(OBJDIR)\nsXBLWindowKeyHandler.obj \ + .\$(OBJDIR)\nsXBLWindowDragHandler.obj \ .\$(OBJDIR)\nsXBLKeyHandler.obj \ .\$(OBJDIR)\nsXBLMouseHandler.obj \ .\$(OBJDIR)\nsXBLMouseMotionHandler.obj \ diff --git a/mozilla/content/xbl/src/nsBindingManager.cpp b/mozilla/content/xbl/src/nsBindingManager.cpp index e1ec4d7598a..f11e16937b3 100644 --- a/mozilla/content/xbl/src/nsBindingManager.cpp +++ b/mozilla/content/xbl/src/nsBindingManager.cpp @@ -83,8 +83,8 @@ public: NS_IMETHOD GetDocumentURI(nsCString& aDocURI) { aDocURI = mDocURI; return NS_OK; }; - NS_IMETHOD GetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding** aResult); - NS_IMETHOD SetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding* aBinding); + NS_IMETHOD GetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding** aResult); + NS_IMETHOD SetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding* aBinding); private: nsCOMPtr mDocument; @@ -150,25 +150,27 @@ nsXBLDocumentInfo::GetRuleProcessors(nsISupportsArray** aResult) } NS_IMETHODIMP -nsXBLDocumentInfo::GetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding** aResult) +nsXBLDocumentInfo::GetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding** aResult) { *aResult = nsnull; if (!mBindingTable) return NS_OK; - nsCStringKey key(aRef); + const char* str = nsPromiseFlatCString(aRef); + nsCStringKey key(str); *aResult = NS_STATIC_CAST(nsIXBLPrototypeBinding*, mBindingTable->Get(&key)); // Addref happens here. return NS_OK; } NS_IMETHODIMP -nsXBLDocumentInfo::SetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding* aBinding) +nsXBLDocumentInfo::SetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding* aBinding) { if (!mBindingTable) mBindingTable = new nsSupportsHashtable(); - nsCStringKey key(aRef); + const char* str = nsPromiseFlatCString(aRef); + nsCStringKey key(str); mBindingTable->Put(&key, aBinding); return NS_OK; diff --git a/mozilla/content/xbl/src/nsXBLPrototypeBinding.cpp b/mozilla/content/xbl/src/nsXBLPrototypeBinding.cpp index 6b9c772958a..311e5727300 100644 --- a/mozilla/content/xbl/src/nsXBLPrototypeBinding.cpp +++ b/mozilla/content/xbl/src/nsXBLPrototypeBinding.cpp @@ -134,7 +134,7 @@ static const PRInt32 kInitialSize = (NS_SIZE_IN_HEAP(sizeof(nsXBLAttributeEntry) NS_IMPL_ISUPPORTS1(nsXBLPrototypeBinding, nsIXBLPrototypeBinding) // Constructors/Destructors -nsXBLPrototypeBinding::nsXBLPrototypeBinding(const nsCString& aID, nsIContent* aElement, +nsXBLPrototypeBinding::nsXBLPrototypeBinding(const nsAReadableCString& aID, nsIContent* aElement, nsIXBLDocumentInfo* aInfo) : mID(aID), mInheritStyle(PR_TRUE), @@ -828,7 +828,7 @@ nsXBLPrototypeBinding::GetNestedChildren(nsIAtom* aTag, nsIContent* aContent, ns // Creation Routine /////////////////////////////////////////////////////////////////////// nsresult -NS_NewXBLPrototypeBinding(const nsCString& aRef, nsIContent* aElement, +NS_NewXBLPrototypeBinding(const nsAReadableCString& aRef, nsIContent* aElement, nsIXBLDocumentInfo* aInfo, nsIXBLPrototypeBinding** aResult) { *aResult = new nsXBLPrototypeBinding(aRef, aElement, aInfo); diff --git a/mozilla/content/xbl/src/nsXBLPrototypeBinding.h b/mozilla/content/xbl/src/nsXBLPrototypeBinding.h index 0c90c4ac9b7..6c1c08cd74d 100644 --- a/mozilla/content/xbl/src/nsXBLPrototypeBinding.h +++ b/mozilla/content/xbl/src/nsXBLPrototypeBinding.h @@ -85,7 +85,7 @@ class nsXBLPrototypeBinding: public nsIXBLPrototypeBinding NS_IMETHOD SetBaseTag(PRInt32 aNamespaceID, nsIAtom* aTag); public: - nsXBLPrototypeBinding(const nsCString& aRef, nsIContent* aElement, + nsXBLPrototypeBinding(const nsAReadableCString& aRef, nsIContent* aElement, nsIXBLDocumentInfo* aInfo); virtual ~nsXBLPrototypeBinding(); diff --git a/mozilla/content/xbl/src/nsXBLPrototypeHandler.cpp b/mozilla/content/xbl/src/nsXBLPrototypeHandler.cpp index 189ae2cb11c..78f06f9c08a 100644 --- a/mozilla/content/xbl/src/nsXBLPrototypeHandler.cpp +++ b/mozilla/content/xbl/src/nsXBLPrototypeHandler.cpp @@ -194,14 +194,14 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver, nsIDOMEven mHandlerElement->GetAttribute(kNameSpaceID_None, kCommandAtom, command); if (!command.IsEmpty()) { - // Make sure the XBL doc is chrome. + // Make sure the XBL doc is chrome or resource // Fix for bug #45989 nsCOMPtr document; mHandlerElement->GetDocument(*getter_AddRefs(document)); nsCOMPtr url = getter_AddRefs(document->GetDocumentURL()); nsXPIDLCString scheme; url->GetScheme(getter_Copies(scheme)); - if (PL_strcmp(scheme, "chrome") != 0) + if (PL_strcmp(scheme, "chrome") != 0 && PL_strcmp(scheme, "resource") != 0) return NS_OK; // We are the default action for this command. diff --git a/mozilla/content/xbl/src/nsXBLService.cpp b/mozilla/content/xbl/src/nsXBLService.cpp index dba82016e00..88ac69cbd8f 100644 --- a/mozilla/content/xbl/src/nsXBLService.cpp +++ b/mozilla/content/xbl/src/nsXBLService.cpp @@ -19,13 +19,16 @@ * * Original Author: David W. Hyatt (hyatt@netscape.com) * - * Contributor(s): Brendan Eich (brendan@mozilla.org) + * Contributor(s): + * - Brendan Eich (brendan@mozilla.org) + * - Mike Pinkerton (pinkerton@netscape.com) */ #include "nsCOMPtr.h" #include "nsXBLService.h" #include "nsIXBLPrototypeHandler.h" #include "nsXBLWindowKeyHandler.h" +#include "nsXBLWindowDragHandler.h" #include "nsIInputStream.h" #include "nsINameSpace.h" #include "nsINameSpaceManager.h" @@ -807,31 +810,40 @@ nsXBLService::GetXBLDocumentInfo(const nsCString& aURLStr, nsIContent* aBoundEle return NS_OK; } + +// +// AttachGlobalKeyHandler +// +// Creates a new key handler and prepares to listen to key events on the given +// event receiver (either a document or an content node). If the receiver is content, +// then extra work needs to be done to hook it up to the document (XXX WHY??) +// NS_IMETHODIMP nsXBLService::AttachGlobalKeyHandler(nsIDOMEventReceiver* aReceiver) { - // Create the key handler + // check if the receiver is a content node (not a document), and hook + // it to the document if that is the case. nsCOMPtr rec = aReceiver; - nsCOMPtr element(do_QueryInterface(aReceiver)); - - if (element) { + nsCOMPtr contentNode(do_QueryInterface(aReceiver)); + if (contentNode) { nsCOMPtr doc; - element->GetDocument(*getter_AddRefs(doc)); + contentNode->GetDocument(*getter_AddRefs(doc)); if (doc) rec = do_QueryInterface(doc); // We're a XUL keyset. Attach to our document. } - + if (!rec) return NS_ERROR_FAILURE; + + nsCOMPtr elt(do_QueryInterface(contentNode)); - nsCOMPtr elt(do_QueryInterface(element)); - + // Create the key handler nsXBLWindowKeyHandler* handler; - NS_NewXBLWindowKeyHandler(elt, rec, &handler); // THis call addrefs us. - + NS_NewXBLWindowKeyHandler(elt, rec, &handler); // This addRef's if (!handler) return NS_ERROR_FAILURE; + // listen to these events rec->AddEventListener(NS_LITERAL_STRING("keydown"), handler, PR_FALSE); rec->AddEventListener(NS_LITERAL_STRING("keyup"), handler, PR_FALSE); rec->AddEventListener(NS_LITERAL_STRING("keypress"), handler, PR_FALSE); @@ -842,6 +854,37 @@ nsXBLService::AttachGlobalKeyHandler(nsIDOMEventReceiver* aReceiver) return NS_OK; } + +// +// AttachGlobalDragDropHandler +// +// Creates a new drag handler and prepares to listen to dragNdrop events on the given +// event receiver. +// +NS_IMETHODIMP +nsXBLService::AttachGlobalDragHandler(nsIDOMEventReceiver* aReceiver) +{ + // Create the DnD handler + nsXBLWindowDragHandler* handler; + NS_NewXBLWindowDragHandler(aReceiver, &handler); + if (!handler) + return NS_ERROR_FAILURE; + + // listen to these events + aReceiver->AddEventListener(NS_LITERAL_STRING("draggesture"), handler, PR_FALSE); + aReceiver->AddEventListener(NS_LITERAL_STRING("dragenter"), handler, PR_FALSE); + aReceiver->AddEventListener(NS_LITERAL_STRING("dragexit"), handler, PR_FALSE); + aReceiver->AddEventListener(NS_LITERAL_STRING("dragover"), handler, PR_FALSE); + aReceiver->AddEventListener(NS_LITERAL_STRING("dragdrop"), handler, PR_FALSE); + + // Release. Do this so that only the event receiver holds onto the handler. + NS_RELEASE(handler); + + return NS_OK; + +} // AttachGlobalDragDropHandler + + NS_IMETHODIMP nsXBLService::Observe(nsISupports* aSubject, const PRUnichar* aTopic, const PRUnichar* aSomeData) { @@ -1353,6 +1396,8 @@ nsXBLService::BuildHandlerChain(nsIContent* aContent, nsIXBLPrototypeHandler** a // Creation Routine /////////////////////////////////////////////////////////////////////// +nsresult NS_NewXBLService(nsIXBLService** aResult); + nsresult NS_NewXBLService(nsIXBLService** aResult) { diff --git a/mozilla/content/xbl/src/nsXBLService.h b/mozilla/content/xbl/src/nsXBLService.h index 293765e06d9..87f545cf032 100644 --- a/mozilla/content/xbl/src/nsXBLService.h +++ b/mozilla/content/xbl/src/nsXBLService.h @@ -19,7 +19,9 @@ * * Original Author: David W. Hyatt (hyatt@netscape.com) * - * Contributor(s): Brendan Eich (brendan@mozilla.org) + * Contributor(s): + * - Brendan Eich (brendan@mozilla.org) + * - Mike Pinkerton (pinkerton@netscape.com) */ ////////////////////////////////////////////////////////////////////////////////////////// @@ -80,6 +82,7 @@ class nsXBLService : public nsIXBLService, public nsIObserver, public nsSupports // Used by XUL key bindings and for window XBL. NS_IMETHOD AttachGlobalKeyHandler(nsIDOMEventReceiver* aElement); + NS_IMETHOD AttachGlobalDragHandler(nsIDOMEventReceiver* aElement); NS_DECL_NSIOBSERVER diff --git a/mozilla/content/xbl/src/nsXBLWindowKeyHandler.cpp b/mozilla/content/xbl/src/nsXBLWindowKeyHandler.cpp index 69ff45d174c..fa331be977b 100644 --- a/mozilla/content/xbl/src/nsXBLWindowKeyHandler.cpp +++ b/mozilla/content/xbl/src/nsXBLWindowKeyHandler.cpp @@ -19,53 +19,37 @@ * * Original Author: David W. Hyatt (hyatt@netscape.com) * + * Contributor(s): + * - Mike Pinkerton (pinkerton@netscape.com) */ #include "nsCOMPtr.h" #include "nsIXBLPrototypeHandler.h" #include "nsXBLWindowKeyHandler.h" -#include "nsIXBLPrototypeBinding.h" #include "nsIContent.h" #include "nsIAtom.h" #include "nsIDOMNSUIEvent.h" #include "nsIDOMKeyEvent.h" #include "nsIDOMEventReceiver.h" -#include "nsIPrivateDOMEvent.h" #include "nsXBLService.h" #include "nsIServiceManager.h" #include "nsHTMLAtoms.h" #include "nsINameSpaceManager.h" #include "nsIXBLDocumentInfo.h" #include "nsIScriptGlobalObject.h" -#include "nsIDOMWindowInternal.h" -#include "nsPIDOMWindow.h" -#include "nsIFocusController.h" -#include "nsIDocShell.h" -#include "nsIPresShell.h" -#include "nsIDOMDocument.h" -#include "nsIDocument.h" #include "nsIDOMElement.h" -#include "nsPIWindowRoot.h" PRUint32 nsXBLWindowKeyHandler::gRefCnt = 0; nsIAtom* nsXBLWindowKeyHandler::kKeyDownAtom = nsnull; nsIAtom* nsXBLWindowKeyHandler::kKeyUpAtom = nsnull; nsIAtom* nsXBLWindowKeyHandler::kKeyPressAtom = nsnull; -struct nsXBLSpecialDocInfo { - nsCOMPtr mHTMLBindings; - nsCOMPtr mPlatformHTMLBindings; - PRBool mFilesPresent; - - nsXBLSpecialDocInfo() :mFilesPresent(PR_TRUE) {}; -}; nsXBLWindowKeyHandler::nsXBLWindowKeyHandler(nsIDOMElement* aElement, nsIDOMEventReceiver* aReceiver) + : nsXBLWindowHandler(aElement, aReceiver) { NS_INIT_ISUPPORTS(); - mElement = aElement; - mReceiver = aReceiver; - mXBLSpecialDocInfo = nsnull; + gRefCnt++; if (gRefCnt == 1) { kKeyUpAtom = NS_NewAtom("keyup"); @@ -76,8 +60,6 @@ nsXBLWindowKeyHandler::nsXBLWindowKeyHandler(nsIDOMElement* aElement, nsIDOMEven nsXBLWindowKeyHandler::~nsXBLWindowKeyHandler() { - delete mXBLSpecialDocInfo; - gRefCnt--; if (gRefCnt == 0) { NS_RELEASE(kKeyUpAtom); @@ -88,186 +70,32 @@ nsXBLWindowKeyHandler::~nsXBLWindowKeyHandler() NS_IMPL_ISUPPORTS1(nsXBLWindowKeyHandler, nsIDOMKeyListener) -PRBool -nsXBLWindowKeyHandler::IsEditor() -{ - nsCOMPtr windowRoot(do_QueryInterface(mReceiver)); - nsCOMPtr focusController; - windowRoot->GetFocusController(getter_AddRefs(focusController)); - if (!focusController) { - NS_WARNING("********* Something went wrong! No focus controller on the root!!!\n"); - return PR_FALSE; - } - - nsCOMPtr focusedWindow; - focusController->GetFocusedWindow(getter_AddRefs(focusedWindow)); - if (!focusedWindow) - return PR_FALSE; - - nsCOMPtr obj(do_QueryInterface(focusedWindow)); - nsCOMPtr docShell; - obj->GetDocShell(getter_AddRefs(docShell)); - nsCOMPtr presShell; - if (docShell) - docShell->GetPresShell(getter_AddRefs(presShell)); - - if (presShell) { - PRBool isEditor; - presShell->GetDisplayNonTextSelection(&isEditor); - return isEditor; - } - - return PR_FALSE; -} - -static void GetHandlers(nsIXBLDocumentInfo* aInfo, const nsCString& aDocURI, - const nsCString& aRef, nsIXBLPrototypeHandler** aResult) -{ - nsCOMPtr binding; - aInfo->GetPrototypeBinding(aRef, getter_AddRefs(binding)); - if (!binding) { - nsCOMPtr doc; - aInfo->GetDocument(getter_AddRefs(doc)); - nsCOMPtr root = getter_AddRefs(doc->GetRootContent()); - PRInt32 childCount; - root->ChildCount(childCount); - for (PRInt32 i = 0; i < childCount; i++) { - nsCOMPtr child; - root->ChildAt(i, *getter_AddRefs(child)); - nsAutoString id; - child->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, id); - if (id.EqualsWithConversion(aRef)) { - NS_NewXBLPrototypeBinding(aRef, child, aInfo, getter_AddRefs(binding)); - aInfo->SetPrototypeBinding(aRef, binding); - break; - } - } - } - - nsCOMPtr dummy; - binding->GetPrototypeHandlers(aResult, getter_AddRefs(dummy)); // Addref happens here. -} +// +// EnsureHandlers +// +// Lazily load the XBL handlers. Overridden to handle being attached +// to a particular element rather than the document +// NS_IMETHODIMP nsXBLWindowKeyHandler::EnsureHandlers() { + nsresult rv = NS_ERROR_FAILURE; + if (mElement) { if (mHandler) return NS_OK; - // Call into the XBL service. nsCOMPtr content(do_QueryInterface(mElement)); nsCOMPtr dummy; - nsXBLService::BuildHandlerChain(content, getter_AddRefs(mHandler), getter_AddRefs(dummy)); + rv = nsXBLService::BuildHandlerChain(content, getter_AddRefs(mHandler), getter_AddRefs(dummy)); } - else { - if (!mXBLSpecialDocInfo) - mXBLSpecialDocInfo = new nsXBLSpecialDocInfo(); - - if (!mXBLSpecialDocInfo) - return NS_ERROR_OUT_OF_MEMORY; - - if (!mXBLSpecialDocInfo->mFilesPresent) - return NS_OK; - - if (!mXBLSpecialDocInfo->mHTMLBindings || !mXBLSpecialDocInfo->mPlatformHTMLBindings) { - nsresult rv; - NS_WITH_SERVICE(nsIXBLService, xblService, "@mozilla.org/xbl;1", &rv); - if (xblService) { - // Obtain the two doc infos we need. - xblService->LoadBindingDocumentInfo(nsnull, nsnull, - nsCAutoString("chrome://global/content/htmlBindings.xml"), - nsCAutoString(""), PR_TRUE, - getter_AddRefs(mXBLSpecialDocInfo->mHTMLBindings)); - xblService->LoadBindingDocumentInfo(nsnull, nsnull, - nsCAutoString("chrome://global/content/platformHTMLBindings.xml"), - nsCAutoString(""), PR_TRUE, - getter_AddRefs(mXBLSpecialDocInfo->mPlatformHTMLBindings)); - - if (!mXBLSpecialDocInfo->mHTMLBindings || !mXBLSpecialDocInfo->mPlatformHTMLBindings) { - mXBLSpecialDocInfo->mFilesPresent = PR_FALSE; - return NS_OK; - } - } - } - - // Now determine which handlers we should be using. - if (IsEditor()) { - GetHandlers(mXBLSpecialDocInfo->mPlatformHTMLBindings, - nsCAutoString("chrome://global/content/platformHTMLBindings.xml"), - nsCAutoString("editor"), - getter_AddRefs(mPlatformHandler)); - GetHandlers(mXBLSpecialDocInfo->mHTMLBindings, - nsCAutoString("chrome://global/content/htmlBindings.xml"), - nsCAutoString("editorBase"), - getter_AddRefs(mHandler)); - } - else { - GetHandlers(mXBLSpecialDocInfo->mPlatformHTMLBindings, - nsCAutoString("chrome://global/content/platformHTMLBindings.xml"), - nsCAutoString("browser"), - getter_AddRefs(mPlatformHandler)); - GetHandlers(mXBLSpecialDocInfo->mHTMLBindings, - nsCAutoString("chrome://global/content/htmlBindings.xml"), - nsCAutoString("browserBase"), - getter_AddRefs(mHandler)); - } - } - - return NS_OK; -} - -NS_IMETHODIMP -nsXBLWindowKeyHandler::WalkHandlersInternal(nsIDOMKeyEvent* aKeyEvent, nsIAtom* aEventType, - nsIXBLPrototypeHandler* aHandler) -{ - nsresult rv; - nsCOMPtr currHandler = aHandler; - while (currHandler) { - - PRBool stopped; - nsCOMPtr privateEvent(do_QueryInterface(aKeyEvent)); - privateEvent->IsDispatchStopped(&stopped); - if (stopped) - return NS_OK; - - PRBool matched = PR_FALSE; - currHandler->KeyEventMatched(aEventType, aKeyEvent, &matched); + else + nsXBLWindowHandler::EnsureHandlers(); - if (matched) { - // Make sure it's not disabled. - nsAutoString disabled; - - nsCOMPtr elt; - currHandler->GetHandlerElement(getter_AddRefs(elt)); - - /*nsAutoString id; - elt->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, id); - nsCAutoString idc; idc.AssignWithConversion(id); - - if (!idc.IsEmpty()) - printf("Key matched with id of: %s\n", (const char*)idc); -*/ - - elt->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::disabled, disabled); - if (!disabled.Equals(NS_LITERAL_STRING("true"))) { - nsCOMPtr rec = mReceiver; - if (mElement) - rec = do_QueryInterface(elt); - rv = currHandler->ExecuteHandler(rec, aKeyEvent); - if (NS_SUCCEEDED(rv)) { - return NS_OK; - } - } - } - - nsCOMPtr nextHandler; - currHandler->GetNextHandler(getter_AddRefs(nextHandler)); - currHandler = nextHandler; - } - - return NS_OK; + return rv; } + NS_IMETHODIMP nsXBLWindowKeyHandler::WalkHandlers(nsIDOMEvent* aKeyEvent, nsIAtom* aEventType) { @@ -277,6 +105,7 @@ nsXBLWindowKeyHandler::WalkHandlers(nsIDOMEvent* aKeyEvent, nsIAtom* aEventType) if (prevent) return NS_OK; + // Make sure our event is really a key event nsCOMPtr keyEvent(do_QueryInterface(aKeyEvent)); if (!keyEvent) return NS_OK; @@ -284,13 +113,13 @@ nsXBLWindowKeyHandler::WalkHandlers(nsIDOMEvent* aKeyEvent, nsIAtom* aEventType) EnsureHandlers(); if (!mElement) { - WalkHandlersInternal(keyEvent, aEventType, mPlatformHandler); + WalkHandlersInternal(aKeyEvent, aEventType, mPlatformHandler); evt->GetPreventDefault(&prevent); if (prevent) return NS_OK; // Handled by the platform. Our work here is done. } - WalkHandlersInternal(keyEvent, aEventType, mHandler); + WalkHandlersInternal(aKeyEvent, aEventType, mHandler); return NS_OK; } @@ -309,6 +138,25 @@ nsresult nsXBLWindowKeyHandler::KeyPress(nsIDOMEvent* aKeyEvent) { return WalkHandlers(aKeyEvent, kKeyPressAtom); } + + +// +// EventMatched +// +// See if the given handler cares about this particular key event +// +PRBool +nsXBLWindowKeyHandler :: EventMatched ( nsIXBLPrototypeHandler* inHandler, nsIAtom* inEventType, nsIDOMEvent* inEvent ) +{ + PRBool matched = PR_FALSE; + + nsCOMPtr keyEvent ( do_QueryInterface(inEvent) ); + if ( keyEvent ) + inHandler->KeyEventMatched(inEventType, keyEvent, &matched); + + return matched; +} + /////////////////////////////////////////////////////////////////////////////////// diff --git a/mozilla/content/xbl/src/nsXBLWindowKeyHandler.h b/mozilla/content/xbl/src/nsXBLWindowKeyHandler.h index ca333168d11..7ac6d62abef 100644 --- a/mozilla/content/xbl/src/nsXBLWindowKeyHandler.h +++ b/mozilla/content/xbl/src/nsXBLWindowKeyHandler.h @@ -20,6 +20,7 @@ * Original Author: David W. Hyatt (hyatt@netscape.com) * * Contributor(s): + * - Mike Pinkerton (pinkerton@netscape.com) */ #ifndef nsXBLWindowKeyHandler_h__ @@ -27,12 +28,12 @@ #include "nsIDOMKeyListener.h" #include "nsIDOMElement.h" +#include "nsXBLWindowHandler.h" class nsIAtom; class nsIDOMEventReceiver; -struct nsXBLSpecialDocInfo; -class nsXBLWindowKeyHandler : public nsIDOMKeyListener +class nsXBLWindowKeyHandler : public nsIDOMKeyListener, public nsXBLWindowHandler { public: nsXBLWindowKeyHandler(nsIDOMElement* aElement, nsIDOMEventReceiver* aReceiver); @@ -40,7 +41,6 @@ public: // nsIDOMetc. virtual nsresult HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; }; - virtual nsresult KeyUp(nsIDOMEvent* aKeyEvent); virtual nsresult KeyDown(nsIDOMEvent* aKeyEvent); virtual nsresult KeyPress(nsIDOMEvent* aKeyEvent); @@ -48,28 +48,25 @@ public: NS_DECL_ISUPPORTS protected: + NS_IMETHOD WalkHandlers(nsIDOMEvent* aKeyEvent, nsIAtom* aEventType); - NS_IMETHOD WalkHandlersInternal(nsIDOMKeyEvent* aKeyEvent, nsIAtom* aEventType, - nsIXBLPrototypeHandler* aHandler); - NS_IMETHOD EnsureHandlers(); - - PRBool IsEditor(); + // lazily load the handlers. Overridden to handle being attached + // to a particular element rather than the document + virtual nsresult EnsureHandlers(); + + // check if the given handler cares about the given key event + PRBool EventMatched ( nsIXBLPrototypeHandler* inHandler, nsIAtom* inEventType, + nsIDOMEvent* inEvent ) ; + // We need our own refcount (even though our base class has one) because + // we have our own statics that need to be initialized and the creation of + // other subclasses would cause us to miss things if we shared the counter. static PRUint32 gRefCnt; static nsIAtom* kKeyUpAtom; static nsIAtom* kKeyDownAtom; static nsIAtom* kKeyPressAtom; -protected: - // Members - nsIDOMElement* mElement; - nsCOMPtr mHandler; - nsCOMPtr mPlatformHandler; - - nsXBLSpecialDocInfo* mXBLSpecialDocInfo; - - nsIDOMEventReceiver* mReceiver; }; extern nsresult diff --git a/mozilla/dom/src/base/nsGlobalWindow.cpp b/mozilla/dom/src/base/nsGlobalWindow.cpp index 9248bc9a621..9eee16e1f1b 100644 --- a/mozilla/dom/src/base/nsGlobalWindow.cpp +++ b/mozilla/dom/src/base/nsGlobalWindow.cpp @@ -315,6 +315,7 @@ NS_IMETHODIMP GlobalWindowImpl::SetNewDocument(nsIDOMDocument* aDocument) if (xblService) { nsCOMPtr rec(do_QueryInterface(mChromeEventHandler)); xblService->AttachGlobalKeyHandler(rec); + xblService->AttachGlobalDragHandler(rec); } } } diff --git a/mozilla/layout/html/document/src/html.css b/mozilla/layout/html/document/src/html.css index eba7152fd2e..d4d5210dde6 100644 --- a/mozilla/layout/html/document/src/html.css +++ b/mozilla/layout/html/document/src/html.css @@ -429,7 +429,7 @@ input { vertical-align: bottom; -moz-box-sizing: border-box; -moz-user-focus: normal; - -moz-binding: url("chrome://global/content/platformHTMLBindings.xml#inputFields"); + -moz-binding: url("resource:///res/builtin/platformHTMLBindings.xml#inputFields"); } textarea { @@ -442,7 +442,7 @@ textarea { vertical-align: bottom; -moz-box-sizing: border-box; -moz-user-focus: normal; - -moz-binding: url("chrome://global/content/platformHTMLBindings.xml#textAreas"); + -moz-binding: url("resource:///res/builtin/platformHTMLBindings.xml#textAreas"); } :-moz-singleline-textcontrol-frame { diff --git a/mozilla/layout/macbuild/layout.mcp b/mozilla/layout/macbuild/layout.mcp index 92911265767..ad74d984c0a 100644 Binary files a/mozilla/layout/macbuild/layout.mcp and b/mozilla/layout/macbuild/layout.mcp differ diff --git a/mozilla/layout/style/html.css b/mozilla/layout/style/html.css index eba7152fd2e..d4d5210dde6 100644 --- a/mozilla/layout/style/html.css +++ b/mozilla/layout/style/html.css @@ -429,7 +429,7 @@ input { vertical-align: bottom; -moz-box-sizing: border-box; -moz-user-focus: normal; - -moz-binding: url("chrome://global/content/platformHTMLBindings.xml#inputFields"); + -moz-binding: url("resource:///res/builtin/platformHTMLBindings.xml#inputFields"); } textarea { @@ -442,7 +442,7 @@ textarea { vertical-align: bottom; -moz-box-sizing: border-box; -moz-user-focus: normal; - -moz-binding: url("chrome://global/content/platformHTMLBindings.xml#textAreas"); + -moz-binding: url("resource:///res/builtin/platformHTMLBindings.xml#textAreas"); } :-moz-singleline-textcontrol-frame { diff --git a/mozilla/layout/xbl/Makefile.in b/mozilla/layout/xbl/Makefile.in index 22edea02654..aa3a9844dec 100644 --- a/mozilla/layout/xbl/Makefile.in +++ b/mozilla/layout/xbl/Makefile.in @@ -26,7 +26,7 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk -DIRS = public src +DIRS = public src builtin include $(topsrcdir)/config/rules.mk diff --git a/mozilla/layout/xbl/public/nsIXBLDocumentInfo.h b/mozilla/layout/xbl/public/nsIXBLDocumentInfo.h index d70fdd711da..32f72799530 100644 --- a/mozilla/layout/xbl/public/nsIXBLDocumentInfo.h +++ b/mozilla/layout/xbl/public/nsIXBLDocumentInfo.h @@ -58,8 +58,8 @@ public: NS_IMETHOD GetDocumentURI(nsCString& aDocURI)=0; - NS_IMETHOD GetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding** aResult)=0; - NS_IMETHOD SetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding* aBinding)=0; + NS_IMETHOD GetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding** aResult)=0; + NS_IMETHOD SetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding* aBinding)=0; }; extern nsresult diff --git a/mozilla/layout/xbl/public/nsIXBLPrototypeBinding.h b/mozilla/layout/xbl/public/nsIXBLPrototypeBinding.h index 72bcaf7f46f..91c499b884f 100644 --- a/mozilla/layout/xbl/public/nsIXBLPrototypeBinding.h +++ b/mozilla/layout/xbl/public/nsIXBLPrototypeBinding.h @@ -87,7 +87,7 @@ public: }; extern nsresult -NS_NewXBLPrototypeBinding(const nsCString& aRef, +NS_NewXBLPrototypeBinding(const nsAReadableCString& aRef, nsIContent* aElement, nsIXBLDocumentInfo* aInfo, nsIXBLPrototypeBinding** aResult); diff --git a/mozilla/layout/xbl/public/nsIXBLService.h b/mozilla/layout/xbl/public/nsIXBLService.h index e169c40ff67..ae82854bfea 100644 --- a/mozilla/layout/xbl/public/nsIXBLService.h +++ b/mozilla/layout/xbl/public/nsIXBLService.h @@ -79,7 +79,9 @@ public: const nsCString& aURI, const nsCString& aRef, PRBool aForceSyncLoad, nsIXBLDocumentInfo** aResult) = 0; + // Hooks up the global key and DragDrop event handlers to the document root. NS_IMETHOD AttachGlobalKeyHandler(nsIDOMEventReceiver* aElement)=0; + NS_IMETHOD AttachGlobalDragHandler(nsIDOMEventReceiver* aElement)=0; }; #endif // nsIXBLService_h__ diff --git a/mozilla/layout/xbl/src/Makefile.in b/mozilla/layout/xbl/src/Makefile.in index f339e721ee4..f70f9865d04 100644 --- a/mozilla/layout/xbl/src/Makefile.in +++ b/mozilla/layout/xbl/src/Makefile.in @@ -34,7 +34,9 @@ CPPSRCS = \ nsXBLBinding.cpp \ nsXBLPrototypeBinding.cpp \ nsXBLEventHandler.cpp \ + nsXBLWindowHandler.cpp \ nsXBLWindowKeyHandler.cpp \ + nsXBLWindowDragHandler.cpp \ nsXBLPrototypeHandler.cpp \ nsXBLFocusHandler.cpp \ nsXBLDragHandler.cpp \ diff --git a/mozilla/layout/xbl/src/makefile.win b/mozilla/layout/xbl/src/makefile.win index 45b075e8010..23f1f164600 100644 --- a/mozilla/layout/xbl/src/makefile.win +++ b/mozilla/layout/xbl/src/makefile.win @@ -31,7 +31,9 @@ CPPSRCS= \ nsXBLPrototypeBinding.cpp \ nsXBLService.cpp \ nsXBLEventHandler.cpp \ + nsXBLWindowHandler.cpp \ nsXBLWindowKeyHandler.cpp \ + nsXBLWindowDragHandler.cpp \ nsXBLKeyHandler.cpp \ nsXBLMouseHandler.cpp \ nsXBLMouseMotionHandler.cpp \ @@ -50,7 +52,9 @@ CPP_OBJS= \ .\$(OBJDIR)\nsXBLBinding.obj \ .\$(OBJDIR)\nsXBLPrototypeBinding.obj \ .\$(OBJDIR)\nsXBLEventHandler.obj \ + .\$(OBJDIR)\nsXBLWindowHandler.obj \ .\$(OBJDIR)\nsXBLWindowKeyHandler.obj \ + .\$(OBJDIR)\nsXBLWindowDragHandler.obj \ .\$(OBJDIR)\nsXBLKeyHandler.obj \ .\$(OBJDIR)\nsXBLMouseHandler.obj \ .\$(OBJDIR)\nsXBLMouseMotionHandler.obj \ diff --git a/mozilla/layout/xbl/src/nsBindingManager.cpp b/mozilla/layout/xbl/src/nsBindingManager.cpp index e1ec4d7598a..f11e16937b3 100644 --- a/mozilla/layout/xbl/src/nsBindingManager.cpp +++ b/mozilla/layout/xbl/src/nsBindingManager.cpp @@ -83,8 +83,8 @@ public: NS_IMETHOD GetDocumentURI(nsCString& aDocURI) { aDocURI = mDocURI; return NS_OK; }; - NS_IMETHOD GetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding** aResult); - NS_IMETHOD SetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding* aBinding); + NS_IMETHOD GetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding** aResult); + NS_IMETHOD SetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding* aBinding); private: nsCOMPtr mDocument; @@ -150,25 +150,27 @@ nsXBLDocumentInfo::GetRuleProcessors(nsISupportsArray** aResult) } NS_IMETHODIMP -nsXBLDocumentInfo::GetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding** aResult) +nsXBLDocumentInfo::GetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding** aResult) { *aResult = nsnull; if (!mBindingTable) return NS_OK; - nsCStringKey key(aRef); + const char* str = nsPromiseFlatCString(aRef); + nsCStringKey key(str); *aResult = NS_STATIC_CAST(nsIXBLPrototypeBinding*, mBindingTable->Get(&key)); // Addref happens here. return NS_OK; } NS_IMETHODIMP -nsXBLDocumentInfo::SetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding* aBinding) +nsXBLDocumentInfo::SetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding* aBinding) { if (!mBindingTable) mBindingTable = new nsSupportsHashtable(); - nsCStringKey key(aRef); + const char* str = nsPromiseFlatCString(aRef); + nsCStringKey key(str); mBindingTable->Put(&key, aBinding); return NS_OK; diff --git a/mozilla/layout/xbl/src/nsXBLPrototypeBinding.cpp b/mozilla/layout/xbl/src/nsXBLPrototypeBinding.cpp index 6b9c772958a..311e5727300 100644 --- a/mozilla/layout/xbl/src/nsXBLPrototypeBinding.cpp +++ b/mozilla/layout/xbl/src/nsXBLPrototypeBinding.cpp @@ -134,7 +134,7 @@ static const PRInt32 kInitialSize = (NS_SIZE_IN_HEAP(sizeof(nsXBLAttributeEntry) NS_IMPL_ISUPPORTS1(nsXBLPrototypeBinding, nsIXBLPrototypeBinding) // Constructors/Destructors -nsXBLPrototypeBinding::nsXBLPrototypeBinding(const nsCString& aID, nsIContent* aElement, +nsXBLPrototypeBinding::nsXBLPrototypeBinding(const nsAReadableCString& aID, nsIContent* aElement, nsIXBLDocumentInfo* aInfo) : mID(aID), mInheritStyle(PR_TRUE), @@ -828,7 +828,7 @@ nsXBLPrototypeBinding::GetNestedChildren(nsIAtom* aTag, nsIContent* aContent, ns // Creation Routine /////////////////////////////////////////////////////////////////////// nsresult -NS_NewXBLPrototypeBinding(const nsCString& aRef, nsIContent* aElement, +NS_NewXBLPrototypeBinding(const nsAReadableCString& aRef, nsIContent* aElement, nsIXBLDocumentInfo* aInfo, nsIXBLPrototypeBinding** aResult) { *aResult = new nsXBLPrototypeBinding(aRef, aElement, aInfo); diff --git a/mozilla/layout/xbl/src/nsXBLPrototypeBinding.h b/mozilla/layout/xbl/src/nsXBLPrototypeBinding.h index 0c90c4ac9b7..6c1c08cd74d 100644 --- a/mozilla/layout/xbl/src/nsXBLPrototypeBinding.h +++ b/mozilla/layout/xbl/src/nsXBLPrototypeBinding.h @@ -85,7 +85,7 @@ class nsXBLPrototypeBinding: public nsIXBLPrototypeBinding NS_IMETHOD SetBaseTag(PRInt32 aNamespaceID, nsIAtom* aTag); public: - nsXBLPrototypeBinding(const nsCString& aRef, nsIContent* aElement, + nsXBLPrototypeBinding(const nsAReadableCString& aRef, nsIContent* aElement, nsIXBLDocumentInfo* aInfo); virtual ~nsXBLPrototypeBinding(); diff --git a/mozilla/layout/xbl/src/nsXBLPrototypeHandler.cpp b/mozilla/layout/xbl/src/nsXBLPrototypeHandler.cpp index 189ae2cb11c..78f06f9c08a 100644 --- a/mozilla/layout/xbl/src/nsXBLPrototypeHandler.cpp +++ b/mozilla/layout/xbl/src/nsXBLPrototypeHandler.cpp @@ -194,14 +194,14 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver, nsIDOMEven mHandlerElement->GetAttribute(kNameSpaceID_None, kCommandAtom, command); if (!command.IsEmpty()) { - // Make sure the XBL doc is chrome. + // Make sure the XBL doc is chrome or resource // Fix for bug #45989 nsCOMPtr document; mHandlerElement->GetDocument(*getter_AddRefs(document)); nsCOMPtr url = getter_AddRefs(document->GetDocumentURL()); nsXPIDLCString scheme; url->GetScheme(getter_Copies(scheme)); - if (PL_strcmp(scheme, "chrome") != 0) + if (PL_strcmp(scheme, "chrome") != 0 && PL_strcmp(scheme, "resource") != 0) return NS_OK; // We are the default action for this command. diff --git a/mozilla/layout/xbl/src/nsXBLService.cpp b/mozilla/layout/xbl/src/nsXBLService.cpp index dba82016e00..88ac69cbd8f 100644 --- a/mozilla/layout/xbl/src/nsXBLService.cpp +++ b/mozilla/layout/xbl/src/nsXBLService.cpp @@ -19,13 +19,16 @@ * * Original Author: David W. Hyatt (hyatt@netscape.com) * - * Contributor(s): Brendan Eich (brendan@mozilla.org) + * Contributor(s): + * - Brendan Eich (brendan@mozilla.org) + * - Mike Pinkerton (pinkerton@netscape.com) */ #include "nsCOMPtr.h" #include "nsXBLService.h" #include "nsIXBLPrototypeHandler.h" #include "nsXBLWindowKeyHandler.h" +#include "nsXBLWindowDragHandler.h" #include "nsIInputStream.h" #include "nsINameSpace.h" #include "nsINameSpaceManager.h" @@ -807,31 +810,40 @@ nsXBLService::GetXBLDocumentInfo(const nsCString& aURLStr, nsIContent* aBoundEle return NS_OK; } + +// +// AttachGlobalKeyHandler +// +// Creates a new key handler and prepares to listen to key events on the given +// event receiver (either a document or an content node). If the receiver is content, +// then extra work needs to be done to hook it up to the document (XXX WHY??) +// NS_IMETHODIMP nsXBLService::AttachGlobalKeyHandler(nsIDOMEventReceiver* aReceiver) { - // Create the key handler + // check if the receiver is a content node (not a document), and hook + // it to the document if that is the case. nsCOMPtr rec = aReceiver; - nsCOMPtr element(do_QueryInterface(aReceiver)); - - if (element) { + nsCOMPtr contentNode(do_QueryInterface(aReceiver)); + if (contentNode) { nsCOMPtr doc; - element->GetDocument(*getter_AddRefs(doc)); + contentNode->GetDocument(*getter_AddRefs(doc)); if (doc) rec = do_QueryInterface(doc); // We're a XUL keyset. Attach to our document. } - + if (!rec) return NS_ERROR_FAILURE; + + nsCOMPtr elt(do_QueryInterface(contentNode)); - nsCOMPtr elt(do_QueryInterface(element)); - + // Create the key handler nsXBLWindowKeyHandler* handler; - NS_NewXBLWindowKeyHandler(elt, rec, &handler); // THis call addrefs us. - + NS_NewXBLWindowKeyHandler(elt, rec, &handler); // This addRef's if (!handler) return NS_ERROR_FAILURE; + // listen to these events rec->AddEventListener(NS_LITERAL_STRING("keydown"), handler, PR_FALSE); rec->AddEventListener(NS_LITERAL_STRING("keyup"), handler, PR_FALSE); rec->AddEventListener(NS_LITERAL_STRING("keypress"), handler, PR_FALSE); @@ -842,6 +854,37 @@ nsXBLService::AttachGlobalKeyHandler(nsIDOMEventReceiver* aReceiver) return NS_OK; } + +// +// AttachGlobalDragDropHandler +// +// Creates a new drag handler and prepares to listen to dragNdrop events on the given +// event receiver. +// +NS_IMETHODIMP +nsXBLService::AttachGlobalDragHandler(nsIDOMEventReceiver* aReceiver) +{ + // Create the DnD handler + nsXBLWindowDragHandler* handler; + NS_NewXBLWindowDragHandler(aReceiver, &handler); + if (!handler) + return NS_ERROR_FAILURE; + + // listen to these events + aReceiver->AddEventListener(NS_LITERAL_STRING("draggesture"), handler, PR_FALSE); + aReceiver->AddEventListener(NS_LITERAL_STRING("dragenter"), handler, PR_FALSE); + aReceiver->AddEventListener(NS_LITERAL_STRING("dragexit"), handler, PR_FALSE); + aReceiver->AddEventListener(NS_LITERAL_STRING("dragover"), handler, PR_FALSE); + aReceiver->AddEventListener(NS_LITERAL_STRING("dragdrop"), handler, PR_FALSE); + + // Release. Do this so that only the event receiver holds onto the handler. + NS_RELEASE(handler); + + return NS_OK; + +} // AttachGlobalDragDropHandler + + NS_IMETHODIMP nsXBLService::Observe(nsISupports* aSubject, const PRUnichar* aTopic, const PRUnichar* aSomeData) { @@ -1353,6 +1396,8 @@ nsXBLService::BuildHandlerChain(nsIContent* aContent, nsIXBLPrototypeHandler** a // Creation Routine /////////////////////////////////////////////////////////////////////// +nsresult NS_NewXBLService(nsIXBLService** aResult); + nsresult NS_NewXBLService(nsIXBLService** aResult) { diff --git a/mozilla/layout/xbl/src/nsXBLService.h b/mozilla/layout/xbl/src/nsXBLService.h index 293765e06d9..87f545cf032 100644 --- a/mozilla/layout/xbl/src/nsXBLService.h +++ b/mozilla/layout/xbl/src/nsXBLService.h @@ -19,7 +19,9 @@ * * Original Author: David W. Hyatt (hyatt@netscape.com) * - * Contributor(s): Brendan Eich (brendan@mozilla.org) + * Contributor(s): + * - Brendan Eich (brendan@mozilla.org) + * - Mike Pinkerton (pinkerton@netscape.com) */ ////////////////////////////////////////////////////////////////////////////////////////// @@ -80,6 +82,7 @@ class nsXBLService : public nsIXBLService, public nsIObserver, public nsSupports // Used by XUL key bindings and for window XBL. NS_IMETHOD AttachGlobalKeyHandler(nsIDOMEventReceiver* aElement); + NS_IMETHOD AttachGlobalDragHandler(nsIDOMEventReceiver* aElement); NS_DECL_NSIOBSERVER diff --git a/mozilla/layout/xbl/src/nsXBLWindowKeyHandler.cpp b/mozilla/layout/xbl/src/nsXBLWindowKeyHandler.cpp index 69ff45d174c..fa331be977b 100644 --- a/mozilla/layout/xbl/src/nsXBLWindowKeyHandler.cpp +++ b/mozilla/layout/xbl/src/nsXBLWindowKeyHandler.cpp @@ -19,53 +19,37 @@ * * Original Author: David W. Hyatt (hyatt@netscape.com) * + * Contributor(s): + * - Mike Pinkerton (pinkerton@netscape.com) */ #include "nsCOMPtr.h" #include "nsIXBLPrototypeHandler.h" #include "nsXBLWindowKeyHandler.h" -#include "nsIXBLPrototypeBinding.h" #include "nsIContent.h" #include "nsIAtom.h" #include "nsIDOMNSUIEvent.h" #include "nsIDOMKeyEvent.h" #include "nsIDOMEventReceiver.h" -#include "nsIPrivateDOMEvent.h" #include "nsXBLService.h" #include "nsIServiceManager.h" #include "nsHTMLAtoms.h" #include "nsINameSpaceManager.h" #include "nsIXBLDocumentInfo.h" #include "nsIScriptGlobalObject.h" -#include "nsIDOMWindowInternal.h" -#include "nsPIDOMWindow.h" -#include "nsIFocusController.h" -#include "nsIDocShell.h" -#include "nsIPresShell.h" -#include "nsIDOMDocument.h" -#include "nsIDocument.h" #include "nsIDOMElement.h" -#include "nsPIWindowRoot.h" PRUint32 nsXBLWindowKeyHandler::gRefCnt = 0; nsIAtom* nsXBLWindowKeyHandler::kKeyDownAtom = nsnull; nsIAtom* nsXBLWindowKeyHandler::kKeyUpAtom = nsnull; nsIAtom* nsXBLWindowKeyHandler::kKeyPressAtom = nsnull; -struct nsXBLSpecialDocInfo { - nsCOMPtr mHTMLBindings; - nsCOMPtr mPlatformHTMLBindings; - PRBool mFilesPresent; - - nsXBLSpecialDocInfo() :mFilesPresent(PR_TRUE) {}; -}; nsXBLWindowKeyHandler::nsXBLWindowKeyHandler(nsIDOMElement* aElement, nsIDOMEventReceiver* aReceiver) + : nsXBLWindowHandler(aElement, aReceiver) { NS_INIT_ISUPPORTS(); - mElement = aElement; - mReceiver = aReceiver; - mXBLSpecialDocInfo = nsnull; + gRefCnt++; if (gRefCnt == 1) { kKeyUpAtom = NS_NewAtom("keyup"); @@ -76,8 +60,6 @@ nsXBLWindowKeyHandler::nsXBLWindowKeyHandler(nsIDOMElement* aElement, nsIDOMEven nsXBLWindowKeyHandler::~nsXBLWindowKeyHandler() { - delete mXBLSpecialDocInfo; - gRefCnt--; if (gRefCnt == 0) { NS_RELEASE(kKeyUpAtom); @@ -88,186 +70,32 @@ nsXBLWindowKeyHandler::~nsXBLWindowKeyHandler() NS_IMPL_ISUPPORTS1(nsXBLWindowKeyHandler, nsIDOMKeyListener) -PRBool -nsXBLWindowKeyHandler::IsEditor() -{ - nsCOMPtr windowRoot(do_QueryInterface(mReceiver)); - nsCOMPtr focusController; - windowRoot->GetFocusController(getter_AddRefs(focusController)); - if (!focusController) { - NS_WARNING("********* Something went wrong! No focus controller on the root!!!\n"); - return PR_FALSE; - } - - nsCOMPtr focusedWindow; - focusController->GetFocusedWindow(getter_AddRefs(focusedWindow)); - if (!focusedWindow) - return PR_FALSE; - - nsCOMPtr obj(do_QueryInterface(focusedWindow)); - nsCOMPtr docShell; - obj->GetDocShell(getter_AddRefs(docShell)); - nsCOMPtr presShell; - if (docShell) - docShell->GetPresShell(getter_AddRefs(presShell)); - - if (presShell) { - PRBool isEditor; - presShell->GetDisplayNonTextSelection(&isEditor); - return isEditor; - } - - return PR_FALSE; -} - -static void GetHandlers(nsIXBLDocumentInfo* aInfo, const nsCString& aDocURI, - const nsCString& aRef, nsIXBLPrototypeHandler** aResult) -{ - nsCOMPtr binding; - aInfo->GetPrototypeBinding(aRef, getter_AddRefs(binding)); - if (!binding) { - nsCOMPtr doc; - aInfo->GetDocument(getter_AddRefs(doc)); - nsCOMPtr root = getter_AddRefs(doc->GetRootContent()); - PRInt32 childCount; - root->ChildCount(childCount); - for (PRInt32 i = 0; i < childCount; i++) { - nsCOMPtr child; - root->ChildAt(i, *getter_AddRefs(child)); - nsAutoString id; - child->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, id); - if (id.EqualsWithConversion(aRef)) { - NS_NewXBLPrototypeBinding(aRef, child, aInfo, getter_AddRefs(binding)); - aInfo->SetPrototypeBinding(aRef, binding); - break; - } - } - } - - nsCOMPtr dummy; - binding->GetPrototypeHandlers(aResult, getter_AddRefs(dummy)); // Addref happens here. -} +// +// EnsureHandlers +// +// Lazily load the XBL handlers. Overridden to handle being attached +// to a particular element rather than the document +// NS_IMETHODIMP nsXBLWindowKeyHandler::EnsureHandlers() { + nsresult rv = NS_ERROR_FAILURE; + if (mElement) { if (mHandler) return NS_OK; - // Call into the XBL service. nsCOMPtr content(do_QueryInterface(mElement)); nsCOMPtr dummy; - nsXBLService::BuildHandlerChain(content, getter_AddRefs(mHandler), getter_AddRefs(dummy)); + rv = nsXBLService::BuildHandlerChain(content, getter_AddRefs(mHandler), getter_AddRefs(dummy)); } - else { - if (!mXBLSpecialDocInfo) - mXBLSpecialDocInfo = new nsXBLSpecialDocInfo(); - - if (!mXBLSpecialDocInfo) - return NS_ERROR_OUT_OF_MEMORY; - - if (!mXBLSpecialDocInfo->mFilesPresent) - return NS_OK; - - if (!mXBLSpecialDocInfo->mHTMLBindings || !mXBLSpecialDocInfo->mPlatformHTMLBindings) { - nsresult rv; - NS_WITH_SERVICE(nsIXBLService, xblService, "@mozilla.org/xbl;1", &rv); - if (xblService) { - // Obtain the two doc infos we need. - xblService->LoadBindingDocumentInfo(nsnull, nsnull, - nsCAutoString("chrome://global/content/htmlBindings.xml"), - nsCAutoString(""), PR_TRUE, - getter_AddRefs(mXBLSpecialDocInfo->mHTMLBindings)); - xblService->LoadBindingDocumentInfo(nsnull, nsnull, - nsCAutoString("chrome://global/content/platformHTMLBindings.xml"), - nsCAutoString(""), PR_TRUE, - getter_AddRefs(mXBLSpecialDocInfo->mPlatformHTMLBindings)); - - if (!mXBLSpecialDocInfo->mHTMLBindings || !mXBLSpecialDocInfo->mPlatformHTMLBindings) { - mXBLSpecialDocInfo->mFilesPresent = PR_FALSE; - return NS_OK; - } - } - } - - // Now determine which handlers we should be using. - if (IsEditor()) { - GetHandlers(mXBLSpecialDocInfo->mPlatformHTMLBindings, - nsCAutoString("chrome://global/content/platformHTMLBindings.xml"), - nsCAutoString("editor"), - getter_AddRefs(mPlatformHandler)); - GetHandlers(mXBLSpecialDocInfo->mHTMLBindings, - nsCAutoString("chrome://global/content/htmlBindings.xml"), - nsCAutoString("editorBase"), - getter_AddRefs(mHandler)); - } - else { - GetHandlers(mXBLSpecialDocInfo->mPlatformHTMLBindings, - nsCAutoString("chrome://global/content/platformHTMLBindings.xml"), - nsCAutoString("browser"), - getter_AddRefs(mPlatformHandler)); - GetHandlers(mXBLSpecialDocInfo->mHTMLBindings, - nsCAutoString("chrome://global/content/htmlBindings.xml"), - nsCAutoString("browserBase"), - getter_AddRefs(mHandler)); - } - } - - return NS_OK; -} - -NS_IMETHODIMP -nsXBLWindowKeyHandler::WalkHandlersInternal(nsIDOMKeyEvent* aKeyEvent, nsIAtom* aEventType, - nsIXBLPrototypeHandler* aHandler) -{ - nsresult rv; - nsCOMPtr currHandler = aHandler; - while (currHandler) { - - PRBool stopped; - nsCOMPtr privateEvent(do_QueryInterface(aKeyEvent)); - privateEvent->IsDispatchStopped(&stopped); - if (stopped) - return NS_OK; - - PRBool matched = PR_FALSE; - currHandler->KeyEventMatched(aEventType, aKeyEvent, &matched); + else + nsXBLWindowHandler::EnsureHandlers(); - if (matched) { - // Make sure it's not disabled. - nsAutoString disabled; - - nsCOMPtr elt; - currHandler->GetHandlerElement(getter_AddRefs(elt)); - - /*nsAutoString id; - elt->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, id); - nsCAutoString idc; idc.AssignWithConversion(id); - - if (!idc.IsEmpty()) - printf("Key matched with id of: %s\n", (const char*)idc); -*/ - - elt->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::disabled, disabled); - if (!disabled.Equals(NS_LITERAL_STRING("true"))) { - nsCOMPtr rec = mReceiver; - if (mElement) - rec = do_QueryInterface(elt); - rv = currHandler->ExecuteHandler(rec, aKeyEvent); - if (NS_SUCCEEDED(rv)) { - return NS_OK; - } - } - } - - nsCOMPtr nextHandler; - currHandler->GetNextHandler(getter_AddRefs(nextHandler)); - currHandler = nextHandler; - } - - return NS_OK; + return rv; } + NS_IMETHODIMP nsXBLWindowKeyHandler::WalkHandlers(nsIDOMEvent* aKeyEvent, nsIAtom* aEventType) { @@ -277,6 +105,7 @@ nsXBLWindowKeyHandler::WalkHandlers(nsIDOMEvent* aKeyEvent, nsIAtom* aEventType) if (prevent) return NS_OK; + // Make sure our event is really a key event nsCOMPtr keyEvent(do_QueryInterface(aKeyEvent)); if (!keyEvent) return NS_OK; @@ -284,13 +113,13 @@ nsXBLWindowKeyHandler::WalkHandlers(nsIDOMEvent* aKeyEvent, nsIAtom* aEventType) EnsureHandlers(); if (!mElement) { - WalkHandlersInternal(keyEvent, aEventType, mPlatformHandler); + WalkHandlersInternal(aKeyEvent, aEventType, mPlatformHandler); evt->GetPreventDefault(&prevent); if (prevent) return NS_OK; // Handled by the platform. Our work here is done. } - WalkHandlersInternal(keyEvent, aEventType, mHandler); + WalkHandlersInternal(aKeyEvent, aEventType, mHandler); return NS_OK; } @@ -309,6 +138,25 @@ nsresult nsXBLWindowKeyHandler::KeyPress(nsIDOMEvent* aKeyEvent) { return WalkHandlers(aKeyEvent, kKeyPressAtom); } + + +// +// EventMatched +// +// See if the given handler cares about this particular key event +// +PRBool +nsXBLWindowKeyHandler :: EventMatched ( nsIXBLPrototypeHandler* inHandler, nsIAtom* inEventType, nsIDOMEvent* inEvent ) +{ + PRBool matched = PR_FALSE; + + nsCOMPtr keyEvent ( do_QueryInterface(inEvent) ); + if ( keyEvent ) + inHandler->KeyEventMatched(inEventType, keyEvent, &matched); + + return matched; +} + /////////////////////////////////////////////////////////////////////////////////// diff --git a/mozilla/layout/xbl/src/nsXBLWindowKeyHandler.h b/mozilla/layout/xbl/src/nsXBLWindowKeyHandler.h index ca333168d11..7ac6d62abef 100644 --- a/mozilla/layout/xbl/src/nsXBLWindowKeyHandler.h +++ b/mozilla/layout/xbl/src/nsXBLWindowKeyHandler.h @@ -20,6 +20,7 @@ * Original Author: David W. Hyatt (hyatt@netscape.com) * * Contributor(s): + * - Mike Pinkerton (pinkerton@netscape.com) */ #ifndef nsXBLWindowKeyHandler_h__ @@ -27,12 +28,12 @@ #include "nsIDOMKeyListener.h" #include "nsIDOMElement.h" +#include "nsXBLWindowHandler.h" class nsIAtom; class nsIDOMEventReceiver; -struct nsXBLSpecialDocInfo; -class nsXBLWindowKeyHandler : public nsIDOMKeyListener +class nsXBLWindowKeyHandler : public nsIDOMKeyListener, public nsXBLWindowHandler { public: nsXBLWindowKeyHandler(nsIDOMElement* aElement, nsIDOMEventReceiver* aReceiver); @@ -40,7 +41,6 @@ public: // nsIDOMetc. virtual nsresult HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; }; - virtual nsresult KeyUp(nsIDOMEvent* aKeyEvent); virtual nsresult KeyDown(nsIDOMEvent* aKeyEvent); virtual nsresult KeyPress(nsIDOMEvent* aKeyEvent); @@ -48,28 +48,25 @@ public: NS_DECL_ISUPPORTS protected: + NS_IMETHOD WalkHandlers(nsIDOMEvent* aKeyEvent, nsIAtom* aEventType); - NS_IMETHOD WalkHandlersInternal(nsIDOMKeyEvent* aKeyEvent, nsIAtom* aEventType, - nsIXBLPrototypeHandler* aHandler); - NS_IMETHOD EnsureHandlers(); - - PRBool IsEditor(); + // lazily load the handlers. Overridden to handle being attached + // to a particular element rather than the document + virtual nsresult EnsureHandlers(); + + // check if the given handler cares about the given key event + PRBool EventMatched ( nsIXBLPrototypeHandler* inHandler, nsIAtom* inEventType, + nsIDOMEvent* inEvent ) ; + // We need our own refcount (even though our base class has one) because + // we have our own statics that need to be initialized and the creation of + // other subclasses would cause us to miss things if we shared the counter. static PRUint32 gRefCnt; static nsIAtom* kKeyUpAtom; static nsIAtom* kKeyDownAtom; static nsIAtom* kKeyPressAtom; -protected: - // Members - nsIDOMElement* mElement; - nsCOMPtr mHandler; - nsCOMPtr mPlatformHandler; - - nsXBLSpecialDocInfo* mXBLSpecialDocInfo; - - nsIDOMEventReceiver* mReceiver; }; extern nsresult