mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 551704 - Part 3: Don't copy invisible BR nodes to the clipboard for editable elements, to make us more compatible with WebKit and Opera; r=bzbarsky a=blocking-betaN+
This commit is contained in:
parent
472326895e
commit
844dd2ffc0
@ -68,6 +68,10 @@
|
||||
#include "nsLWBrkCIID.h"
|
||||
#include "nsIScriptElement.h"
|
||||
#include "nsAttrName.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIEditorDocShell.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsIHTMLEditor.h"
|
||||
|
||||
static const PRInt32 kLongLineLen = 128;
|
||||
|
||||
@ -81,6 +85,40 @@ nsresult NS_NewHTMLContentSerializer(nsIContentSerializer** aSerializer)
|
||||
return CallQueryInterface(it, aSerializer);
|
||||
}
|
||||
|
||||
static
|
||||
PRBool
|
||||
IsInvisibleBreak(nsIContent *aNode, nsIAtom *aTag) {
|
||||
// xxxehsan: we should probably figure out a way to determine
|
||||
// if a BR node is visible without using the editor.
|
||||
if (aTag != nsGkAtoms::br || !aNode->IsEditable()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Grab the editor associated with the document
|
||||
nsIDocument *doc = aNode->GetCurrentDoc();
|
||||
if (doc) {
|
||||
nsPIDOMWindow *window = doc->GetWindow();
|
||||
if (window) {
|
||||
nsIDocShell *docShell = window->GetDocShell();
|
||||
if (docShell) {
|
||||
nsCOMPtr<nsIEditorDocShell> editorDocShell = do_QueryInterface(docShell);
|
||||
if (editorDocShell) {
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
editorDocShell->GetEditor(getter_AddRefs(editor));
|
||||
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(editor);
|
||||
if (htmlEditor) {
|
||||
PRBool isVisible = PR_FALSE;
|
||||
nsCOMPtr<nsIDOMNode> domNode = do_QueryInterface(aNode);
|
||||
htmlEditor->BreakIsVisible(domNode, &isVisible);
|
||||
return !isVisible;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsHTMLContentSerializer::nsHTMLContentSerializer()
|
||||
{
|
||||
mIsHTMLSerializer = PR_TRUE;
|
||||
@ -204,6 +242,12 @@ nsHTMLContentSerializer::AppendElementStart(nsIContent *aElement,
|
||||
}
|
||||
|
||||
nsIAtom *name = content->Tag();
|
||||
|
||||
if ((mFlags & nsIDocumentEncoder::OutputPreformatted) &&
|
||||
IsInvisibleBreak(content, name)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool lineBreakBeforeOpen = LineBreakBeforeOpen(content->GetNameSpaceID(), name);
|
||||
|
||||
if ((mDoFormat || forceFormat) && !mPreLevel && !mDoRaw) {
|
||||
|
@ -51,7 +51,7 @@ interface nsIContentFilter;
|
||||
NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_EDITOR, 1)
|
||||
|
||||
%}
|
||||
[scriptable, uuid(afc36593-5787-4420-93d9-b2c0ccbf0cad)]
|
||||
[scriptable, uuid(c964b8b0-e9e8-11df-9492-0800200c9a66)]
|
||||
|
||||
interface nsIHTMLEditor : nsISupports
|
||||
{
|
||||
@ -608,5 +608,10 @@ interface nsIHTMLEditor : nsISupports
|
||||
* @return true if CR in a paragraph creates a new paragraph
|
||||
*/
|
||||
attribute boolean returnInParagraphCreatesNewParagraph;
|
||||
|
||||
/**
|
||||
* Checks whether a BR node is visible to the user.
|
||||
*/
|
||||
boolean breakIsVisible(in nsIDOMNode aNode);
|
||||
};
|
||||
|
||||
|
@ -1342,6 +1342,16 @@ PRBool nsHTMLEditor::IsVisBreak(nsIDOMNode *aNode)
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::BreakIsVisible(nsIDOMNode *aNode, PRBool *aIsVisible)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aNode && aIsVisible);
|
||||
|
||||
*aIsVisible = IsVisBreak(aNode);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::GetIsDocumentEditable(PRBool *aIsDocumentEditable)
|
||||
|
@ -15,17 +15,90 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=551704
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
<div id="preformatted" style="white-space: pre" contenteditable>a b</div>
|
||||
<div id="test1" contenteditable><br></div>
|
||||
<div id="test2" contenteditable>a<br></div>
|
||||
<div id="test3" contenteditable style="white-space: pre"><br></div>
|
||||
<div id="test4" contenteditable style="white-space: pre">a<br></div>
|
||||
<div id="test5" contenteditable></div>
|
||||
<div id="test6" contenteditable>a</div>
|
||||
<div id="test7" contenteditable style="white-space: pre"></div>
|
||||
<div id="test8" contenteditable style="white-space: pre">a</div>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
function testLineBreak(div, type, expectedText, expectedHTML, callback)
|
||||
{
|
||||
div.focus();
|
||||
getSelection().collapse(div, 0);
|
||||
type();
|
||||
is(div.innerHTML, expectedHTML, "The expected HTML after editing should be correct");
|
||||
SimpleTest.waitForClipboard(expectedText,
|
||||
function() {
|
||||
getSelection().selectAllChildren(div);
|
||||
synthesizeKey("C", {accelKey: true});
|
||||
},
|
||||
function() {
|
||||
var t = document.createElement("textarea");
|
||||
document.body.appendChild(t);
|
||||
t.focus();
|
||||
synthesizeKey("V", {accelKey: true});
|
||||
is(t.value, expectedText, "The expected text should be copied to the clipboard");
|
||||
callback();
|
||||
},
|
||||
function() {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function typeABCDEF() {
|
||||
synthesizeKey("a", {});
|
||||
typeBCDEF_chars();
|
||||
}
|
||||
|
||||
function typeBCDEF() {
|
||||
synthesizeKey("VK_RIGHT", {});
|
||||
typeBCDEF_chars();
|
||||
}
|
||||
|
||||
function typeBCDEF_chars() {
|
||||
synthesizeKey("b", {});
|
||||
synthesizeKey("c", {});
|
||||
synthesizeKey("VK_ENTER", {});
|
||||
synthesizeKey("d", {});
|
||||
synthesizeKey("e", {});
|
||||
synthesizeKey("f", {});
|
||||
}
|
||||
|
||||
/** Test for Bug 551704 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(function() {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
var preformatted = document.getElementById("preformatted");
|
||||
is(preformatted.innerHTML, "a\nb", "No BR node should be injected for preformatted editable fields");
|
||||
|
||||
SimpleTest.finish();
|
||||
var divs = [];
|
||||
for (var i = 0; i < 8; ++i) {
|
||||
divs[i] = document.getElementById("test" + (i+1));
|
||||
}
|
||||
var current = 0;
|
||||
function doNextTest() {
|
||||
if (current == divs.length) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
var div = divs[current++];
|
||||
if (div.textContent == "a") {
|
||||
var type = typeBCDEF;
|
||||
} else {
|
||||
var type = typeABCDEF;
|
||||
}
|
||||
var expectedHTML = "abc<br>def<br>";
|
||||
var expectedText = "abc\ndef";
|
||||
testLineBreak(div, type, expectedText, expectedHTML, doNextTest);
|
||||
}
|
||||
|
||||
doNextTest();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
Loading…
Reference in New Issue
Block a user