Make it possible to drag a non-selectable node again. b=574596 r=dbaron

This commit is contained in:
Mats Palmgren 2010-07-12 22:24:25 +02:00
parent 6989f1220a
commit 03d190d02f
5 changed files with 144 additions and 35 deletions

View File

@ -39,6 +39,7 @@
#define nsCopySupport_h__
#include "nscore.h"
#include "nsINode.h"
class nsISelection;
class nsIDocument;
@ -47,7 +48,6 @@ class nsIContent;
class nsITransferable;
class nsACString;
class nsAString;
class nsIDOMNode;
class nsIPresShell;
class nsCopySupport
@ -69,10 +69,14 @@ class nsCopySupport
// 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);
static nsresult GetTransferableForSelection(nsISelection* aSelection,
nsIDocument* aDocument,
nsITransferable** aTransferable);
// Same as GetTransferableForSelection, but doesn't skip invisible content.
static nsresult GetTransferableForNode(nsINode* aNode,
nsIDocument* aDoc,
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

View File

@ -79,7 +79,6 @@
#include "nsIScriptSecurityManager.h"
#include "nsIPrincipal.h"
#include "nsIDocShellTreeItem.h"
#include "nsRange.h"
#include "nsIWebBrowserPersist.h"
#include "nsEscape.h"
#include "nsContentUtils.h"
@ -92,9 +91,7 @@
#define kHTMLContext "text/_moz_htmlcontext"
#define kHTMLInfo "text/_moz_htmlinfo"
nsresult NS_NewDomSelection(nsISelection **aDomSelection);
// if inNode is null, use the selection from the window
// if aNode is null, use the selection from the window
static nsresult
GetTransferableForNodeOrSelection(nsIDOMWindow* aWindow,
nsIContent* aNode,
@ -108,25 +105,15 @@ GetTransferableForNodeOrSelection(nsIDOMWindow* aWindow,
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
nsresult rv;
nsCOMPtr<nsISelection> selection;
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aNode);
if (node) {
// Make a temporary selection with this node in a single range.
rv = NS_NewDomSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMRange> range;
rv = NS_NewRange(getter_AddRefs(range));
NS_ENSURE_SUCCESS(rv, rv);
rv = range->SelectNode(node);
NS_ENSURE_SUCCESS(rv, rv);
rv = selection->AddRange(range);
NS_ENSURE_SUCCESS(rv, rv);
if (aNode) {
rv = nsCopySupport::GetTransferableForNode(aNode, doc, aTransferable);
} else {
nsCOMPtr<nsISelection> selection;
aWindow->GetSelection(getter_AddRefs(selection));
rv = nsCopySupport::GetTransferableForSelection(selection, doc,
aTransferable);
}
rv = nsCopySupport::GetTransferableForSelection(selection, doc,
aTransferable);
NS_ENSURE_SUCCESS(rv, rv);
return rv;
}
@ -424,7 +411,6 @@ DragDataProducer::GetNodeString(nsIContent* inNode,
}
}
nsresult
DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
PRBool* aCanDrag,

View File

@ -50,6 +50,7 @@
#include "nsXPCOM.h"
#include "nsISupportsPrimitives.h"
#include "nsIDOMRange.h"
#include "nsRange.h"
#include "imgIContainer.h"
#include "nsIPresShell.h"
#include "nsFocusManager.h"
@ -78,6 +79,8 @@
#include "nsContentUtils.h"
#include "nsContentCID.h"
nsresult NS_NewDomSelection(nsISelection **aDomSelection);
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID);
static NS_DEFINE_CID(kHTMLConverterCID, NS_HTMLFORMATCONVERTER_CID);
@ -100,7 +103,7 @@ static nsresult AppendDOMNode(nsITransferable *aTransferable,
static nsresult
SelectionCopyHelper(nsISelection *aSel, nsIDocument *aDoc,
PRBool doPutOnClipboard, PRInt16 aClipboardID,
nsITransferable ** aTransferable)
PRUint32 aFlags, nsITransferable ** aTransferable)
{
// Clear the output parameter for the transferable, if provided.
if (aTransferable) {
@ -135,9 +138,8 @@ SelectionCopyHelper(nsISelection *aSel, nsIDocument *aDoc,
// we want preformatted for the case where the selection is inside input/textarea
// and we don't want pretty printing for others cases, to not have additionnal
// line breaks which are then converted into spaces by the htmlConverter (see bug #524975)
PRUint32 flags = nsIDocumentEncoder::OutputPreformatted
| nsIDocumentEncoder::OutputRaw
| nsIDocumentEncoder::SkipInvisibleContent;
PRUint32 flags = aFlags | nsIDocumentEncoder::OutputPreformatted
| nsIDocumentEncoder::OutputRaw;
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aDoc);
NS_ASSERTION(domDoc, "Need a document");
@ -178,7 +180,7 @@ SelectionCopyHelper(nsISelection *aSel, nsIDocument *aDoc,
mimeType.AssignLiteral(kHTMLMime);
flags = nsIDocumentEncoder::SkipInvisibleContent;
flags = aFlags;
rv = docEncoder->Init(domDoc, mimeType, flags);
NS_ENSURE_SUCCESS(rv, rv);
@ -279,17 +281,47 @@ SelectionCopyHelper(nsISelection *aSel, nsIDocument *aDoc,
return rv;
}
nsresult nsCopySupport::HTMLCopy(nsISelection *aSel, nsIDocument *aDoc, PRInt16 aClipboardID)
nsresult
nsCopySupport::HTMLCopy(nsISelection* aSel, nsIDocument* aDoc,
PRInt16 aClipboardID)
{
return SelectionCopyHelper(aSel, aDoc, PR_TRUE, aClipboardID, nsnull);
return SelectionCopyHelper(aSel, aDoc, PR_TRUE, aClipboardID,
nsIDocumentEncoder::SkipInvisibleContent,
nsnull);
}
nsresult
nsCopySupport::GetTransferableForSelection(nsISelection * aSel,
nsIDocument * aDoc,
nsITransferable ** aTransferable)
nsCopySupport::GetTransferableForSelection(nsISelection* aSel,
nsIDocument* aDoc,
nsITransferable** aTransferable)
{
return SelectionCopyHelper(aSel, aDoc, PR_FALSE, 0, aTransferable);
return SelectionCopyHelper(aSel, aDoc, PR_FALSE, 0,
nsIDocumentEncoder::SkipInvisibleContent,
aTransferable);
}
nsresult
nsCopySupport::GetTransferableForNode(nsINode* aNode,
nsIDocument* aDoc,
nsITransferable** aTransferable)
{
nsCOMPtr<nsISelection> selection;
// Make a temporary selection with aNode in a single range.
nsresult rv = NS_NewDomSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMRange> range;
rv = NS_NewRange(getter_AddRefs(range));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aNode);
NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
rv = range->SelectNode(node);
NS_ENSURE_SUCCESS(rv, rv);
rv = selection->AddRange(range);
NS_ENSURE_SUCCESS(rv, rv);
// It's not the primary selection - so don't skip invisible content.
PRUint32 flags = 0;
return SelectionCopyHelper(selection, aDoc, PR_FALSE, 0, flags,
aTransferable);
}
nsresult nsCopySupport::DoHooks(nsIDocument *aDoc, nsITransferable *aTrans,

View File

@ -402,6 +402,7 @@ _TEST_FILES2 = \
test_websocket.html \
file_websocket_wsh.py \
file_websocket_http_resource.txt \
test_bug574596.html \
$(NULL)
# This test fails on the Mac for some reason

View File

@ -0,0 +1,86 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=574596
-->
<head>
<title>Test for Bug 574596</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/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>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=574596">Mozilla Bug 574596</a>
<style type="text/css">
#link1 a { -moz-user-select:none; }
</style>
<div id="link1"><a href="http://www.mozilla.org/">link1</a></div>
<div id="link2"><a href="http://www.mozilla.org/">link2</a></div>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 574596 **/
function ignoreFunc(actualData, expectedData) {
return true;
}
var dragLinkText = [[
{ type:"text/x-moz-url", data:"", eqTest:ignoreFunc },
{ type:"text/x-moz-url-data", data:"http://www.mozilla.org/" },
{ type:"text/x-moz-url-desc", data:"link1" },
{ type:"text/uri-list", data:"http://www.mozilla.org/" },
{ type:"text/_moz_htmlcontext", data:"", eqTest:ignoreFunc },
{ type:"text/_moz_htmlinfo", data:"", eqTest:ignoreFunc },
{ type:"text/html", data:'<div id="link1"><a href="http://www.mozilla.org/">link1</a></div>' },
{ type:"text/plain", data:"http://www.mozilla.org/" }
]];
function dumpTransfer(dataTransfer,expect) {
dtData = dataTransfer.mozItemCount + "items:\n";
for (var i = 0; i < dataTransfer.mozItemCount; i++) {
var dtTypes = dataTransfer.mozTypesAt(i);
for (var j = 0; j < dtTypes.length; j++) {
var actualData = dataTransfer.mozGetDataAt(dtTypes[j],i)
if (expect && expect[i] && expect[i][j]) {
if (expect[i][j].eqTest)
dtData += expect[i][j].eqTest(actualData,expect[i][j].data) ? "ok" : "fail";
else
dtData += (actualData == expect[i][j].data) ? "ok" : "fail";
}
dtData += "["+i+"]" + "["+j+"]: " + '"' + dtTypes[j] + '" "' + actualData + '"\n';
}
}
alert(dtData);
}
function runTest() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var result = synthesizeDragStart($('link1'), dragLinkText, window);
is(result, null, "Drag -moz-user-select:none link (#link1)");
// if (result) dumpTransfer(result,dragLinkText);
dragLinkText[0][2].data = "link2";
dragLinkText[0][6].data = '<div id="link2"><a href="http://www.mozilla.org/">link2</a></div>'
var result = synthesizeDragStart($('link2'), dragLinkText, window);
is(result, null, "Drag link (#link2)");
// if (result) dumpTransfer(result,dragLinkText);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(runTest);
</script>
</pre>
</body>
</html>