зеркало из https://github.com/mozilla/gecko-dev.git
Bug 499008, part 2, move editor dragstart handling to ContentAreaDragDrop, r=ehsan
This commit is contained in:
Родитель
2996ec9d75
Коммит
11d52d2eeb
|
@ -48,6 +48,7 @@
|
||||||
#include "nsCopySupport.h"
|
#include "nsCopySupport.h"
|
||||||
#include "nsIDOMUIEvent.h"
|
#include "nsIDOMUIEvent.h"
|
||||||
#include "nsISelection.h"
|
#include "nsISelection.h"
|
||||||
|
#include "nsISelectionController.h"
|
||||||
#include "nsIDOMNode.h"
|
#include "nsIDOMNode.h"
|
||||||
#include "nsIDOMNodeList.h"
|
#include "nsIDOMNodeList.h"
|
||||||
#include "nsIDOMEvent.h"
|
#include "nsIDOMEvent.h"
|
||||||
|
@ -70,6 +71,7 @@
|
||||||
#include "nsIDocShell.h"
|
#include "nsIDocShell.h"
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
#include "nsIImageLoadingContent.h"
|
#include "nsIImageLoadingContent.h"
|
||||||
|
#include "nsITextControlElement.h"
|
||||||
#include "nsUnicharUtils.h"
|
#include "nsUnicharUtils.h"
|
||||||
#include "nsIURL.h"
|
#include "nsIURL.h"
|
||||||
#include "nsIDocument.h"
|
#include "nsIDocument.h"
|
||||||
|
@ -88,33 +90,6 @@
|
||||||
#define kHTMLContext "text/_moz_htmlcontext"
|
#define kHTMLContext "text/_moz_htmlcontext"
|
||||||
#define kHTMLInfo "text/_moz_htmlinfo"
|
#define kHTMLInfo "text/_moz_htmlinfo"
|
||||||
|
|
||||||
// if aNode is null, use the selection from the window
|
|
||||||
static nsresult
|
|
||||||
GetTransferableForNodeOrSelection(nsIDOMWindow* aWindow,
|
|
||||||
nsIContent* aNode,
|
|
||||||
nsITransferable** aTransferable)
|
|
||||||
{
|
|
||||||
NS_ENSURE_ARG_POINTER(aWindow);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
|
||||||
aWindow->GetDocument(getter_AddRefs(domDoc));
|
|
||||||
NS_ENSURE_TRUE(domDoc, NS_ERROR_FAILURE);
|
|
||||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
|
|
||||||
|
|
||||||
nsresult rv;
|
|
||||||
if (aNode) {
|
|
||||||
rv = nsCopySupport::GetTransferableForNode(aNode, doc, aTransferable);
|
|
||||||
} else {
|
|
||||||
nsCOMPtr<nsISelection> selection;
|
|
||||||
aWindow->GetSelection(getter_AddRefs(selection));
|
|
||||||
rv = nsCopySupport::GetTransferableForSelection(selection, doc,
|
|
||||||
aTransferable);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
class NS_STACK_CLASS DragDataProducer
|
class NS_STACK_CLASS DragDataProducer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -124,7 +99,7 @@ public:
|
||||||
bool aIsAltKeyPressed);
|
bool aIsAltKeyPressed);
|
||||||
nsresult Produce(nsDOMDataTransfer* aDataTransfer,
|
nsresult Produce(nsDOMDataTransfer* aDataTransfer,
|
||||||
bool* aCanDrag,
|
bool* aCanDrag,
|
||||||
bool* aDragSelection,
|
nsISelection** aSelection,
|
||||||
nsIContent** aDragNode);
|
nsIContent** aDragNode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -172,7 +147,7 @@ nsContentAreaDragDrop::GetDragData(nsIDOMWindow* aWindow,
|
||||||
bool aIsAltKeyPressed,
|
bool aIsAltKeyPressed,
|
||||||
nsDOMDataTransfer* aDataTransfer,
|
nsDOMDataTransfer* aDataTransfer,
|
||||||
bool* aCanDrag,
|
bool* aCanDrag,
|
||||||
bool* aDragSelection,
|
nsISelection** aSelection,
|
||||||
nsIContent** aDragNode)
|
nsIContent** aDragNode)
|
||||||
{
|
{
|
||||||
NS_ENSURE_TRUE(aSelectionTargetNode, NS_ERROR_INVALID_ARG);
|
NS_ENSURE_TRUE(aSelectionTargetNode, NS_ERROR_INVALID_ARG);
|
||||||
|
@ -181,7 +156,7 @@ nsContentAreaDragDrop::GetDragData(nsIDOMWindow* aWindow,
|
||||||
|
|
||||||
DragDataProducer
|
DragDataProducer
|
||||||
provider(aWindow, aTarget, aSelectionTargetNode, aIsAltKeyPressed);
|
provider(aWindow, aTarget, aSelectionTargetNode, aIsAltKeyPressed);
|
||||||
return provider.Produce(aDataTransfer, aCanDrag, aDragSelection, aDragNode);
|
return provider.Produce(aDataTransfer, aCanDrag, aSelection, aDragNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -412,10 +387,10 @@ DragDataProducer::GetNodeString(nsIContent* inNode,
|
||||||
nsresult
|
nsresult
|
||||||
DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
|
DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
|
||||||
bool* aCanDrag,
|
bool* aCanDrag,
|
||||||
bool* aDragSelection,
|
nsISelection** aSelection,
|
||||||
nsIContent** aDragNode)
|
nsIContent** aDragNode)
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(aCanDrag && aDragSelection && aDataTransfer && aDragNode,
|
NS_PRECONDITION(aCanDrag && aSelection && aDataTransfer && aDragNode,
|
||||||
"null pointer passed to Produce");
|
"null pointer passed to Produce");
|
||||||
NS_ASSERTION(mWindow, "window not set");
|
NS_ASSERTION(mWindow, "window not set");
|
||||||
NS_ASSERTION(mSelectionTargetNode, "selection target node should have been set");
|
NS_ASSERTION(mSelectionTargetNode, "selection target node should have been set");
|
||||||
|
@ -424,33 +399,72 @@ DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
nsIContent* dragNode = nsnull;
|
nsIContent* dragNode = nsnull;
|
||||||
|
*aSelection = nsnull;
|
||||||
|
|
||||||
// find the selection to see what we could be dragging and if
|
// Find the selection to see what we could be dragging and if what we're
|
||||||
// what we're dragging is in what is selected.
|
// dragging is in what is selected. If this is an editable textbox, use
|
||||||
|
// the textbox's selection, otherwise use the window's selection.
|
||||||
nsCOMPtr<nsISelection> selection;
|
nsCOMPtr<nsISelection> selection;
|
||||||
mWindow->GetSelection(getter_AddRefs(selection));
|
nsIContent* editingElement = mSelectionTargetNode->IsEditable() ?
|
||||||
if (!selection) {
|
mSelectionTargetNode->GetEditingHost() : nsnull;
|
||||||
return NS_OK;
|
nsCOMPtr<nsITextControlElement> textControl(do_QueryInterface(editingElement));
|
||||||
}
|
if (textControl) {
|
||||||
|
nsISelectionController* selcon = textControl->GetSelectionController();
|
||||||
// check if the node is inside a form control. If so, dragging will be
|
if (selcon) {
|
||||||
// handled in editor code (nsPlaintextDataTransfer::DoDrag). Don't set
|
selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
|
||||||
// aCanDrag to false however, as we still want to allow the drag.
|
if (!selection)
|
||||||
nsCOMPtr<nsIContent> findFormNode = mSelectionTargetNode;
|
return NS_OK;
|
||||||
nsIContent* findFormParent = findFormNode->GetParent();
|
}
|
||||||
while (findFormParent) {
|
}
|
||||||
nsCOMPtr<nsIFormControl> form(do_QueryInterface(findFormParent));
|
else {
|
||||||
if (form && !form->AllowDraggableChildren()) {
|
mWindow->GetSelection(getter_AddRefs(selection));
|
||||||
return NS_OK;
|
if (!selection)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
// Check if the node is inside a form control. Don't set aCanDrag to false
|
||||||
|
//however, as we still want to allow the drag.
|
||||||
|
nsCOMPtr<nsIContent> findFormNode = mSelectionTargetNode;
|
||||||
|
nsIContent* findFormParent = findFormNode->GetParent();
|
||||||
|
while (findFormParent) {
|
||||||
|
nsCOMPtr<nsIFormControl> form(do_QueryInterface(findFormParent));
|
||||||
|
if (form && !form->AllowDraggableChildren()) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
findFormParent = findFormParent->GetParent();
|
||||||
}
|
}
|
||||||
findFormParent = findFormParent->GetParent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if set, serialize the content under this node
|
// if set, serialize the content under this node
|
||||||
nsCOMPtr<nsIContent> nodeToSerialize;
|
nsCOMPtr<nsIContent> nodeToSerialize;
|
||||||
*aDragSelection = false;
|
|
||||||
|
|
||||||
{
|
bool isChromeShell = false;
|
||||||
|
nsCOMPtr<nsIWebNavigation> webnav = do_GetInterface(mWindow);
|
||||||
|
nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(webnav);
|
||||||
|
if (dsti) {
|
||||||
|
PRInt32 type = -1;
|
||||||
|
if (NS_SUCCEEDED(dsti->GetItemType(&type)) &&
|
||||||
|
type == nsIDocShellTreeItem::typeChrome) {
|
||||||
|
isChromeShell = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// In chrome shells, only allow dragging inside editable areas.
|
||||||
|
if (isChromeShell && !editingElement)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
if (isChromeShell && textControl) {
|
||||||
|
// Only use the selection if it isn't collapsed.
|
||||||
|
bool isCollapsed = false;
|
||||||
|
selection->GetIsCollapsed(&isCollapsed);
|
||||||
|
if (!isCollapsed)
|
||||||
|
selection.swap(*aSelection);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// In content shells, a number of checks are made below to determine
|
||||||
|
// whether an image or a link is being dragged. If so, add additional
|
||||||
|
// data to the data transfer. This is also done for chrome shells, but
|
||||||
|
// only when in a non-textbox editor.
|
||||||
|
|
||||||
bool haveSelectedContent = false;
|
bool haveSelectedContent = false;
|
||||||
|
|
||||||
// possible parent link node
|
// possible parent link node
|
||||||
|
@ -490,7 +504,7 @@ DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
*aDragSelection = true;
|
selection.swap(*aSelection);
|
||||||
} else if (selectedImageOrLinkNode) {
|
} else if (selectedImageOrLinkNode) {
|
||||||
// an image is selected
|
// an image is selected
|
||||||
image = do_QueryInterface(selectedImageOrLinkNode);
|
image = do_QueryInterface(selectedImageOrLinkNode);
|
||||||
|
@ -660,20 +674,28 @@ DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nodeToSerialize || *aDragSelection) {
|
if (nodeToSerialize || *aSelection) {
|
||||||
// if we have selected text, use it in preference to the node
|
|
||||||
if (*aDragSelection) {
|
|
||||||
nodeToSerialize = nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
mHtmlString.Truncate();
|
mHtmlString.Truncate();
|
||||||
mContextString.Truncate();
|
mContextString.Truncate();
|
||||||
mInfoString.Truncate();
|
mInfoString.Truncate();
|
||||||
mTitleString.Truncate();
|
mTitleString.Truncate();
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||||
|
mWindow->GetDocument(getter_AddRefs(domDoc));
|
||||||
|
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
|
||||||
|
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
// if we have selected text, use it in preference to the node
|
||||||
nsCOMPtr<nsITransferable> transferable;
|
nsCOMPtr<nsITransferable> transferable;
|
||||||
rv = ::GetTransferableForNodeOrSelection(mWindow, nodeToSerialize,
|
if (*aSelection) {
|
||||||
getter_AddRefs(transferable));
|
rv = nsCopySupport::GetTransferableForSelection(*aSelection, doc,
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
getter_AddRefs(transferable));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rv = nsCopySupport::GetTransferableForNode(nodeToSerialize, doc,
|
||||||
|
getter_AddRefs(transferable));
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsISupportsString> data;
|
nsCOMPtr<nsISupportsString> data;
|
||||||
PRUint32 dataSize;
|
PRUint32 dataSize;
|
||||||
rv = transferable->GetTransferData(kHTMLMime, getter_AddRefs(data), &dataSize);
|
rv = transferable->GetTransferData(kHTMLMime, getter_AddRefs(data), &dataSize);
|
||||||
|
@ -747,15 +769,17 @@ DragDataProducer::AddStringsToDataTransfer(nsIContent* aDragNode,
|
||||||
AddString(aDataTransfer, NS_LITERAL_STRING("text/uri-list"), mUrlString, principal);
|
AddString(aDataTransfer, NS_LITERAL_STRING("text/uri-list"), mUrlString, principal);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add a special flavor, even if we don't have html context data
|
// add a special flavor for the html context data
|
||||||
AddString(aDataTransfer, NS_LITERAL_STRING(kHTMLContext), mContextString, principal);
|
if (!mContextString.IsEmpty())
|
||||||
|
AddString(aDataTransfer, NS_LITERAL_STRING(kHTMLContext), mContextString, principal);
|
||||||
|
|
||||||
// add a special flavor if we have html info data
|
// add a special flavor if we have html info data
|
||||||
if (!mInfoString.IsEmpty())
|
if (!mInfoString.IsEmpty())
|
||||||
AddString(aDataTransfer, NS_LITERAL_STRING(kHTMLInfo), mInfoString, principal);
|
AddString(aDataTransfer, NS_LITERAL_STRING(kHTMLInfo), mInfoString, principal);
|
||||||
|
|
||||||
// add the full html
|
// add the full html
|
||||||
AddString(aDataTransfer, NS_LITERAL_STRING(kHTMLMime), mHtmlString, principal);
|
if (!mHtmlString.IsEmpty())
|
||||||
|
AddString(aDataTransfer, NS_LITERAL_STRING(kHTMLMime), mHtmlString, principal);
|
||||||
|
|
||||||
// add the plain text. we use the url for text/plain data if an anchor is
|
// add the plain text. we use the url for text/plain data if an anchor is
|
||||||
// being dragged, rather than the title text of the link or the alt text for
|
// being dragged, rather than the title text of the link or the alt text for
|
||||||
|
|
|
@ -78,8 +78,8 @@ public:
|
||||||
* aDataTransfer - the dataTransfer for the drag event.
|
* aDataTransfer - the dataTransfer for the drag event.
|
||||||
* aCanDrag - [out] set to true if the drag may proceed, false to stop the
|
* aCanDrag - [out] set to true if the drag may proceed, false to stop the
|
||||||
* drag entirely
|
* drag entirely
|
||||||
* aDragSelection - [out] set to true to indicate that a selection is being
|
* aSelection - [out] set to the selection being dragged, or null if no
|
||||||
* dragged, rather than a specific node
|
* selection is being dragged.
|
||||||
* aDragNode - [out] the link, image or area being dragged, or null if the
|
* aDragNode - [out] the link, image or area being dragged, or null if the
|
||||||
* drag occurred on another element.
|
* drag occurred on another element.
|
||||||
*/
|
*/
|
||||||
|
@ -89,7 +89,7 @@ public:
|
||||||
bool aIsAltKeyPressed,
|
bool aIsAltKeyPressed,
|
||||||
nsDOMDataTransfer* aDataTransfer,
|
nsDOMDataTransfer* aDataTransfer,
|
||||||
bool* aCanDrag,
|
bool* aCanDrag,
|
||||||
bool* aDragSelection,
|
nsISelection** aSelection,
|
||||||
nsIContent** aDragNode);
|
nsIContent** aDragNode);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2081,14 +2081,12 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
||||||
if (!dataTransfer)
|
if (!dataTransfer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool isInEditor = false;
|
nsCOMPtr<nsISelection> selection;
|
||||||
bool isSelection = false;
|
|
||||||
nsCOMPtr<nsIContent> eventContent, targetContent;
|
nsCOMPtr<nsIContent> eventContent, targetContent;
|
||||||
mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(eventContent));
|
mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(eventContent));
|
||||||
if (eventContent)
|
if (eventContent)
|
||||||
DetermineDragTarget(aPresContext, eventContent, dataTransfer,
|
DetermineDragTarget(aPresContext, eventContent, dataTransfer,
|
||||||
&isSelection, &isInEditor,
|
getter_AddRefs(selection), getter_AddRefs(targetContent));
|
||||||
getter_AddRefs(targetContent));
|
|
||||||
|
|
||||||
// Stop tracking the drag gesture now. This should stop us from
|
// Stop tracking the drag gesture now. This should stop us from
|
||||||
// reentering GenerateDragGesture inside DOM event processing.
|
// reentering GenerateDragGesture inside DOM event processing.
|
||||||
|
@ -2129,9 +2127,8 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
||||||
// elements in an editor, only fire the draggesture event so that the
|
// elements in an editor, only fire the draggesture event so that the
|
||||||
// editor code can handle it but content doesn't see a dragstart.
|
// editor code can handle it but content doesn't see a dragstart.
|
||||||
nsEventStatus status = nsEventStatus_eIgnore;
|
nsEventStatus status = nsEventStatus_eIgnore;
|
||||||
if (!isInEditor)
|
nsEventDispatcher::Dispatch(targetContent, aPresContext, &startEvent, nsnull,
|
||||||
nsEventDispatcher::Dispatch(targetContent, aPresContext, &startEvent, nsnull,
|
&status);
|
||||||
&status);
|
|
||||||
|
|
||||||
nsDragEvent* event = &startEvent;
|
nsDragEvent* event = &startEvent;
|
||||||
if (status != nsEventStatus_eConsumeNoDefault) {
|
if (status != nsEventStatus_eConsumeNoDefault) {
|
||||||
|
@ -2148,7 +2145,7 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
||||||
|
|
||||||
if (status != nsEventStatus_eConsumeNoDefault) {
|
if (status != nsEventStatus_eConsumeNoDefault) {
|
||||||
bool dragStarted = DoDefaultDragStart(aPresContext, event, dataTransfer,
|
bool dragStarted = DoDefaultDragStart(aPresContext, event, dataTransfer,
|
||||||
targetContent, isSelection);
|
targetContent, selection);
|
||||||
if (dragStarted) {
|
if (dragStarted) {
|
||||||
sActiveESM = nsnull;
|
sActiveESM = nsnull;
|
||||||
aEvent->flags |= NS_EVENT_FLAG_STOP_DISPATCH;
|
aEvent->flags |= NS_EVENT_FLAG_STOP_DISPATCH;
|
||||||
|
@ -2173,37 +2170,27 @@ void
|
||||||
nsEventStateManager::DetermineDragTarget(nsPresContext* aPresContext,
|
nsEventStateManager::DetermineDragTarget(nsPresContext* aPresContext,
|
||||||
nsIContent* aSelectionTarget,
|
nsIContent* aSelectionTarget,
|
||||||
nsDOMDataTransfer* aDataTransfer,
|
nsDOMDataTransfer* aDataTransfer,
|
||||||
bool* aIsSelection,
|
nsISelection** aSelection,
|
||||||
bool* aIsInEditor,
|
|
||||||
nsIContent** aTargetNode)
|
nsIContent** aTargetNode)
|
||||||
{
|
{
|
||||||
*aTargetNode = nsnull;
|
*aTargetNode = nsnull;
|
||||||
*aIsInEditor = false;
|
|
||||||
|
|
||||||
nsCOMPtr<nsISupports> container = aPresContext->GetContainer();
|
nsCOMPtr<nsISupports> container = aPresContext->GetContainer();
|
||||||
nsCOMPtr<nsIDOMWindow> window = do_GetInterface(container);
|
nsCOMPtr<nsIDOMWindow> window = do_GetInterface(container);
|
||||||
|
|
||||||
// GetDragData determines if a selection, link or image in the content
|
// GetDragData determines if a selection, link or image in the content
|
||||||
// should be dragged, and places the data associated with the drag in the
|
// should be dragged, and places the data associated with the drag in the
|
||||||
// data transfer. Skip this check for chrome shells.
|
// data transfer.
|
||||||
|
// mGestureDownContent is the node where the mousedown event for the drag
|
||||||
|
// occurred, and aSelectionTarget is the node to use when a selection is used
|
||||||
bool canDrag;
|
bool canDrag;
|
||||||
nsCOMPtr<nsIContent> dragDataNode;
|
nsCOMPtr<nsIContent> dragDataNode;
|
||||||
nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(container);
|
nsresult rv = nsContentAreaDragDrop::GetDragData(window, mGestureDownContent,
|
||||||
if (dsti) {
|
aSelectionTarget, mGestureDownAlt,
|
||||||
PRInt32 type = -1;
|
aDataTransfer, &canDrag, aSelection,
|
||||||
if (NS_SUCCEEDED(dsti->GetItemType(&type)) &&
|
getter_AddRefs(dragDataNode));
|
||||||
type != nsIDocShellTreeItem::typeChrome) {
|
if (NS_FAILED(rv) || !canDrag)
|
||||||
// mGestureDownContent is the node where the mousedown event for the drag
|
return;
|
||||||
// occurred, and aSelectionTarget is the node to use when a selection is used
|
|
||||||
nsresult rv =
|
|
||||||
nsContentAreaDragDrop::GetDragData(window, mGestureDownContent,
|
|
||||||
aSelectionTarget, mGestureDownAlt,
|
|
||||||
aDataTransfer, &canDrag, aIsSelection,
|
|
||||||
getter_AddRefs(dragDataNode));
|
|
||||||
if (NS_FAILED(rv) || !canDrag)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if GetDragData returned a node, use that as the node being dragged.
|
// if GetDragData returned a node, use that as the node being dragged.
|
||||||
// Otherwise, if a selection is being dragged, use the node within the
|
// Otherwise, if a selection is being dragged, use the node within the
|
||||||
|
@ -2211,7 +2198,7 @@ nsEventStateManager::DetermineDragTarget(nsPresContext* aPresContext,
|
||||||
nsIContent* dragContent = mGestureDownContent;
|
nsIContent* dragContent = mGestureDownContent;
|
||||||
if (dragDataNode)
|
if (dragDataNode)
|
||||||
dragContent = dragDataNode;
|
dragContent = dragDataNode;
|
||||||
else if (*aIsSelection)
|
else if (*aSelection)
|
||||||
dragContent = aSelectionTarget;
|
dragContent = aSelectionTarget;
|
||||||
|
|
||||||
nsIContent* originalDragContent = dragContent;
|
nsIContent* originalDragContent = dragContent;
|
||||||
|
@ -2220,7 +2207,7 @@ nsEventStateManager::DetermineDragTarget(nsPresContext* aPresContext,
|
||||||
// draggable property set. If one is found, use that as the target of the
|
// draggable property set. If one is found, use that as the target of the
|
||||||
// drag instead of the node that was clicked on. If a draggable node wasn't
|
// drag instead of the node that was clicked on. If a draggable node wasn't
|
||||||
// found, just use the clicked node.
|
// found, just use the clicked node.
|
||||||
if (!*aIsSelection) {
|
if (!*aSelection) {
|
||||||
while (dragContent) {
|
while (dragContent) {
|
||||||
nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(dragContent);
|
nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(dragContent);
|
||||||
if (htmlElement) {
|
if (htmlElement) {
|
||||||
|
@ -2245,17 +2232,6 @@ nsEventStateManager::DetermineDragTarget(nsPresContext* aPresContext,
|
||||||
// otherwise, it's not an HTML or XUL element, so just keep looking
|
// otherwise, it's not an HTML or XUL element, so just keep looking
|
||||||
}
|
}
|
||||||
dragContent = dragContent->GetParent();
|
dragContent = dragContent->GetParent();
|
||||||
|
|
||||||
// if an editable parent is encountered, then we don't look at any
|
|
||||||
// ancestors. This is used because the editor attaches a draggesture
|
|
||||||
// listener to the editable element and we want to call it without
|
|
||||||
// making the editable element draggable. This should be removed once
|
|
||||||
// the editor is switched over to using the proper drag and drop api.
|
|
||||||
nsCOMPtr<nsIDOMNSEditableElement> editableElement = do_QueryInterface(dragContent);
|
|
||||||
if (editableElement) {
|
|
||||||
*aIsInEditor = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2279,7 +2255,7 @@ nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
|
||||||
nsDragEvent* aDragEvent,
|
nsDragEvent* aDragEvent,
|
||||||
nsDOMDataTransfer* aDataTransfer,
|
nsDOMDataTransfer* aDataTransfer,
|
||||||
nsIContent* aDragTarget,
|
nsIContent* aDragTarget,
|
||||||
bool aIsSelection)
|
nsISelection* aSelection)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIDragService> dragService =
|
nsCOMPtr<nsIDragService> dragService =
|
||||||
do_GetService("@mozilla.org/widget/dragservice;1");
|
do_GetService("@mozilla.org/widget/dragservice;1");
|
||||||
|
@ -2333,22 +2309,6 @@ nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
|
||||||
PRInt32 imageX, imageY;
|
PRInt32 imageX, imageY;
|
||||||
nsIDOMElement* dragImage = aDataTransfer->GetDragImage(&imageX, &imageY);
|
nsIDOMElement* dragImage = aDataTransfer->GetDragImage(&imageX, &imageY);
|
||||||
|
|
||||||
// If a selection is being dragged, and no custom drag image was
|
|
||||||
// set, get the selection so that the drag region can be created
|
|
||||||
// from the selection area. If a custom image was set, it doesn't
|
|
||||||
// matter what the selection is since the image will be used instead.
|
|
||||||
nsISelection* selection = nsnull;
|
|
||||||
if (aIsSelection && !dragImage) {
|
|
||||||
nsIDocument* doc = aDragTarget->GetCurrentDoc();
|
|
||||||
if (doc) {
|
|
||||||
nsIPresShell* presShell = doc->GetShell();
|
|
||||||
if (presShell) {
|
|
||||||
selection = presShell->GetCurrentSelection(
|
|
||||||
nsISelectionController::SELECTION_NORMAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsISupportsArray> transArray;
|
nsCOMPtr<nsISupportsArray> transArray;
|
||||||
aDataTransfer->GetTransferables(getter_AddRefs(transArray));
|
aDataTransfer->GetTransferables(getter_AddRefs(transArray));
|
||||||
if (!transArray)
|
if (!transArray)
|
||||||
|
@ -2363,8 +2323,13 @@ nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
|
||||||
nsCOMPtr<nsIDOMDragEvent> domDragEvent = do_QueryInterface(domEvent);
|
nsCOMPtr<nsIDOMDragEvent> domDragEvent = do_QueryInterface(domEvent);
|
||||||
// if creating a drag event failed, starting a drag session will
|
// if creating a drag event failed, starting a drag session will
|
||||||
// just fail.
|
// just fail.
|
||||||
if (selection) {
|
|
||||||
dragService->InvokeDragSessionWithSelection(selection, transArray,
|
// Use InvokeDragSessionWithSelection if a selection is being dragged,
|
||||||
|
// such that the image can be generated from the selected text. However,
|
||||||
|
// use InvokeDragSessionWithImage if a custom image was set or something
|
||||||
|
// other than a selection is being dragged.
|
||||||
|
if (!dragImage && aSelection) {
|
||||||
|
dragService->InvokeDragSessionWithSelection(aSelection, transArray,
|
||||||
action, domDragEvent,
|
action, domDragEvent,
|
||||||
aDataTransfer);
|
aDataTransfer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -417,15 +417,13 @@ protected:
|
||||||
*
|
*
|
||||||
* aSelectionTarget - target to check for selection
|
* aSelectionTarget - target to check for selection
|
||||||
* aDataTransfer - data transfer object that will contain the data to drag
|
* aDataTransfer - data transfer object that will contain the data to drag
|
||||||
* aIsSelection - [out] set to true if a selection is being dragged
|
* aSelection - [out] set to the selection to be dragged
|
||||||
* aIsInEditor - [out] set to true if the content is in an editor field
|
|
||||||
* aTargetNode - [out] the draggable node, or null if there isn't one
|
* aTargetNode - [out] the draggable node, or null if there isn't one
|
||||||
*/
|
*/
|
||||||
void DetermineDragTarget(nsPresContext* aPresContext,
|
void DetermineDragTarget(nsPresContext* aPresContext,
|
||||||
nsIContent* aSelectionTarget,
|
nsIContent* aSelectionTarget,
|
||||||
nsDOMDataTransfer* aDataTransfer,
|
nsDOMDataTransfer* aDataTransfer,
|
||||||
bool* aIsSelection,
|
nsISelection** aSelection,
|
||||||
bool* aIsInEditor,
|
|
||||||
nsIContent** aTargetNode);
|
nsIContent** aTargetNode);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -436,13 +434,13 @@ protected:
|
||||||
* aDragEvent - the dragstart/draggesture event
|
* aDragEvent - the dragstart/draggesture event
|
||||||
* aDataTransfer - the data transfer that holds the data to be dragged
|
* aDataTransfer - the data transfer that holds the data to be dragged
|
||||||
* aDragTarget - the target of the drag
|
* aDragTarget - the target of the drag
|
||||||
* aIsSelection - true if a selection is being dragged
|
* aSelection - the selection to be dragged
|
||||||
*/
|
*/
|
||||||
bool DoDefaultDragStart(nsPresContext* aPresContext,
|
bool DoDefaultDragStart(nsPresContext* aPresContext,
|
||||||
nsDragEvent* aDragEvent,
|
nsDragEvent* aDragEvent,
|
||||||
nsDOMDataTransfer* aDataTransfer,
|
nsDOMDataTransfer* aDataTransfer,
|
||||||
nsIContent* aDragTarget,
|
nsIContent* aDragTarget,
|
||||||
bool aIsSelection);
|
nsISelection* aSelection);
|
||||||
|
|
||||||
bool IsTrackingDragGesture ( ) const { return mGestureDownContent != nsnull; }
|
bool IsTrackingDragGesture ( ) const { return mGestureDownContent != nsnull; }
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -55,7 +55,7 @@ interface nsIEditActionListener;
|
||||||
interface nsIInlineSpellChecker;
|
interface nsIInlineSpellChecker;
|
||||||
interface nsITransferable;
|
interface nsITransferable;
|
||||||
|
|
||||||
[scriptable, uuid(20ee0b70-c528-11e0-9572-0800200c9a66)]
|
[scriptable, uuid(B53516F8-270D-4DCF-85B2-01047650CEA0)]
|
||||||
|
|
||||||
interface nsIEditor : nsISupports
|
interface nsIEditor : nsISupports
|
||||||
{
|
{
|
||||||
|
@ -361,19 +361,7 @@ interface nsIEditor : nsISupports
|
||||||
void endOfDocument();
|
void endOfDocument();
|
||||||
|
|
||||||
/* ------------ Drag/Drop methods -------------- */
|
/* ------------ Drag/Drop methods -------------- */
|
||||||
|
|
||||||
/**
|
|
||||||
* canDrag decides if a drag should be started
|
|
||||||
* (for example, based on the current selection and mousepoint).
|
|
||||||
*/
|
|
||||||
boolean canDrag(in nsIDOMEvent aEvent);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* doDrag transfers the relevant data (as appropriate)
|
|
||||||
* to a transferable so it can later be dropped.
|
|
||||||
*/
|
|
||||||
void doDrag(in nsIDOMEvent aEvent);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* insertFromDrop looks for a dragsession and inserts the
|
* insertFromDrop looks for a dragsession and inserts the
|
||||||
* relevant data in response to a drop.
|
* relevant data in response to a drop.
|
||||||
|
|
|
@ -52,7 +52,7 @@ interface nsIContentFilter;
|
||||||
NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_EDITOR, 1)
|
NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_EDITOR, 1)
|
||||||
|
|
||||||
%}
|
%}
|
||||||
[scriptable, uuid(68890CBB-999D-42D0-A15C-5D534CF25C00)]
|
[scriptable, uuid(77271525-543F-4432-8BD6-B7686E562D9C)]
|
||||||
|
|
||||||
interface nsIHTMLEditor : nsISupports
|
interface nsIHTMLEditor : nsISupports
|
||||||
{
|
{
|
||||||
|
@ -201,18 +201,6 @@ interface nsIHTMLEditor : nsISupports
|
||||||
|
|
||||||
/* ------------ Drag/Drop methods -------------- */
|
/* ------------ Drag/Drop methods -------------- */
|
||||||
|
|
||||||
/**
|
|
||||||
* canDrag decides if a drag should be started
|
|
||||||
* (for example, based on the current selection and mousepoint).
|
|
||||||
*/
|
|
||||||
boolean canDrag(in nsIDOMEvent aEvent);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* doDrag transfers the relevant data (as appropriate)
|
|
||||||
* to a transferable so it can later be dropped.
|
|
||||||
*/
|
|
||||||
void doDrag(in nsIDOMEvent aEvent);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* insertFromDrop looks for a dragsession and inserts the
|
* insertFromDrop looks for a dragsession and inserts the
|
||||||
* relevant data in response to a drop.
|
* relevant data in response to a drop.
|
||||||
|
|
|
@ -1191,18 +1191,6 @@ nsEditor::CanPasteTransferable(nsITransferable *aTransferable, bool *aCanPaste)
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsEditor::CanDrag(nsIDOMEvent *aEvent, bool *aCanDrag)
|
|
||||||
{
|
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsEditor::DoDrag(nsIDOMEvent *aEvent)
|
|
||||||
{
|
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsEditor::InsertFromDrop(nsIDOMEvent *aEvent)
|
nsEditor::InsertFromDrop(nsIDOMEvent *aEvent)
|
||||||
{
|
{
|
||||||
|
|
|
@ -158,11 +158,6 @@ nsEditorEventListener::InstallToEditor()
|
||||||
NS_LITERAL_STRING("keypress"),
|
NS_LITERAL_STRING("keypress"),
|
||||||
NS_EVENT_FLAG_BUBBLE |
|
NS_EVENT_FLAG_BUBBLE |
|
||||||
NS_EVENT_FLAG_SYSTEM_EVENT);
|
NS_EVENT_FLAG_SYSTEM_EVENT);
|
||||||
// See bug 455215, we cannot use the standard dragstart event yet
|
|
||||||
elmP->AddEventListenerByType(this,
|
|
||||||
NS_LITERAL_STRING("draggesture"),
|
|
||||||
NS_EVENT_FLAG_BUBBLE |
|
|
||||||
NS_EVENT_FLAG_SYSTEM_EVENT);
|
|
||||||
elmP->AddEventListenerByType(this,
|
elmP->AddEventListenerByType(this,
|
||||||
NS_LITERAL_STRING("dragenter"),
|
NS_LITERAL_STRING("dragenter"),
|
||||||
NS_EVENT_FLAG_BUBBLE |
|
NS_EVENT_FLAG_BUBBLE |
|
||||||
|
@ -255,10 +250,6 @@ nsEditorEventListener::UninstallFromEditor()
|
||||||
NS_LITERAL_STRING("keypress"),
|
NS_LITERAL_STRING("keypress"),
|
||||||
NS_EVENT_FLAG_BUBBLE |
|
NS_EVENT_FLAG_BUBBLE |
|
||||||
NS_EVENT_FLAG_SYSTEM_EVENT);
|
NS_EVENT_FLAG_SYSTEM_EVENT);
|
||||||
elmP->RemoveEventListenerByType(this,
|
|
||||||
NS_LITERAL_STRING("draggesture"),
|
|
||||||
NS_EVENT_FLAG_BUBBLE |
|
|
||||||
NS_EVENT_FLAG_SYSTEM_EVENT);
|
|
||||||
elmP->RemoveEventListenerByType(this,
|
elmP->RemoveEventListenerByType(this,
|
||||||
NS_LITERAL_STRING("dragenter"),
|
NS_LITERAL_STRING("dragenter"),
|
||||||
NS_EVENT_FLAG_BUBBLE |
|
NS_EVENT_FLAG_BUBBLE |
|
||||||
|
@ -332,8 +323,6 @@ nsEditorEventListener::HandleEvent(nsIDOMEvent* aEvent)
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMDragEvent> dragEvent = do_QueryInterface(aEvent);
|
nsCOMPtr<nsIDOMDragEvent> dragEvent = do_QueryInterface(aEvent);
|
||||||
if (dragEvent) {
|
if (dragEvent) {
|
||||||
if (eventType.EqualsLiteral("draggesture"))
|
|
||||||
return DragGesture(dragEvent);
|
|
||||||
if (eventType.EqualsLiteral("dragenter"))
|
if (eventType.EqualsLiteral("dragenter"))
|
||||||
return DragEnter(dragEvent);
|
return DragEnter(dragEvent);
|
||||||
if (eventType.EqualsLiteral("dragover"))
|
if (eventType.EqualsLiteral("dragover"))
|
||||||
|
@ -658,18 +647,6 @@ nsEditorEventListener::HandleText(nsIDOMEvent* aTextEvent)
|
||||||
* Drag event implementation
|
* Drag event implementation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsEditorEventListener::DragGesture(nsIDOMDragEvent* aDragEvent)
|
|
||||||
{
|
|
||||||
// ...figure out if a drag should be started...
|
|
||||||
bool canDrag;
|
|
||||||
nsresult rv = mEditor->CanDrag(aDragEvent, &canDrag);
|
|
||||||
if ( NS_SUCCEEDED(rv) && canDrag )
|
|
||||||
rv = mEditor->DoDrag(aDragEvent);
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsEditorEventListener::DragEnter(nsIDOMDragEvent* aDragEvent)
|
nsEditorEventListener::DragEnter(nsIDOMDragEvent* aDragEvent)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1611,119 +1611,6 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsHTMLEditor::CanDrag(nsIDOMEvent *aDragEvent, bool *aCanDrag)
|
|
||||||
{
|
|
||||||
return nsPlaintextEditor::CanDrag(aDragEvent, aCanDrag);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsHTMLEditor::PutDragDataInTransferable(nsITransferable **aTransferable)
|
|
||||||
{
|
|
||||||
NS_ENSURE_ARG_POINTER(aTransferable);
|
|
||||||
*aTransferable = nsnull;
|
|
||||||
nsCOMPtr<nsIDocumentEncoder> docEncoder;
|
|
||||||
nsresult rv = SetupDocEncoder(getter_AddRefs(docEncoder));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
NS_ENSURE_TRUE(docEncoder, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
// grab a string
|
|
||||||
nsAutoString buffer, parents, info;
|
|
||||||
|
|
||||||
// find out if we're a plaintext control or not
|
|
||||||
if (!IsPlaintextEditor())
|
|
||||||
{
|
|
||||||
// encode the selection as html with contextual info
|
|
||||||
rv = docEncoder->EncodeToStringWithContext(parents, info, buffer);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// encode the selection
|
|
||||||
rv = docEncoder->EncodeToString(buffer);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we have an empty string, we're done; otherwise continue
|
|
||||||
if ( buffer.IsEmpty() )
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
nsCOMPtr<nsISupportsString> dataWrapper, contextWrapper, infoWrapper;
|
|
||||||
|
|
||||||
dataWrapper = do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
rv = dataWrapper->SetData(buffer);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
/* create html flavor transferable */
|
|
||||||
nsCOMPtr<nsITransferable> trans = do_CreateInstance("@mozilla.org/widget/transferable;1");
|
|
||||||
NS_ENSURE_TRUE(trans, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
if (IsPlaintextEditor())
|
|
||||||
{
|
|
||||||
// Add the unicode flavor to the transferable
|
|
||||||
rv = trans->AddDataFlavor(kUnicodeMime);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// QI the data object an |nsISupports| so that when the transferable holds
|
|
||||||
// onto it, it will addref the correct interface.
|
|
||||||
nsCOMPtr<nsISupports> genericDataObj(do_QueryInterface(dataWrapper));
|
|
||||||
rv = trans->SetTransferData(kUnicodeMime, genericDataObj,
|
|
||||||
buffer.Length() * sizeof(PRUnichar));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
contextWrapper = do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
|
|
||||||
NS_ENSURE_TRUE(contextWrapper, NS_ERROR_FAILURE);
|
|
||||||
infoWrapper = do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
|
|
||||||
NS_ENSURE_TRUE(infoWrapper, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
contextWrapper->SetData(parents);
|
|
||||||
infoWrapper->SetData(info);
|
|
||||||
|
|
||||||
rv = trans->AddDataFlavor(kHTMLMime);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFormatConverter> htmlConverter =
|
|
||||||
do_CreateInstance("@mozilla.org/widget/htmlformatconverter;1");
|
|
||||||
NS_ENSURE_TRUE(htmlConverter, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
rv = trans->SetConverter(htmlConverter);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCOMPtr<nsISupports> genericDataObj(do_QueryInterface(dataWrapper));
|
|
||||||
rv = trans->SetTransferData(kHTMLMime, genericDataObj,
|
|
||||||
buffer.Length() * sizeof(PRUnichar));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (!parents.IsEmpty())
|
|
||||||
{
|
|
||||||
// Add the htmlcontext DataFlavor to the transferable
|
|
||||||
trans->AddDataFlavor(kHTMLContext);
|
|
||||||
genericDataObj = do_QueryInterface(contextWrapper);
|
|
||||||
trans->SetTransferData(kHTMLContext, genericDataObj,
|
|
||||||
parents.Length() * sizeof(PRUnichar));
|
|
||||||
}
|
|
||||||
if (!info.IsEmpty())
|
|
||||||
{
|
|
||||||
// Add the htmlinfo DataFlavor to the transferable
|
|
||||||
trans->AddDataFlavor(kHTMLInfo);
|
|
||||||
genericDataObj = do_QueryInterface(infoWrapper);
|
|
||||||
trans->SetTransferData(kHTMLInfo, genericDataObj,
|
|
||||||
info.Length() * sizeof(PRUnichar));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*aTransferable = trans;
|
|
||||||
NS_ADDREF(*aTransferable);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsHTMLEditor::DoDrag(nsIDOMEvent *aDragEvent)
|
|
||||||
{
|
|
||||||
return nsPlaintextEditor::DoDrag(aDragEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nsHTMLEditor::HavePrivateHTMLFlavor(nsIClipboard *aClipboard)
|
bool nsHTMLEditor::HavePrivateHTMLFlavor(nsIClipboard *aClipboard)
|
||||||
{
|
{
|
||||||
// check the clipboard for our special kHTMLContext flavor. If that is there, we know
|
// check the clipboard for our special kHTMLContext flavor. If that is there, we know
|
||||||
|
|
|
@ -576,7 +576,6 @@ protected:
|
||||||
// factored methods for handling insertion of data from transferables (drag&drop or clipboard)
|
// factored methods for handling insertion of data from transferables (drag&drop or clipboard)
|
||||||
NS_IMETHOD PrepareTransferable(nsITransferable **transferable);
|
NS_IMETHOD PrepareTransferable(nsITransferable **transferable);
|
||||||
NS_IMETHOD PrepareHTMLTransferable(nsITransferable **transferable, bool havePrivFlavor);
|
NS_IMETHOD PrepareHTMLTransferable(nsITransferable **transferable, bool havePrivFlavor);
|
||||||
nsresult PutDragDataInTransferable(nsITransferable **aTransferable);
|
|
||||||
NS_IMETHOD InsertFromTransferable(nsITransferable *transferable,
|
NS_IMETHOD InsertFromTransferable(nsITransferable *transferable,
|
||||||
nsIDOMDocument *aSourceDoc,
|
nsIDOMDocument *aSourceDoc,
|
||||||
const nsAString & aContextStr,
|
const nsAString & aContextStr,
|
||||||
|
|
|
@ -307,112 +307,6 @@ NS_IMETHODIMP nsPlaintextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsPlaintextEditor::CanDrag(nsIDOMEvent *aDragEvent, bool *aCanDrag)
|
|
||||||
{
|
|
||||||
NS_ENSURE_TRUE(aCanDrag, NS_ERROR_NULL_POINTER);
|
|
||||||
/* we really should be checking the XY coordinates of the mouseevent and ensure that
|
|
||||||
* that particular point is actually within the selection (not just that there is a selection)
|
|
||||||
*/
|
|
||||||
*aCanDrag = false;
|
|
||||||
|
|
||||||
// KLUDGE to work around bug 50703
|
|
||||||
// After double click and object property editing,
|
|
||||||
// we get a spurious drag event
|
|
||||||
if (mIgnoreSpuriousDragEvent)
|
|
||||||
{
|
|
||||||
mIgnoreSpuriousDragEvent = false;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsISelection> selection;
|
|
||||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
|
||||||
|
|
||||||
bool isCollapsed;
|
|
||||||
res = selection->GetIsCollapsed(&isCollapsed);
|
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
|
||||||
|
|
||||||
// if we are collapsed, we have no selection so nothing to drag
|
|
||||||
if ( isCollapsed )
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMEventTarget> eventTarget;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNSEvent> nsevent(do_QueryInterface(aDragEvent));
|
|
||||||
if (nsevent) {
|
|
||||||
res = nsevent->GetTmpRealOriginalTarget(getter_AddRefs(eventTarget));
|
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eventTarget)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIDOMNode> eventTargetDomNode = do_QueryInterface(eventTarget);
|
|
||||||
if ( eventTargetDomNode )
|
|
||||||
{
|
|
||||||
bool isTargetedCorrectly = false;
|
|
||||||
res = selection->ContainsNode(eventTargetDomNode, false, &isTargetedCorrectly);
|
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
|
||||||
|
|
||||||
*aCanDrag = isTargetedCorrectly;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsPlaintextEditor::DoDrag(nsIDOMEvent *aDragEvent)
|
|
||||||
{
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
nsCOMPtr<nsITransferable> trans;
|
|
||||||
rv = PutDragDataInTransferable(getter_AddRefs(trans));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
NS_ENSURE_TRUE(trans, NS_OK); // maybe there was nothing to copy?
|
|
||||||
|
|
||||||
/* get the drag service */
|
|
||||||
nsCOMPtr<nsIDragService> dragService =
|
|
||||||
do_GetService("@mozilla.org/widget/dragservice;1", &rv);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
/* create an array of transferables */
|
|
||||||
nsCOMPtr<nsISupportsArray> transferableArray;
|
|
||||||
NS_NewISupportsArray(getter_AddRefs(transferableArray));
|
|
||||||
NS_ENSURE_TRUE(transferableArray, NS_ERROR_OUT_OF_MEMORY);
|
|
||||||
|
|
||||||
/* add the transferable to the array */
|
|
||||||
rv = transferableArray->AppendElement(trans);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// check our transferable hooks (if any)
|
|
||||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
|
||||||
GetDocument(getter_AddRefs(domdoc));
|
|
||||||
|
|
||||||
/* invoke drag */
|
|
||||||
nsCOMPtr<nsIDOMEventTarget> eventTarget;
|
|
||||||
rv = aDragEvent->GetTarget(getter_AddRefs(eventTarget));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
nsCOMPtr<nsIDOMNode> domnode = do_QueryInterface(eventTarget);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIScriptableRegion> selRegion;
|
|
||||||
nsCOMPtr<nsISelection> selection;
|
|
||||||
rv = GetSelection(getter_AddRefs(selection));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
unsigned int flags;
|
|
||||||
// in some cases we'll want to cut rather than copy... hmmmmm...
|
|
||||||
flags = nsIDragService::DRAGDROP_ACTION_COPY + nsIDragService::DRAGDROP_ACTION_MOVE;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMDragEvent> dragEvent(do_QueryInterface(aDragEvent));
|
|
||||||
rv = dragService->InvokeDragSessionWithSelection(selection, transferableArray,
|
|
||||||
flags, dragEvent, nsnull);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
aDragEvent->StopPropagation();
|
|
||||||
aDragEvent->PreventDefault();
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsPlaintextEditor::Paste(PRInt32 aSelectionType)
|
NS_IMETHODIMP nsPlaintextEditor::Paste(PRInt32 aSelectionType)
|
||||||
{
|
{
|
||||||
if (!FireClipboardEvent(NS_PASTE))
|
if (!FireClipboardEvent(NS_PASTE))
|
||||||
|
@ -521,102 +415,3 @@ NS_IMETHODIMP nsPlaintextEditor::CanPasteTransferable(nsITransferable *aTransfer
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsPlaintextEditor::SetupDocEncoder(nsIDocumentEncoder **aDocEncoder)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
|
||||||
nsresult rv = GetDocument(getter_AddRefs(domDoc));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// find out if we're a plaintext control or not
|
|
||||||
// get correct mimeType and document encoder flags set
|
|
||||||
nsAutoString mimeType;
|
|
||||||
PRUint32 docEncoderFlags = 0;
|
|
||||||
if (IsPlaintextEditor())
|
|
||||||
{
|
|
||||||
docEncoderFlags |= nsIDocumentEncoder::OutputBodyOnly | nsIDocumentEncoder::OutputPreformatted;
|
|
||||||
mimeType.AssignLiteral(kUnicodeMime);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
mimeType.AssignLiteral(kHTMLMime);
|
|
||||||
|
|
||||||
// set up docEncoder
|
|
||||||
nsCOMPtr<nsIDocumentEncoder> encoder = do_CreateInstance(NS_HTMLCOPY_ENCODER_CONTRACTID);
|
|
||||||
NS_ENSURE_TRUE(encoder, NS_ERROR_OUT_OF_MEMORY);
|
|
||||||
|
|
||||||
rv = encoder->Init(domDoc, mimeType, docEncoderFlags);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
/* get the selection to be dragged */
|
|
||||||
nsCOMPtr<nsISelection> selection;
|
|
||||||
rv = GetSelection(getter_AddRefs(selection));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = encoder->SetSelection(selection);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
*aDocEncoder = encoder;
|
|
||||||
NS_ADDREF(*aDocEncoder);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsPlaintextEditor::PutDragDataInTransferable(nsITransferable **aTransferable)
|
|
||||||
{
|
|
||||||
*aTransferable = nsnull;
|
|
||||||
nsCOMPtr<nsIDocumentEncoder> docEncoder;
|
|
||||||
nsresult rv = SetupDocEncoder(getter_AddRefs(docEncoder));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// grab a string
|
|
||||||
nsAutoString buffer;
|
|
||||||
rv = docEncoder->EncodeToString(buffer);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// if we have an empty string, we're done; otherwise continue
|
|
||||||
if (buffer.IsEmpty())
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
nsCOMPtr<nsISupportsString> dataWrapper =
|
|
||||||
do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = dataWrapper->SetData(buffer);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
/* create html flavor transferable */
|
|
||||||
nsCOMPtr<nsITransferable> trans = do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// find out if we're a plaintext control or not
|
|
||||||
if (IsPlaintextEditor())
|
|
||||||
{
|
|
||||||
// Add the unicode flavor to the transferable
|
|
||||||
rv = trans->AddDataFlavor(kUnicodeMime);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rv = trans->AddDataFlavor(kHTMLMime);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFormatConverter> htmlConverter = do_CreateInstance("@mozilla.org/widget/htmlformatconverter;1");
|
|
||||||
NS_ENSURE_TRUE(htmlConverter, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
rv = trans->SetConverter(htmlConverter);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
// QI the data object an |nsISupports| so that when the transferable holds
|
|
||||||
// onto it, it will addref the correct interface.
|
|
||||||
nsCOMPtr<nsISupports> nsisupportsDataWrapper = do_QueryInterface(dataWrapper);
|
|
||||||
rv = trans->SetTransferData(IsPlaintextEditor() ? kUnicodeMime : kHTMLMime,
|
|
||||||
nsisupportsDataWrapper, buffer.Length() * sizeof(PRUnichar));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
*aTransferable = trans;
|
|
||||||
NS_ADDREF(*aTransferable);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
|
@ -118,8 +118,6 @@ public:
|
||||||
NS_IMETHOD PasteTransferable(nsITransferable *aTransferable);
|
NS_IMETHOD PasteTransferable(nsITransferable *aTransferable);
|
||||||
NS_IMETHOD CanPasteTransferable(nsITransferable *aTransferable, bool *aCanPaste);
|
NS_IMETHOD CanPasteTransferable(nsITransferable *aTransferable, bool *aCanPaste);
|
||||||
|
|
||||||
NS_IMETHOD CanDrag(nsIDOMEvent *aDragEvent, bool *aCanDrag);
|
|
||||||
NS_IMETHOD DoDrag(nsIDOMEvent *aDragEvent);
|
|
||||||
NS_IMETHOD InsertFromDrop(nsIDOMEvent* aDropEvent);
|
NS_IMETHOD InsertFromDrop(nsIDOMEvent* aDropEvent);
|
||||||
|
|
||||||
NS_IMETHOD OutputToString(const nsAString& aFormatType,
|
NS_IMETHOD OutputToString(const nsAString& aFormatType,
|
||||||
|
@ -205,8 +203,6 @@ protected:
|
||||||
nsIDOMNode *aDestinationNode,
|
nsIDOMNode *aDestinationNode,
|
||||||
PRInt32 aDestOffset,
|
PRInt32 aDestOffset,
|
||||||
bool aDoDeleteSelection);
|
bool aDoDeleteSelection);
|
||||||
virtual nsresult SetupDocEncoder(nsIDocumentEncoder **aDocEncoder);
|
|
||||||
virtual nsresult PutDragDataInTransferable(nsITransferable **aTransferable);
|
|
||||||
|
|
||||||
/** shared outputstring; returns whether selection is collapsed and resulting string */
|
/** shared outputstring; returns whether selection is collapsed and resulting string */
|
||||||
nsresult SharedOutputString(PRUint32 aFlags, bool* aIsCollapsed, nsAString& aResult);
|
nsresult SharedOutputString(PRUint32 aFlags, bool* aIsCollapsed, nsAString& aResult);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче