Bug 39098 - Elements with visibility:hidden, visibility:collapse, or display:none get copied to the clipboard. r=dbaron

This commit is contained in:
Mats Palmgren 2010-05-25 01:24:15 +02:00
Родитель c345de3323
Коммит fe08c8398a
6 изменённых файлов: 310 добавлений и 177 удалений

Просмотреть файл

@ -61,7 +61,7 @@ interface nsIDocumentEncoderNodeFixup : nsISupports
nsIDOMNode fixupNode(in nsIDOMNode aNode, out boolean aSerializeCloneKids);
};
[scriptable, uuid(f85c5a20-258d-11db-a98b-0800200c9a66)]
[scriptable, uuid(196a3aee-006e-4f8f-a420-e1c1b0958a26)]
interface nsIDocumentEncoder : nsISupports
{
// Output methods flag bits. There are a frightening number of these,
@ -215,6 +215,13 @@ interface nsIDocumentEncoder : nsISupports
*/
const unsigned long OutputDontRewriteEncodingDeclaration = (1 << 18);
/**
* When using the HTML or XHTML serializer, skip elements that are not
* visible when this flag is set. Elements are not visible when they
* have CSS style display:none or visibility:collapse, for example.
*/
const unsigned long SkipInvisibleContent = (1 << 19);
/**
* Initialize with a pointer to the document and the mime type.
* @param aDocument Document to encode.

Просмотреть файл

@ -45,7 +45,7 @@
#include "nsString.h"
// Interfaces needed to be included
#include "nsIVariant.h"
#include "nsCopySupport.h"
#include "nsIDOMNSUIEvent.h"
#include "nsIDOMUIEvent.h"
#include "nsISelection.h"
@ -59,9 +59,7 @@
#include "nsIDOMDocument.h"
#include "nsIDOMDocumentRange.h"
#include "nsIDOMRange.h"
#include "nsIDocumentEncoder.h"
#include "nsIFormControl.h"
#include "nsISelectionPrivate.h"
#include "nsIDOMHTMLAreaElement.h"
#include "nsIDOMHTMLAnchorElement.h"
#include "nsITransferable.h"
@ -75,14 +73,12 @@
#include "nsIDocShell.h"
#include "nsIContent.h"
#include "nsIImageLoadingContent.h"
#include "nsINameSpaceManager.h"
#include "nsUnicharUtils.h"
#include "nsIURL.h"
#include "nsIDocument.h"
#include "nsIScriptSecurityManager.h"
#include "nsIPrincipal.h"
#include "nsIDocShellTreeItem.h"
#include "nsIFrame.h"
#include "nsRange.h"
#include "nsIWebBrowserPersist.h"
#include "nsEscape.h"
@ -90,18 +86,50 @@
#include "nsIMIMEService.h"
#include "imgIContainer.h"
#include "imgIRequest.h"
#include "nsContentCID.h"
#include "nsDOMDataTransfer.h"
#include "nsISelectionController.h"
#include "nsFrameSelection.h"
#include "nsWidgetsCID.h"
static NS_DEFINE_CID(kHTMLConverterCID, NS_HTMLFORMATCONVERTER_CID);
// private clipboard data flavors for html copy, used by editor when pasting
#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
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;
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);
} else {
aWindow->GetSelection(getter_AddRefs(selection));
}
rv = nsCopySupport::GetTransferableForSelection(selection, doc,
aTransferable);
NS_ENSURE_SUCCESS(rv, rv);
return rv;
}
class NS_STACK_CLASS DragDataProducer
{
@ -134,13 +162,6 @@ private:
static void GetSelectedLink(nsISelection* inSelection,
nsIContent **outLinkNode);
// if inNode is null, use the selection from the window
static nsresult SerializeNodeOrSelection(nsIDOMWindow* inWindow,
nsIContent* inNode,
nsAString& outResultString,
nsAString& outHTMLContext,
nsAString& outHTMLInfo);
nsCOMPtr<nsIDOMWindow> mWindow;
nsCOMPtr<nsIContent> mTarget;
nsCOMPtr<nsIContent> mSelectionTargetNode;
@ -417,6 +438,7 @@ DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
*aDragNode = nsnull;
nsresult rv;
nsIContent* dragNode = nsnull;
// find the selection to see what we could be dragging and if
@ -663,24 +685,31 @@ DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
nodeToSerialize = nsnull;
}
SerializeNodeOrSelection(mWindow, nodeToSerialize,
mHtmlString, mContextString, mInfoString);
nsCOMPtr<nsIFormatConverter> htmlConverter =
do_CreateInstance(kHTMLConverterCID);
NS_ENSURE_TRUE(htmlConverter, NS_ERROR_FAILURE);
nsCOMPtr<nsISupportsString> html =
do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
NS_ENSURE_TRUE(html, NS_ERROR_FAILURE);
html->SetData(mHtmlString);
nsCOMPtr<nsISupportsString> text;
PRUint32 textLen;
htmlConverter->Convert(kHTMLMime, html, mHtmlString.Length() * 2,
kUnicodeMime, getter_AddRefs(text), &textLen);
NS_ENSURE_TRUE(text, NS_ERROR_FAILURE);
text->GetData(mTitleString);
mHtmlString.Truncate();
mContextString.Truncate();
mInfoString.Truncate();
mTitleString.Truncate();
nsCOMPtr<nsITransferable> transferable;
rv = ::GetTransferableForNodeOrSelection(mWindow, nodeToSerialize,
getter_AddRefs(transferable));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupportsString> data;
PRUint32 dataSize;
rv = transferable->GetTransferData(kHTMLMime, getter_AddRefs(data), &dataSize);
if (NS_SUCCEEDED(rv)) {
data->GetData(mHtmlString);
}
rv = transferable->GetTransferData(kHTMLContext, getter_AddRefs(data), &dataSize);
if (NS_SUCCEEDED(rv)) {
data->GetData(mContextString);
}
rv = transferable->GetTransferData(kHTMLInfo, getter_AddRefs(data), &dataSize);
if (NS_SUCCEEDED(rv)) {
data->GetData(mInfoString);
}
rv = transferable->GetTransferData(kUnicodeMime, getter_AddRefs(data), &dataSize);
NS_ENSURE_SUCCESS(rv, rv); // require plain text at a minimum
data->GetData(mTitleString);
}
// default text value is the URL
@ -694,8 +723,8 @@ DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
// if there is no drag node, which will be the case for a selection, just
// use the selection target node.
nsresult rv = AddStringsToDataTransfer(
dragNode ? dragNode : mSelectionTargetNode.get(), aDataTransfer);
rv = AddStringsToDataTransfer(
dragNode ? dragNode : mSelectionTargetNode.get(), aDataTransfer);
NS_ENSURE_SUCCESS(rv, rv);
NS_IF_ADDREF(*aDragNode = dragNode);
@ -982,52 +1011,3 @@ DragDataProducer::GetSelectedLink(nsISelection* inSelection,
return;
}
// static
nsresult
DragDataProducer::SerializeNodeOrSelection(nsIDOMWindow* inWindow,
nsIContent* inNode,
nsAString& outResultString,
nsAString& outContext,
nsAString& outInfo)
{
NS_ENSURE_ARG_POINTER(inWindow);
nsresult rv;
nsCOMPtr<nsIDocumentEncoder> encoder =
do_CreateInstance(NS_HTMLCOPY_ENCODER_CONTRACTID);
NS_ENSURE_TRUE(encoder, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMDocument> domDoc;
inWindow->GetDocument(getter_AddRefs(domDoc));
NS_ENSURE_TRUE(domDoc, NS_ERROR_FAILURE);
PRUint32 flags = nsIDocumentEncoder::OutputAbsoluteLinks |
nsIDocumentEncoder::OutputEncodeHTMLEntities |
nsIDocumentEncoder::OutputRaw;
nsCOMPtr<nsIDOMRange> range;
nsCOMPtr<nsISelection> selection;
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(inNode);
if (node) {
// make a range around this node
rv = NS_NewRange(getter_AddRefs(range));
NS_ENSURE_SUCCESS(rv, rv);
rv = range->SelectNode(node);
NS_ENSURE_SUCCESS(rv, rv);
} else {
inWindow->GetSelection(getter_AddRefs(selection));
flags |= nsIDocumentEncoder::OutputSelectionOnly;
}
rv = encoder->Init(domDoc, NS_LITERAL_STRING(kHTMLMime), flags);
NS_ENSURE_SUCCESS(rv, rv);
if (range) {
encoder->SetRange(range);
} else if (selection) {
encoder->SetSelection(selection);
}
return encoder->EncodeToStringWithContext(outContext, outInfo,
outResultString);
}

Просмотреть файл

@ -22,6 +22,7 @@
* Contributor(s):
* Kathleen Brade <brade@netscape.com>
* David Gardiner <david.gardiner@unisa.edu.au>
* Mats Palmgren <matpal@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -134,7 +135,9 @@ 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;
PRUint32 flags = nsIDocumentEncoder::OutputPreformatted
| nsIDocumentEncoder::OutputRaw
| nsIDocumentEncoder::SkipInvisibleContent;
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aDoc);
NS_ASSERTION(domDoc, "Need a document");
@ -175,7 +178,7 @@ SelectionCopyHelper(nsISelection *aSel, nsIDocument *aDoc,
mimeType.AssignLiteral(kHTMLMime);
flags = 0;
flags = nsIDocumentEncoder::SkipInvisibleContent;
rv = docEncoder->Init(domDoc, mimeType, flags);
NS_ENSURE_SUCCESS(rv, rv);
@ -420,7 +423,7 @@ nsCopySupport::GetContents(const nsACString& aMimeType, PRUint32 aFlags, nsISele
docEncoder = do_CreateInstance(encoderContractID.get());
NS_ENSURE_TRUE(docEncoder, NS_ERROR_FAILURE);
PRUint32 flags = aFlags;
PRUint32 flags = aFlags | nsIDocumentEncoder::SkipInvisibleContent;
if (aMimeType.Equals("text/plain"))
flags |= nsIDocumentEncoder::OutputPreformatted;

Просмотреть файл

@ -21,6 +21,7 @@
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
* Mats Palmgren <matpal@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -50,7 +51,6 @@
#include "nsIServiceManager.h"
#include "nsIDocument.h"
#include "nsIHTMLDocument.h"
#include "nsISelection.h"
#include "nsCOMPtr.h"
#include "nsIContentSerializer.h"
#include "nsIUnicodeEncoder.h"
@ -69,11 +69,13 @@
#include "nsGkAtoms.h"
#include "nsIContent.h"
#include "nsIEnumerator.h"
#include "nsISelectionPrivate.h"
#include "nsIParserService.h"
#include "nsIScriptContext.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptSecurityManager.h"
#include "nsISelection.h"
#include "nsISelectionPrivate.h"
#include "nsITransferable.h" // for kUnicodeMime
#include "nsContentUtils.h"
#include "nsUnicharUtils.h"
#include "nsReadableUtils.h"
@ -119,6 +121,29 @@ protected:
nsresult FlushText(nsAString& aString, PRBool aForce);
PRBool IsVisibleNode(nsINode* aNode)
{
NS_PRECONDITION(aNode, "");
if (mFlags & SkipInvisibleContent) {
nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
if (content) {
nsIFrame* frame = content->GetPrimaryFrame();
if (!frame) {
if (aNode->IsNodeOfType(nsINode::eTEXT)) {
// We have already checked that our parent is visible.
return PR_TRUE;
}
return PR_FALSE;
}
PRBool isVisible = frame->GetStyleVisibility()->IsVisible();
if (!isVisible && aNode->IsNodeOfType(nsINode::eTEXT))
return PR_FALSE;
}
}
return PR_TRUE;
}
static PRBool IsTag(nsIContent* aContent, nsIAtom* aAtom);
virtual PRBool IncludeInContext(nsINode *aNode);
@ -269,8 +294,9 @@ nsDocumentEncoder::SerializeNodeStart(nsINode* aNode,
nsAString& aStr,
nsINode* aOriginalNode)
{
PRUint16 type;
if (!IsVisibleNode(aNode))
return NS_OK;
nsINode* node = nsnull;
nsCOMPtr<nsINode> fixedNodeKungfuDeathGrip;
@ -292,6 +318,7 @@ nsDocumentEncoder::SerializeNodeStart(nsINode* aNode,
if (!node)
node = aNode;
PRUint16 type;
node->GetNodeType(&type);
switch (type) {
case nsIDOMNode::ELEMENT_NODE:
@ -341,6 +368,9 @@ nsresult
nsDocumentEncoder::SerializeNodeEnd(nsINode* aNode,
nsAString& aStr)
{
if (!IsVisibleNode(aNode))
return NS_OK;
if (aNode->IsElement()) {
mSerializer->AppendElementEnd(static_cast<nsIContent*>(aNode), aStr);
}
@ -352,6 +382,9 @@ nsDocumentEncoder::SerializeToStringRecursive(nsINode* aNode,
nsAString& aStr,
PRBool aDontSerializeRoot)
{
if (!IsVisibleNode(aNode))
return NS_OK;
nsresult rv = NS_OK;
PRBool serializeClonedChildren = PR_FALSE;
nsINode* maybeFixedNode = nsnull;
@ -656,19 +689,24 @@ nsDocumentEncoder::SerializeRangeNodes(nsIRange* aRange,
nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
nsresult rv=NS_OK;
if (!IsVisibleNode(aNode))
return NS_OK;
nsresult rv = NS_OK;
// get start and end nodes for this recursion level
nsCOMPtr<nsIContent> startNode, endNode;
PRInt32 start = mStartRootIndex - aDepth;
if (start >= 0 && (PRUint32)start <= mStartNodes.Length())
startNode = mStartNodes[start];
{
PRInt32 start = mStartRootIndex - aDepth;
if (start >= 0 && (PRUint32)start <= mStartNodes.Length())
startNode = mStartNodes[start];
PRInt32 end = mEndRootIndex - aDepth;
if (end >= 0 && (PRUint32)end <= mEndNodes.Length())
endNode = mEndNodes[end];
PRInt32 end = mEndRootIndex - aDepth;
if (end >= 0 && (PRUint32)end <= mEndNodes.Length())
endNode = mEndNodes[end];
}
if ((startNode != content) && (endNode != content))
if (startNode != content && endNode != content)
{
// node is completely contained in range. Serialize the whole subtree
// rooted by this node.
@ -858,6 +896,16 @@ nsDocumentEncoder::SerializeRangeToString(nsIRange *aRange,
if ((startParent == endParent) && IsTextNode(startParent))
{
if (mFlags & SkipInvisibleContent) {
// Check that the parent is visible if we don't a frame.
// IsVisibleNode() will do it when there's a frame.
nsCOMPtr<nsIContent> content = do_QueryInterface(startParent);
if (content && !content->GetPrimaryFrame()) {
nsIContent* parent = content->GetParent();
if (!parent || !IsVisibleNode(parent))
return NS_OK;
}
}
rv = SerializeNodeStart(startParent, startOffset, endOffset, aOutputString);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -1080,7 +1128,7 @@ nsHTMLCopyEncoder::~nsHTMLCopyEncoder()
NS_IMETHODIMP
nsHTMLCopyEncoder::Init(nsIDOMDocument* aDocument,
const nsAString& aMimetype,
const nsAString& aMimeType,
PRUint32 aFlags)
{
if (!aDocument)
@ -1094,7 +1142,7 @@ nsHTMLCopyEncoder::Init(nsIDOMDocument* aDocument,
NS_ENSURE_TRUE(mDocument, NS_ERROR_FAILURE);
mMimeType.AssignLiteral("text/html");
// Make all links absolute when copying
// (see related bugs #57296, #41924, #58646, #32768)
mFlags = aFlags | OutputAbsoluteLinks;

Просмотреть файл

@ -30,89 +30,155 @@ function testCopyPaste () {
var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"]
.getService(Components.interfaces.nsIClipboard);
var transferable, node;
var data = {};
var textarea = document.getElementById('input');
// ============ copy paste test from a simple text content to a textarea
function copySelectionToClipboard() {
documentViewer.copySelection();
is(clipboard.hasDataMatchingFlavors(["text/unicode"], 1,1), true);
is(clipboard.hasDataMatchingFlavors(["text/html"], 1,1), true);
}
function copyToClipboard(node) {
textarea.blur();
clipboard.emptyClipboard(1);
var sel = window.getSelection();
sel.removeAllRanges();
var r = document.createRange();
r.selectNode(node);
window.getSelection().addRange(r);
copySelectionToClipboard();
}
function copyRangeToClipboard(startNode,startIndex,endNode,endIndex) {
textarea.blur();
clipboard.emptyClipboard(1);
var sel = window.getSelection();
sel.removeAllRanges();
var r = document.createRange();
r.setStart(startNode,startIndex)
r.setEnd(endNode,endIndex)
window.getSelection().addRange(r);
copySelectionToClipboard();
}
function copyChildrenToClipboard(id) {
textarea.blur();
clipboard.emptyClipboard(1);
window.getSelection().selectAllChildren(document.getElementById(id));
copySelectionToClipboard();
}
function getClipboardData(mime) {
var transferable = Components.classes['@mozilla.org/widget/transferable;1']
.createInstance(Components.interfaces.nsITransferable);
transferable.addDataFlavor(mime);
clipboard.getData(transferable, 1);
var data = {};
transferable.getTransferData(mime, data, {}) ;
return data;
}
function testClipboardValue(mime, expected) {
var data = getClipboardData(mime);
is (data.value == null ? data.value :
data.value.QueryInterface(Components.interfaces.nsISupportsString).data,
expected,
mime + " value in the clipboard");
return data.value;
}
function testPasteText(expected) {
textarea.value="";
textarea.focus();
textarea.QueryInterface(Components.interfaces.nsIDOMNSEditableElement)
.editor.paste(1);
is(textarea.value, expected, "value of the textarea after the paste");
}
function testSelectionToString(expected) {
is(window.getSelection().toString().replace(/\r\n/g,"\n"), expected, "Selection.toString");
}
function testInnerHTML(id, expected) {
var value = document.getElementById(id).innerHTML;
is(value, expected, id + ".innerHTML");
}
function testEmptyChildren(id) {
copyChildrenToClipboard(id);
testSelectionToString("");
testClipboardValue("text/unicode", null);
testClipboardValue("text/html", null);
testPasteText("");
}
// selection of the node
node = document.getElementById('draggable');
window.getSelection().selectAllChildren(node);
copyChildrenToClipboard("draggable");
testSelectionToString("This is a draggable bit of text.");
testClipboardValue("text/unicode",
"This is a draggable bit of text.");
testClipboardValue("text/html",
"<div id=\"draggable\" title=\"title to have a long HTML line\">This is a <em>draggable</em> bit of text.</div>");
testPasteText("This is a draggable bit of text.");
// let's copy the selection
documentViewer.copySelection();
copyChildrenToClipboard("alist");
testSelectionToString("bla\n\n * foo\n * bar\n\n");
testClipboardValue("text/unicode", " bla\n\n * foo\n * bar\n\n");
testClipboardValue("text/html", "<div id=\"alist\">\n bla\n <ul>\n <li>foo</li>\n \n <li>bar</li>\n </ul>\n </div>");
testPasteText(" bla\n\n * foo\n * bar\n\n");
is(clipboard.hasDataMatchingFlavors(["text/unicode"], 1,1), true);
is(clipboard.hasDataMatchingFlavors(["text/html"], 1,1), true);
copyChildrenToClipboard("div4");
testSelectionToString("Tt t t ");
testClipboardValue("text/unicode", " Tt t t ");
testClipboardValue("text/html", "<div id=\"div4\">\n T<textarea>t t t</textarea>\n</div>");
testInnerHTML("div4", "\n T<textarea>t t t</textarea>\n");
testPasteText(" Tt t t ");
// is the clipboard contain a text/unicode data ?
transferable = Components.classes['@mozilla.org/widget/transferable;1']
.createInstance(Components.interfaces.nsITransferable);
transferable.addDataFlavor("text/unicode");
clipboard.getData(transferable, 1);
copyChildrenToClipboard("div5");
testSelectionToString("T ");
testClipboardValue("text/unicode", " T ");
testClipboardValue("text/html", "<div id=\"div5\">\n T<textarea> </textarea>\n</div>");
testInnerHTML("div5", "\n T<textarea> </textarea>\n");
testPasteText(" T ");
transferable.getTransferData ("text/unicode", data, {} ) ;
is (data.value.QueryInterface(Components.interfaces.nsISupportsString).data,
"This is a draggable bit of text.",
"text/unicode value in the clipboard");
// is the clipboard contain a text/html data ?
transferable = Components.classes['@mozilla.org/widget/transferable;1']
.createInstance(Components.interfaces.nsITransferable);
transferable.addDataFlavor("text/html");
clipboard.getData(transferable, 1);
copyRangeToClipboard($("div6").childNodes[0],0, $("div6").childNodes[1],1);
testSelectionToString("");
// START Disabled due to bug 564688
if (false) {
testClipboardValue("text/unicode", "");
testClipboardValue("text/html", "");
}
// END Disabled due to bug 564688
testInnerHTML("div6", "div6");
transferable.getTransferData ("text/html", data, {} ) ;
is (data.value.QueryInterface(Components.interfaces.nsISupportsString).data,
"<div id=\"draggable\" title=\"title to have a long HTML line\">This is a <em>draggable</em> bit of text.</div>",
"text/html value in the clipboard");
// let's paste now in the textarea and verify its content
textarea.focus();
textarea.QueryInterface(Components.interfaces.nsIDOMNSEditableElement)
.editor.paste(1);
is(textarea.value, "This is a draggable bit of text.", "value of the textarea after the paste");
copyRangeToClipboard($("div7").childNodes[0],0, $("div7").childNodes[0],4);
testSelectionToString("");
// START Disabled due to bug 564688
if (false) {
testClipboardValue("text/unicode", "");
testClipboardValue("text/html", "");
}
// END Disabled due to bug 564688
testInnerHTML("div7", "div7");
copyRangeToClipboard($("div8").childNodes[0],0, $("div8").childNodes[0],4);
testSelectionToString("");
// START Disabled due to bug 564688
if (false) {
testClipboardValue("text/unicode", "");
testClipboardValue("text/html", "");
}
// END Disabled due to bug 564688
testInnerHTML("div8", "div8");
// ============ copy paste test from a piece of HTML to a textarea
textarea.blur();
node = document.getElementById('alist');
window.getSelection().selectAllChildren(node);
documentViewer.copySelection();
copyRangeToClipboard($("div9").childNodes[0],0, $("div9").childNodes[0],4);
testSelectionToString("div9");
testClipboardValue("text/unicode", "div9");
testClipboardValue("text/html", "div9");
testInnerHTML("div9", "div9");
is(clipboard.hasDataMatchingFlavors(["text/unicode"], 1,1), true);
is(clipboard.hasDataMatchingFlavors(["text/html"], 1,1), true);
copyToClipboard($("div10"));
testSelectionToString("");
testInnerHTML("div10", "div10");
// let's verify the clipboard content for the text/unicode flavor
transferable = Components.classes['@mozilla.org/widget/transferable;1']
.createInstance(Components.interfaces.nsITransferable);
transferable.addDataFlavor("text/unicode");
clipboard.getData(transferable, 1);
data = {};
transferable.getTransferData ("text/unicode", data, {} ) ;
is (data.value.QueryInterface(Components.interfaces.nsISupportsString).data,
" bla\n\n * foo\n * bar\n\n",
"text/unicode value in the clipboard (html piece)");
copyToClipboard($("div10").firstChild);
testSelectionToString("");
// let's verify the clipboard content for the text/html flavor
transferable = Components.classes['@mozilla.org/widget/transferable;1']
.createInstance(Components.interfaces.nsITransferable);
transferable.addDataFlavor("text/html");
clipboard.getData(transferable, 1);
data = {};
transferable.getTransferData ("text/html", data, {} ) ;
is (data.value.QueryInterface(Components.interfaces.nsISupportsString).data,
"<div id=\"alist\">\n bla\n <ul>\n <li>foo</li>\n <li>bar</li>\n </ul>\n </div>",
"text/html value in the clipboard (html piece)");
// let's paste now in the textarea and verify its content
textarea.value="";
textarea.focus();
textarea.QueryInterface(Components.interfaces.nsIDOMNSEditableElement)
.editor.paste(1);
is(textarea.value, " bla\n\n * foo\n * bar\n\n", "value of the textarea after the paste (html piece)");
copyRangeToClipboard($("div10").childNodes[0],0, $("div10").childNodes[0],1);
testSelectionToString("");
copyRangeToClipboard($("div10").childNodes[1],0, $("div10").childNodes[1],1);
testSelectionToString("");
// ============ copy/paste test from/to a textarea
@ -145,10 +211,37 @@ addLoadEvent(testCopyPaste);
bla
<ul>
<li>foo</li>
<li style="display: none;">baz</li>
<li>bar</li>
</ul>
</div>
<div id="div4">
T<textarea>t t t</textarea>
</div>
<div id="div5">
T<textarea> </textarea>
</div>
<div id="div6" style="display:none"></div>
<script>
var x = $("div6")
x.appendChild(document.createTextNode('di'))
x.appendChild(document.createTextNode('v6'))
</script>
<div id="div7" style="display:none">div7</div>
<div id="div8" style="visibility:hidden">div8</div>
<div style="visibility:hidden"><div id="div9" style="visibility:visible">div9</div></div>
<div style="visibility:hidden"><div><div><div id="div10"></div></div></div></div>
<script>
var x = $("div10")
x.appendChild(document.createTextNode('div'))
x.appendChild(document.createTextNode('10'))
</script>
</div>
</body>
</html>

Просмотреть файл

@ -1301,7 +1301,9 @@ nsFrameSelection::MoveCaret(PRUint32 aKeycode,
NS_IMETHODIMP
nsTypedSelection::ToString(PRUnichar **aReturn)
{
return ToStringWithFormat("text/plain", 0, 0, aReturn);
return ToStringWithFormat("text/plain",
nsIDocumentEncoder::SkipInvisibleContent,
0, aReturn);
}