From 58190bba57e56f615b0992c76d8d85334dea4af0 Mon Sep 17 00:00:00 2001 From: "dr%netscape.com" Date: Wed, 18 Apr 2001 06:06:31 +0000 Subject: [PATCH] 64313 (Implement cmd_copyLink, cmd_copyImageLocation, cmd_copyImageContents). Implement the commands, hook them up in the navigator and mailnews frontends, provide hooks for embedding. r=hyatt, sr=waterson git-svn-id: svn://10.0.0.236/trunk@92667 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/base/src/nsDocumentViewer.cpp | 244 ++++++++++- .../xul/document/src/nsXULDocument.cpp | 63 ++- .../content/xul/document/src/nsXULDocument.h | 36 +- .../docshell/base/nsIContentViewerEdit.idl | 10 +- mozilla/dom/public/base/nsIFocusController.h | 5 + mozilla/dom/src/base/nsFocusController.cpp | 25 ++ mozilla/dom/src/base/nsFocusController.h | 5 + mozilla/dom/src/base/nsGlobalWindow.cpp | 185 ++++++--- mozilla/dom/src/base/nsGlobalWindow.h | 7 +- .../webBrowser/nsDocShellTreeOwner.cpp | 24 +- .../browser/webBrowser/nsDocShellTreeOwner.h | 8 +- mozilla/layout/base/nsDocumentViewer.cpp | 244 ++++++++++- mozilla/layout/base/nsIPresShell.h | 16 +- mozilla/layout/base/nsPresShell.cpp | 173 +++++++- mozilla/layout/base/public/nsIPresShell.h | 16 +- mozilla/layout/html/base/src/nsPresShell.cpp | 173 +++++++- .../resources/content/mailWindowOverlay.xul | 7 +- .../plugin/base/src/nsPluginViewer.cpp | 38 +- .../modules/plugin/nglsrc/nsPluginViewer.cpp | 38 +- .../resources/content/navigatorOverlay.xul | 7 +- .../content/contentAreaContextOverlay.xul | 4 +- .../resources/content/nsContextMenu.js | 55 +-- .../resources/content/utilityOverlay.js | 2 +- .../resources/content/utilityOverlay.xul | 393 +++++++++++------- 24 files changed, 1449 insertions(+), 329 deletions(-) diff --git a/mozilla/content/base/src/nsDocumentViewer.cpp b/mozilla/content/base/src/nsDocumentViewer.cpp index 2bcb69e06a6..59a4919b25e 100644 --- a/mozilla/content/base/src/nsDocumentViewer.cpp +++ b/mozilla/content/base/src/nsDocumentViewer.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 0 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file @@ -17,8 +17,10 @@ * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * - * Contributor(s): + * Contributor(s): + * Dan Rosen */ + #include "nslayout.h" #include "nsCOMPtr.h" #include "nsCRT.h" @@ -81,6 +83,8 @@ #include "nsIFrameManager.h" #include "nsIParser.h" #include "nsIPrintContext.h" +#include "nsIDOMHTMLAnchorElement.h" +#include "nsIDOMHTMLImageElement.h" #include "nsIChromeRegistry.h" @@ -187,10 +191,10 @@ class nsPagePrintTimer; // a small delegate class used to avoid circular references #ifdef XP_MAC -#pragma mark ** nsDocViwerSelectionListener ** +#pragma mark ** nsDocViewerSelectionListener ** #endif -class nsDocViwerSelectionListener : public nsISelectionListener +class nsDocViewerSelectionListener : public nsISelectionListener { public: @@ -200,7 +204,7 @@ public: // nsISelectionListerner interface NS_DECL_NSISELECTIONLISTENER - nsDocViwerSelectionListener() + nsDocViewerSelectionListener() : mDocViewer(NULL) , mGotSelectionState(PR_FALSE) , mSelectionWasCollapsed(PR_FALSE) @@ -208,7 +212,7 @@ public: NS_INIT_REFCNT(); } - virtual ~nsDocViwerSelectionListener() {} + virtual ~nsDocViewerSelectionListener() {} nsresult Init(DocumentViewerImpl *aDocViewer); @@ -346,7 +350,7 @@ class DocumentViewerImpl : public nsIDocumentViewer, public nsIMarkupDocumentViewer, public nsIImageGroupObserver { - friend class nsDocViwerSelectionListener; + friend class nsDocViewerSelectionListener; public: DocumentViewerImpl(); @@ -429,6 +433,11 @@ private: PRPackedBool& aDoesContainFrameset); PRBool IsWindowsInOurSubTree(nsIDOMWindowInternal * aDOMWindow); + + nsresult GetPopupNode(nsIDOMNode** aNode); + nsresult GetPopupLinkNode(nsIDOMNode** aNode); + nsresult GetPopupImageNode(nsIDOMNode** aNode); + //--------------------------------------------------------------------- void BuildDocTree(nsIDocShellTreeNode * aParentNode, nsVoidArray * aDocList, @@ -965,8 +974,8 @@ DocumentViewerImpl::Init(nsIWidget* aParentWidget, // now register ourselves as a selection listener, so that we get called // when the selection changes in the window - nsDocViwerSelectionListener *selectionListener; - NS_NEWXPCOM(selectionListener, nsDocViwerSelectionListener); + nsDocViewerSelectionListener *selectionListener; + NS_NEWXPCOM(selectionListener, nsDocViewerSelectionListener); if (!selectionListener) return NS_ERROR_OUT_OF_MEMORY; selectionListener->Init(this); @@ -3870,10 +3879,42 @@ NS_IMETHODIMP DocumentViewerImpl::SelectAll() NS_IMETHODIMP DocumentViewerImpl::CopySelection() { - if (!mPresShell) return NS_ERROR_NOT_INITIALIZED; + NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED); return mPresShell->DoCopy(); } +NS_IMETHODIMP DocumentViewerImpl::CopyLinkLocation() +{ + NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED); + nsCOMPtr node; + nsresult rv = GetPopupLinkNode(getter_AddRefs(node)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(node, NS_ERROR_FAILURE); + return mPresShell->DoCopyLinkLocation(node); +} + +NS_IMETHODIMP DocumentViewerImpl::CopyImageLocation() +{ + NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED); + nsCOMPtr node; + nsresult rv = GetPopupImageNode(getter_AddRefs(node)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(node, NS_ERROR_FAILURE); + NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED); + return mPresShell->DoCopyImageLocation(node); +} + +NS_IMETHODIMP DocumentViewerImpl::CopyImageContents() +{ + NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED); + nsCOMPtr node; + nsresult rv = GetPopupImageNode(getter_AddRefs(node)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(node, NS_ERROR_FAILURE); + NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED); + return mPresShell->DoCopyImageContents(node); +} + NS_IMETHODIMP DocumentViewerImpl::GetCopyable(PRBool *aCopyable) { nsCOMPtr selection; @@ -4856,16 +4897,193 @@ NS_IMETHODIMP DocumentViewerImpl::SizeToContent() #pragma mark - #endif -NS_IMPL_ISUPPORTS(nsDocViwerSelectionListener, NS_GET_IID(nsISelectionListener)); +NS_IMPL_ISUPPORTS(nsDocViewerSelectionListener, NS_GET_IID(nsISelectionListener)); -nsresult nsDocViwerSelectionListener::Init(DocumentViewerImpl *aDocViewer) +nsresult nsDocViewerSelectionListener::Init(DocumentViewerImpl *aDocViewer) { mDocViewer = aDocViewer; return NS_OK; } +/* + * GetPopupNode, GetPopupLinkNode and GetPopupImageNode are helpers + * for the cmd_copyLink / cmd_copyImageLocation / cmd_copyImageContents family + * of commands. The focus controller stores the popup node, these retrieve + * them and munge appropriately. Note that we have to store the popup node + * rather than retrieving it from EventStateManager::GetFocusedContent because + * not all content (images included) can receive focus. + */ -NS_IMETHODIMP nsDocViwerSelectionListener::NotifySelectionChanged(nsIDOMDocument *, nsISelection *, short) +nsresult +DocumentViewerImpl::GetPopupNode(nsIDOMNode** aNode) +{ + NS_ENSURE_ARG_POINTER(aNode); + + nsresult rv; + + // get the document + nsCOMPtr document; + rv = GetDocument(*getter_AddRefs(document)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(document, NS_ERROR_FAILURE); + + // get the script global object + nsCOMPtr global; + rv = document->GetScriptGlobalObject(getter_AddRefs(global)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(global, NS_ERROR_FAILURE); + + // get the internal dom window + nsCOMPtr internalWin(do_QueryInterface(global, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(internalWin, NS_ERROR_FAILURE); + + // get the private dom window + nsCOMPtr privateWin(do_QueryInterface(internalWin, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(privateWin, NS_ERROR_FAILURE); + + // get the focus controller + nsCOMPtr focusController; + rv = privateWin->GetRootFocusController(getter_AddRefs(focusController)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(focusController, NS_ERROR_FAILURE); + + // get the popup node + rv = focusController->GetPopupNode(aNode); // addref happens here + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(*aNode, NS_ERROR_FAILURE); + + return rv; +} + +/* + * XXX dr + * ------ + * Note: the args to these two methods are DOM nodes and not specifically + * HTML anchor or image nodes because a link can also be an xlink, and an + * image can also be an object... The impls are broken right now to just + * think about HTML anchors and images but consumers of these methods should + * do their own checking. + */ + +nsresult +DocumentViewerImpl::GetPopupLinkNode(nsIDOMNode** aNode) +{ + NS_ENSURE_ARG_POINTER(aNode); + + // you get null unless i say so + *aNode = nsnull; + + // find popup node + nsCOMPtr node; + nsresult rv = GetPopupNode(getter_AddRefs(node)); + NS_ENSURE_SUCCESS(rv, rv); + + // find out if we have an anchor in our ancestry. this really ought + // to look for xlinks also, but this is good enough for now. + while (node) { + + // are we an anchor? + nsCOMPtr anchor(do_QueryInterface(node, &rv)); + if (NS_SUCCEEDED(rv) && anchor) { + *aNode = node; + NS_IF_ADDREF(*aNode); // addref + return NS_OK; + } + else { + // if not, get our parent and keep trying... + nsCOMPtr parentNode; + node->GetParentNode(getter_AddRefs(parentNode)); + node = parentNode; + } + } + + // if we have no node, fail + return NS_ERROR_FAILURE; +} + +nsresult +DocumentViewerImpl::GetPopupImageNode(nsIDOMNode** aNode) +{ + NS_ENSURE_ARG_POINTER(aNode); + + // you get null unless i say so + *aNode = nsnull; + + // find popup node + nsCOMPtr node; + nsresult rv = GetPopupNode(getter_AddRefs(node)); + NS_ENSURE_SUCCESS(rv, rv); + + // find out if we're an image. this really ought to look for objects + // with type "image/...", but this is good enough for now. + nsCOMPtr img(do_QueryInterface(node, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(img, NS_ERROR_FAILURE); + + // if we made it here, we're an image. + *aNode = node; + NS_IF_ADDREF(*aNode); // addref + return NS_OK; +} + +/* + * XXX dr + * ------ + * These two functions -- GetInLink and GetInImage -- are kind of annoying + * in that they only get called from the controller (in + * nsDOMWindowController::IsCommandEnabled). The actual construction of the + * context menus in communicator (nsContextMenu.js) has its own, redundant + * tests. No big deal, but good to keep in mind if we ever clean context + * menus. + */ + +NS_IMETHODIMP DocumentViewerImpl::GetInLink(PRBool* aInLink) +{ +#ifdef DEBUG_dr + printf("dr :: DocumentViewerImpl::GetInLink\n"); +#endif + + NS_ENSURE_ARG_POINTER(aInLink); + + // we're not in a link unless i say so + *aInLink = PR_FALSE; + + // get the popup link + nsCOMPtr node; + nsresult rv = GetPopupLinkNode(getter_AddRefs(node)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(node, NS_ERROR_FAILURE); + + // if we made it here, we're in a link + *aInLink = PR_TRUE; + return NS_OK; +} + +NS_IMETHODIMP DocumentViewerImpl::GetInImage(PRBool* aInImage) +{ +#ifdef DEBUG_dr + printf("dr :: DocumentViewerImpl::GetInImage\n"); +#endif + + NS_ENSURE_ARG_POINTER(aInImage); + + // we're not in an image unless i say so + *aInImage = PR_FALSE; + + // get the popup image + nsCOMPtr node; + nsresult rv = GetPopupImageNode(getter_AddRefs(node)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(node, NS_ERROR_FAILURE); + + // if we made it here, we're in an image + *aInImage = PR_TRUE; + return NS_OK; +} + +NS_IMETHODIMP nsDocViewerSelectionListener::NotifySelectionChanged(nsIDOMDocument *, nsISelection *, short) { NS_ASSERTION(mDocViewer, "Should have doc viewer!"); diff --git a/mozilla/content/xul/document/src/nsXULDocument.cpp b/mozilla/content/xul/document/src/nsXULDocument.cpp index 4594c20aea9..ae2ecf418c4 100644 --- a/mozilla/content/xul/document/src/nsXULDocument.cpp +++ b/mozilla/content/xul/document/src/nsXULDocument.cpp @@ -23,6 +23,7 @@ * Contributor(s): * Ben Goodger * Pete Collins + * Dan Rosen */ /* @@ -116,6 +117,7 @@ #include "nsRDFDOMNodeList.h" #include "nsXPIDLString.h" #include "nsIDOMWindowInternal.h" +#include "nsPIDOMWindow.h" #include "nsXULCommandDispatcher.h" #include "nsXULDocument.h" #include "nsXULElement.h" @@ -2840,16 +2842,41 @@ nsXULDocument::SetDir(const nsAReadableString& aDirection) NS_IMETHODIMP nsXULDocument::GetPopupNode(nsIDOMNode** aNode) { - *aNode = mPopupNode; - NS_IF_ADDREF(*aNode); - return NS_OK; +#ifdef DEBUG_dr + printf("dr :: nsXULDocument::GetPopupNode\n"); +#endif + + nsresult rv; + + // get focus controller + nsCOMPtr focusController; + rv = GetFocusController(getter_AddRefs(focusController)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(focusController, NS_ERROR_FAILURE); + // get popup node + rv = focusController->GetPopupNode(aNode); // addref happens here + + return rv; } NS_IMETHODIMP nsXULDocument::SetPopupNode(nsIDOMNode* aNode) { - mPopupNode = dont_QueryInterface(aNode); - return NS_OK; +#ifdef DEBUG_dr + printf("dr :: nsXULDocument::SetPopupNode\n"); +#endif + + nsresult rv; + + // get focus controller + nsCOMPtr focusController; + rv = GetFocusController(getter_AddRefs(focusController)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(focusController, NS_ERROR_FAILURE); + // set popup node + rv = focusController->SetPopupNode(aNode); + + return rv; } NS_IMETHODIMP @@ -6368,3 +6395,29 @@ XULElementFactoryImpl::CreateInstanceByTag(nsINodeInfo *aNodeInfo, +nsresult nsXULDocument::GetFocusController(nsIFocusController** aController) +{ + NS_ENSURE_ARG_POINTER(aController); + + nsresult rv; + + // get the script global object + nsCOMPtr global; + rv = GetScriptGlobalObject(getter_AddRefs(global)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(global, NS_ERROR_FAILURE); + // get the internal dom window + nsCOMPtr internalWin(do_QueryInterface(global, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(internalWin, NS_ERROR_FAILURE); + // get the private dom window + nsCOMPtr privateWin(do_QueryInterface(internalWin, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(privateWin, NS_ERROR_FAILURE); + // get the focus controller + rv = privateWin->GetRootFocusController(aController); // addref is here + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(*aController, NS_ERROR_FAILURE); + + return rv; +} diff --git a/mozilla/content/xul/document/src/nsXULDocument.h b/mozilla/content/xul/document/src/nsXULDocument.h index aa42cc8419e..d9cd8483552 100644 --- a/mozilla/content/xul/document/src/nsXULDocument.h +++ b/mozilla/content/xul/document/src/nsXULDocument.h @@ -20,7 +20,8 @@ * Original Author(s): * Chris Waterson * - * Contributor(s): + * Contributor(s): + * Dan Rosen */ #ifndef nsXULDocument_h__ @@ -69,6 +70,7 @@ #include "nsIBindingManager.h" #include "nsINodeInfo.h" #include "nsIDOMDocumentEvent.h" +#include "nsIFocusController.h" class nsIAtom; class nsIElementFactory; @@ -534,15 +536,23 @@ protected: PRBool mBidiEnabled; #endif // IBMBIDI - // The following are pointers into the content model which provide access to - // the objects triggering either a popup or a tooltip. These are marked as - // [OWNER] only because someone could, through DOM calls, delete the object from the - // content model while the popup/tooltip was visible. If we didn't have a reference - // to it, the object would go away and we'd be left pointing to garbage. This - // does not introduce cycles into the ownership model because this is still - // parent/child ownership. Just wanted the reader to know hyatt and I had thought about - // this (pinkerton). - nsCOMPtr mPopupNode; // [OWNER] element triggering the popup + /* + * XXX dr + * ------ + * We used to have two pointers into the content model: mPopupNode and + * mTooltipNode, which were used to retrieve the objects triggering a + * popup or tooltip. You need that access because your reference has + * disappeared by the time you click on a popup item or do whatever + * with a tooltip. These were owning references (no cycles, as pinkerton + * pointed out, since we're still parent-child). + * + * We still have mTooltipNode, but mPopupNode has moved to the + * FocusController. The APIs (IDL attributes popupNode and tooltipNode) + * are still here for compatibility and ease of use, but we should + * probably move the mTooltipNode over to FocusController at some point + * as well, for consistency. + */ + nsCOMPtr mTooltipNode; // [OWNER] element triggering the tooltip nsCOMPtr mNodeInfoManager; // [OWNER] list of names in the document @@ -786,6 +796,12 @@ protected: }; friend class ParserObserver; + +private: + // helpers + + nsresult GetFocusController(nsIFocusController** aController); + }; diff --git a/mozilla/docshell/base/nsIContentViewerEdit.idl b/mozilla/docshell/base/nsIContentViewerEdit.idl index 76ead3064d7..fe13f3ef1c0 100644 --- a/mozilla/docshell/base/nsIContentViewerEdit.idl +++ b/mozilla/docshell/base/nsIContentViewerEdit.idl @@ -18,6 +18,7 @@ * * Contributor(s): * Travis Bogard + * Dan Rosen */ #include "nsISupports.idl" @@ -34,9 +35,16 @@ interface nsIContentViewerEdit : nsISupports void copySelection(); readonly attribute boolean copyable; + void copyLinkLocation(); + readonly attribute boolean inLink; + + void copyImageLocation(); + void copyImageContents(); + readonly attribute boolean inImage; + void cutSelection(); readonly attribute boolean cutable; void paste(); readonly attribute boolean pasteable; -}; \ No newline at end of file +}; diff --git a/mozilla/dom/public/base/nsIFocusController.h b/mozilla/dom/public/base/nsIFocusController.h index 1c4f1a345dc..d024c737a69 100644 --- a/mozilla/dom/public/base/nsIFocusController.h +++ b/mozilla/dom/public/base/nsIFocusController.h @@ -18,6 +18,7 @@ * * Contributor(s): * David W. Hyatt (Original Author) + * Dan Rosen */ #ifndef nsIFocusController_h__ @@ -26,6 +27,7 @@ #include "nsISupports.h" class nsIDOMElement; +class nsIDOMNode; class nsIDOMWindowInternal; class nsIController; class nsIControllers; @@ -53,6 +55,9 @@ public: NS_IMETHOD GetActive(PRBool* aActive)=0; NS_IMETHOD SetActive(PRBool aActive)=0; + NS_IMETHOD GetPopupNode(nsIDOMNode** aNode)=0; + NS_IMETHOD SetPopupNode(nsIDOMNode* aNode)=0; + NS_IMETHOD GetControllerForCommand(const nsAReadableString& aCommand, nsIController** aResult)=0; NS_IMETHOD GetControllers(nsIControllers** aResult)=0; diff --git a/mozilla/dom/src/base/nsFocusController.cpp b/mozilla/dom/src/base/nsFocusController.cpp index f1832fed165..08dfaeec307 100644 --- a/mozilla/dom/src/base/nsFocusController.cpp +++ b/mozilla/dom/src/base/nsFocusController.cpp @@ -18,6 +18,7 @@ * * Contributor(s): * David W. Hyatt (Original Author) + * Dan Rosen */ #include "nsIContent.h" @@ -431,3 +432,27 @@ nsFocusController::SetActive(PRBool aActive) return NS_OK; } +NS_IMETHODIMP +nsFocusController::GetPopupNode(nsIDOMNode** aNode) +{ +#ifdef DEBUG_dr + printf("dr :: nsFocusController::GetPopupNode\n"); +#endif + + *aNode = mPopupNode; + NS_IF_ADDREF(*aNode); + return NS_OK; +} + +NS_IMETHODIMP +nsFocusController::SetPopupNode(nsIDOMNode* aNode) +{ +#ifdef DEBUG_dr + printf("dr :: nsFocusController::SetPopupNode\n"); +#endif + + mPopupNode = aNode; + return NS_OK; +} + + diff --git a/mozilla/dom/src/base/nsFocusController.h b/mozilla/dom/src/base/nsFocusController.h index 0f4c45840f8..72ef1fe27bd 100644 --- a/mozilla/dom/src/base/nsFocusController.h +++ b/mozilla/dom/src/base/nsFocusController.h @@ -18,6 +18,7 @@ * * Contributor(s): * David W. Hyatt (Original Author) + * Dan Rosen */ #ifndef nsFocusController_h__ @@ -62,6 +63,9 @@ public: NS_IMETHOD GetActive(PRBool* aActive); NS_IMETHOD SetActive(PRBool aActive); + NS_IMETHOD GetPopupNode(nsIDOMNode** aNode); + NS_IMETHOD SetPopupNode(nsIDOMNode* aNode); + NS_IMETHOD GetControllerForCommand(const nsAReadableString& aCommand, nsIController** aResult); NS_IMETHOD GetControllers(nsIControllers** aResult); @@ -84,6 +88,7 @@ public: protected: nsCOMPtr mCurrentElement; // [OWNER] nsCOMPtr mCurrentWindow; // [OWNER] + nsCOMPtr mPopupNode; // [OWNER] PRUint32 mSuppressFocus; PRBool mSuppressFocusScroll; diff --git a/mozilla/dom/src/base/nsGlobalWindow.cpp b/mozilla/dom/src/base/nsGlobalWindow.cpp index 6b02299fd2f..b4d5a6c855f 100644 --- a/mozilla/dom/src/base/nsGlobalWindow.cpp +++ b/mozilla/dom/src/base/nsGlobalWindow.cpp @@ -20,7 +20,8 @@ * Contributor(s): * Travis Bogard * Brendan Eich - * David Hyatt (hyatt@netscape.com) + * David Hyatt + * Dan Rosen */ // Local Includes @@ -4424,6 +4425,9 @@ const char * const sCopyString = "cmd_copy"; const char * const sCutString = "cmd_cut"; const char * const sPasteString = "cmd_paste"; const char * const sSelectAllString = "cmd_selectAll"; +const char * const sCopyLinkString = "cmd_copyLink"; +const char * const sCopyImageLocationString = "cmd_copyImageLocation"; +const char * const sCopyImageContentsString = "cmd_copyImageContents"; const char * const sScrollTopString = "cmd_scrollTop"; const char * const sScrollBottomString = "cmd_scrollBottom"; @@ -4542,10 +4546,11 @@ NS_IMETHODIMP nsDOMWindowController::IsCommandEnabled(const nsAReadableString & nsCOMPtr editInterface; rv = GetEditInterface(getter_AddRefs(editInterface)); - if (NS_FAILED(rv)) - return rv; + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(editInterface, NS_ERROR_NOT_INITIALIZED); - nsCAutoString commandName; commandName.AssignWithConversion(aCommand); + nsCAutoString commandName; + commandName.AssignWithConversion(aCommand); if (commandName.Equals(sCopyString)) { rv = editInterface->GetCopyable(aResult); @@ -4560,8 +4565,17 @@ NS_IMETHODIMP nsDOMWindowController::IsCommandEnabled(const nsAReadableString & *aResult = PR_TRUE; rv = NS_OK; } - return rv; + else if (commandName.Equals(sCopyLinkString)) { + rv = editInterface->GetInLink(aResult); + } + else if (commandName.Equals(sCopyImageLocationString)) { + rv = editInterface->GetInImage(aResult); + } + else if (commandName.Equals(sCopyImageContentsString)) { + rv = editInterface->GetInImage(aResult); + } + return rv; } NS_IMETHODIMP nsDOMWindowController::SupportsCommand(const nsAReadableString & aCommand, PRBool *outSupported) @@ -4570,7 +4584,8 @@ NS_IMETHODIMP nsDOMWindowController::SupportsCommand(const nsAReadableString & a *outSupported = PR_FALSE; - nsCAutoString commandName; commandName.AssignWithConversion(aCommand); + nsCAutoString commandName; + commandName.AssignWithConversion(aCommand); if (commandName.Equals(sCopyString) || commandName.Equals(sSelectAllString) || @@ -4578,6 +4593,9 @@ NS_IMETHODIMP nsDOMWindowController::SupportsCommand(const nsAReadableString & a commandName.Equals(sPasteString) || commandName.Equals(sScrollTopString) || commandName.Equals(sScrollBottomString) || + commandName.Equals(sCopyLinkString) || + commandName.Equals(sCopyImageLocationString) || + commandName.Equals(sCopyImageContentsString) || commandName.Equals(sScrollPageUpString) || commandName.Equals(sScrollPageDownString) || commandName.Equals(sScrollLineUpString) || @@ -4600,86 +4618,153 @@ NS_IMETHODIMP nsDOMWindowController::SupportsCommand(const nsAReadableString & a commandName.Equals(sSelectPageNextString) || commandName.Equals(sSelectMoveTopString) || commandName.Equals(sSelectMoveBottomString) - ) { - *outSupported=PR_TRUE; - } + ) + *outSupported = PR_TRUE; return NS_OK; } NS_IMETHODIMP nsDOMWindowController::DoCommand(const nsAReadableString & aCommand) { + +#ifdef DEBUG_dr + printf("dr :: nsDOMWindowController::DoCommand: %s\n", + NS_ConvertUCS2toUTF8(aCommand).get()); +#endif + nsresult rv = NS_ERROR_FAILURE; + nsCAutoString commandName; + commandName.AssignWithConversion(aCommand); + + if (commandName.Equals(sCopyString) || + commandName.Equals(sSelectAllString) || + commandName.Equals(sCutString) || + commandName.Equals(sPasteString) || + commandName.Equals(sCopyLinkString) || + commandName.Equals(sCopyImageLocationString) || + commandName.Equals(sCopyImageContentsString)) + rv = DoCommandWithEditInterface(commandName); + + else if (commandName.Equals(sScrollTopString) || + commandName.Equals(sScrollBottomString) || + commandName.Equals(sScrollPageUpString) || + commandName.Equals(sScrollPageDownString) || + commandName.Equals(sScrollLineUpString) || + commandName.Equals(sScrollLineDownString) || + commandName.Equals(sScrollLeftString) || + commandName.Equals(sScrollRightString) || + commandName.Equals(sSelectCharPreviousString) || + commandName.Equals(sSelectCharNextString) || + commandName.Equals(sWordPreviousString) || + commandName.Equals(sWordNextString) || + commandName.Equals(sSelectWordPreviousString) || + commandName.Equals(sSelectWordNextString) || + commandName.Equals(sBeginLineString) || + commandName.Equals(sEndLineString) || + commandName.Equals(sSelectBeginLineString) || + commandName.Equals(sSelectEndLineString) || + commandName.Equals(sSelectLinePreviousString) || + commandName.Equals(sSelectLineNextString) || + commandName.Equals(sSelectMoveTopString) || + commandName.Equals(sSelectMoveBottomString)) + rv = DoCommandWithSelectionController(commandName); + + return rv; + +} + +nsresult nsDOMWindowController::DoCommandWithEditInterface(const nsCAutoString& aCommandName) +{ + + // get edit interface... nsCOMPtr editInterface; - rv = GetEditInterface(getter_AddRefs(editInterface)); - if (!editInterface) - return rv; + nsresult rv = GetEditInterface(getter_AddRefs(editInterface)); + // if we can't get an edit interface, that's bad + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(editInterface, NS_ERROR_NOT_INITIALIZED); - nsCAutoString commandName; commandName.AssignWithConversion(aCommand); + rv = NS_ERROR_FAILURE; - if (commandName.Equals(sCopyString)) - return editInterface->CopySelection(); - if (commandName.Equals(sSelectAllString)) - return editInterface->SelectAll(); - if (commandName.Equals(sCutString)) - return editInterface->CutSelection(); - - nsCOMPtr selCont; - rv = GetSelectionController(getter_AddRefs(selCont)); - if (!selCont) - return rv; - - if (commandName.Equals(sPasteString)) + if (aCommandName.Equals(sCopyString)) + rv = editInterface->CopySelection(); + else if (aCommandName.Equals(sSelectAllString)) + rv = editInterface->SelectAll(); + else if (aCommandName.Equals(sCutString)) + rv = editInterface->CutSelection(); + else if (aCommandName.Equals(sPasteString)) rv = editInterface->Paste(); - else if (commandName.Equals(sScrollTopString)) + else if (aCommandName.Equals(sCopyLinkString)) + rv = editInterface->CopyLinkLocation(); + else if (aCommandName.Equals(sCopyImageLocationString)) + rv = editInterface->CopyImageLocation(); + else if (aCommandName.Equals(sCopyImageContentsString)) + rv = editInterface->CopyImageContents(); + + return rv; + +} + +nsresult nsDOMWindowController::DoCommandWithSelectionController(const nsCAutoString& aCommandName) { + + // get selection controller... + nsCOMPtr selCont; + nsresult rv = GetSelectionController(getter_AddRefs(selCont)); + // if we can't get a selection controller, that's bad + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(selCont, NS_ERROR_NOT_INITIALIZED); + + rv = NS_ERROR_FAILURE; + + if (aCommandName.Equals(sScrollTopString)) rv = (mBrowseWithCaret? selCont->CompleteMove(PR_FALSE, PR_FALSE): selCont->CompleteScroll(PR_FALSE)); - else if (commandName.Equals(sScrollBottomString)) + else if (aCommandName.Equals(sScrollBottomString)) rv = (mBrowseWithCaret? selCont->CompleteMove(PR_TRUE, PR_FALSE): selCont->CompleteScroll(PR_TRUE)); - else if (commandName.Equals(sScrollPageUpString)) + else if (aCommandName.Equals(sScrollPageUpString)) rv = (mBrowseWithCaret? selCont->PageMove(PR_FALSE, PR_FALSE): selCont->ScrollPage(PR_FALSE)); - else if (commandName.Equals(sScrollPageDownString)) + else if (aCommandName.Equals(sScrollPageDownString)) rv = (mBrowseWithCaret? selCont->PageMove(PR_TRUE, PR_FALSE): selCont->ScrollPage(PR_TRUE)); - else if (commandName.Equals(sScrollLineUpString)) + else if (aCommandName.Equals(sScrollLineUpString)) rv = (mBrowseWithCaret? selCont->LineMove(PR_FALSE, PR_FALSE): selCont->ScrollLine(PR_FALSE)); - else if (commandName.Equals(sScrollLineDownString)) + else if (aCommandName.Equals(sScrollLineDownString)) rv = (mBrowseWithCaret? selCont->LineMove(PR_TRUE, PR_FALSE): selCont->ScrollLine(PR_TRUE)); - else if (commandName.Equals(sScrollLeftString)) + else if (aCommandName.Equals(sScrollLeftString)) rv = (mBrowseWithCaret? selCont->CharacterMove(PR_FALSE, PR_FALSE): selCont->ScrollHorizontal(PR_TRUE)); - else if (commandName.Equals(sScrollRightString)) + else if (aCommandName.Equals(sScrollRightString)) rv = (mBrowseWithCaret? selCont->CharacterMove(PR_TRUE, PR_FALSE): selCont->ScrollHorizontal(PR_FALSE)); // These commands are so the browser can use editor navigation key bindings - // Helps with accessibility - aaronl@chorus.net - else if (commandName.Equals(sSelectCharPreviousString)) + else if (aCommandName.Equals(sSelectCharPreviousString)) rv = selCont->CharacterMove(PR_FALSE, PR_TRUE); - else if (commandName.Equals(sSelectCharNextString)) + else if (aCommandName.Equals(sSelectCharNextString)) rv = selCont->CharacterMove(PR_TRUE, PR_TRUE); - else if (commandName.Equals(sWordPreviousString)) + else if (aCommandName.Equals(sWordPreviousString)) rv = selCont->WordMove(PR_FALSE, PR_FALSE); - else if (commandName.Equals(sWordNextString)) + else if (aCommandName.Equals(sWordNextString)) rv = selCont->WordMove(PR_TRUE, PR_FALSE); - else if (commandName.Equals(sSelectWordPreviousString)) + else if (aCommandName.Equals(sSelectWordPreviousString)) rv = selCont->WordMove(PR_FALSE, PR_TRUE); - else if (commandName.Equals(sSelectWordNextString)) + else if (aCommandName.Equals(sSelectWordNextString)) rv = selCont->WordMove(PR_TRUE, PR_TRUE); - else if (commandName.Equals(sBeginLineString)) + else if (aCommandName.Equals(sBeginLineString)) rv = selCont->IntraLineMove(PR_FALSE, PR_FALSE); - else if (commandName.Equals(sEndLineString)) + else if (aCommandName.Equals(sEndLineString)) rv = selCont->IntraLineMove(PR_TRUE, PR_FALSE); - else if (commandName.Equals(sSelectBeginLineString)) + else if (aCommandName.Equals(sSelectBeginLineString)) rv = selCont->IntraLineMove(PR_FALSE, PR_TRUE); - else if (commandName.Equals(sSelectEndLineString)) + else if (aCommandName.Equals(sSelectEndLineString)) rv = selCont->IntraLineMove(PR_TRUE, PR_TRUE); - else if (commandName.Equals(sSelectLinePreviousString)) + else if (aCommandName.Equals(sSelectLinePreviousString)) rv = selCont->LineMove(PR_FALSE, PR_TRUE); - else if (commandName.Equals(sSelectLineNextString)) + else if (aCommandName.Equals(sSelectLineNextString)) rv = selCont->LineMove(PR_TRUE, PR_TRUE); - else if (commandName.Equals(sSelectMoveTopString)) + else if (aCommandName.Equals(sSelectMoveTopString)) rv = selCont->CompleteMove(PR_FALSE, PR_TRUE); - else if (commandName.Equals(sSelectMoveBottomString)) + else if (aCommandName.Equals(sSelectMoveBottomString)) rv = selCont->CompleteMove(PR_TRUE, PR_TRUE); - return rv; -} + return rv; + +} NS_IMETHODIMP nsDOMWindowController::OnEvent(const nsAReadableString & aEventName) { diff --git a/mozilla/dom/src/base/nsGlobalWindow.h b/mozilla/dom/src/base/nsGlobalWindow.h index e66a9236289..59d87551c82 100644 --- a/mozilla/dom/src/base/nsGlobalWindow.h +++ b/mozilla/dom/src/base/nsGlobalWindow.h @@ -18,8 +18,10 @@ * Rights Reserved. * * Contributor(s): - * Travis Bogard + * Travis Bogard + * Dan Rosen */ + #ifndef nsGlobalWindow_h___ #define nsGlobalWindow_h___ @@ -413,6 +415,9 @@ private: nsresult GetEditInterface( nsIContentViewerEdit** aEditInterface); nsresult GetSelectionController(nsISelectionController ** aSelCon); + nsresult DoCommandWithEditInterface(const nsCAutoString& aCommandName); + nsresult DoCommandWithSelectionController(const nsCAutoString& aCommandName); + nsIDOMWindowInternal *mWindow; PRBool mBrowseWithCaret; }; diff --git a/mozilla/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp b/mozilla/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp index 0a69ed47ffc..54b90c1bf1e 100644 --- a/mozilla/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp +++ b/mozilla/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file @@ -20,6 +20,7 @@ * Travis Bogard * Adam Lock * Mike Pinkerton + * Dan Rosen */ // Local Includes @@ -1467,6 +1468,27 @@ ChromeContextMenuListener :: ContextMenu ( nsIDOMEvent* aMouseEvent ) node = parentNode; } while (node); + // we need to cache the event target into the focus controller's popupNode + // so we can get at it later from command code, etc.: + + // get the dom window + nsCOMPtr win; + res = mWebBrowser->GetContentDOMWindow(getter_AddRefs(win)); + NS_ENSURE_SUCCESS(res, res); + NS_ENSURE_TRUE(win, NS_ERROR_FAILURE); + // get the private dom window + nsCOMPtr privateWin(do_QueryInterface(win, &res)); + NS_ENSURE_SUCCESS(res, res); + NS_ENSURE_TRUE(privateWin, NS_ERROR_FAILURE); + // get the focus controller + nsCOMPtr focusController; + res = privateWin->GetRootFocusController(getter_AddRefs(focusController)); + NS_ENSURE_SUCCESS(res, res); + NS_ENSURE_TRUE(focusController, NS_ERROR_FAILURE); + // set the focus controller's popup node to the event target + res = focusController->SetPopupNode(targetDOMnode); + NS_ENSURE_SUCCESS(res, res); + // Tell the listener all about the event nsCOMPtr menuListener(do_QueryInterface(mWebBrowserChrome)); if ( menuListener ) diff --git a/mozilla/embedding/browser/webBrowser/nsDocShellTreeOwner.h b/mozilla/embedding/browser/webBrowser/nsDocShellTreeOwner.h index f066ba8fea9..e86c3532e35 100644 --- a/mozilla/embedding/browser/webBrowser/nsDocShellTreeOwner.h +++ b/mozilla/embedding/browser/webBrowser/nsDocShellTreeOwner.h @@ -237,12 +237,12 @@ public: ChromeContextMenuListener ( nsWebBrowser* inBrowser, nsIWebBrowserChrome* inChrome ) ; virtual ~ChromeContextMenuListener ( ) ; - // nsIDOMContextMenuListener - virtual nsresult HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; } + // nsIDOMContextMenuListener + virtual nsresult HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; } virtual nsresult ContextMenu ( nsIDOMEvent* aEvent ); - // Add/remove the relevant listeners, based on what interfaces - // the embedding chrome implements. + // Add/remove the relevant listeners, based on what interfaces + // the embedding chrome implements. NS_IMETHOD AddChromeListeners(); NS_IMETHOD RemoveChromeListeners(); diff --git a/mozilla/layout/base/nsDocumentViewer.cpp b/mozilla/layout/base/nsDocumentViewer.cpp index 2bcb69e06a6..59a4919b25e 100644 --- a/mozilla/layout/base/nsDocumentViewer.cpp +++ b/mozilla/layout/base/nsDocumentViewer.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 0 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file @@ -17,8 +17,10 @@ * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * - * Contributor(s): + * Contributor(s): + * Dan Rosen */ + #include "nslayout.h" #include "nsCOMPtr.h" #include "nsCRT.h" @@ -81,6 +83,8 @@ #include "nsIFrameManager.h" #include "nsIParser.h" #include "nsIPrintContext.h" +#include "nsIDOMHTMLAnchorElement.h" +#include "nsIDOMHTMLImageElement.h" #include "nsIChromeRegistry.h" @@ -187,10 +191,10 @@ class nsPagePrintTimer; // a small delegate class used to avoid circular references #ifdef XP_MAC -#pragma mark ** nsDocViwerSelectionListener ** +#pragma mark ** nsDocViewerSelectionListener ** #endif -class nsDocViwerSelectionListener : public nsISelectionListener +class nsDocViewerSelectionListener : public nsISelectionListener { public: @@ -200,7 +204,7 @@ public: // nsISelectionListerner interface NS_DECL_NSISELECTIONLISTENER - nsDocViwerSelectionListener() + nsDocViewerSelectionListener() : mDocViewer(NULL) , mGotSelectionState(PR_FALSE) , mSelectionWasCollapsed(PR_FALSE) @@ -208,7 +212,7 @@ public: NS_INIT_REFCNT(); } - virtual ~nsDocViwerSelectionListener() {} + virtual ~nsDocViewerSelectionListener() {} nsresult Init(DocumentViewerImpl *aDocViewer); @@ -346,7 +350,7 @@ class DocumentViewerImpl : public nsIDocumentViewer, public nsIMarkupDocumentViewer, public nsIImageGroupObserver { - friend class nsDocViwerSelectionListener; + friend class nsDocViewerSelectionListener; public: DocumentViewerImpl(); @@ -429,6 +433,11 @@ private: PRPackedBool& aDoesContainFrameset); PRBool IsWindowsInOurSubTree(nsIDOMWindowInternal * aDOMWindow); + + nsresult GetPopupNode(nsIDOMNode** aNode); + nsresult GetPopupLinkNode(nsIDOMNode** aNode); + nsresult GetPopupImageNode(nsIDOMNode** aNode); + //--------------------------------------------------------------------- void BuildDocTree(nsIDocShellTreeNode * aParentNode, nsVoidArray * aDocList, @@ -965,8 +974,8 @@ DocumentViewerImpl::Init(nsIWidget* aParentWidget, // now register ourselves as a selection listener, so that we get called // when the selection changes in the window - nsDocViwerSelectionListener *selectionListener; - NS_NEWXPCOM(selectionListener, nsDocViwerSelectionListener); + nsDocViewerSelectionListener *selectionListener; + NS_NEWXPCOM(selectionListener, nsDocViewerSelectionListener); if (!selectionListener) return NS_ERROR_OUT_OF_MEMORY; selectionListener->Init(this); @@ -3870,10 +3879,42 @@ NS_IMETHODIMP DocumentViewerImpl::SelectAll() NS_IMETHODIMP DocumentViewerImpl::CopySelection() { - if (!mPresShell) return NS_ERROR_NOT_INITIALIZED; + NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED); return mPresShell->DoCopy(); } +NS_IMETHODIMP DocumentViewerImpl::CopyLinkLocation() +{ + NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED); + nsCOMPtr node; + nsresult rv = GetPopupLinkNode(getter_AddRefs(node)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(node, NS_ERROR_FAILURE); + return mPresShell->DoCopyLinkLocation(node); +} + +NS_IMETHODIMP DocumentViewerImpl::CopyImageLocation() +{ + NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED); + nsCOMPtr node; + nsresult rv = GetPopupImageNode(getter_AddRefs(node)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(node, NS_ERROR_FAILURE); + NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED); + return mPresShell->DoCopyImageLocation(node); +} + +NS_IMETHODIMP DocumentViewerImpl::CopyImageContents() +{ + NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED); + nsCOMPtr node; + nsresult rv = GetPopupImageNode(getter_AddRefs(node)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(node, NS_ERROR_FAILURE); + NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED); + return mPresShell->DoCopyImageContents(node); +} + NS_IMETHODIMP DocumentViewerImpl::GetCopyable(PRBool *aCopyable) { nsCOMPtr selection; @@ -4856,16 +4897,193 @@ NS_IMETHODIMP DocumentViewerImpl::SizeToContent() #pragma mark - #endif -NS_IMPL_ISUPPORTS(nsDocViwerSelectionListener, NS_GET_IID(nsISelectionListener)); +NS_IMPL_ISUPPORTS(nsDocViewerSelectionListener, NS_GET_IID(nsISelectionListener)); -nsresult nsDocViwerSelectionListener::Init(DocumentViewerImpl *aDocViewer) +nsresult nsDocViewerSelectionListener::Init(DocumentViewerImpl *aDocViewer) { mDocViewer = aDocViewer; return NS_OK; } +/* + * GetPopupNode, GetPopupLinkNode and GetPopupImageNode are helpers + * for the cmd_copyLink / cmd_copyImageLocation / cmd_copyImageContents family + * of commands. The focus controller stores the popup node, these retrieve + * them and munge appropriately. Note that we have to store the popup node + * rather than retrieving it from EventStateManager::GetFocusedContent because + * not all content (images included) can receive focus. + */ -NS_IMETHODIMP nsDocViwerSelectionListener::NotifySelectionChanged(nsIDOMDocument *, nsISelection *, short) +nsresult +DocumentViewerImpl::GetPopupNode(nsIDOMNode** aNode) +{ + NS_ENSURE_ARG_POINTER(aNode); + + nsresult rv; + + // get the document + nsCOMPtr document; + rv = GetDocument(*getter_AddRefs(document)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(document, NS_ERROR_FAILURE); + + // get the script global object + nsCOMPtr global; + rv = document->GetScriptGlobalObject(getter_AddRefs(global)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(global, NS_ERROR_FAILURE); + + // get the internal dom window + nsCOMPtr internalWin(do_QueryInterface(global, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(internalWin, NS_ERROR_FAILURE); + + // get the private dom window + nsCOMPtr privateWin(do_QueryInterface(internalWin, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(privateWin, NS_ERROR_FAILURE); + + // get the focus controller + nsCOMPtr focusController; + rv = privateWin->GetRootFocusController(getter_AddRefs(focusController)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(focusController, NS_ERROR_FAILURE); + + // get the popup node + rv = focusController->GetPopupNode(aNode); // addref happens here + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(*aNode, NS_ERROR_FAILURE); + + return rv; +} + +/* + * XXX dr + * ------ + * Note: the args to these two methods are DOM nodes and not specifically + * HTML anchor or image nodes because a link can also be an xlink, and an + * image can also be an object... The impls are broken right now to just + * think about HTML anchors and images but consumers of these methods should + * do their own checking. + */ + +nsresult +DocumentViewerImpl::GetPopupLinkNode(nsIDOMNode** aNode) +{ + NS_ENSURE_ARG_POINTER(aNode); + + // you get null unless i say so + *aNode = nsnull; + + // find popup node + nsCOMPtr node; + nsresult rv = GetPopupNode(getter_AddRefs(node)); + NS_ENSURE_SUCCESS(rv, rv); + + // find out if we have an anchor in our ancestry. this really ought + // to look for xlinks also, but this is good enough for now. + while (node) { + + // are we an anchor? + nsCOMPtr anchor(do_QueryInterface(node, &rv)); + if (NS_SUCCEEDED(rv) && anchor) { + *aNode = node; + NS_IF_ADDREF(*aNode); // addref + return NS_OK; + } + else { + // if not, get our parent and keep trying... + nsCOMPtr parentNode; + node->GetParentNode(getter_AddRefs(parentNode)); + node = parentNode; + } + } + + // if we have no node, fail + return NS_ERROR_FAILURE; +} + +nsresult +DocumentViewerImpl::GetPopupImageNode(nsIDOMNode** aNode) +{ + NS_ENSURE_ARG_POINTER(aNode); + + // you get null unless i say so + *aNode = nsnull; + + // find popup node + nsCOMPtr node; + nsresult rv = GetPopupNode(getter_AddRefs(node)); + NS_ENSURE_SUCCESS(rv, rv); + + // find out if we're an image. this really ought to look for objects + // with type "image/...", but this is good enough for now. + nsCOMPtr img(do_QueryInterface(node, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(img, NS_ERROR_FAILURE); + + // if we made it here, we're an image. + *aNode = node; + NS_IF_ADDREF(*aNode); // addref + return NS_OK; +} + +/* + * XXX dr + * ------ + * These two functions -- GetInLink and GetInImage -- are kind of annoying + * in that they only get called from the controller (in + * nsDOMWindowController::IsCommandEnabled). The actual construction of the + * context menus in communicator (nsContextMenu.js) has its own, redundant + * tests. No big deal, but good to keep in mind if we ever clean context + * menus. + */ + +NS_IMETHODIMP DocumentViewerImpl::GetInLink(PRBool* aInLink) +{ +#ifdef DEBUG_dr + printf("dr :: DocumentViewerImpl::GetInLink\n"); +#endif + + NS_ENSURE_ARG_POINTER(aInLink); + + // we're not in a link unless i say so + *aInLink = PR_FALSE; + + // get the popup link + nsCOMPtr node; + nsresult rv = GetPopupLinkNode(getter_AddRefs(node)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(node, NS_ERROR_FAILURE); + + // if we made it here, we're in a link + *aInLink = PR_TRUE; + return NS_OK; +} + +NS_IMETHODIMP DocumentViewerImpl::GetInImage(PRBool* aInImage) +{ +#ifdef DEBUG_dr + printf("dr :: DocumentViewerImpl::GetInImage\n"); +#endif + + NS_ENSURE_ARG_POINTER(aInImage); + + // we're not in an image unless i say so + *aInImage = PR_FALSE; + + // get the popup image + nsCOMPtr node; + nsresult rv = GetPopupImageNode(getter_AddRefs(node)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(node, NS_ERROR_FAILURE); + + // if we made it here, we're in an image + *aInImage = PR_TRUE; + return NS_OK; +} + +NS_IMETHODIMP nsDocViewerSelectionListener::NotifySelectionChanged(nsIDOMDocument *, nsISelection *, short) { NS_ASSERTION(mDocViewer, "Should have doc viewer!"); diff --git a/mozilla/layout/base/nsIPresShell.h b/mozilla/layout/base/nsIPresShell.h index a5e12a3265b..3b41c5a5ca3 100644 --- a/mozilla/layout/base/nsIPresShell.h +++ b/mozilla/layout/base/nsIPresShell.h @@ -17,8 +17,9 @@ * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * - * Contributor(s): - * Steve Clark (buster@netscape.com) + * Contributor(s): + * Steve Clark + * Dan Rosen * * IBM Corporation * @@ -390,6 +391,17 @@ public: */ NS_IMETHOD DoCopy() = 0; + /** + * Copy link location. + */ + NS_IMETHOD DoCopyLinkLocation(nsIDOMNode* aNode) = 0; + + /** + * Copy image methods. + */ + NS_IMETHOD DoCopyImageLocation(nsIDOMNode* aNode) = 0; + NS_IMETHOD DoCopyImageContents(nsIDOMNode* aNode) = 0; + /** * Get the caret, if it exists. AddRefs it. */ diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp index 48f239d855b..2d91039f631 100644 --- a/mozilla/layout/base/nsPresShell.cpp +++ b/mozilla/layout/base/nsPresShell.cpp @@ -18,8 +18,9 @@ * Rights Reserved. * * Contributor(s): - * Steve Clark (buster@netscape.com) - * Håkan Waara (hwaara@chello.se) + * Steve Clark + * Håkan Waara + * Dan Rosen * * IBM Corporation * @@ -34,7 +35,7 @@ * Date Modified by Description of modification * 05/03/2000 IBM Corp. Observer events for reflow states */ - + #define PL_ARENA_CONST_ALIGN_MASK 3 #include "nsIPresShell.h" #include "nsISpaceManager.h" @@ -132,6 +133,8 @@ #include "prlong.h" #include "nsIDragService.h" #include "nsCopySupport.h" +#include "nsIDOMHTMLAnchorElement.h" +#include "nsIDOMHTMLImageElement.h" #include "nsITimer.h" // Dummy layout request @@ -899,6 +902,9 @@ public: NS_IMETHOD GetFrameManager(nsIFrameManager** aFrameManager) const; NS_IMETHOD DoCopy(); + NS_IMETHOD DoCopyLinkLocation(nsIDOMNode* aNode); + NS_IMETHOD DoCopyImageLocation(nsIDOMNode* aNode); + NS_IMETHOD DoCopyImageContents(nsIDOMNode* aNode); NS_IMETHOD CaptureHistoryState(nsILayoutHistoryState** aLayoutHistoryState, PRBool aLeavingPage); NS_IMETHOD GetHistoryState(nsILayoutHistoryState** aLayoutHistoryState); @@ -1172,7 +1178,13 @@ protected: ReflowCountMgr * mReflowCountMgr; #endif -private: +private: + + // copy string to clipboard methods + static nsresult CopyStringToClipboard(nsString& aString, + PRInt32 aClipboardID); + static nsresult CopyStringToClipboard(nsString& aString); + void FreeDynamicStack(); //helper funcs for disabing autoscrolling @@ -2442,7 +2454,7 @@ PresShell::InitialReflow(nscoord aWidth, nscoord aHeight) if (uri) { char* url = nsnull; uri->GetSpec(&url); - printf("*** PresShell::InitialReflow (this=%p, url='%s')\n", this, url); + printf("*** PresShell::InitialReflow (this=%p, url='%s')\n", (void*)this, url); Recycle(url); } } @@ -3296,7 +3308,7 @@ PresShell::AlreadyInQueue(nsIReflowCommand* aReflowCommand, RCType == queuedRCType) { #ifdef DEBUG if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) { - printf("*** PresShell::AlreadyInQueue(): Discarding reflow command: this=%p\n", this); + printf("*** PresShell::AlreadyInQueue(): Discarding reflow command: this=%p\n", (void*)this); aReflowCommand->List(stdout); } #endif @@ -3340,7 +3352,7 @@ PresShell::AppendReflowCommandInternal(nsIReflowCommand* aReflowCommand, return NS_OK; } if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) { - printf("\nPresShell@%p: adding reflow command\n", this); + printf("\nPresShell@%p: adding reflow command\n", (void*)this); aReflowCommand->List(stdout); if (VERIFY_REFLOW_REALLY_NOISY_RC & gVerifyReflowFlags) { printf("Current content model:\n"); @@ -3430,7 +3442,7 @@ PresShell::CancelReflowCommandInternal(nsIFrame* aTargetFrame, } #ifdef DEBUG if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) { - printf("PresShell: removing rc=%p for frame ", rc); + printf("PresShell: removing rc=%p for frame ", (void*)rc); nsFrame::ListTag(stdout, aTargetFrame); printf("\n"); } @@ -3901,6 +3913,137 @@ PresShell::ScrollFrameIntoView(nsIFrame *aFrame, return rv; } +// CopyStringToClipboard: copy simple string to clipboard +nsresult PresShell::CopyStringToClipboard(nsString& aString, + PRInt32 aClipboardID) +{ + nsresult rv; + + // get the clipboard + nsCOMPtr + clipboard(do_GetService("@mozilla.org/widget/clipboard;1", &rv)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(clipboard, NS_ERROR_FAILURE); + + // create a transferable for putting data on the clipboard + nsCOMPtr + trans(do_CreateInstance("@mozilla.org/widget/transferable;1", &rv)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(trans, NS_ERROR_FAILURE); + + // Add the text data flavor to the transferable + rv = trans->AddDataFlavor(kUnicodeMime); + NS_ENSURE_SUCCESS(rv, rv); + + // get wStrings to hold clip data + nsCOMPtr + data(do_CreateInstance("@mozilla.org/supports-wstring;1", &rv)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(data, NS_ERROR_FAILURE); + + // populate the string + rv = data->SetData(NS_CONST_CAST(PRUnichar*, aString.GetUnicode())); + NS_ENSURE_SUCCESS(rv, rv); + + // qi the data object an |nsISupports| so that when the transferable holds + // onto it, it will addref the correct interface. + nsCOMPtr genericData(do_QueryInterface(data, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(genericData, NS_ERROR_FAILURE); + + // set the transfer data + rv = trans->SetTransferData(kUnicodeMime, genericData, + aString.Length() * 2); + NS_ENSURE_SUCCESS(rv, rv); + + // put the transferable on the clipboard + rv = clipboard->SetData(trans, nsnull, aClipboardID); + NS_ENSURE_SUCCESS(rv, rv); + + return NS_OK; +} + +// CopyStringToClipboard: copy string to clipboard(s) for platform +nsresult PresShell::CopyStringToClipboard(nsString& aString) +{ +#ifdef DEBUG_dr + printf("dr :: CopyStringToClipboard: %s\n", + NS_ConvertUCS2toUTF8(aString).get()); +#endif + + nsresult rv; + + // copy to the global clipboard + rv = CopyStringToClipboard(aString, nsIClipboard::kGlobalClipboard); + NS_ENSURE_SUCCESS(rv, rv); + +#ifdef XP_UNIX + // unix also needs us to copy to the selection clipboard + rv = CopyStringToClipboard(aString, nsIClipboard::kSelectionClipboard); + NS_ENSURE_SUCCESS(rv, rv); +#endif + + return NS_OK; +} + +// DoCopyLinkLocation: copy link location to clipboard +NS_IMETHODIMP PresShell::DoCopyLinkLocation(nsIDOMNode* aNode) +{ +#ifdef DEBUG_dr + printf("dr :: PresShell::DoCopyLinkLocation\n"); +#endif + + NS_ENSURE_ARG_POINTER(aNode); + nsresult rv; + + // are we an anchor? + nsCOMPtr anchor(do_QueryInterface(aNode, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + if (anchor) { + // if so, copy the link: + nsAutoString anchorText; + rv = anchor->GetHref(anchorText); + NS_ENSURE_SUCCESS(rv, rv); + return CopyStringToClipboard(anchorText); + } + + // if no link, fail. + return NS_ERROR_FAILURE; +} + +// DoCopyImageLocation: copy image location to clipboard +NS_IMETHODIMP PresShell::DoCopyImageLocation(nsIDOMNode* aNode) +{ +#ifdef DEBUG_dr + printf("dr :: PresShell::DoCopyImageLocation\n"); +#endif + + NS_ENSURE_ARG_POINTER(aNode); + nsresult rv; + + // are we an image? + nsCOMPtr img(do_QueryInterface(aNode, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + if (img) { + // if so, copy the location: + nsAutoString srcText; + rv = img->GetSrc(srcText); + NS_ENSURE_SUCCESS(rv, rv); + return CopyStringToClipboard(srcText); + } + + // if no image, fail. + return NS_ERROR_FAILURE; +} + +// DoCopyImageContents: copy image contents to clipboard +NS_IMETHODIMP PresShell::DoCopyImageContents(nsIDOMNode* aNode) +{ + // XXX dr: platform-specific widget code works on windows and mac. + // when linux copy image contents works, this should get written + // and hooked up to the front end, similarly to cmd_copyImageLocation. + return NS_ERROR_NOT_IMPLEMENTED; +} NS_IMETHODIMP PresShell::DoCopy() @@ -5354,7 +5497,7 @@ struct ReflowEvent : public PLEvent { if (presShell) { #ifdef DEBUG if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) { - printf("\n*** Handling reflow event: PresShell=%p, event=%p\n", presShell.get(), this); + printf("\n*** Handling reflow event: PresShell=%p, event=%p\n", (void*)presShell.get(), (void*)this); } #endif // XXX Statically cast the pres shell pointer so that we can call @@ -5417,7 +5560,7 @@ PresShell::PostReflowEvent() mPendingReflowEvent = PR_TRUE; #ifdef DEBUG if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) { - printf("\n*** PresShell::PostReflowEvent(), this=%p, event=%p\n", this, ev); + printf("\n*** PresShell::PostReflowEvent(), this=%p, event=%p\n", (void*)this, (void*)ev); } #endif } @@ -5501,7 +5644,7 @@ PresShell::ProcessReflowCommands(PRBool aInterruptible) } if (VERIFY_REFLOW_DUMP_COMMANDS & gVerifyReflowFlags) { PRInt32 i, n = mReflowCommands.Count(); - printf("\nPresShell::ProcessReflowCommands: this=%p, count=%d\n", this, n); + printf("\nPresShell::ProcessReflowCommands: this=%p, count=%d\n", (void*)this, n); for (i = 0; i < n; i++) { nsIReflowCommand* rc = (nsIReflowCommand*) mReflowCommands.ElementAt(i); @@ -5539,7 +5682,7 @@ PresShell::ProcessReflowCommands(PRBool aInterruptible) #ifdef DEBUG if (VERIFY_REFLOW_DUMP_COMMANDS & gVerifyReflowFlags) { printf("Time spent in PresShell::ProcessReflowCommands(), this=%p, time=%d micro seconds\n", - this, mAccumulatedReflowTime); + (void*)this, mAccumulatedReflowTime); } #endif mAccumulatedReflowTime = 0; @@ -5548,7 +5691,7 @@ PresShell::ProcessReflowCommands(PRBool aInterruptible) #ifdef DEBUG if (VERIFY_REFLOW_DUMP_COMMANDS & gVerifyReflowFlags) { - printf("\nPresShell::ProcessReflowCommands() finished: this=%p\n", this); + printf("\nPresShell::ProcessReflowCommands() finished: this=%p\n", (void*)this); } if (nsIFrameDebug::GetVerifyTreeEnable()) { @@ -5863,7 +6006,7 @@ LogVerifyMessage(nsIFrame* k1, nsIFrame* k2, const char* aMsg, fprintf(stdout, " "); frameDebug->GetFrameName(name); fputs(name, stdout); - fprintf(stdout, " %p ", k1); + fprintf(stdout, " %p ", (void*)k1); } printf("{%d, %d, %d, %d}", r1.x, r1.y, r1.width, r1.height); @@ -5874,7 +6017,7 @@ LogVerifyMessage(nsIFrame* k1, nsIFrame* k2, const char* aMsg, fprintf(stdout, " "); frameDebug->GetFrameName(name); fputs(name, stdout); - fprintf(stdout, " %p ", k2); + fprintf(stdout, " %p ", (void*)k2); } printf("{%d, %d, %d, %d}\n", r2.x, r2.y, r2.width, r2.height); diff --git a/mozilla/layout/base/public/nsIPresShell.h b/mozilla/layout/base/public/nsIPresShell.h index a5e12a3265b..3b41c5a5ca3 100644 --- a/mozilla/layout/base/public/nsIPresShell.h +++ b/mozilla/layout/base/public/nsIPresShell.h @@ -17,8 +17,9 @@ * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * - * Contributor(s): - * Steve Clark (buster@netscape.com) + * Contributor(s): + * Steve Clark + * Dan Rosen * * IBM Corporation * @@ -390,6 +391,17 @@ public: */ NS_IMETHOD DoCopy() = 0; + /** + * Copy link location. + */ + NS_IMETHOD DoCopyLinkLocation(nsIDOMNode* aNode) = 0; + + /** + * Copy image methods. + */ + NS_IMETHOD DoCopyImageLocation(nsIDOMNode* aNode) = 0; + NS_IMETHOD DoCopyImageContents(nsIDOMNode* aNode) = 0; + /** * Get the caret, if it exists. AddRefs it. */ diff --git a/mozilla/layout/html/base/src/nsPresShell.cpp b/mozilla/layout/html/base/src/nsPresShell.cpp index 48f239d855b..2d91039f631 100644 --- a/mozilla/layout/html/base/src/nsPresShell.cpp +++ b/mozilla/layout/html/base/src/nsPresShell.cpp @@ -18,8 +18,9 @@ * Rights Reserved. * * Contributor(s): - * Steve Clark (buster@netscape.com) - * Håkan Waara (hwaara@chello.se) + * Steve Clark + * Håkan Waara + * Dan Rosen * * IBM Corporation * @@ -34,7 +35,7 @@ * Date Modified by Description of modification * 05/03/2000 IBM Corp. Observer events for reflow states */ - + #define PL_ARENA_CONST_ALIGN_MASK 3 #include "nsIPresShell.h" #include "nsISpaceManager.h" @@ -132,6 +133,8 @@ #include "prlong.h" #include "nsIDragService.h" #include "nsCopySupport.h" +#include "nsIDOMHTMLAnchorElement.h" +#include "nsIDOMHTMLImageElement.h" #include "nsITimer.h" // Dummy layout request @@ -899,6 +902,9 @@ public: NS_IMETHOD GetFrameManager(nsIFrameManager** aFrameManager) const; NS_IMETHOD DoCopy(); + NS_IMETHOD DoCopyLinkLocation(nsIDOMNode* aNode); + NS_IMETHOD DoCopyImageLocation(nsIDOMNode* aNode); + NS_IMETHOD DoCopyImageContents(nsIDOMNode* aNode); NS_IMETHOD CaptureHistoryState(nsILayoutHistoryState** aLayoutHistoryState, PRBool aLeavingPage); NS_IMETHOD GetHistoryState(nsILayoutHistoryState** aLayoutHistoryState); @@ -1172,7 +1178,13 @@ protected: ReflowCountMgr * mReflowCountMgr; #endif -private: +private: + + // copy string to clipboard methods + static nsresult CopyStringToClipboard(nsString& aString, + PRInt32 aClipboardID); + static nsresult CopyStringToClipboard(nsString& aString); + void FreeDynamicStack(); //helper funcs for disabing autoscrolling @@ -2442,7 +2454,7 @@ PresShell::InitialReflow(nscoord aWidth, nscoord aHeight) if (uri) { char* url = nsnull; uri->GetSpec(&url); - printf("*** PresShell::InitialReflow (this=%p, url='%s')\n", this, url); + printf("*** PresShell::InitialReflow (this=%p, url='%s')\n", (void*)this, url); Recycle(url); } } @@ -3296,7 +3308,7 @@ PresShell::AlreadyInQueue(nsIReflowCommand* aReflowCommand, RCType == queuedRCType) { #ifdef DEBUG if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) { - printf("*** PresShell::AlreadyInQueue(): Discarding reflow command: this=%p\n", this); + printf("*** PresShell::AlreadyInQueue(): Discarding reflow command: this=%p\n", (void*)this); aReflowCommand->List(stdout); } #endif @@ -3340,7 +3352,7 @@ PresShell::AppendReflowCommandInternal(nsIReflowCommand* aReflowCommand, return NS_OK; } if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) { - printf("\nPresShell@%p: adding reflow command\n", this); + printf("\nPresShell@%p: adding reflow command\n", (void*)this); aReflowCommand->List(stdout); if (VERIFY_REFLOW_REALLY_NOISY_RC & gVerifyReflowFlags) { printf("Current content model:\n"); @@ -3430,7 +3442,7 @@ PresShell::CancelReflowCommandInternal(nsIFrame* aTargetFrame, } #ifdef DEBUG if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) { - printf("PresShell: removing rc=%p for frame ", rc); + printf("PresShell: removing rc=%p for frame ", (void*)rc); nsFrame::ListTag(stdout, aTargetFrame); printf("\n"); } @@ -3901,6 +3913,137 @@ PresShell::ScrollFrameIntoView(nsIFrame *aFrame, return rv; } +// CopyStringToClipboard: copy simple string to clipboard +nsresult PresShell::CopyStringToClipboard(nsString& aString, + PRInt32 aClipboardID) +{ + nsresult rv; + + // get the clipboard + nsCOMPtr + clipboard(do_GetService("@mozilla.org/widget/clipboard;1", &rv)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(clipboard, NS_ERROR_FAILURE); + + // create a transferable for putting data on the clipboard + nsCOMPtr + trans(do_CreateInstance("@mozilla.org/widget/transferable;1", &rv)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(trans, NS_ERROR_FAILURE); + + // Add the text data flavor to the transferable + rv = trans->AddDataFlavor(kUnicodeMime); + NS_ENSURE_SUCCESS(rv, rv); + + // get wStrings to hold clip data + nsCOMPtr + data(do_CreateInstance("@mozilla.org/supports-wstring;1", &rv)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(data, NS_ERROR_FAILURE); + + // populate the string + rv = data->SetData(NS_CONST_CAST(PRUnichar*, aString.GetUnicode())); + NS_ENSURE_SUCCESS(rv, rv); + + // qi the data object an |nsISupports| so that when the transferable holds + // onto it, it will addref the correct interface. + nsCOMPtr genericData(do_QueryInterface(data, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(genericData, NS_ERROR_FAILURE); + + // set the transfer data + rv = trans->SetTransferData(kUnicodeMime, genericData, + aString.Length() * 2); + NS_ENSURE_SUCCESS(rv, rv); + + // put the transferable on the clipboard + rv = clipboard->SetData(trans, nsnull, aClipboardID); + NS_ENSURE_SUCCESS(rv, rv); + + return NS_OK; +} + +// CopyStringToClipboard: copy string to clipboard(s) for platform +nsresult PresShell::CopyStringToClipboard(nsString& aString) +{ +#ifdef DEBUG_dr + printf("dr :: CopyStringToClipboard: %s\n", + NS_ConvertUCS2toUTF8(aString).get()); +#endif + + nsresult rv; + + // copy to the global clipboard + rv = CopyStringToClipboard(aString, nsIClipboard::kGlobalClipboard); + NS_ENSURE_SUCCESS(rv, rv); + +#ifdef XP_UNIX + // unix also needs us to copy to the selection clipboard + rv = CopyStringToClipboard(aString, nsIClipboard::kSelectionClipboard); + NS_ENSURE_SUCCESS(rv, rv); +#endif + + return NS_OK; +} + +// DoCopyLinkLocation: copy link location to clipboard +NS_IMETHODIMP PresShell::DoCopyLinkLocation(nsIDOMNode* aNode) +{ +#ifdef DEBUG_dr + printf("dr :: PresShell::DoCopyLinkLocation\n"); +#endif + + NS_ENSURE_ARG_POINTER(aNode); + nsresult rv; + + // are we an anchor? + nsCOMPtr anchor(do_QueryInterface(aNode, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + if (anchor) { + // if so, copy the link: + nsAutoString anchorText; + rv = anchor->GetHref(anchorText); + NS_ENSURE_SUCCESS(rv, rv); + return CopyStringToClipboard(anchorText); + } + + // if no link, fail. + return NS_ERROR_FAILURE; +} + +// DoCopyImageLocation: copy image location to clipboard +NS_IMETHODIMP PresShell::DoCopyImageLocation(nsIDOMNode* aNode) +{ +#ifdef DEBUG_dr + printf("dr :: PresShell::DoCopyImageLocation\n"); +#endif + + NS_ENSURE_ARG_POINTER(aNode); + nsresult rv; + + // are we an image? + nsCOMPtr img(do_QueryInterface(aNode, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + if (img) { + // if so, copy the location: + nsAutoString srcText; + rv = img->GetSrc(srcText); + NS_ENSURE_SUCCESS(rv, rv); + return CopyStringToClipboard(srcText); + } + + // if no image, fail. + return NS_ERROR_FAILURE; +} + +// DoCopyImageContents: copy image contents to clipboard +NS_IMETHODIMP PresShell::DoCopyImageContents(nsIDOMNode* aNode) +{ + // XXX dr: platform-specific widget code works on windows and mac. + // when linux copy image contents works, this should get written + // and hooked up to the front end, similarly to cmd_copyImageLocation. + return NS_ERROR_NOT_IMPLEMENTED; +} NS_IMETHODIMP PresShell::DoCopy() @@ -5354,7 +5497,7 @@ struct ReflowEvent : public PLEvent { if (presShell) { #ifdef DEBUG if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) { - printf("\n*** Handling reflow event: PresShell=%p, event=%p\n", presShell.get(), this); + printf("\n*** Handling reflow event: PresShell=%p, event=%p\n", (void*)presShell.get(), (void*)this); } #endif // XXX Statically cast the pres shell pointer so that we can call @@ -5417,7 +5560,7 @@ PresShell::PostReflowEvent() mPendingReflowEvent = PR_TRUE; #ifdef DEBUG if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) { - printf("\n*** PresShell::PostReflowEvent(), this=%p, event=%p\n", this, ev); + printf("\n*** PresShell::PostReflowEvent(), this=%p, event=%p\n", (void*)this, (void*)ev); } #endif } @@ -5501,7 +5644,7 @@ PresShell::ProcessReflowCommands(PRBool aInterruptible) } if (VERIFY_REFLOW_DUMP_COMMANDS & gVerifyReflowFlags) { PRInt32 i, n = mReflowCommands.Count(); - printf("\nPresShell::ProcessReflowCommands: this=%p, count=%d\n", this, n); + printf("\nPresShell::ProcessReflowCommands: this=%p, count=%d\n", (void*)this, n); for (i = 0; i < n; i++) { nsIReflowCommand* rc = (nsIReflowCommand*) mReflowCommands.ElementAt(i); @@ -5539,7 +5682,7 @@ PresShell::ProcessReflowCommands(PRBool aInterruptible) #ifdef DEBUG if (VERIFY_REFLOW_DUMP_COMMANDS & gVerifyReflowFlags) { printf("Time spent in PresShell::ProcessReflowCommands(), this=%p, time=%d micro seconds\n", - this, mAccumulatedReflowTime); + (void*)this, mAccumulatedReflowTime); } #endif mAccumulatedReflowTime = 0; @@ -5548,7 +5691,7 @@ PresShell::ProcessReflowCommands(PRBool aInterruptible) #ifdef DEBUG if (VERIFY_REFLOW_DUMP_COMMANDS & gVerifyReflowFlags) { - printf("\nPresShell::ProcessReflowCommands() finished: this=%p\n", this); + printf("\nPresShell::ProcessReflowCommands() finished: this=%p\n", (void*)this); } if (nsIFrameDebug::GetVerifyTreeEnable()) { @@ -5863,7 +6006,7 @@ LogVerifyMessage(nsIFrame* k1, nsIFrame* k2, const char* aMsg, fprintf(stdout, " "); frameDebug->GetFrameName(name); fputs(name, stdout); - fprintf(stdout, " %p ", k1); + fprintf(stdout, " %p ", (void*)k1); } printf("{%d, %d, %d, %d}", r1.x, r1.y, r1.width, r1.height); @@ -5874,7 +6017,7 @@ LogVerifyMessage(nsIFrame* k1, nsIFrame* k2, const char* aMsg, fprintf(stdout, " "); frameDebug->GetFrameName(name); fputs(name, stdout); - fprintf(stdout, " %p ", k2); + fprintf(stdout, " %p ", (void*)k2); } printf("{%d, %d, %d, %d}\n", r2.x, r2.y, r2.width, r2.height); diff --git a/mozilla/mailnews/base/resources/content/mailWindowOverlay.xul b/mozilla/mailnews/base/resources/content/mailWindowOverlay.xul index f3fb63476ba..db8958e8e18 100644 --- a/mozilla/mailnews/base/resources/content/mailWindowOverlay.xul +++ b/mozilla/mailnews/base/resources/content/mailWindowOverlay.xul @@ -121,6 +121,9 @@ Rights Reserved. + + + + command="cmd_copyLink"/> + command="cmd_copyImageLocation"/> */ + #include "nsCOMPtr.h" #include "nscore.h" #include "nsCRT.h" @@ -753,6 +755,40 @@ PluginViewerImpl::PrintContent(nsIWebShell * aParent, return NS_OK; } +NS_IMETHODIMP +PluginViewerImpl::GetInLink(PRBool* aInLink) +{ + NS_ENSURE_ARG_POINTER(aInLink); + *aInLink = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP +PluginViewerImpl::GetInImage(PRBool* aInImage) +{ + NS_ENSURE_ARG_POINTER(aInImage); + *aInImage = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP +PluginViewerImpl::CopyLinkLocation() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +PluginViewerImpl::CopyImageLocation() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +PluginViewerImpl::CopyImageContents() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + //---------------------------------------------------------------------- diff --git a/mozilla/modules/plugin/nglsrc/nsPluginViewer.cpp b/mozilla/modules/plugin/nglsrc/nsPluginViewer.cpp index 9b1d1b3b431..36f66424da3 100644 --- a/mozilla/modules/plugin/nglsrc/nsPluginViewer.cpp +++ b/mozilla/modules/plugin/nglsrc/nsPluginViewer.cpp @@ -17,8 +17,10 @@ * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * - * Contributor(s): + * Contributor(s): + * Dan Rosen */ + #include "nsCOMPtr.h" #include "nscore.h" #include "nsCRT.h" @@ -753,6 +755,40 @@ PluginViewerImpl::PrintContent(nsIWebShell * aParent, return NS_OK; } +NS_IMETHODIMP +PluginViewerImpl::GetInLink(PRBool* aInLink) +{ + NS_ENSURE_ARG_POINTER(aInLink); + *aInLink = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP +PluginViewerImpl::GetInImage(PRBool* aInImage) +{ + NS_ENSURE_ARG_POINTER(aInImage); + *aInImage = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP +PluginViewerImpl::CopyLinkLocation() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +PluginViewerImpl::CopyImageLocation() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +PluginViewerImpl::CopyImageContents() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + //---------------------------------------------------------------------- diff --git a/mozilla/xpfe/browser/resources/content/navigatorOverlay.xul b/mozilla/xpfe/browser/resources/content/navigatorOverlay.xul index 3bae32d5410..9075eceb6ad 100644 --- a/mozilla/xpfe/browser/resources/content/navigatorOverlay.xul +++ b/mozilla/xpfe/browser/resources/content/navigatorOverlay.xul @@ -121,7 +121,12 @@ - + + + + + + diff --git a/mozilla/xpfe/communicator/resources/content/contentAreaContextOverlay.xul b/mozilla/xpfe/communicator/resources/content/contentAreaContextOverlay.xul index cdf9294a87f..db52f7fcf4b 100644 --- a/mozilla/xpfe/communicator/resources/content/contentAreaContextOverlay.xul +++ b/mozilla/xpfe/communicator/resources/content/contentAreaContextOverlay.xul @@ -150,11 +150,11 @@ + command="cmd_copyLink"/> + command="cmd_copyImageLocation"/> is an image. objectIsImage : function ( objElem ) { var result = false; diff --git a/mozilla/xpfe/communicator/resources/content/utilityOverlay.js b/mozilla/xpfe/communicator/resources/content/utilityOverlay.js index 7a25d6e7c94..e6c364a70bd 100644 --- a/mozilla/xpfe/communicator/resources/content/utilityOverlay.js +++ b/mozilla/xpfe/communicator/resources/content/utilityOverlay.js @@ -209,7 +209,7 @@ function goAboutDialog() window.openDialog( getBrowserURL(), "_blank", "chrome,all,dialog=no", 'chrome://global/locale/about.html' ); } - +// update menu items that rely on focus function goUpdateGlobalEditMenuItems() { goUpdateCommand('cmd_undo'); diff --git a/mozilla/xpfe/communicator/resources/content/utilityOverlay.xul b/mozilla/xpfe/communicator/resources/content/utilityOverlay.xul index 3db44f81998..705b63a6409 100644 --- a/mozilla/xpfe/communicator/resources/content/utilityOverlay.xul +++ b/mozilla/xpfe/communicator/resources/content/utilityOverlay.xul @@ -1,170 +1,285 @@ + + + %brandDTD; - + %globalRegionDTD; - + %utilityDTD; + ]> - -