mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Bug 501154, consolidate places where clipboard events are fired from, r=smaug,sr=neil
This commit is contained in:
parent
aed5827557
commit
3ea1a5bd7d
@ -48,6 +48,7 @@ class nsITransferable;
|
|||||||
class nsACString;
|
class nsACString;
|
||||||
class nsAString;
|
class nsAString;
|
||||||
class nsIDOMNode;
|
class nsIDOMNode;
|
||||||
|
class nsIPresShell;
|
||||||
|
|
||||||
class nsCopySupport
|
class nsCopySupport
|
||||||
{
|
{
|
||||||
@ -66,16 +67,51 @@ class nsCopySupport
|
|||||||
static nsresult ImageCopy(nsIImageLoadingContent* aImageElement,
|
static nsresult ImageCopy(nsIImageLoadingContent* aImageElement,
|
||||||
PRInt32 aCopyFlags);
|
PRInt32 aCopyFlags);
|
||||||
|
|
||||||
// Given the current selection, find the target that
|
|
||||||
// before[copy,cut,paste] and [copy,cut,paste] events will fire on.
|
|
||||||
static nsresult GetClipboardEventTarget(nsISelection *aSel,
|
|
||||||
nsIDOMNode **aEventTarget);
|
|
||||||
|
|
||||||
// Get the selection as a transferable. Similar to HTMLCopy except does
|
// Get the selection as a transferable. Similar to HTMLCopy except does
|
||||||
// not deal with the clipboard.
|
// not deal with the clipboard.
|
||||||
static nsresult GetTransferableForSelection(nsISelection * aSelection,
|
static nsresult GetTransferableForSelection(nsISelection * aSelection,
|
||||||
nsIDocument * aDocument,
|
nsIDocument * aDocument,
|
||||||
nsITransferable ** aTransferable);
|
nsITransferable ** aTransferable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the selection for the given document. If the current focus
|
||||||
|
* within the document has its own selection, aSelection will be set to it
|
||||||
|
* and this focused content node returned. Otherwise, aSelection will be
|
||||||
|
* set to the document's selection and null will be returned.
|
||||||
|
*/
|
||||||
|
static nsIContent* GetSelectionForCopy(nsIDocument* aDocument,
|
||||||
|
nsISelection** aSelection);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if a copy operation is currently permitted based on the
|
||||||
|
* current focus and selection within the specified document.
|
||||||
|
*/
|
||||||
|
static PRBool CanCopy(nsIDocument* aDocument);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fires a cut, copy or paste event, on the given presshell, depending
|
||||||
|
* on the value of aType, which should be either NS_CUT, NS_COPY or
|
||||||
|
* NS_PASTE, and perform the default copy action if the event was not
|
||||||
|
* cancelled.
|
||||||
|
*
|
||||||
|
* If aSelection is specified, then this selection is used as the target
|
||||||
|
* of the operation. Otherwise, GetSelectionForCopy is used to retrieve
|
||||||
|
* the current selection.
|
||||||
|
*
|
||||||
|
* This will fire a cut, copy or paste event at the node at the start
|
||||||
|
* point of the selection. If a cut or copy event is not cancelled, the
|
||||||
|
* selection is copied to the clipboard and true is returned. Paste events
|
||||||
|
* have no default behaviour but true will be returned. It is expected
|
||||||
|
* that the caller will execute any needed default paste behaviour. Also,
|
||||||
|
* note that this method only copies text to the clipboard, the caller is
|
||||||
|
* responsible for removing the content during a cut operation if true is
|
||||||
|
* returned.
|
||||||
|
*
|
||||||
|
* If the event is cancelled or an error occurs, false will be returned.
|
||||||
|
*/
|
||||||
|
static PRBool FireClipboardEvent(PRInt32 aType,
|
||||||
|
nsIPresShell* aPresShell,
|
||||||
|
nsISelection* aSelection);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -50,18 +50,26 @@
|
|||||||
#include "nsISupportsPrimitives.h"
|
#include "nsISupportsPrimitives.h"
|
||||||
#include "nsIDOMRange.h"
|
#include "nsIDOMRange.h"
|
||||||
#include "imgIContainer.h"
|
#include "imgIContainer.h"
|
||||||
|
#include "nsIPresShell.h"
|
||||||
|
#include "nsFocusManager.h"
|
||||||
|
#include "nsEventDispatcher.h"
|
||||||
|
|
||||||
#include "nsIDocShell.h"
|
#include "nsIDocShell.h"
|
||||||
#include "nsIContentViewerEdit.h"
|
#include "nsIContentViewerEdit.h"
|
||||||
#include "nsIClipboardDragDropHooks.h"
|
#include "nsIClipboardDragDropHooks.h"
|
||||||
#include "nsIClipboardDragDropHookList.h"
|
#include "nsIClipboardDragDropHookList.h"
|
||||||
|
#include "nsIClipboardHelper.h"
|
||||||
|
#include "nsISelectionController.h"
|
||||||
|
|
||||||
|
#include "nsPIDOMWindow.h"
|
||||||
#include "nsIDocument.h"
|
#include "nsIDocument.h"
|
||||||
#include "nsIDOMNode.h"
|
#include "nsIDOMNode.h"
|
||||||
#include "nsIDOMElement.h"
|
#include "nsIDOMElement.h"
|
||||||
#include "nsIDOMDocument.h"
|
#include "nsIDOMDocument.h"
|
||||||
#include "nsIHTMLDocument.h"
|
#include "nsIHTMLDocument.h"
|
||||||
#include "nsGkAtoms.h"
|
#include "nsGkAtoms.h"
|
||||||
|
#include "nsGUIEvent.h"
|
||||||
|
#include "nsIFrame.h"
|
||||||
|
|
||||||
// image copy stuff
|
// image copy stuff
|
||||||
#include "nsIImageLoadingContent.h"
|
#include "nsIImageLoadingContent.h"
|
||||||
@ -582,26 +590,128 @@ static nsresult AppendDOMNode(nsITransferable *aTransferable,
|
|||||||
return AppendString(aTransferable, context, kHTMLContext);
|
return AppendString(aTransferable, context, kHTMLContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the target that onbefore[copy,cut,paste] and on[copy,cut,paste]
|
nsIContent*
|
||||||
// events will fire on -- the start node of the copy selection.
|
nsCopySupport::GetSelectionForCopy(nsIDocument* aDocument, nsISelection** aSelection)
|
||||||
nsresult nsCopySupport::GetClipboardEventTarget(nsISelection *aSel,
|
|
||||||
nsIDOMNode **aEventTarget)
|
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG(aSel);
|
*aSelection = nsnull;
|
||||||
NS_ENSURE_ARG_POINTER(aEventTarget);
|
|
||||||
*aEventTarget = nsnull;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMRange> range;
|
nsIPresShell* presShell = aDocument->GetPrimaryShell();
|
||||||
nsresult rv = aSel->GetRangeAt(0, getter_AddRefs(range));
|
if (!presShell)
|
||||||
if (rv == NS_ERROR_INVALID_ARG) // empty selection
|
return nsnull;
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (!range)
|
// check if the focused node in the window has a selection
|
||||||
return NS_ERROR_FAILURE;
|
nsCOMPtr<nsPIDOMWindow> focusedWindow;
|
||||||
|
nsIContent* content =
|
||||||
|
nsFocusManager::GetFocusedDescendant(aDocument->GetWindow(), PR_FALSE,
|
||||||
|
getter_AddRefs(focusedWindow));
|
||||||
|
if (content) {
|
||||||
|
nsIFrame* frame = content->GetPrimaryFrame();
|
||||||
|
if (frame) {
|
||||||
|
nsCOMPtr<nsISelectionController> selCon;
|
||||||
|
frame->GetSelectionController(presShell->GetPresContext(), getter_AddRefs(selCon));
|
||||||
|
if (selCon) {
|
||||||
|
selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, aSelection);
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rv = range->GetStartContainer(aEventTarget);
|
// if no selection was found, use the main selection for the window
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_IF_ADDREF(*aSelection = presShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL));
|
||||||
|
return nsnull;
|
||||||
return (*aEventTarget) ? NS_OK : NS_ERROR_FAILURE;
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsCopySupport::CanCopy(nsIDocument* aDocument)
|
||||||
|
{
|
||||||
|
if (!aDocument)
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
nsCOMPtr<nsISelection> sel;
|
||||||
|
GetSelectionForCopy(aDocument, getter_AddRefs(sel));
|
||||||
|
|
||||||
|
PRBool isCollapsed;
|
||||||
|
sel->GetIsCollapsed(&isCollapsed);
|
||||||
|
return !isCollapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsCopySupport::FireClipboardEvent(PRInt32 aType, nsIPresShell* aPresShell, nsISelection* aSelection)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(aType == NS_CUT || aType == NS_COPY || aType == NS_PASTE,
|
||||||
|
"Invalid clipboard event type");
|
||||||
|
|
||||||
|
nsCOMPtr<nsIPresShell> presShell = aPresShell;
|
||||||
|
if (!presShell)
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDocument> doc = presShell->GetDocument();
|
||||||
|
if (!doc)
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
nsCOMPtr<nsPIDOMWindow> piWindow = doc->GetWindow();
|
||||||
|
if (!piWindow)
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
// if a selection was not supplied, try to find it
|
||||||
|
nsCOMPtr<nsIContent> content;
|
||||||
|
nsCOMPtr<nsISelection> sel = aSelection;
|
||||||
|
if (!sel)
|
||||||
|
content = GetSelectionForCopy(doc, getter_AddRefs(sel));
|
||||||
|
|
||||||
|
// retrieve the event target node from the start of the selection
|
||||||
|
if (sel) {
|
||||||
|
// Only cut or copy when there is an uncollapsed selection
|
||||||
|
if (aType == NS_CUT || aType == NS_COPY) {
|
||||||
|
PRBool isCollapsed;
|
||||||
|
sel->GetIsCollapsed(&isCollapsed);
|
||||||
|
if (isCollapsed)
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMRange> range;
|
||||||
|
nsresult rv = sel->GetRangeAt(0, getter_AddRefs(range));
|
||||||
|
if (NS_SUCCEEDED(rv) && range) {
|
||||||
|
nsCOMPtr<nsIDOMNode> startContainer;
|
||||||
|
range->GetStartContainer(getter_AddRefs(startContainer));
|
||||||
|
if (startContainer)
|
||||||
|
content = do_QueryInterface(startContainer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if no content node was set, just get the root
|
||||||
|
if (!content) {
|
||||||
|
content = doc->GetRootContent();
|
||||||
|
if (!content)
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// It seems to be unsafe to fire an event handler during reflow (bug 393696)
|
||||||
|
if (!nsContentUtils::IsSafeToRunScript())
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
// next, fire the cut or copy event
|
||||||
|
nsEventStatus status = nsEventStatus_eIgnore;
|
||||||
|
nsEvent evt(PR_TRUE, aType);
|
||||||
|
nsEventDispatcher::Dispatch(content, presShell->GetPresContext(), &evt, nsnull,
|
||||||
|
&status);
|
||||||
|
// if the event was cancelled, don't do the clipboard operation
|
||||||
|
if (status == nsEventStatus_eConsumeNoDefault)
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
// no need to do anything special during a paste. Either an event listener
|
||||||
|
// took care of it and cancelled the event, or the caller will handle it.
|
||||||
|
// Return true to indicate the event wasn't cancelled.
|
||||||
|
if (aType == NS_PASTE)
|
||||||
|
return PR_TRUE;
|
||||||
|
|
||||||
|
// call the copy code
|
||||||
|
if (NS_FAILED(nsCopySupport::HTMLCopy(sel, doc, nsIClipboard::kGlobalClipboard)))
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
// Now that we have copied, update the clipboard commands. This should have
|
||||||
|
// the effect of updating the paste menu item.
|
||||||
|
piWindow->UpdateCommands(NS_LITERAL_STRING("clipboard"));
|
||||||
|
|
||||||
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -89,8 +89,8 @@ nsContentEventHandler::InitCommon()
|
|||||||
nsresult rv = mPresShell->FlushPendingNotifications(Flush_Layout);
|
nsresult rv = mPresShell->FlushPendingNotifications(Flush_Layout);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
rv = mPresShell->GetSelectionForCopy(getter_AddRefs(mSelection));
|
nsCopySupport::GetSelectionForCopy(mPresShell->GetDocument(),
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
getter_AddRefs(mSelection));
|
||||||
NS_ASSERTION(mSelection,
|
NS_ASSERTION(mSelection,
|
||||||
"GetSelectionForCopy succeeded, but the result is null");
|
"GetSelectionForCopy succeeded, but the result is null");
|
||||||
|
|
||||||
|
@ -40,12 +40,9 @@
|
|||||||
|
|
||||||
#include "nsISupports.idl"
|
#include "nsISupports.idl"
|
||||||
|
|
||||||
[scriptable, uuid(1691a02f-53b2-4cb8-8769-48e7efc908b8)]
|
[scriptable, uuid(AF13EA3A-D488-4308-B843-526E055AB943)]
|
||||||
interface nsIContentViewerEdit : nsISupports
|
interface nsIContentViewerEdit : nsISupports
|
||||||
{
|
{
|
||||||
void search();
|
|
||||||
readonly attribute boolean searchable;
|
|
||||||
|
|
||||||
void clearSelection();
|
void clearSelection();
|
||||||
void selectAll();
|
void selectAll();
|
||||||
|
|
||||||
@ -62,12 +59,6 @@ interface nsIContentViewerEdit : nsISupports
|
|||||||
void copyImage(in long aCopyFlags);
|
void copyImage(in long aCopyFlags);
|
||||||
readonly attribute boolean inImage;
|
readonly attribute boolean inImage;
|
||||||
|
|
||||||
void cutSelection();
|
|
||||||
readonly attribute boolean cutable;
|
|
||||||
|
|
||||||
void paste();
|
|
||||||
readonly attribute boolean pasteable;
|
|
||||||
|
|
||||||
AString getContents(in string aMimeType, in boolean aSelectionOnly);
|
AString getContents(in string aMimeType, in boolean aSelectionOnly);
|
||||||
readonly attribute boolean canGetContents;
|
readonly attribute boolean canGetContents;
|
||||||
};
|
};
|
||||||
|
@ -59,6 +59,8 @@
|
|||||||
#include "nsIContentViewerEdit.h"
|
#include "nsIContentViewerEdit.h"
|
||||||
#include "nsIContentViewer.h"
|
#include "nsIContentViewer.h"
|
||||||
#include "nsFocusManager.h"
|
#include "nsFocusManager.h"
|
||||||
|
#include "nsCopySupport.h"
|
||||||
|
#include "nsGUIEvent.h"
|
||||||
|
|
||||||
#include "nsIClipboardDragDropHooks.h"
|
#include "nsIClipboardDragDropHooks.h"
|
||||||
#include "nsIClipboardDragDropHookList.h"
|
#include "nsIClipboardDragDropHookList.h"
|
||||||
@ -407,7 +409,71 @@ nsSelectCommand::DoSelectCommand(const char *aCommandName, nsIDOMWindow *aWindow
|
|||||||
#pragma mark -
|
#pragma mark -
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class nsClipboardBaseCommand : public nsIControllerCommand
|
class nsClipboardCommand : public nsIControllerCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSICONTROLLERCOMMAND
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(nsClipboardCommand, nsIControllerCommand)
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsClipboardCommand::IsCommandEnabled(const char* aCommandName, nsISupports *aContext, PRBool *outCmdEnabled)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(outCmdEnabled);
|
||||||
|
*outCmdEnabled = PR_FALSE;
|
||||||
|
|
||||||
|
if (strcmp(aCommandName, "cmd_copy"))
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aContext);
|
||||||
|
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDocument> doc = do_QueryInterface(window->GetExtantDocument());
|
||||||
|
*outCmdEnabled = nsCopySupport::CanCopy(doc);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsClipboardCommand::DoCommand(const char *aCommandName, nsISupports *aContext)
|
||||||
|
{
|
||||||
|
if (strcmp(aCommandName, "cmd_copy"))
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aContext);
|
||||||
|
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
nsIDocShell *docShell = window->GetDocShell();
|
||||||
|
NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIPresShell> presShell;
|
||||||
|
docShell->GetPresShell(getter_AddRefs(presShell));
|
||||||
|
NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
nsCopySupport::FireClipboardEvent(NS_COPY, presShell, nsnull);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsClipboardCommand::GetCommandStateParams(const char *aCommandName,
|
||||||
|
nsICommandParams *aParams, nsISupports *aCommandContext)
|
||||||
|
{
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsClipboardCommand::DoCommandParams(const char *aCommandName, nsICommandParams* aParams, nsISupports *aContext)
|
||||||
|
{
|
||||||
|
return DoCommand(aCommandName, aContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#pragma mark -
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class nsSelectionCommand : public nsIControllerCommand
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -425,19 +491,19 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(nsClipboardBaseCommand, nsIControllerCommand)
|
NS_IMPL_ISUPPORTS1(nsSelectionCommand, nsIControllerCommand)
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
|
|
||||||
nsClipboardBaseCommand
|
nsSelectionCommand
|
||||||
|
|
||||||
----------------------------------------------------------------------------*/
|
----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsClipboardBaseCommand::IsCommandEnabled(const char * aCommandName,
|
nsSelectionCommand::IsCommandEnabled(const char * aCommandName,
|
||||||
nsISupports *aCommandContext,
|
nsISupports *aCommandContext,
|
||||||
PRBool *outCmdEnabled)
|
PRBool *outCmdEnabled)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG_POINTER(outCmdEnabled);
|
NS_ENSURE_ARG_POINTER(outCmdEnabled);
|
||||||
*outCmdEnabled = PR_FALSE;
|
*outCmdEnabled = PR_FALSE;
|
||||||
@ -450,8 +516,8 @@ nsClipboardBaseCommand::IsCommandEnabled(const char * aCommandName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsClipboardBaseCommand::DoCommand(const char *aCommandName,
|
nsSelectionCommand::DoCommand(const char *aCommandName,
|
||||||
nsISupports *aCommandContext)
|
nsISupports *aCommandContext)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIContentViewerEdit> contentEdit;
|
nsCOMPtr<nsIContentViewerEdit> contentEdit;
|
||||||
GetContentViewerEditFromContext(aCommandContext, getter_AddRefs(contentEdit));
|
GetContentViewerEditFromContext(aCommandContext, getter_AddRefs(contentEdit));
|
||||||
@ -461,17 +527,17 @@ nsClipboardBaseCommand::DoCommand(const char *aCommandName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsClipboardBaseCommand::GetCommandStateParams(const char *aCommandName,
|
nsSelectionCommand::GetCommandStateParams(const char *aCommandName,
|
||||||
nsICommandParams *aParams,
|
nsICommandParams *aParams,
|
||||||
nsISupports *aCommandContext)
|
nsISupports *aCommandContext)
|
||||||
{
|
{
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsClipboardBaseCommand::DoCommandParams(const char *aCommandName,
|
nsSelectionCommand::DoCommandParams(const char *aCommandName,
|
||||||
nsICommandParams *aParams,
|
nsICommandParams *aParams,
|
||||||
nsISupports *aCommandContext)
|
nsISupports *aCommandContext)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIContentViewerEdit> contentEdit;
|
nsCOMPtr<nsIContentViewerEdit> contentEdit;
|
||||||
GetContentViewerEditFromContext(aCommandContext, getter_AddRefs(contentEdit));
|
GetContentViewerEditFromContext(aCommandContext, getter_AddRefs(contentEdit));
|
||||||
@ -481,8 +547,8 @@ nsClipboardBaseCommand::DoCommandParams(const char *aCommandName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsClipboardBaseCommand::GetContentViewerEditFromContext(nsISupports *aContext,
|
nsSelectionCommand::GetContentViewerEditFromContext(nsISupports *aContext,
|
||||||
nsIContentViewerEdit **aEditInterface)
|
nsIContentViewerEdit **aEditInterface)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG(aEditInterface);
|
NS_ENSURE_ARG(aEditInterface);
|
||||||
*aEditInterface = nsnull;
|
*aEditInterface = nsnull;
|
||||||
@ -508,7 +574,7 @@ nsClipboardBaseCommand::GetContentViewerEditFromContext(nsISupports *aContext,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define NS_DECL_CLIPBOARD_COMMAND(_cmd) \
|
#define NS_DECL_CLIPBOARD_COMMAND(_cmd) \
|
||||||
class _cmd : public nsClipboardBaseCommand \
|
class _cmd : public nsSelectionCommand \
|
||||||
{ \
|
{ \
|
||||||
protected: \
|
protected: \
|
||||||
\
|
\
|
||||||
@ -519,68 +585,11 @@ protected:
|
|||||||
/* no member variables, please, we're stateless! */ \
|
/* no member variables, please, we're stateless! */ \
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_DECL_CLIPBOARD_COMMAND(nsClipboardCopyCommand)
|
|
||||||
NS_DECL_CLIPBOARD_COMMAND(nsClipboardCutCommand)
|
|
||||||
NS_DECL_CLIPBOARD_COMMAND(nsClipboardPasteCommand)
|
|
||||||
NS_DECL_CLIPBOARD_COMMAND(nsClipboardCopyLinkCommand)
|
NS_DECL_CLIPBOARD_COMMAND(nsClipboardCopyLinkCommand)
|
||||||
NS_DECL_CLIPBOARD_COMMAND(nsClipboardImageCommands)
|
NS_DECL_CLIPBOARD_COMMAND(nsClipboardImageCommands)
|
||||||
NS_DECL_CLIPBOARD_COMMAND(nsClipboardSelectAllNoneCommands)
|
NS_DECL_CLIPBOARD_COMMAND(nsClipboardSelectAllNoneCommands)
|
||||||
NS_DECL_CLIPBOARD_COMMAND(nsClipboardGetContentsCommand)
|
NS_DECL_CLIPBOARD_COMMAND(nsClipboardGetContentsCommand)
|
||||||
|
|
||||||
#if 0
|
|
||||||
#pragma mark -
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsClipboardCutCommand::IsClipboardCommandEnabled(const char* aCommandName, nsIContentViewerEdit* aEdit, PRBool *outCmdEnabled)
|
|
||||||
{
|
|
||||||
return aEdit->GetCutable(outCmdEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsClipboardCutCommand::DoClipboardCommand(const char *aCommandName, nsIContentViewerEdit* aEdit, nsICommandParams* aParams)
|
|
||||||
{
|
|
||||||
return aEdit->CutSelection();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
#pragma mark -
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsClipboardCopyCommand::IsClipboardCommandEnabled(const char* aCommandName, nsIContentViewerEdit* aEdit, PRBool *outCmdEnabled)
|
|
||||||
{
|
|
||||||
return aEdit->GetCopyable(outCmdEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsClipboardCopyCommand::DoClipboardCommand(const char *aCommandName, nsIContentViewerEdit* aEdit, nsICommandParams* aParams)
|
|
||||||
{
|
|
||||||
return aEdit->CopySelection();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
#pragma mark -
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsClipboardPasteCommand::IsClipboardCommandEnabled(const char* aCommandName, nsIContentViewerEdit* aEdit, PRBool *outCmdEnabled)
|
|
||||||
{
|
|
||||||
return aEdit->GetPasteable(outCmdEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsClipboardPasteCommand::DoClipboardCommand(const char *aCommandName, nsIContentViewerEdit* aEdit, nsICommandParams* aParams)
|
|
||||||
{
|
|
||||||
return aEdit->Paste();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
#pragma mark -
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsClipboardCopyLinkCommand::IsClipboardCommandEnabled(const char* aCommandName, nsIContentViewerEdit* aEdit, PRBool *outCmdEnabled)
|
nsClipboardCopyLinkCommand::IsClipboardCommandEnabled(const char* aCommandName, nsIContentViewerEdit* aEdit, PRBool *outCmdEnabled)
|
||||||
{
|
{
|
||||||
@ -965,9 +974,9 @@ nsWindowCommandRegistration::RegisterWindowCommands(
|
|||||||
NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectTopString);
|
NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectTopString);
|
||||||
NS_REGISTER_LAST_COMMAND(nsSelectCommand, sSelectBottomString);
|
NS_REGISTER_LAST_COMMAND(nsSelectCommand, sSelectBottomString);
|
||||||
|
|
||||||
NS_REGISTER_ONE_COMMAND(nsClipboardCopyCommand, "cmd_copy");
|
NS_REGISTER_ONE_COMMAND(nsClipboardCommand, "cmd_cut");
|
||||||
NS_REGISTER_ONE_COMMAND(nsClipboardCutCommand, "cmd_cut");
|
NS_REGISTER_ONE_COMMAND(nsClipboardCommand, "cmd_copy");
|
||||||
NS_REGISTER_ONE_COMMAND(nsClipboardPasteCommand, "cmd_paste");
|
NS_REGISTER_ONE_COMMAND(nsClipboardCommand, "cmd_paste");
|
||||||
NS_REGISTER_ONE_COMMAND(nsClipboardCopyLinkCommand, "cmd_copyLink");
|
NS_REGISTER_ONE_COMMAND(nsClipboardCopyLinkCommand, "cmd_copyLink");
|
||||||
NS_REGISTER_FIRST_COMMAND(nsClipboardImageCommands, sCopyImageLocationString);
|
NS_REGISTER_FIRST_COMMAND(nsClipboardImageCommands, sCopyImageLocationString);
|
||||||
NS_REGISTER_NEXT_COMMAND(nsClipboardImageCommands, sCopyImageContentsString);
|
NS_REGISTER_NEXT_COMMAND(nsClipboardImageCommands, sCopyImageContentsString);
|
||||||
|
@ -55,6 +55,7 @@ _TEST_FILES = \
|
|||||||
test_offsets.js \
|
test_offsets.js \
|
||||||
test_offsets.xul \
|
test_offsets.xul \
|
||||||
test_windowProperties.html \
|
test_windowProperties.html \
|
||||||
|
test_clipboard_events.html \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
libs:: $(_TEST_FILES)
|
libs:: $(_TEST_FILES)
|
||||||
|
322
dom/tests/mochitest/general/test_clipboard_events.html
Normal file
322
dom/tests/mochitest/general/test_clipboard_events.html
Normal file
@ -0,0 +1,322 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Test for Clipboard Events</title>
|
||||||
|
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||||
|
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="border: 3px solid black; padding: 3em;">CONTENT TEXT<input id="content-input" value="INPUT TEXT"></div>
|
||||||
|
|
||||||
|
<pre id="test">
|
||||||
|
<script class="testbody" type="text/javascript;version=1.7">
|
||||||
|
|
||||||
|
// Enable full privledges for clipboard read/write operations.
|
||||||
|
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||||
|
|
||||||
|
var content = document.getElementById("content");
|
||||||
|
var contentInput = document.getElementById("content-input");
|
||||||
|
var clipboardInitialValue = "empty";
|
||||||
|
|
||||||
|
// Test that clearing and reading the clipboard works. A random number
|
||||||
|
// is used to make sure that leftover clipboard values from a previous
|
||||||
|
// test run don't cause a false-positive test.
|
||||||
|
var cb_text = "empty_" + Math.random();
|
||||||
|
setClipboardText(cb_text);
|
||||||
|
is(getClipboardText(), cb_text, "set/get clipboard text failed");
|
||||||
|
|
||||||
|
// Some test functions need to be run with delays.
|
||||||
|
var delayedTests = [];
|
||||||
|
|
||||||
|
// Ensure window focus before running tests, otherwise key events can
|
||||||
|
// misfire. We set the onfocus event handler here to actually begin
|
||||||
|
// running tests, and call window.focus() afterwards.
|
||||||
|
window.onfocus = function()
|
||||||
|
{
|
||||||
|
window.onfocus = null;
|
||||||
|
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||||
|
|
||||||
|
// A list of test functions to run. Before each test function is run, the
|
||||||
|
// clipboard is initialized to clipboardInitialValue, and the contents of
|
||||||
|
// div#content are set as the window's selection.
|
||||||
|
var testFunctions = [
|
||||||
|
test_dom_oncopy,
|
||||||
|
test_dom_oncut,
|
||||||
|
test_dom_onpaste,
|
||||||
|
test_dom_oncopy_abort,
|
||||||
|
test_input_oncopy,
|
||||||
|
test_input_oncut,
|
||||||
|
test_input_onpaste,
|
||||||
|
test_input_oncopy_abort,
|
||||||
|
test_input_oncut_abort,
|
||||||
|
test_input_onpaste_abort,
|
||||||
|
];
|
||||||
|
|
||||||
|
// Run the main tests. This will also populate the delayedTests array
|
||||||
|
for (let i = 0; i < testFunctions.length; i++) {
|
||||||
|
// Init clipboard
|
||||||
|
setClipboardText(clipboardInitialValue);
|
||||||
|
|
||||||
|
// Reset value of contentInput.
|
||||||
|
contentInput.value = "INPUT TEXT";
|
||||||
|
|
||||||
|
var func = testFunctions[i];
|
||||||
|
func();
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calling .focus begins the test run.
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
window.focus();
|
||||||
|
|
||||||
|
function getClipboardText() {
|
||||||
|
var trans = Components.classes["@mozilla.org/widget/transferable;1"]
|
||||||
|
.createInstance();
|
||||||
|
trans = trans.QueryInterface(Components.interfaces.nsITransferable);
|
||||||
|
trans.addDataFlavor("text/unicode");
|
||||||
|
|
||||||
|
var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"]
|
||||||
|
.getService();
|
||||||
|
clipboard = clipboard.QueryInterface(Components.interfaces.nsIClipboard);
|
||||||
|
clipboard.getData(trans, clipboard.kGlobalClipboard);
|
||||||
|
|
||||||
|
var str = new Object();
|
||||||
|
var strLen = new Object();
|
||||||
|
|
||||||
|
try {
|
||||||
|
trans.getTransferData("text/unicode", str, strLen);
|
||||||
|
} catch(e) {
|
||||||
|
// NS_ERROR_FAILURE will occur if the transferable object has no
|
||||||
|
// text/unicode data in it. In that case, it's not an error:
|
||||||
|
if (e instanceof Components.interfaces.nsIXPCException &&
|
||||||
|
e.result == Components.results.NS_ERROR_FAILURE) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
// if we don't know how to handle it then rethrow
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!str) return null;
|
||||||
|
|
||||||
|
str = str.value.QueryInterface(Components.interfaces.nsISupportsString);
|
||||||
|
if (!str) return null;
|
||||||
|
|
||||||
|
str = str.data.substring(0, strLen.value / 2);
|
||||||
|
if (!str) return null;
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function setClipboardText(text) {
|
||||||
|
var helper = Components.classes["@mozilla.org/widget/clipboardhelper;1"]
|
||||||
|
.getService(Components.interfaces.nsIClipboardHelper);
|
||||||
|
helper.copyString(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectContentDiv() {
|
||||||
|
// Set selection
|
||||||
|
var selection = window.getSelection();
|
||||||
|
selection.removeAllRanges();
|
||||||
|
selection.selectAllChildren(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectContentInput() {
|
||||||
|
contentInput.select();
|
||||||
|
contentInput.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_dom_oncopy() {
|
||||||
|
// Setup an oncopy event handler, fire copy. Ensure that the event
|
||||||
|
// handler was called, and the clipboard contents have set to CONTENT TEXT.
|
||||||
|
// Test firing oncopy event on ctrl-c:
|
||||||
|
selectContentDiv();
|
||||||
|
var oncopy_fired = false;
|
||||||
|
content.oncopy = function() { oncopy_fired = true; };
|
||||||
|
try {
|
||||||
|
synthesizeKey("c", {accelKey: 1});
|
||||||
|
ok(oncopy_fired, "copy event firing on DOM element");
|
||||||
|
is(getClipboardText(), "CONTENT TEXT",
|
||||||
|
"copy on DOM element set clipboard correctly");
|
||||||
|
} finally {
|
||||||
|
content.oncopy = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_dom_oncut() {
|
||||||
|
// Setup an oncut event handler, fire cut. Ensure that the event handler
|
||||||
|
// was called. The <div> doesn't handle a cut, so ensure that the
|
||||||
|
// clipboard text is clipboardInitialValue, NOT "CONTENT TEXT".
|
||||||
|
selectContentDiv();
|
||||||
|
var oncut_fired = false;
|
||||||
|
content.oncut = function() { oncut_fired = true; };
|
||||||
|
try {
|
||||||
|
synthesizeKey("x", {accelKey: 1});
|
||||||
|
ok(!oncut_fired, "cut event firing on DOM element")
|
||||||
|
is(getClipboardText(), clipboardInitialValue,
|
||||||
|
"cut on DOM element did not modify clipboard");
|
||||||
|
} finally {
|
||||||
|
content.oncut = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function test_dom_onpaste() {
|
||||||
|
// Setup an onpaste event handler, fire paste. Ensure that the event
|
||||||
|
// handler was called.
|
||||||
|
selectContentDiv();
|
||||||
|
var onpaste_fired = false;
|
||||||
|
content.onpaste = function() { onpaste_fired = true; };
|
||||||
|
try {
|
||||||
|
synthesizeKey("v", {accelKey: 1});
|
||||||
|
ok(!onpaste_fired, "paste event firing on DOM element");
|
||||||
|
} finally {
|
||||||
|
content.onpaste = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function test_dom_oncopy_abort() {
|
||||||
|
// Setup an oncopy event handler that aborts the copy, and fire the copy
|
||||||
|
// event. Ensure that the event handler was fired, and the clipboard
|
||||||
|
// contents have not been modified.
|
||||||
|
selectContentDiv();
|
||||||
|
var oncopy_fired = false;
|
||||||
|
content.oncopy = function() { oncopy_fired = true; return false; };
|
||||||
|
try {
|
||||||
|
synthesizeKey("c", {accelKey: 1});
|
||||||
|
ok(oncopy_fired, "copy event (to-be-cancelled) firing on DOM element");
|
||||||
|
is(getClipboardText(), clipboardInitialValue,
|
||||||
|
"aborted copy on DOM element did not modify clipboard");
|
||||||
|
} finally {
|
||||||
|
content.oncopy = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function test_input_oncopy() {
|
||||||
|
// Setup an oncopy event handler, fire copy. Ensure that the event
|
||||||
|
// handler was called, and the clipboard contents have set to INPUT TEXT.
|
||||||
|
// Test firing oncopy event on ctrl-c:
|
||||||
|
selectContentInput();
|
||||||
|
var oncopy_fired = false;
|
||||||
|
contentInput.oncopy = function() { oncopy_fired = true; };
|
||||||
|
try {
|
||||||
|
synthesizeKey("c", {accelKey: 1});
|
||||||
|
ok(oncopy_fired, "copy event firing on plaintext editor");
|
||||||
|
is(getClipboardText(), "INPUT TEXT",
|
||||||
|
"copy on plaintext editor set clipboard correctly");
|
||||||
|
} finally {
|
||||||
|
contentInput.oncopy = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function test_input_oncut() {
|
||||||
|
// Setup an oncut event handler, and fire cut. Ensure that the event
|
||||||
|
// handler was fired, the clipboard contains the INPUT TEXT, and
|
||||||
|
// that the input itself is empty.
|
||||||
|
selectContentInput();
|
||||||
|
var oncut_fired = false;
|
||||||
|
contentInput.oncut = function() { oncut_fired = true; };
|
||||||
|
try {
|
||||||
|
synthesizeKey("x", {accelKey: 1});
|
||||||
|
ok(oncut_fired, "cut event firing on plaintext editor");
|
||||||
|
is(getClipboardText(), "INPUT TEXT",
|
||||||
|
"cut on plaintext editor set clipboard correctly");
|
||||||
|
is(contentInput.value, "",
|
||||||
|
"cut on plaintext editor emptied editor");
|
||||||
|
} finally {
|
||||||
|
contentInput.oncut = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function test_input_onpaste() {
|
||||||
|
// Setup an onpaste event handler, and fire paste. Ensure that the event
|
||||||
|
// handler was fired, the clipboard contents didn't change, and that the
|
||||||
|
// input value did change (ie. paste succeeded).
|
||||||
|
selectContentInput();
|
||||||
|
var onpaste_fired = false;
|
||||||
|
contentInput.onpaste = function() { onpaste_fired = true; };
|
||||||
|
try {
|
||||||
|
synthesizeKey("v", {accelKey: 1});
|
||||||
|
ok(onpaste_fired, "paste event firing on plaintext editor");
|
||||||
|
is(getClipboardText(), clipboardInitialValue,
|
||||||
|
"paste on plaintext editor did not modify clipboard contents");
|
||||||
|
is(contentInput.value, clipboardInitialValue,
|
||||||
|
"paste on plaintext editor did modify editor value");
|
||||||
|
} finally {
|
||||||
|
contentInput.onpaste = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function test_input_oncopy_abort() {
|
||||||
|
// Setup an oncopy event handler, fire copy. Ensure that the event
|
||||||
|
// handler was called, and that the clipboard value did NOT change.
|
||||||
|
selectContentInput();
|
||||||
|
var oncopy_fired = false;
|
||||||
|
contentInput.oncopy = function() { oncopy_fired = true; return false; };
|
||||||
|
try {
|
||||||
|
synthesizeKey("c", {accelKey: 1});
|
||||||
|
ok(oncopy_fired, "copy event (to-be-cancelled) firing on plaintext editor");
|
||||||
|
is(getClipboardText(), clipboardInitialValue,
|
||||||
|
"aborted copy on plaintext editor did not modify clipboard");
|
||||||
|
} finally {
|
||||||
|
contentInput.oncopy = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function test_input_oncut_abort() {
|
||||||
|
// Setup an oncut event handler, and fire cut. Ensure that the event
|
||||||
|
// handler was fired, the clipboard contains the INPUT TEXT, and
|
||||||
|
// that the input itself is empty.
|
||||||
|
selectContentInput();
|
||||||
|
var oncut_fired = false;
|
||||||
|
contentInput.oncut = function() { oncut_fired = true; return false; };
|
||||||
|
try {
|
||||||
|
synthesizeKey("x", {accelKey: 1});
|
||||||
|
ok(oncut_fired, "cut event (to-be-cancelled) firing on plaintext editor");
|
||||||
|
is(getClipboardText(), clipboardInitialValue,
|
||||||
|
"aborted cut on plaintext editor did not modify clipboard.");
|
||||||
|
is(contentInput.value, "INPUT TEXT",
|
||||||
|
"aborted cut on plaintext editor did not modify editor contents");
|
||||||
|
} finally {
|
||||||
|
contentInput.oncut = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function test_input_onpaste_abort() {
|
||||||
|
// Setup an onpaste event handler, and fire paste. Ensure that the event
|
||||||
|
// handler was fired, the clipboard contents didn't change, and that the
|
||||||
|
// input value did change (ie. paste succeeded).
|
||||||
|
selectContentInput();
|
||||||
|
var onpaste_fired = false;
|
||||||
|
contentInput.onpaste = function() { onpaste_fired = true; return false; };
|
||||||
|
try {
|
||||||
|
synthesizeKey("v", {accelKey: 1});
|
||||||
|
ok(onpaste_fired,
|
||||||
|
"paste event (to-be-cancelled) firing on plaintext editor");
|
||||||
|
is(getClipboardText(), clipboardInitialValue,
|
||||||
|
"aborted paste on plaintext editor did not modify clipboard");
|
||||||
|
is(contentInput.value, "INPUT TEXT",
|
||||||
|
"aborted paste on plaintext editor did not modify modified editor value");
|
||||||
|
} finally {
|
||||||
|
contentInput.onpaste = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -1847,14 +1847,11 @@ PRBool nsHTMLEditor::HavePrivateHTMLFlavor(nsIClipboard *aClipboard)
|
|||||||
|
|
||||||
NS_IMETHODIMP nsHTMLEditor::Paste(PRInt32 aSelectionType)
|
NS_IMETHODIMP nsHTMLEditor::Paste(PRInt32 aSelectionType)
|
||||||
{
|
{
|
||||||
ForceCompositionEnd();
|
if (!FireClipboardEvent(NS_PASTE))
|
||||||
|
return NS_OK;
|
||||||
PRBool preventDefault;
|
|
||||||
nsresult rv = FireClipboardEvent(NS_PASTE, &preventDefault);
|
|
||||||
if (NS_FAILED(rv) || preventDefault)
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
// Get Clipboard Service
|
// Get Clipboard Service
|
||||||
|
nsresult rv;
|
||||||
nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1", &rv));
|
nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1", &rv));
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
@ -1932,12 +1929,8 @@ NS_IMETHODIMP nsHTMLEditor::Paste(PRInt32 aSelectionType)
|
|||||||
|
|
||||||
NS_IMETHODIMP nsHTMLEditor::PasteTransferable(nsITransferable *aTransferable)
|
NS_IMETHODIMP nsHTMLEditor::PasteTransferable(nsITransferable *aTransferable)
|
||||||
{
|
{
|
||||||
ForceCompositionEnd();
|
if (!FireClipboardEvent(NS_PASTE))
|
||||||
|
return NS_OK;
|
||||||
PRBool preventDefault;
|
|
||||||
nsresult rv = FireClipboardEvent(NS_PASTE, &preventDefault);
|
|
||||||
if (NS_FAILED(rv) || preventDefault)
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
// handle transferable hooks
|
// handle transferable hooks
|
||||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||||
@ -1948,10 +1941,8 @@ NS_IMETHODIMP nsHTMLEditor::PasteTransferable(nsITransferable *aTransferable)
|
|||||||
// Beware! This may flush notifications via synchronous
|
// Beware! This may flush notifications via synchronous
|
||||||
// ScrollSelectionIntoView.
|
// ScrollSelectionIntoView.
|
||||||
nsAutoString contextStr, infoStr;
|
nsAutoString contextStr, infoStr;
|
||||||
rv = InsertFromTransferable(aTransferable, nsnull, contextStr, infoStr,
|
return InsertFromTransferable(aTransferable, nsnull, contextStr, infoStr,
|
||||||
nsnull, 0, PR_TRUE);
|
nsnull, 0, PR_TRUE);
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
#include "nsITransferable.h"
|
#include "nsITransferable.h"
|
||||||
#include "nsIDragService.h"
|
#include "nsIDragService.h"
|
||||||
#include "nsIDOMNSUIEvent.h"
|
#include "nsIDOMNSUIEvent.h"
|
||||||
|
#include "nsCopySupport.h"
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
#include "nsEditorUtils.h"
|
#include "nsEditorUtils.h"
|
||||||
@ -409,14 +410,11 @@ NS_IMETHODIMP nsPlaintextEditor::DoDrag(nsIDOMEvent *aDragEvent)
|
|||||||
|
|
||||||
NS_IMETHODIMP nsPlaintextEditor::Paste(PRInt32 aSelectionType)
|
NS_IMETHODIMP nsPlaintextEditor::Paste(PRInt32 aSelectionType)
|
||||||
{
|
{
|
||||||
ForceCompositionEnd();
|
if (!FireClipboardEvent(NS_PASTE))
|
||||||
|
return NS_OK;
|
||||||
PRBool preventDefault;
|
|
||||||
nsresult rv = FireClipboardEvent(NS_PASTE, &preventDefault);
|
|
||||||
if (NS_FAILED(rv) || preventDefault)
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
// Get Clipboard Service
|
// Get Clipboard Service
|
||||||
|
nsresult rv;
|
||||||
nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1", &rv));
|
nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1", &rv));
|
||||||
if ( NS_FAILED(rv) )
|
if ( NS_FAILED(rv) )
|
||||||
return rv;
|
return rv;
|
||||||
@ -446,12 +444,8 @@ NS_IMETHODIMP nsPlaintextEditor::Paste(PRInt32 aSelectionType)
|
|||||||
|
|
||||||
NS_IMETHODIMP nsPlaintextEditor::PasteTransferable(nsITransferable *aTransferable)
|
NS_IMETHODIMP nsPlaintextEditor::PasteTransferable(nsITransferable *aTransferable)
|
||||||
{
|
{
|
||||||
ForceCompositionEnd();
|
if (!FireClipboardEvent(NS_PASTE))
|
||||||
|
return NS_OK;
|
||||||
PRBool preventDefault;
|
|
||||||
nsresult rv = FireClipboardEvent(NS_PASTE, &preventDefault);
|
|
||||||
if (NS_FAILED(rv) || preventDefault)
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
if (!IsModifiable())
|
if (!IsModifiable())
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -464,9 +458,7 @@ NS_IMETHODIMP nsPlaintextEditor::PasteTransferable(nsITransferable *aTransferabl
|
|||||||
|
|
||||||
// Beware! This may flush notifications via synchronous
|
// Beware! This may flush notifications via synchronous
|
||||||
// ScrollSelectionIntoView.
|
// ScrollSelectionIntoView.
|
||||||
rv = InsertTextFromTransferable(aTransferable, nsnull, nsnull, PR_TRUE);
|
return InsertTextFromTransferable(aTransferable, nsnull, nsnull, PR_TRUE);
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsPlaintextEditor::CanPaste(PRInt32 aSelectionType, PRBool *aCanPaste)
|
NS_IMETHODIMP nsPlaintextEditor::CanPaste(PRInt32 aSelectionType, PRBool *aCanPaste)
|
||||||
|
@ -1142,128 +1142,66 @@ nsPlaintextEditor::Redo(PRUint32 aCount)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult nsPlaintextEditor::GetClipboardEventTarget(nsIDOMNode** aEventTarget)
|
PRBool
|
||||||
|
nsPlaintextEditor::CanCutOrCopy()
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG_POINTER(aEventTarget);
|
|
||||||
*aEventTarget = nsnull;
|
|
||||||
|
|
||||||
nsCOMPtr<nsISelection> selection;
|
nsCOMPtr<nsISelection> selection;
|
||||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
if (NS_FAILED(GetSelection(getter_AddRefs(selection))))
|
||||||
if (NS_FAILED(res))
|
return PR_FALSE;
|
||||||
return res;
|
|
||||||
|
|
||||||
return nsCopySupport::GetClipboardEventTarget(selection, aEventTarget);
|
PRBool isCollapsed;
|
||||||
|
selection->GetIsCollapsed(&isCollapsed);
|
||||||
|
return !isCollapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult nsPlaintextEditor::FireClipboardEvent(PRUint32 msg,
|
PRBool
|
||||||
PRBool* aPreventDefault)
|
nsPlaintextEditor::FireClipboardEvent(PRInt32 aType)
|
||||||
{
|
{
|
||||||
*aPreventDefault = PR_FALSE;
|
if (aType == NS_PASTE)
|
||||||
|
ForceCompositionEnd();
|
||||||
|
|
||||||
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
|
nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShellWeak);
|
||||||
if (!ps)
|
NS_ENSURE_TRUE(presShell, PR_FALSE);
|
||||||
return NS_ERROR_NOT_INITIALIZED;
|
|
||||||
|
|
||||||
// Unsafe to fire event during reflow (bug 396108)
|
nsCOMPtr<nsISelection> selection;
|
||||||
PRBool isReflowing = PR_TRUE;
|
if (NS_FAILED(GetSelection(getter_AddRefs(selection))))
|
||||||
nsresult rv = ps->IsReflowLocked(&isReflowing);
|
return PR_FALSE;
|
||||||
if (NS_FAILED(rv) || isReflowing)
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> eventTarget;
|
if (!nsCopySupport::FireClipboardEvent(aType, presShell, selection))
|
||||||
rv = GetClipboardEventTarget(getter_AddRefs(eventTarget));
|
return PR_FALSE;
|
||||||
if (NS_FAILED(rv))
|
|
||||||
// On failure to get event target, just forget about it and don't fire.
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
nsEventStatus status = nsEventStatus_eIgnore;
|
// If the event handler caused the editor to be destroyed, return false.
|
||||||
nsEvent evt(PR_TRUE, msg);
|
// Otherwise return true to indicate that the event was not cancelled.
|
||||||
nsEventDispatcher::Dispatch(eventTarget, ps->GetPresContext(), &evt,
|
return !mDidPreDestroy;
|
||||||
nsnull, &status);
|
|
||||||
// if event handler return'd false (PreventDefault)
|
|
||||||
if (status == nsEventStatus_eConsumeNoDefault)
|
|
||||||
*aPreventDefault = PR_TRUE;
|
|
||||||
|
|
||||||
// Did the event handler cause the editor to be destroyed? (ie. the input
|
|
||||||
// element was removed from the document) Don't proceed with command,
|
|
||||||
// could crash, definitely does during paste.
|
|
||||||
if (mDidPreDestroy)
|
|
||||||
return NS_ERROR_NOT_INITIALIZED;
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsPlaintextEditor::Cut()
|
NS_IMETHODIMP nsPlaintextEditor::Cut()
|
||||||
{
|
{
|
||||||
PRBool preventDefault;
|
if (FireClipboardEvent(NS_CUT))
|
||||||
nsresult rv = FireClipboardEvent(NS_CUT, &preventDefault);
|
return DeleteSelection(eNone);
|
||||||
if (NS_FAILED(rv) || preventDefault)
|
return NS_OK;
|
||||||
return rv;
|
|
||||||
|
|
||||||
nsCOMPtr<nsISelection> selection;
|
|
||||||
rv = GetSelection(getter_AddRefs(selection));
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
PRBool isCollapsed;
|
|
||||||
if (NS_SUCCEEDED(selection->GetIsCollapsed(&isCollapsed)) && isCollapsed)
|
|
||||||
return NS_OK; // just return ok so no JS error is thrown
|
|
||||||
|
|
||||||
// ps should be guaranteed by FireClipboardEvent not failing
|
|
||||||
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
|
|
||||||
rv = ps->DoCopy();
|
|
||||||
if (NS_SUCCEEDED(rv))
|
|
||||||
rv = DeleteSelection(eNone);
|
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsPlaintextEditor::CanCut(PRBool *aCanCut)
|
NS_IMETHODIMP nsPlaintextEditor::CanCut(PRBool *aCanCut)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG_POINTER(aCanCut);
|
NS_ENSURE_ARG_POINTER(aCanCut);
|
||||||
*aCanCut = PR_FALSE;
|
*aCanCut = IsModifiable() && CanCutOrCopy();
|
||||||
|
|
||||||
nsCOMPtr<nsISelection> selection;
|
|
||||||
nsresult rv = GetSelection(getter_AddRefs(selection));
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
PRBool isCollapsed;
|
|
||||||
rv = selection->GetIsCollapsed(&isCollapsed);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
*aCanCut = !isCollapsed && IsModifiable();
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsPlaintextEditor::Copy()
|
NS_IMETHODIMP nsPlaintextEditor::Copy()
|
||||||
{
|
{
|
||||||
PRBool preventDefault;
|
FireClipboardEvent(NS_COPY);
|
||||||
nsresult rv = FireClipboardEvent(NS_COPY, &preventDefault);
|
return NS_OK;
|
||||||
if (NS_FAILED(rv) || preventDefault)
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
// ps should be guaranteed by FireClipboardEvent not failing
|
|
||||||
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
|
|
||||||
return ps->DoCopy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsPlaintextEditor::CanCopy(PRBool *aCanCopy)
|
NS_IMETHODIMP nsPlaintextEditor::CanCopy(PRBool *aCanCopy)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG_POINTER(aCanCopy);
|
NS_ENSURE_ARG_POINTER(aCanCopy);
|
||||||
*aCanCopy = PR_FALSE;
|
*aCanCopy = CanCutOrCopy();
|
||||||
|
|
||||||
nsCOMPtr<nsISelection> selection;
|
|
||||||
nsresult rv = GetSelection(getter_AddRefs(selection));
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
PRBool isCollapsed;
|
|
||||||
rv = selection->GetIsCollapsed(&isCollapsed);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
*aCanCopy = !isCollapsed;
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Shared between OutputToString and OutputToStream
|
// Shared between OutputToString and OutputToStream
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsPlaintextEditor::GetAndInitDocEncoder(const nsAString& aFormatType,
|
nsPlaintextEditor::GetAndInitDocEncoder(const nsAString& aFormatType,
|
||||||
|
@ -219,10 +219,8 @@ protected:
|
|||||||
PRBool mIgnoreSpuriousDragEvent;
|
PRBool mIgnoreSpuriousDragEvent;
|
||||||
NS_IMETHOD IgnoreSpuriousDragEvent(PRBool aIgnoreSpuriousDragEvent) {mIgnoreSpuriousDragEvent = aIgnoreSpuriousDragEvent; return NS_OK;}
|
NS_IMETHOD IgnoreSpuriousDragEvent(PRBool aIgnoreSpuriousDragEvent) {mIgnoreSpuriousDragEvent = aIgnoreSpuriousDragEvent; return NS_OK;}
|
||||||
|
|
||||||
// Wrapper for nsCopySupport::GetClipboardEventTarget, finds target to fire
|
PRBool CanCutOrCopy();
|
||||||
// [cut,copy,paste] and [beforecut,beforecopy,beforepaste] events at.
|
PRBool FireClipboardEvent(PRInt32 aType);
|
||||||
nsresult GetClipboardEventTarget(nsIDOMNode** aEventTarget);
|
|
||||||
nsresult FireClipboardEvent(PRUint32 msg, PRBool* aPreventDefault);
|
|
||||||
|
|
||||||
// Data members
|
// Data members
|
||||||
protected:
|
protected:
|
||||||
|
@ -398,9 +398,6 @@ private:
|
|||||||
|
|
||||||
nsresult GetDocumentSelection(nsISelection **aSelection);
|
nsresult GetDocumentSelection(nsISelection **aSelection);
|
||||||
|
|
||||||
nsresult GetClipboardEventTarget(nsIDOMNode **aEventTarget);
|
|
||||||
nsresult FireClipboardEvent(PRUint32 msg, PRBool* aPreventDefault);
|
|
||||||
|
|
||||||
void DestroyPresShell();
|
void DestroyPresShell();
|
||||||
|
|
||||||
#ifdef NS_PRINTING
|
#ifdef NS_PRINTING
|
||||||
@ -2410,8 +2407,7 @@ DocumentViewerImpl::CreateDeviceContext(nsIView* aContainerView)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return the selection for the document. Note that text fields have their
|
// Return the selection for the document. Note that text fields have their
|
||||||
// own selection, which cannot be accessed with this method. Use
|
// own selection, which cannot be accessed with this method.
|
||||||
// mPresShell->GetSelectionForCopy() instead.
|
|
||||||
nsresult DocumentViewerImpl::GetDocumentSelection(nsISelection **aSelection)
|
nsresult DocumentViewerImpl::GetDocumentSelection(nsISelection **aSelection)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG_POINTER(aSelection);
|
NS_ENSURE_ARG_POINTER(aSelection);
|
||||||
@ -2431,25 +2427,12 @@ nsresult DocumentViewerImpl::GetDocumentSelection(nsISelection **aSelection)
|
|||||||
* nsIContentViewerEdit
|
* nsIContentViewerEdit
|
||||||
* ======================================================================================== */
|
* ======================================================================================== */
|
||||||
|
|
||||||
NS_IMETHODIMP DocumentViewerImpl::Search()
|
|
||||||
{
|
|
||||||
// Nothing to do here.
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP DocumentViewerImpl::GetSearchable(PRBool *aSearchable)
|
|
||||||
{
|
|
||||||
// Nothing to do here.
|
|
||||||
*aSearchable = PR_FALSE;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP DocumentViewerImpl::ClearSelection()
|
NS_IMETHODIMP DocumentViewerImpl::ClearSelection()
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
nsCOMPtr<nsISelection> selection;
|
nsCOMPtr<nsISelection> selection;
|
||||||
|
|
||||||
// use mPresShell->GetSelectionForCopy() ?
|
// use nsCopySupport::GetSelectionForCopy() ?
|
||||||
rv = GetDocumentSelection(getter_AddRefs(selection));
|
rv = GetDocumentSelection(getter_AddRefs(selection));
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
@ -2464,7 +2447,7 @@ NS_IMETHODIMP DocumentViewerImpl::SelectAll()
|
|||||||
nsCOMPtr<nsISelection> selection;
|
nsCOMPtr<nsISelection> selection;
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
// use mPresShell->GetSelectionForCopy() ?
|
// use nsCopySupport::GetSelectionForCopy() ?
|
||||||
rv = GetDocumentSelection(getter_AddRefs(selection));
|
rv = GetDocumentSelection(getter_AddRefs(selection));
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
@ -2494,12 +2477,8 @@ NS_IMETHODIMP DocumentViewerImpl::SelectAll()
|
|||||||
|
|
||||||
NS_IMETHODIMP DocumentViewerImpl::CopySelection()
|
NS_IMETHODIMP DocumentViewerImpl::CopySelection()
|
||||||
{
|
{
|
||||||
PRBool preventDefault;
|
nsCopySupport::FireClipboardEvent(NS_COPY, mPresShell, nsnull);
|
||||||
nsresult rv = FireClipboardEvent(NS_COPY, &preventDefault);
|
return NS_OK;
|
||||||
if (NS_FAILED(rv) || preventDefault)
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
return mPresShell->DoCopy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP DocumentViewerImpl::CopyLinkLocation()
|
NS_IMETHODIMP DocumentViewerImpl::CopyLinkLocation()
|
||||||
@ -2532,118 +2511,47 @@ NS_IMETHODIMP DocumentViewerImpl::CopyImage(PRInt32 aCopyFlags)
|
|||||||
return nsCopySupport::ImageCopy(node, aCopyFlags);
|
return nsCopySupport::ImageCopy(node, aCopyFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult DocumentViewerImpl::GetClipboardEventTarget(nsIDOMNode** aEventTarget)
|
|
||||||
{
|
|
||||||
NS_ENSURE_ARG_POINTER(aEventTarget);
|
|
||||||
*aEventTarget = nsnull;
|
|
||||||
|
|
||||||
if (!mPresShell)
|
|
||||||
return NS_ERROR_NOT_INITIALIZED;
|
|
||||||
|
|
||||||
nsCOMPtr<nsISelection> sel;
|
|
||||||
nsresult rv = mPresShell->GetSelectionForCopy(getter_AddRefs(sel));
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return rv;
|
|
||||||
if (!sel)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
return nsCopySupport::GetClipboardEventTarget(sel, aEventTarget);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult DocumentViewerImpl::FireClipboardEvent(PRUint32 msg,
|
|
||||||
PRBool* aPreventDefault)
|
|
||||||
{
|
|
||||||
*aPreventDefault = PR_FALSE;
|
|
||||||
|
|
||||||
NS_ENSURE_TRUE(mPresContext, NS_ERROR_NOT_INITIALIZED);
|
|
||||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED);
|
|
||||||
|
|
||||||
// It seems to be unsafe to fire an event handler during reflow (bug 393696)
|
|
||||||
PRBool isReflowing = PR_TRUE;
|
|
||||||
nsresult rv = mPresShell->IsReflowLocked(&isReflowing);
|
|
||||||
if (NS_FAILED(rv) || isReflowing)
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> eventTarget;
|
|
||||||
rv = GetClipboardEventTarget(getter_AddRefs(eventTarget));
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
// On failure to get event target, just forget about it and don't fire.
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
nsEventStatus status = nsEventStatus_eIgnore;
|
|
||||||
nsEvent evt(PR_TRUE, msg);
|
|
||||||
nsEventDispatcher::Dispatch(eventTarget, mPresContext, &evt, nsnull,
|
|
||||||
&status);
|
|
||||||
// if event handler return'd false (PreventDefault)
|
|
||||||
if (status == nsEventStatus_eConsumeNoDefault)
|
|
||||||
*aPreventDefault = PR_TRUE;
|
|
||||||
|
|
||||||
// Ensure that the calling function can use mPresShell -- if the event
|
|
||||||
// handler closed this window, mPresShell will be gone.
|
|
||||||
NS_ENSURE_STATE(mPresShell);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP DocumentViewerImpl::GetCopyable(PRBool *aCopyable)
|
NS_IMETHODIMP DocumentViewerImpl::GetCopyable(PRBool *aCopyable)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG_POINTER(aCopyable);
|
NS_ENSURE_ARG_POINTER(aCopyable);
|
||||||
*aCopyable = PR_FALSE;
|
*aCopyable = nsCopySupport::CanCopy(mDocument);
|
||||||
|
|
||||||
NS_ENSURE_STATE(mPresShell);
|
|
||||||
nsCOMPtr<nsISelection> selection;
|
|
||||||
nsresult rv = mPresShell->GetSelectionForCopy(getter_AddRefs(selection));
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
PRBool isCollapsed;
|
|
||||||
selection->GetIsCollapsed(&isCollapsed);
|
|
||||||
|
|
||||||
*aCopyable = !isCollapsed;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP DocumentViewerImpl::CutSelection()
|
|
||||||
{
|
|
||||||
// preventDefault's value is ignored because cut from the document has no
|
|
||||||
// default behaviour.
|
|
||||||
PRBool preventDefault;
|
|
||||||
return FireClipboardEvent(NS_CUT, &preventDefault);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP DocumentViewerImpl::GetCutable(PRBool *aCutable)
|
|
||||||
{
|
|
||||||
NS_ENSURE_ARG_POINTER(aCutable);
|
|
||||||
*aCutable = PR_FALSE;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP DocumentViewerImpl::Paste()
|
|
||||||
{
|
|
||||||
// preventDefault's value is ignored because paste into the document has no
|
|
||||||
// default behaviour.
|
|
||||||
PRBool preventDefault;
|
|
||||||
return FireClipboardEvent(NS_PASTE, &preventDefault);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP DocumentViewerImpl::GetPasteable(PRBool *aPasteable)
|
|
||||||
{
|
|
||||||
NS_ENSURE_ARG_POINTER(aPasteable);
|
|
||||||
*aPasteable = PR_FALSE;
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* AString getContents (in string mimeType, in boolean selectionOnly); */
|
/* AString getContents (in string mimeType, in boolean selectionOnly); */
|
||||||
NS_IMETHODIMP DocumentViewerImpl::GetContents(const char *mimeType, PRBool selectionOnly, nsAString& aOutValue)
|
NS_IMETHODIMP DocumentViewerImpl::GetContents(const char *mimeType, PRBool selectionOnly, nsAString& aOutValue)
|
||||||
{
|
{
|
||||||
|
aOutValue.Truncate();
|
||||||
|
|
||||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED);
|
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED);
|
||||||
return mPresShell->DoGetContents(nsDependentCString(mimeType), 0, selectionOnly, aOutValue);
|
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_INITIALIZED);
|
||||||
|
|
||||||
|
// Now we have the selection. Make sure it's nonzero:
|
||||||
|
nsCOMPtr<nsISelection> sel;
|
||||||
|
if (selectionOnly) {
|
||||||
|
nsCopySupport::GetSelectionForCopy(mDocument, getter_AddRefs(sel));
|
||||||
|
NS_ENSURE_TRUE(sel, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
PRBool isCollapsed;
|
||||||
|
sel->GetIsCollapsed(&isCollapsed);
|
||||||
|
if (isCollapsed)
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// call the copy code
|
||||||
|
return nsCopySupport::GetContents(nsDependentCString(mimeType), 0, sel,
|
||||||
|
mDocument, aOutValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* readonly attribute boolean canGetContents; */
|
/* readonly attribute boolean canGetContents; */
|
||||||
NS_IMETHODIMP DocumentViewerImpl::GetCanGetContents(PRBool *aCanGetContents)
|
NS_IMETHODIMP DocumentViewerImpl::GetCanGetContents(PRBool *aCanGetContents)
|
||||||
{
|
{
|
||||||
return GetCopyable(aCanGetContents);
|
NS_ENSURE_ARG_POINTER(aCanGetContents);
|
||||||
|
*aCanGetContents = PR_FALSE;
|
||||||
|
NS_ENSURE_STATE(mDocument);
|
||||||
|
*aCanGetContents = nsCopySupport::CanCopy(mDocument);
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef XP_MAC
|
#ifdef XP_MAC
|
||||||
|
@ -127,8 +127,8 @@ typedef struct CapturingContentInfo {
|
|||||||
} CapturingContentInfo;
|
} CapturingContentInfo;
|
||||||
|
|
||||||
#define NS_IPRESSHELL_IID \
|
#define NS_IPRESSHELL_IID \
|
||||||
{ 0xe5e070ce, 0xbc17, 0x4b5f, \
|
{ 0x0e170e5f, 0xf6d4, 0x44c5, \
|
||||||
{ 0xb2, 0x21, 0xbf, 0xc3, 0xe1, 0x68, 0xbe, 0x9b } }
|
{ 0xbc, 0x2c, 0x44, 0x94, 0x20, 0x7e, 0xcc, 0x30 } }
|
||||||
|
|
||||||
// Constants for ScrollContentIntoView() function
|
// Constants for ScrollContentIntoView() function
|
||||||
#define NS_PRESSHELL_SCROLL_TOP 0
|
#define NS_PRESSHELL_SCROLL_TOP 0
|
||||||
@ -578,27 +578,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
NS_IMETHOD NotifyDestroyingFrame(nsIFrame* aFrame) = 0;
|
NS_IMETHOD NotifyDestroyingFrame(nsIFrame* aFrame) = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify the Clipboard that we have something to copy.
|
|
||||||
*/
|
|
||||||
NS_IMETHOD DoCopy() = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the selection of the focussed element (either the page selection,
|
|
||||||
* or the selection for a text field).
|
|
||||||
*/
|
|
||||||
NS_IMETHOD GetSelectionForCopy(nsISelection** outSelection) = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get link location.
|
* Get link location.
|
||||||
*/
|
*/
|
||||||
NS_IMETHOD GetLinkLocation(nsIDOMNode* aNode, nsAString& aLocation) = 0;
|
NS_IMETHOD GetLinkLocation(nsIDOMNode* aNode, nsAString& aLocation) = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the doc or the selection as text or html.
|
|
||||||
*/
|
|
||||||
NS_IMETHOD DoGetContents(const nsACString& aMimeType, PRUint32 aFlags, PRBool aSelectionOnly, nsAString& outValue) = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the caret, if it exists. AddRefs it.
|
* Get the caret, if it exists. AddRefs it.
|
||||||
*/
|
*/
|
||||||
|
@ -738,12 +738,8 @@ public:
|
|||||||
|
|
||||||
NS_IMETHOD SetIgnoreFrameDestruction(PRBool aIgnore);
|
NS_IMETHOD SetIgnoreFrameDestruction(PRBool aIgnore);
|
||||||
NS_IMETHOD NotifyDestroyingFrame(nsIFrame* aFrame);
|
NS_IMETHOD NotifyDestroyingFrame(nsIFrame* aFrame);
|
||||||
|
|
||||||
NS_IMETHOD DoCopy();
|
|
||||||
NS_IMETHOD GetSelectionForCopy(nsISelection** outSelection);
|
|
||||||
|
|
||||||
NS_IMETHOD GetLinkLocation(nsIDOMNode* aNode, nsAString& aLocationString);
|
NS_IMETHOD GetLinkLocation(nsIDOMNode* aNode, nsAString& aLocationString);
|
||||||
NS_IMETHOD DoGetContents(const nsACString& aMimeType, PRUint32 aFlags, PRBool aSelectionOnly, nsAString& outValue);
|
|
||||||
|
|
||||||
NS_IMETHOD CaptureHistoryState(nsILayoutHistoryState** aLayoutHistoryState, PRBool aLeavingPage);
|
NS_IMETHOD CaptureHistoryState(nsILayoutHistoryState** aLayoutHistoryState, PRBool aLeavingPage);
|
||||||
|
|
||||||
@ -4298,57 +4294,6 @@ NS_IMETHODIMP PresShell::GetLinkLocation(nsIDOMNode* aNode, nsAString& aLocation
|
|||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
PresShell::GetSelectionForCopy(nsISelection** outSelection)
|
|
||||||
{
|
|
||||||
nsresult rv = NS_OK;
|
|
||||||
|
|
||||||
*outSelection = nsnull;
|
|
||||||
|
|
||||||
if (!mDocument) return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> content;
|
|
||||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
|
||||||
if (fm) {
|
|
||||||
nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(mDocument->GetWindow());
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMElement> focusedElement;
|
|
||||||
fm->GetFocusedElementForWindow(window, PR_FALSE, nsnull, getter_AddRefs(focusedElement));
|
|
||||||
content = do_QueryInterface(focusedElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsISelection> sel;
|
|
||||||
if (content)
|
|
||||||
{
|
|
||||||
//check to see if we need to get selection from frame
|
|
||||||
//optimization that MAY need to be expanded as more things implement their own "selection"
|
|
||||||
nsCOMPtr<nsIDOMNSHTMLInputElement> htmlInputElement(do_QueryInterface(content));
|
|
||||||
nsCOMPtr<nsIDOMNSHTMLTextAreaElement> htmlTextAreaElement(do_QueryInterface(content));
|
|
||||||
if (htmlInputElement || htmlTextAreaElement)
|
|
||||||
{
|
|
||||||
nsIFrame *htmlInputFrame = content->GetPrimaryFrame();
|
|
||||||
if (!htmlInputFrame) return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
nsCOMPtr<nsISelectionController> selCon;
|
|
||||||
rv = htmlInputFrame->
|
|
||||||
GetSelectionController(mPresContext,getter_AddRefs(selCon));
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
if (!selCon) return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
rv = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
|
|
||||||
getter_AddRefs(sel));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!sel) {
|
|
||||||
sel = mSelection->GetSelection(nsISelectionController::SELECTION_NORMAL);
|
|
||||||
rv = NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
*outSelection = sel;
|
|
||||||
NS_IF_ADDREF(*outSelection);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP_(void)
|
NS_IMETHODIMP_(void)
|
||||||
PresShell::DispatchSynthMouseMove(nsGUIEvent *aEvent,
|
PresShell::DispatchSynthMouseMove(nsGUIEvent *aEvent,
|
||||||
PRBool aFlushOnHoverChange)
|
PRBool aFlushOnHoverChange)
|
||||||
@ -4405,67 +4350,6 @@ PresShell::ClearMouseCapture(nsIView* aView)
|
|||||||
gCaptureInfo.mAllowed = PR_FALSE;
|
gCaptureInfo.mAllowed = PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
PresShell::DoGetContents(const nsACString& aMimeType, PRUint32 aFlags, PRBool aSelectionOnly, nsAString& aOutValue)
|
|
||||||
{
|
|
||||||
aOutValue.Truncate();
|
|
||||||
|
|
||||||
if (!mDocument) return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
nsresult rv;
|
|
||||||
nsCOMPtr<nsISelection> sel;
|
|
||||||
|
|
||||||
// Now we have the selection. Make sure it's nonzero:
|
|
||||||
if (aSelectionOnly)
|
|
||||||
{
|
|
||||||
rv = GetSelectionForCopy(getter_AddRefs(sel));
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
if (!sel) return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
PRBool isCollapsed;
|
|
||||||
sel->GetIsCollapsed(&isCollapsed);
|
|
||||||
if (isCollapsed)
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// call the copy code
|
|
||||||
return nsCopySupport::GetContents(aMimeType, aFlags, sel,
|
|
||||||
mDocument, aOutValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
PresShell::DoCopy()
|
|
||||||
{
|
|
||||||
if (!mDocument) return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
nsCOMPtr<nsISelection> sel;
|
|
||||||
nsresult rv = GetSelectionForCopy(getter_AddRefs(sel));
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return rv;
|
|
||||||
if (!sel)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
// Now we have the selection. Make sure it's nonzero:
|
|
||||||
PRBool isCollapsed;
|
|
||||||
sel->GetIsCollapsed(&isCollapsed);
|
|
||||||
if (isCollapsed)
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
// call the copy code
|
|
||||||
rv = nsCopySupport::HTMLCopy(sel, mDocument, nsIClipboard::kGlobalClipboard);
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
// Now that we have copied, update the Paste menu item
|
|
||||||
nsPIDOMWindow *domWindow = mDocument->GetWindow();
|
|
||||||
if (domWindow)
|
|
||||||
{
|
|
||||||
domWindow->UpdateCommands(NS_LITERAL_STRING("clipboard"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
PresShell::CaptureHistoryState(nsILayoutHistoryState** aState, PRBool aLeavingPage)
|
PresShell::CaptureHistoryState(nsILayoutHistoryState** aState, PRBool aLeavingPage)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user