зеркало из https://github.com/mozilla/gecko-dev.git
Bug 479093 - Text sent to services includes body of <script> tags. r=smaug, r=josh, sr=roc
This commit is contained in:
Родитель
8bb593e370
Коммит
03b91d6b28
|
@ -70,6 +70,12 @@ class nsCopySupport
|
|||
// 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
|
||||
// not deal with the clipboard.
|
||||
static nsresult GetTransferableForSelection(nsISelection * aSelection,
|
||||
nsIDocument * aDocument,
|
||||
nsITransferable ** aTransferable);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -86,13 +86,23 @@ static nsresult AppendString(nsITransferable *aTransferable,
|
|||
static nsresult AppendDOMNode(nsITransferable *aTransferable,
|
||||
nsIDOMNode *aDOMNode);
|
||||
|
||||
nsresult nsCopySupport::HTMLCopy(nsISelection *aSel, nsIDocument *aDoc, PRInt16 aClipboardID)
|
||||
// Helper used for HTMLCopy and GetTransferableForSelection since both routines
|
||||
// share common code.
|
||||
static nsresult
|
||||
SelectionCopyHelper(nsISelection *aSel, nsIDocument *aDoc,
|
||||
PRBool doPutOnClipboard, PRInt16 aClipboardID,
|
||||
nsITransferable ** aTransferable)
|
||||
{
|
||||
// Clear the output parameter for the transferable, if provided.
|
||||
if (aTransferable) {
|
||||
*aTransferable = nsnull;
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
PRBool bIsPlainTextContext = PR_FALSE;
|
||||
|
||||
rv = IsPlainTextContext(aSel, aDoc, &bIsPlainTextContext);
|
||||
rv = nsCopySupport::IsPlainTextContext(aSel, aDoc, &bIsPlainTextContext);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
|
@ -114,6 +124,7 @@ nsresult nsCopySupport::HTMLCopy(nsISelection *aSel, nsIDocument *aDoc, PRInt16
|
|||
rv = docEncoder->Init(domDoc, mimeType, flags);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = docEncoder->SetSelection(aSel);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
@ -160,42 +171,40 @@ nsresult nsCopySupport::HTMLCopy(nsISelection *aSel, nsIDocument *aDoc, PRInt16
|
|||
}
|
||||
|
||||
// Get the Clipboard
|
||||
nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
nsCOMPtr<nsIClipboard> clipboard;
|
||||
if (doPutOnClipboard) {
|
||||
clipboard = do_GetService(kCClipboardCID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
if ( clipboard )
|
||||
{
|
||||
if ((doPutOnClipboard && clipboard) || aTransferable != nsnull) {
|
||||
// Create a transferable for putting data on the Clipboard
|
||||
nsCOMPtr<nsITransferable> trans = do_CreateInstance(kCTransferableCID);
|
||||
if ( trans )
|
||||
{
|
||||
if (bIsHTMLCopy)
|
||||
{
|
||||
if (trans) {
|
||||
if (bIsHTMLCopy) {
|
||||
// set up the data converter
|
||||
trans->SetConverter(htmlConverter);
|
||||
|
||||
if (!buffer.IsEmpty())
|
||||
{
|
||||
if (!buffer.IsEmpty()) {
|
||||
// Add the html DataFlavor to the transferable
|
||||
rv = AppendString(trans, buffer, kHTMLMime);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
{
|
||||
// Add the htmlcontext DataFlavor to the transferable
|
||||
// Even if parents is empty string, this flavor should
|
||||
// be attached to the transferable
|
||||
rv = AppendString(trans, parents, kHTMLContext);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
if (!info.IsEmpty())
|
||||
{
|
||||
|
||||
// Add the htmlcontext DataFlavor to the transferable
|
||||
// Even if parents is empty string, this flavor should
|
||||
// be attached to the transferable
|
||||
rv = AppendString(trans, parents, kHTMLContext);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!info.IsEmpty()) {
|
||||
// Add the htmlinfo DataFlavor to the transferable
|
||||
rv = AppendString(trans, info, kHTMLInfo);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
if (!plaintextBuffer.IsEmpty())
|
||||
{
|
||||
|
||||
if (!plaintextBuffer.IsEmpty()) {
|
||||
// unicode text
|
||||
// Add the unicode DataFlavor to the transferable
|
||||
// If we didn't have this, then nsDataObj::GetData matches text/unicode against
|
||||
|
@ -223,28 +232,45 @@ nsresult nsCopySupport::HTMLCopy(nsISelection *aSel, nsIDocument *aDoc, PRInt16
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!textBuffer.IsEmpty())
|
||||
{
|
||||
// Add the unicode DataFlavor to the transferable
|
||||
} else {
|
||||
if (!textBuffer.IsEmpty()) {
|
||||
// Add the unicode DataFlavor to the transferable
|
||||
rv = AppendString(trans, textBuffer, kUnicodeMime);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
||||
PRBool doPutOnClipboard = PR_TRUE;
|
||||
DoHooks(aDoc, trans, &doPutOnClipboard);
|
||||
if (doPutOnClipboard && clipboard) {
|
||||
PRBool actuallyPutOnClipboard = PR_TRUE;
|
||||
nsCopySupport::DoHooks(aDoc, trans, &actuallyPutOnClipboard);
|
||||
|
||||
// put the transferable on the clipboard
|
||||
if (doPutOnClipboard)
|
||||
clipboard->SetData(trans, nsnull, aClipboardID);
|
||||
// put the transferable on the clipboard
|
||||
if (actuallyPutOnClipboard)
|
||||
clipboard->SetData(trans, nsnull, aClipboardID);
|
||||
}
|
||||
|
||||
// Return the transferable to the caller if requested.
|
||||
if (aTransferable != nsnull) {
|
||||
trans.swap(*aTransferable);
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsCopySupport::HTMLCopy(nsISelection *aSel, nsIDocument *aDoc, PRInt16 aClipboardID)
|
||||
{
|
||||
return SelectionCopyHelper(aSel, aDoc, PR_TRUE, aClipboardID, nsnull);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCopySupport::GetTransferableForSelection(nsISelection * aSel,
|
||||
nsIDocument * aDoc,
|
||||
nsITransferable ** aTransferable)
|
||||
{
|
||||
return SelectionCopyHelper(aSel, aDoc, PR_FALSE, 0, aTransferable);
|
||||
}
|
||||
|
||||
nsresult nsCopySupport::DoHooks(nsIDocument *aDoc, nsITransferable *aTrans,
|
||||
PRBool *aDoPutOnClipboard)
|
||||
{
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "nsRange.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsCaret.h"
|
||||
#include "nsCopySupport.h"
|
||||
#include "nsFrameSelection.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIView.h"
|
||||
|
@ -92,6 +93,12 @@ nsContentEventHandler::Init(nsQueryContentEvent* aEvent)
|
|||
NS_ASSERTION(mSelection,
|
||||
"GetSelectionForCopy succeeded, but the result is null");
|
||||
|
||||
PRBool isCollapsed;
|
||||
rv = mSelection->GetIsCollapsed(&isCollapsed);
|
||||
if (NS_FAILED(rv))
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
aEvent->mReply.mHasSelection = !isCollapsed;
|
||||
|
||||
nsCOMPtr<nsIDOMRange> firstRange;
|
||||
rv = mSelection->GetRangeAt(0, getter_AddRefs(firstRange));
|
||||
// This shell doesn't support selection.
|
||||
|
@ -111,7 +118,6 @@ nsContentEventHandler::Init(nsQueryContentEvent* aEvent)
|
|||
rv = mPresShell->GetCaret(getter_AddRefs(caret));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ASSERTION(caret, "GetCaret succeeded, but the result is null");
|
||||
PRBool isCollapsed;
|
||||
nsRect r;
|
||||
nsIView* view = nsnull;
|
||||
rv = caret->GetCaretCoordinates(nsCaret::eRenderingViewCoordinates,
|
||||
|
@ -684,6 +690,41 @@ nsContentEventHandler::OnQueryCaretRect(nsQueryContentEvent* aEvent)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsContentEventHandler::OnQueryContentState(nsQueryContentEvent * aEvent)
|
||||
{
|
||||
nsresult rv = Init(aEvent);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
aEvent->mSucceeded = PR_TRUE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsContentEventHandler::OnQuerySelectionAsTransferable(nsQueryContentEvent* aEvent)
|
||||
{
|
||||
nsresult rv = Init(aEvent);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (!aEvent->mReply.mHasSelection) {
|
||||
aEvent->mSucceeded = PR_TRUE;
|
||||
aEvent->mReply.mTransferable = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = mPresShell->GetDocument();
|
||||
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
|
||||
|
||||
rv = nsCopySupport::GetTransferableForSelection(mSelection, doc, getter_AddRefs(aEvent->mReply.mTransferable));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aEvent->mSucceeded = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsContentEventHandler::GetFlatTextOffsetOfRange(nsIContent* aRootContent,
|
||||
nsINode* aNode,
|
||||
|
|
|
@ -77,6 +77,10 @@ public:
|
|||
nsresult OnQueryTextRect(nsQueryContentEvent* aEvent);
|
||||
// NS_QUERY_EDITOR_RECT event handler
|
||||
nsresult OnQueryEditorRect(nsQueryContentEvent* aEvent);
|
||||
// NS_QUERY_CONTENT_STATE event handler
|
||||
nsresult OnQueryContentState(nsQueryContentEvent* aEvent);
|
||||
// NS_QUERY_SELECTION_AS_TRANSFERABLE event handler
|
||||
nsresult OnQuerySelectionAsTransferable(nsQueryContentEvent* aEvent);
|
||||
|
||||
// NS_SELECTION_* event
|
||||
nsresult OnSelectionEvent(nsSelectionEvent* aEvent);
|
||||
|
|
|
@ -1688,6 +1688,18 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
|||
handler.OnQueryEditorRect((nsQueryContentEvent*)aEvent);
|
||||
}
|
||||
break;
|
||||
case NS_QUERY_CONTENT_STATE:
|
||||
{
|
||||
nsContentEventHandler handler(mPresContext);
|
||||
handler.OnQueryContentState(static_cast<nsQueryContentEvent*>(aEvent));
|
||||
}
|
||||
break;
|
||||
case NS_QUERY_SELECTION_AS_TRANSFERABLE:
|
||||
{
|
||||
nsContentEventHandler handler(mPresContext);
|
||||
handler.OnQuerySelectionAsTransferable(static_cast<nsQueryContentEvent*>(aEvent));
|
||||
}
|
||||
break;
|
||||
case NS_SELECTION_SET:
|
||||
{
|
||||
nsContentEventHandler handler(mPresContext);
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "nsIWidget.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "nsITransferable.h"
|
||||
|
||||
class nsIRenderingContext;
|
||||
class nsIRegion;
|
||||
|
@ -362,6 +363,11 @@ class nsHashKey;
|
|||
// Query for the bounding rect of the current focused frame. Result is relative
|
||||
// to top level widget coordinates
|
||||
#define NS_QUERY_EDITOR_RECT (NS_QUERY_CONTENT_EVENT_START + 5)
|
||||
// Query for the current state of the content. The particular members of
|
||||
// mReply that are set for each query content event will be valid on success.
|
||||
#define NS_QUERY_CONTENT_STATE (NS_QUERY_CONTENT_EVENT_START + 6)
|
||||
// Query for the selection in the form of a nsITransferable.
|
||||
#define NS_QUERY_SELECTION_AS_TRANSFERABLE (NS_QUERY_CONTENT_EVENT_START + 7)
|
||||
|
||||
// Video events
|
||||
#ifdef MOZ_MEDIA
|
||||
|
@ -1012,6 +1018,9 @@ public:
|
|||
// The return widget has the caret. This is set at all query events.
|
||||
nsIWidget* mFocusedWidget;
|
||||
PRPackedBool mReversed; // true if selection is reversed (end < start)
|
||||
PRPackedBool mHasSelection; // true if the selection exists
|
||||
// used by NS_QUERY_SELECTION_AS_TRANSFERABLE
|
||||
nsCOMPtr<nsITransferable> mTransferable;
|
||||
} mReply;
|
||||
};
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
#include "nsIMenuRollup.h"
|
||||
|
||||
#include "nsDragService.h"
|
||||
#include "nsClipboard.h"
|
||||
#include "nsCursorManager.h"
|
||||
#include "nsWindowMap.h"
|
||||
#include "nsCocoaUtils.h"
|
||||
|
@ -2391,10 +2392,15 @@ NSEvent* gLastDragEvent = nil;
|
|||
if (!initialized) {
|
||||
// Inform the OS about the types of services (from the "Services" menu)
|
||||
// that we can handle.
|
||||
NSArray *sendTypes = [NSArray arrayWithObject:NSStringPboardType];
|
||||
NSArray *returnTypes = [NSArray array];
|
||||
|
||||
NSArray *sendTypes = [[NSArray alloc] initWithObjects:NSStringPboardType,NSHTMLPboardType,nil];
|
||||
NSArray *returnTypes = [[NSArray alloc] init];
|
||||
|
||||
[NSApp registerServicesMenuSendTypes:sendTypes returnTypes:returnTypes];
|
||||
|
||||
[sendTypes release];
|
||||
[returnTypes release];
|
||||
|
||||
initialized = YES;
|
||||
}
|
||||
}
|
||||
|
@ -6427,7 +6433,7 @@ static BOOL keyUpAlreadySentKeyDown = NO;
|
|||
#pragma mark -
|
||||
|
||||
// Support for the "Services" menu. We currently only support sending strings
|
||||
// to services.
|
||||
// and HTML to system services.
|
||||
|
||||
- (id)validRequestorForSendType:(NSString *)sendType
|
||||
returnType:(NSString *)returnType
|
||||
|
@ -6443,24 +6449,23 @@ static BOOL keyUpAlreadySentKeyDown = NO;
|
|||
// returnType is nil if the service will not return any data.
|
||||
//
|
||||
// The following condition thus triggers when the service expects a string
|
||||
// from us or no data at all AND when the service will not send back any
|
||||
// data to us.
|
||||
// or HTML from us or no data at all AND when the service will not send back
|
||||
// any data to us.
|
||||
|
||||
if ((!sendType || [sendType isEqual:NSStringPboardType]) && !returnType) {
|
||||
// Query Gecko window to determine if there is a current selection.
|
||||
bool hasSelection = false;
|
||||
if ((!sendType || [sendType isEqual:NSStringPboardType] ||
|
||||
[sendType isEqual:NSHTMLPboardType]) && !returnType) {
|
||||
// Query the Gecko window to determine if there is a current selection.
|
||||
if (mGeckoChild) {
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
nsQueryContentEvent selection(PR_TRUE, NS_QUERY_SELECTED_TEXT,
|
||||
mGeckoChild);
|
||||
mGeckoChild->DispatchWindowEvent(selection);
|
||||
if (selection.mSucceeded && !selection.mReply.mString.IsEmpty())
|
||||
hasSelection = true;
|
||||
}
|
||||
|
||||
// Return this object if it can handle the request.
|
||||
if ((!sendType || hasSelection) && !returnType)
|
||||
return self;
|
||||
nsQueryContentEvent event(PR_TRUE, NS_QUERY_CONTENT_STATE, mGeckoChild);
|
||||
mGeckoChild->DispatchWindowEvent(event);
|
||||
|
||||
// Return this object if it can handle the request.
|
||||
if ((!sendType || (event.mSucceeded && event.mReply.mHasSelection)) &&
|
||||
!returnType)
|
||||
return self;
|
||||
}
|
||||
}
|
||||
|
||||
return [super validRequestorForSendType:sendType returnType:returnType];
|
||||
|
@ -6475,24 +6480,55 @@ static BOOL keyUpAlreadySentKeyDown = NO;
|
|||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
|
||||
// Ensure that the service will accept strings. (We only support strings.)
|
||||
if ([types containsObject:NSStringPboardType] == NO)
|
||||
|
||||
// Make sure that the service will accept strings or HTML.
|
||||
if ([types containsObject:NSStringPboardType] == NO &&
|
||||
[types containsObject:NSHTMLPboardType] == NO)
|
||||
return NO;
|
||||
|
||||
// Bail out if there is no Gecko object.
|
||||
if (!mGeckoChild)
|
||||
return NO;
|
||||
|
||||
// Obtain the current selection.
|
||||
if (!mGeckoChild)
|
||||
return NO;
|
||||
nsQueryContentEvent selection(PR_TRUE, NS_QUERY_SELECTED_TEXT, mGeckoChild);
|
||||
mGeckoChild->DispatchWindowEvent(selection);
|
||||
if (!selection.mSucceeded || selection.mReply.mString.IsEmpty())
|
||||
nsQueryContentEvent event(PR_TRUE,
|
||||
NS_QUERY_SELECTION_AS_TRANSFERABLE,
|
||||
mGeckoChild);
|
||||
mGeckoChild->DispatchWindowEvent(event);
|
||||
if (!event.mSucceeded || !event.mReply.mTransferable)
|
||||
return NO;
|
||||
|
||||
// Copy the current selection to the pasteboard.
|
||||
NSArray *typesDeclared = [NSArray arrayWithObject:NSStringPboardType];
|
||||
[pboard declareTypes:typesDeclared owner:nil];
|
||||
return [pboard setString:ToNSString(selection.mReply.mString)
|
||||
forType:NSStringPboardType];
|
||||
// Transform the transferable to an NSDictionary.
|
||||
NSDictionary* pasteboardOutputDict = nsClipboard::PasteboardDictFromTransferable(event.mReply.mTransferable);
|
||||
if (!pasteboardOutputDict)
|
||||
return NO;
|
||||
|
||||
// Declare the pasteboard types.
|
||||
unsigned int typeCount = [pasteboardOutputDict count];
|
||||
NSMutableArray * types = [NSMutableArray arrayWithCapacity:typeCount];
|
||||
[types addObjectsFromArray:[pasteboardOutputDict allKeys]];
|
||||
[pboard declareTypes:types owner:nil];
|
||||
|
||||
// Write the data to the pasteboard.
|
||||
for (unsigned int i = 0; i < typeCount; i++) {
|
||||
NSString* currentKey = [types objectAtIndex:i];
|
||||
id currentValue = [pasteboardOutputDict valueForKey:currentKey];
|
||||
|
||||
if (currentKey == NSStringPboardType ||
|
||||
currentKey == kCorePboardType_url ||
|
||||
currentKey == kCorePboardType_urld ||
|
||||
currentKey == kCorePboardType_urln) {
|
||||
[pboard setString:currentValue forType:currentKey];
|
||||
} else if (currentKey == NSHTMLPboardType) {
|
||||
[pboard setString:(nsClipboard::WrapHtmlForSystemPasteboard(currentValue)) forType:currentKey];
|
||||
} else if (currentKey == NSTIFFPboardType) {
|
||||
[pboard setData:currentValue forType:currentKey];
|
||||
} else if (currentKey == NSFilesPromisePboardType) {
|
||||
[pboard setPropertyList:currentValue forType:currentKey];
|
||||
}
|
||||
}
|
||||
|
||||
return YES;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче