зеркало из https://github.com/mozilla/pjs.git
Bug 499008, part 5, merge the text and html implementations of InsertFromDrop, r=ehsan
This commit is contained in:
Родитель
970192bb66
Коммит
e91ed72e36
|
@ -55,7 +55,7 @@ interface nsIEditActionListener;
|
|||
interface nsIInlineSpellChecker;
|
||||
interface nsITransferable;
|
||||
|
||||
[scriptable, uuid(B53516F8-270D-4DCF-85B2-01047650CEA0)]
|
||||
[scriptable, uuid(94479B76-7FD7-47D3-BB1E-5B77846339D2)]
|
||||
|
||||
interface nsIEditor : nsISupports
|
||||
{
|
||||
|
@ -360,14 +360,6 @@ interface nsIEditor : nsISupports
|
|||
/** sets the document selection to the end of the document */
|
||||
void endOfDocument();
|
||||
|
||||
/* ------------ Drag/Drop methods -------------- */
|
||||
|
||||
/**
|
||||
* insertFromDrop looks for a dragsession and inserts the
|
||||
* relevant data in response to a drop.
|
||||
*/
|
||||
void insertFromDrop(in nsIDOMEvent aEvent);
|
||||
|
||||
/* ------------ Node manipulation methods -------------- */
|
||||
|
||||
/**
|
||||
|
|
|
@ -52,7 +52,7 @@ interface nsIContentFilter;
|
|||
NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_EDITOR, 1)
|
||||
|
||||
%}
|
||||
[scriptable, uuid(77271525-543F-4432-8BD6-B7686E562D9C)]
|
||||
[scriptable, uuid(FF67AD39-ED58-4CD1-A1A3-DCD988390A97)]
|
||||
|
||||
interface nsIHTMLEditor : nsISupports
|
||||
{
|
||||
|
@ -199,14 +199,6 @@ interface nsIHTMLEditor : nsISupports
|
|||
*/
|
||||
void decreaseFontSize();
|
||||
|
||||
/* ------------ Drag/Drop methods -------------- */
|
||||
|
||||
/**
|
||||
* insertFromDrop looks for a dragsession and inserts the
|
||||
* relevant data in response to a drop.
|
||||
*/
|
||||
void insertFromDrop(in nsIDOMEvent aEvent);
|
||||
|
||||
/* ------------ HTML content methods -------------- */
|
||||
|
||||
/**
|
||||
|
|
|
@ -1191,13 +1191,6 @@ nsEditor::CanPasteTransferable(nsITransferable *aTransferable, bool *aCanPaste)
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEditor::InsertFromDrop(nsIDOMEvent *aEvent)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEditor::SetAttribute(nsIDOMElement *aElement, const nsAString & aAttribute, const nsAString & aValue)
|
||||
{
|
||||
|
|
|
@ -757,6 +757,20 @@ public:
|
|||
// added here.
|
||||
void OnFocus(nsIDOMEventTarget* aFocusEventTarget);
|
||||
|
||||
// Used to insert content from a data transfer into the editable area.
|
||||
// This is called for each item in the data transfer, with the index of
|
||||
// each item passed as aIndex.
|
||||
virtual nsresult InsertFromDataTransfer(nsIDOMDataTransfer *aDataTransfer,
|
||||
PRInt32 aIndex,
|
||||
nsIDOMDocument *aSourceDoc,
|
||||
nsIDOMNode *aDestinationNode,
|
||||
PRInt32 aDestOffset,
|
||||
bool aDoDeleteSelection) = 0;
|
||||
|
||||
virtual nsresult InsertFromDrop(nsIDOMEvent* aDropEvent) = 0;
|
||||
|
||||
virtual already_AddRefed<nsIDOMNode> FindUserSelectAllNode(nsIDOMNode* aNode) { return nsnull; }
|
||||
|
||||
protected:
|
||||
|
||||
PRUint32 mModCount; // number of modifications (for undo/redo stack)
|
||||
|
|
|
@ -1417,8 +1417,6 @@ GetStringFromDataTransfer(nsIDOMDataTransfer *aDataTransfer, const nsAString& aT
|
|||
nsresult nsHTMLEditor::InsertFromDataTransfer(nsIDOMDataTransfer *aDataTransfer,
|
||||
PRInt32 aIndex,
|
||||
nsIDOMDocument *aSourceDoc,
|
||||
const nsAString & aContextStr,
|
||||
const nsAString & aInfoStr,
|
||||
nsIDOMNode *aDestinationNode,
|
||||
PRInt32 aDestOffset,
|
||||
bool aDoDeleteSelection)
|
||||
|
@ -1478,13 +1476,15 @@ nsresult nsHTMLEditor::InsertFromDataTransfer(nsIDOMDataTransfer *aDataTransfer,
|
|||
}
|
||||
}
|
||||
else if (type.EqualsLiteral(kHTMLMime)) {
|
||||
nsAutoString text;
|
||||
nsAutoString text, contextString, infoString;
|
||||
GetStringFromDataTransfer(aDataTransfer, type, aIndex, text);
|
||||
GetStringFromDataTransfer(aDataTransfer, NS_LITERAL_STRING(kHTMLContext), aIndex, contextString);
|
||||
GetStringFromDataTransfer(aDataTransfer, NS_LITERAL_STRING(kHTMLInfo), aIndex, infoString);
|
||||
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
if (type.EqualsLiteral(kHTMLMime)) {
|
||||
rv = DoInsertHTMLWithContext(text,
|
||||
aContextStr, aInfoStr, type,
|
||||
contextString, infoString, type,
|
||||
aSourceDoc,
|
||||
aDestinationNode, aDestOffset,
|
||||
aDoDeleteSelection,
|
||||
|
@ -1510,164 +1510,6 @@ nsresult nsHTMLEditor::InsertFromDataTransfer(nsIDOMDataTransfer *aDataTransfer,
|
|||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHTMLEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
||||
{
|
||||
ForceCompositionEnd();
|
||||
|
||||
nsCOMPtr<nsIDOMDragEvent> dragEvent(do_QueryInterface(aDropEvent));
|
||||
NS_ENSURE_TRUE(dragEvent, NS_OK);
|
||||
|
||||
nsCOMPtr<nsIDOMDataTransfer> dataTransfer;
|
||||
nsresult rv = dragEvent->GetDataTransfer(getter_AddRefs(dataTransfer));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint32 numItems = 0;
|
||||
dataTransfer->GetMozItemCount(&numItems);
|
||||
|
||||
// Combine any deletion and drop insertion into one transaction
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
|
||||
// We never have to delete if selection is already collapsed
|
||||
bool deleteSelection = false;
|
||||
nsCOMPtr<nsIDOMNode> newSelectionParent;
|
||||
PRInt32 newSelectionOffset = 0;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> sourceNode;
|
||||
dataTransfer->GetMozSourceNode(getter_AddRefs(sourceNode));
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> srcdomdoc;
|
||||
if (sourceNode) {
|
||||
sourceNode->GetOwnerDocument(getter_AddRefs(srcdomdoc));
|
||||
NS_ENSURE_TRUE(sourceNode, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
PRUint32 i;
|
||||
bool doPlaceCaret = true;
|
||||
for (i = 0; i < numItems; ++i)
|
||||
{
|
||||
nsAutoString contextString, infoString;
|
||||
GetStringFromDataTransfer(dataTransfer, NS_LITERAL_STRING(kHTMLContext), i, contextString);
|
||||
GetStringFromDataTransfer(dataTransfer, NS_LITERAL_STRING(kHTMLInfo), i, infoString);
|
||||
|
||||
if (doPlaceCaret)
|
||||
{
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
rv = GetSelection(getter_AddRefs(selection));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
|
||||
|
||||
bool isCollapsed;
|
||||
rv = selection->GetIsCollapsed(&isCollapsed);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIDOMUIEvent> uiEvent = do_QueryInterface(aDropEvent);
|
||||
NS_ENSURE_TRUE(uiEvent, NS_ERROR_FAILURE);
|
||||
|
||||
// Parent and offset under the mouse cursor
|
||||
rv = uiEvent->GetRangeParent(getter_AddRefs(newSelectionParent));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(newSelectionParent, NS_ERROR_FAILURE);
|
||||
|
||||
rv = uiEvent->GetRangeOffset(&newSelectionOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// XXX: This userSelectNode code is a workaround for bug 195957.
|
||||
//
|
||||
// Check to see if newSelectionParent is part of a "-moz-user-select: all"
|
||||
// subtree. If it is, we need to make sure we don't drop into it!
|
||||
|
||||
nsCOMPtr<nsIDOMNode> userSelectNode = FindUserSelectAllNode(newSelectionParent);
|
||||
|
||||
if (userSelectNode)
|
||||
{
|
||||
// The drop is happening over a "-moz-user-select: all"
|
||||
// subtree so make sure the content we insert goes before
|
||||
// the root of the subtree.
|
||||
//
|
||||
// XXX: Note that inserting before the subtree matches the
|
||||
// current behavior when dropping on top of an image.
|
||||
// The decision for dropping before or after the
|
||||
// subtree should really be done based on coordinates.
|
||||
|
||||
rv = GetNodeLocation(userSelectNode, address_of(newSelectionParent),
|
||||
&newSelectionOffset);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(newSelectionParent, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
// We never have to delete if selection is already collapsed
|
||||
bool cursorIsInSelection = false;
|
||||
|
||||
// Check if mouse is in the selection
|
||||
if (!isCollapsed)
|
||||
{
|
||||
PRInt32 rangeCount;
|
||||
rv = selection->GetRangeCount(&rangeCount);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
for (PRInt32 j = 0; j < rangeCount; j++)
|
||||
{
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
|
||||
rv = selection->GetRangeAt(j, getter_AddRefs(range));
|
||||
if (NS_FAILED(rv) || !range)
|
||||
continue;//don't bail yet, iterate through them all
|
||||
|
||||
rv = range->IsPointInRange(newSelectionParent, newSelectionOffset, &cursorIsInSelection);
|
||||
if(cursorIsInSelection)
|
||||
break;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> destdomdoc;
|
||||
GetDocument(getter_AddRefs(destdomdoc));
|
||||
NS_ENSURE_TRUE(destdomdoc, NS_ERROR_FAILURE);
|
||||
|
||||
if (cursorIsInSelection)
|
||||
{
|
||||
// Dragging within same doc can't drop on itself -- leave!
|
||||
// (We shouldn't get here - drag event shouldn't have started if over selection)
|
||||
if (srcdomdoc == destdomdoc)
|
||||
return NS_OK;
|
||||
|
||||
// Dragging from another window onto a selection
|
||||
// XXX Decision made to NOT do this,
|
||||
// note that 4.x does replace if dropped on
|
||||
//deleteSelection = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We are NOT over the selection
|
||||
if (srcdomdoc == destdomdoc)
|
||||
{
|
||||
// Within the same doc: delete if user doesn't want to copy
|
||||
PRUint32 dropEffect;
|
||||
dataTransfer->GetDropEffectInt(&dropEffect);
|
||||
deleteSelection = !(dropEffect & nsIDragService::DRAGDROP_ACTION_COPY);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Different source doc: Don't delete
|
||||
deleteSelection = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We have to figure out whether to delete/relocate caret only once
|
||||
doPlaceCaret = false;
|
||||
}
|
||||
|
||||
rv = InsertFromDataTransfer(dataTransfer, i, srcdomdoc,
|
||||
contextString, infoString, newSelectionParent,
|
||||
newSelectionOffset, deleteSelection);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
ScrollSelectionIntoView(false);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool nsHTMLEditor::HavePrivateHTMLFlavor(nsIClipboard *aClipboard)
|
||||
{
|
||||
// check the clipboard for our special kHTMLContext flavor. If that is there, we know
|
||||
|
|
|
@ -370,8 +370,7 @@ public:
|
|||
nsCOMPtr<nsIDOMNode> *ioParent,
|
||||
PRInt32 *ioOffset,
|
||||
bool aNoEmptyNodes);
|
||||
already_AddRefed<nsIDOMNode> FindUserSelectAllNode(nsIDOMNode* aNode);
|
||||
|
||||
virtual already_AddRefed<nsIDOMNode> FindUserSelectAllNode(nsIDOMNode* aNode);
|
||||
|
||||
/** returns the absolute position of the end points of aSelection
|
||||
* in the document as a text stream.
|
||||
|
@ -596,8 +595,6 @@ protected:
|
|||
nsresult InsertFromDataTransfer(nsIDOMDataTransfer *aDataTransfer,
|
||||
PRInt32 aIndex,
|
||||
nsIDOMDocument *aSourceDoc,
|
||||
const nsAString & aContextStr,
|
||||
const nsAString & aInfoStr,
|
||||
nsIDOMNode *aDestinationNode,
|
||||
PRInt32 aDestOffset,
|
||||
bool aDoDeleteSelection);
|
||||
|
|
|
@ -163,7 +163,25 @@ NS_IMETHODIMP nsPlaintextEditor::InsertTextFromTransferable(nsITransferable *aTr
|
|||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPlaintextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
||||
nsresult nsPlaintextEditor::InsertFromDataTransfer(nsIDOMDataTransfer *aDataTransfer,
|
||||
PRInt32 aIndex,
|
||||
nsIDOMDocument *aSourceDoc,
|
||||
nsIDOMNode *aDestinationNode,
|
||||
PRInt32 aDestOffset,
|
||||
bool aDoDeleteSelection)
|
||||
{
|
||||
nsCOMPtr<nsIVariant> data;
|
||||
aDataTransfer->MozGetDataAt(NS_LITERAL_STRING("text/plain"), aIndex,
|
||||
getter_AddRefs(data));
|
||||
nsAutoString insertText;
|
||||
data->GetAsAString(insertText);
|
||||
nsContentUtils::PlatformToDOMLineBreaks(insertText);
|
||||
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
return InsertTextAt(insertText, aDestinationNode, aDestOffset, aDoDeleteSelection);
|
||||
}
|
||||
|
||||
nsresult nsPlaintextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
||||
{
|
||||
ForceCompositionEnd();
|
||||
|
||||
|
@ -179,7 +197,7 @@ NS_IMETHODIMP nsPlaintextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
|||
rv = GetDocument(getter_AddRefs(destdomdoc));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint32 numItems = 0;
|
||||
PRUint32 numItems = 0;
|
||||
rv = dataTransfer->GetMozItemCount(&numItems);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (numItems < 1) return NS_ERROR_FAILURE; // nothing to drop?
|
||||
|
@ -212,6 +230,35 @@ NS_IMETHODIMP nsPlaintextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
|||
rv = selection->GetIsCollapsed(&isCollapsed);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> sourceNode;
|
||||
dataTransfer->GetMozSourceNode(getter_AddRefs(sourceNode));
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> srcdomdoc;
|
||||
if (sourceNode) {
|
||||
sourceNode->GetOwnerDocument(getter_AddRefs(srcdomdoc));
|
||||
NS_ENSURE_TRUE(sourceNode, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
// Only the nsHTMLEditor::FindUserSelectAllNode returns a node.
|
||||
nsCOMPtr<nsIDOMNode> userSelectNode = FindUserSelectAllNode(newSelectionParent);
|
||||
if (userSelectNode)
|
||||
{
|
||||
// The drop is happening over a "-moz-user-select: all"
|
||||
// subtree so make sure the content we insert goes before
|
||||
// the root of the subtree.
|
||||
//
|
||||
// XXX: Note that inserting before the subtree matches the
|
||||
// current behavior when dropping on top of an image.
|
||||
// The decision for dropping before or after the
|
||||
// subtree should really be done based on coordinates.
|
||||
|
||||
rv = GetNodeLocation(userSelectNode, address_of(newSelectionParent),
|
||||
&newSelectionOffset);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(newSelectionParent, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
// Check if mouse is in the selection
|
||||
// if so, jump through some hoops to determine if mouse is over selection (bail)
|
||||
// and whether user wants to copy selection or delete it
|
||||
|
@ -236,15 +283,6 @@ NS_IMETHODIMP nsPlaintextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
|||
break;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> sourceNode;
|
||||
dataTransfer->GetMozSourceNode(getter_AddRefs(sourceNode));
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> srcdomdoc;
|
||||
if (sourceNode) {
|
||||
sourceNode->GetOwnerDocument(getter_AddRefs(srcdomdoc));
|
||||
NS_ENSURE_TRUE(sourceNode, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
if (cursorIsInSelection)
|
||||
{
|
||||
// Dragging within same doc can't drop on itself -- leave!
|
||||
|
@ -274,34 +312,22 @@ NS_IMETHODIMP nsPlaintextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
|||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> newSelectionContent =
|
||||
do_QueryInterface(newSelectionParent);
|
||||
nsIContent *content = newSelectionContent;
|
||||
|
||||
while (content) {
|
||||
nsCOMPtr<nsIFormControl> formControl(do_QueryInterface(content));
|
||||
|
||||
if (formControl && !formControl->AllowDrop()) {
|
||||
// Don't allow dropping into a form control that doesn't allow being
|
||||
// dropped into.
|
||||
return NS_OK;
|
||||
if (IsPlaintextEditor()) {
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(newSelectionParent);
|
||||
while (content) {
|
||||
nsCOMPtr<nsIFormControl> formControl(do_QueryInterface(content));
|
||||
if (formControl && !formControl->AllowDrop()) {
|
||||
// Don't allow dropping into a form control that doesn't allow being
|
||||
// dropped into.
|
||||
return NS_OK;
|
||||
}
|
||||
content = content->GetParent();
|
||||
}
|
||||
|
||||
content = content->GetParent();
|
||||
}
|
||||
|
||||
PRUint32 i;
|
||||
for (i = 0; i < numItems; ++i)
|
||||
{
|
||||
nsCOMPtr<nsIVariant> data;
|
||||
dataTransfer->MozGetDataAt(NS_LITERAL_STRING("text/plain"), i,
|
||||
getter_AddRefs(data));
|
||||
nsAutoString insertText;
|
||||
data->GetAsAString(insertText);
|
||||
nsContentUtils::PlatformToDOMLineBreaks(insertText);
|
||||
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
rv = InsertTextAt(insertText, newSelectionParent, newSelectionOffset, deleteSelection);
|
||||
for (PRUint32 i = 0; i < numItems; ++i) {
|
||||
InsertFromDataTransfer(dataTransfer, i, srcdomdoc, newSelectionParent,
|
||||
newSelectionOffset, deleteSelection);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
|
|
|
@ -118,8 +118,6 @@ public:
|
|||
NS_IMETHOD PasteTransferable(nsITransferable *aTransferable);
|
||||
NS_IMETHOD CanPasteTransferable(nsITransferable *aTransferable, bool *aCanPaste);
|
||||
|
||||
NS_IMETHOD InsertFromDrop(nsIDOMEvent* aDropEvent);
|
||||
|
||||
NS_IMETHOD OutputToString(const nsAString& aFormatType,
|
||||
PRUint32 aFlags,
|
||||
nsAString& aOutputString);
|
||||
|
@ -165,6 +163,15 @@ public:
|
|||
PRInt32 aDestOffset,
|
||||
bool aDoDeleteSelection);
|
||||
|
||||
virtual nsresult InsertFromDataTransfer(nsIDOMDataTransfer *aDataTransfer,
|
||||
PRInt32 aIndex,
|
||||
nsIDOMDocument *aSourceDoc,
|
||||
nsIDOMNode *aDestinationNode,
|
||||
PRInt32 aDestOffset,
|
||||
bool aDoDeleteSelection);
|
||||
|
||||
virtual nsresult InsertFromDrop(nsIDOMEvent* aDropEvent);
|
||||
|
||||
/**
|
||||
* Extends the selection for given deletion operation
|
||||
* If done, also update aAction to what's actually left to do after the
|
||||
|
|
Загрузка…
Ссылка в новой задаче