Bug 838954 - Add a newline in .innerHTML serialization of <pre> when first character is a newline. r=smaug

This commit is contained in:
John Dai 2016-08-08 23:55:00 +02:00
parent 3cacba17b7
commit a14b337bab
8 changed files with 149 additions and 12 deletions

View File

@ -279,6 +279,7 @@ bool nsContentUtils::sEncodeDecodeURLHash = false;
bool nsContentUtils::sGettersDecodeURLHash = false;
bool nsContentUtils::sPrivacyResistFingerprinting = false;
bool nsContentUtils::sSendPerformanceTimingNotifications = false;
bool nsContentUtils::sAppendLFInSerialization = false;
uint32_t nsContentUtils::sHandlingInputTimeout = 1000;
@ -593,6 +594,8 @@ nsContentUtils::Init()
"network.cookie.cookieBehavior",
nsICookieService::BEHAVIOR_ACCEPT);
Preferences::AddBoolVarCache(&sAppendLFInSerialization,
"dom.html_fragment_serialisation.appendLF");
#if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
Preferences::AddBoolVarCache(&sDOMWindowDumpEnabled,
"browser.dom.window.dump.enabled");
@ -8979,12 +8982,12 @@ StartElement(Element* aContent, StringBuilder& aBuilder)
aBuilder.Append(">");
/*
// Per HTML spec we should append one \n if the first child of
// pre/textarea/listing is a textnode and starts with a \n.
// But because browsers haven't traditionally had that behavior,
// we're not changing our behavior either - yet.
if (aContent->IsHTMLElement()) {
if (nsContentUtils::AppendLFInSerialization() && aContent->IsHTMLElement()) {
if (localName == nsGkAtoms::pre || localName == nsGkAtoms::textarea ||
localName == nsGkAtoms::listing) {
nsIContent* fc = aContent->GetFirstChild();
@ -8997,7 +9000,7 @@ StartElement(Element* aContent, StringBuilder& aBuilder)
}
}
}
}*/
}
}
static inline bool

View File

@ -1954,6 +1954,10 @@ public:
static already_AddRefed<mozilla::layers::LayerManager>
PersistentLayerManagerForDocument(nsIDocument *aDoc);
/* static */
static bool AppendLFInSerialization()
{ return sAppendLFInSerialization; }
/**
* Determine whether a content node is focused or not,
*
@ -2771,6 +2775,7 @@ private:
static bool sGettersDecodeURLHash;
static bool sPrivacyResistFingerprinting;
static bool sSendPerformanceTimingNotifications;
static bool sAppendLFInSerialization;
static uint32_t sCookiesLifetimePolicy;
static uint32_t sCookiesBehavior;

View File

@ -26,7 +26,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=744830
t.appendChild(document.createElement("textarea"));
t.firstChild.appendChild(document.createTextNode("\nhello"));
// This is the old behavior. Spec requires something else.
is(t.innerHTML, "<textarea>\nhello</textarea>",
is(t.innerHTML, "<textarea>\n\nhello</textarea>",
"No extra newlines should be inserted to the textarea!");
t.innerHTML = null;

View File

@ -5520,3 +5520,9 @@ pref("dom.webkitBlink.filesystem.enabled", true);
// Is the Servo-backed style system enabled?
pref("layout.css.servo.enabled", true);
#endif
#ifdef NIGHTLY_BUILD
pref("dom.html_fragment_serialisation.appendLF", true);
#else
pref("dom.html_fragment_serialisation.appendLF", false);
#endif

View File

@ -350,3 +350,4 @@ user_pref("webextensions.tests", true);
user_pref("startup.homepage_welcome_url", "about:blank");
user_pref("startup.homepage_welcome_url.additional", "");
user_pref("browser.usedOnWindows10.introURL", "");
user_pref("dom.html_fragment_serialisation.appendLF", true);

View File

@ -15341,6 +15341,10 @@
"path": "domparsing/innerhtml-01.xhtml",
"url": "/domparsing/innerhtml-01.xhtml"
},
{
"path": "domparsing/innerhtml-02.html",
"url": "/domparsing/innerhtml-02.html"
},
{
"path": "domparsing/innerhtml-03.xhtml",
"url": "/domparsing/innerhtml-03.xhtml"

View File

@ -1,8 +0,0 @@
[initial-linefeed-pre.html]
type: testharness
[outer div]
expected: FAIL
[inner div]
expected: FAIL

View File

@ -0,0 +1,126 @@
<!DOCTYPE html>
<title>innerHTML in HTML</title>
<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
<link rel="help" href="http://html5.org/specs/dom-parsing.html#innerhtml">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
var voidElements = [
"area", "base", "basefont", "bgsound", "br", "col", "command", "embed",
"frame", "hr", "img", "input", "keygen", "link", "meta", "param", "source",
"track", "wbr"
];
var tests = [
[
function() {
var el = document.createElement("div");
el.appendChild(document.createElement("xmp"))
.appendChild(document.createElement("span"))
.appendChild(document.createTextNode("<"));
return el;
},
"<xmp><span>&lt;<\/span><\/xmp>"
],
[
function() {
var el = document.createElement("xmp");
el.appendChild(document.createElement("span"))
.appendChild(document.createTextNode("<"));
return el;
},
"<span>&lt;<\/span>"
],
[
function() {
var el = document.createElement("xmp");
el.appendChild(document.createTextNode("<"));
return el;
},
"<"
],
[
function() {
var el = document.createElement("div");
el.appendChild(document.createElement("br"));
return el;
},
"<br>"
],
[
function() {
var el = document.createElement("div");
el.appendChild(document.createElement("input"))
.appendChild(document.createElement("span"));
return el;
},
"<input>"
],
[
function() {
var el = document.createElement("img");
el.appendChild(document.createElement("div"))
.appendChild(document.createElement("span"));
return el.firstChild;
},
"<span><\/span>"
],
[
function() {
var el = document.createElement("div");
el.appendChild(document.createElement("style"))
.appendChild(document.createElement("span"));
return el;
},
"<style><span><\/span><\/style>"
],
[
function() {
var el = document.createElement("div");
el.appendChild(document.createElement("style"))
.appendChild(document.createTextNode("<"));
return el;
},
"<style><<\/style>"
],
[
function() {
var el = document.createElement("div");
el.appendChild(document.createElement("style"))
.appendChild(document.createElement("span"))
.appendChild(document.createTextNode("<"));
return el;
},
"<style><span>&lt;<\/span><\/style>"
]
];
voidElements.forEach(function(tag) {
tests.push([
function() {
var el = document.createElement(tag);
el.appendChild(document.createElement("span"));
return el;
},
"<span><\/span>"
]);
});
["pre", "textarea", "listing"].forEach(function(tag) {
tests.push([
function() {
var el = document.createElement("div");
el.appendChild(document.createElement(tag))
.appendChild(document.createTextNode("\nA"));
return el;
},
"<" + tag + ">\n\nA<\/" + tag + ">"
]);
});
test(function() {
tests.forEach(function(t) {
var el = t[0](), expected = t[1];
test(function() {
assert_equals(el.innerHTML, expected);
}, "Expected innerHTML: " + format_value(expected) + " for " + el.localName + ".");
});
});
</script>