зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1370737 - Track seen preformatted elements in the document encoder to maintain stack balance correctly irrespective of element visibility; r=bzbarsky
This commit is contained in:
Родитель
89aa3c7c0f
Коммит
7f656414b1
|
@ -0,0 +1,41 @@
|
|||
<html class="reftest-wait">
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
let n=document.getElementById('a');
|
||||
n.parentNode.removeChild(n);
|
||||
let o=document.getElementById('b');
|
||||
let p=document.getElementById('c');
|
||||
p.id=[o.id, o.id=p.id][0];
|
||||
let l=['d'];
|
||||
let s=window.getSelection();
|
||||
for(let i=0; i<l.length; i++){
|
||||
let e=document.getElementById(l[i]);
|
||||
let r=document.createRange();
|
||||
r.selectNode(e);
|
||||
s.addRange(r);
|
||||
}
|
||||
n=document.getElementById('b');
|
||||
n.parentNode.removeChild(n);
|
||||
window.getSelection().modify('extend','right','word');
|
||||
n.setAttribute('id','e');
|
||||
document.getElementById('f').appendChild(n);
|
||||
l=['e'];
|
||||
for(let i=0; i<l.length; i++){
|
||||
let e=document.getElementById(l[i]);
|
||||
let r=document.createRange();
|
||||
r.selectNode(e);
|
||||
s.addRange(r);
|
||||
}
|
||||
document.documentElement.removeAttribute("class");
|
||||
});
|
||||
</script>
|
||||
<table>
|
||||
<tbody hidden>
|
||||
<th id='c'>
|
||||
<i id='d'>
|
||||
<bdo id='b'></bdo>
|
||||
<td></td>
|
||||
<tbody id='f'>
|
||||
<td id='a' contenteditable='true'>
|
||||
<td>
|
||||
</html>
|
|
@ -212,6 +212,7 @@ pref(dom.webcomponents.enabled,true) load 1341693.html
|
|||
pref(dom.IntersectionObserver.enabled,true) load 1353529.xul
|
||||
pref(dom.IntersectionObserver.enabled,true) load 1369363.xul
|
||||
load 1370072.html
|
||||
pref(clipboard.autocopy,true) load 1370737.html
|
||||
pref(dom.IntersectionObserver.enabled,true) load 1370968.html
|
||||
load structured_clone_container_throws.html
|
||||
HTTP(..) load xhr_abortinprogress.html
|
||||
|
|
|
@ -186,6 +186,10 @@ protected:
|
|||
AutoTArray<int32_t, 8> mStartOffsets;
|
||||
AutoTArray<nsIContent*, 8> mEndNodes;
|
||||
AutoTArray<int32_t, 8> mEndOffsets;
|
||||
// Whether the serializer cares about being notified to scan elements to
|
||||
// keep track of whether they are preformatted. This stores the out
|
||||
// argument of nsIContentSerializer::Init().
|
||||
bool mNeedsPreformatScanning;
|
||||
bool mHaltRangeHint;
|
||||
// Used when context has already been serialized for
|
||||
// table cell selections (where parent is <tr>)
|
||||
|
@ -221,6 +225,7 @@ void nsDocumentEncoder::Initialize(bool aClearCachedSerializer)
|
|||
mEndDepth = 0;
|
||||
mStartRootIndex = 0;
|
||||
mEndRootIndex = 0;
|
||||
mNeedsPreformatScanning = false;
|
||||
mHaltRangeHint = false;
|
||||
mDisableContextSerialize = false;
|
||||
mNodeIsContainer = false;
|
||||
|
@ -351,6 +356,10 @@ nsDocumentEncoder::SerializeNodeStart(nsINode* aNode,
|
|||
nsAString& aStr,
|
||||
nsINode* aOriginalNode)
|
||||
{
|
||||
if (mNeedsPreformatScanning && aNode->IsElement()) {
|
||||
mSerializer->ScanElementForPreformat(aNode->AsElement());
|
||||
}
|
||||
|
||||
if (!IsVisibleNode(aNode))
|
||||
return NS_OK;
|
||||
|
||||
|
@ -428,6 +437,10 @@ nsresult
|
|||
nsDocumentEncoder::SerializeNodeEnd(nsINode* aNode,
|
||||
nsAString& aStr)
|
||||
{
|
||||
if (mNeedsPreformatScanning && aNode->IsElement()) {
|
||||
mSerializer->ForgetElementForPreformat(aNode->AsElement());
|
||||
}
|
||||
|
||||
if (!IsVisibleNode(aNode))
|
||||
return NS_OK;
|
||||
|
||||
|
@ -1075,7 +1088,9 @@ nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength,
|
|||
nsresult rv = NS_OK;
|
||||
|
||||
bool rewriteEncodingDeclaration = !(mSelection || mRange || mNode) && !(mFlags & OutputDontRewriteEncodingDeclaration);
|
||||
mSerializer->Init(mFlags, mWrapColumn, mCharset.get(), mIsCopying, rewriteEncodingDeclaration);
|
||||
mSerializer->Init(mFlags, mWrapColumn, mCharset.get(),
|
||||
mIsCopying, rewriteEncodingDeclaration,
|
||||
&mNeedsPreformatScanning);
|
||||
|
||||
if (mSelection) {
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
|
|
|
@ -30,7 +30,8 @@ class nsIContentSerializer : public nsISupports {
|
|||
|
||||
NS_IMETHOD Init(uint32_t flags, uint32_t aWrapColumn,
|
||||
const char* aCharSet, bool aIsCopying,
|
||||
bool aIsWholeDocument) = 0;
|
||||
bool aIsWholeDocument,
|
||||
bool* aNeedsPerformatScanning) = 0;
|
||||
|
||||
NS_IMETHOD AppendText(nsIContent* aText, int32_t aStartOffset,
|
||||
int32_t aEndOffset, nsAString& aStr) = 0;
|
||||
|
@ -66,6 +67,14 @@ class nsIContentSerializer : public nsISupports {
|
|||
*/
|
||||
NS_IMETHOD AppendDocumentStart(nsIDocument *aDocument,
|
||||
nsAString& aStr) = 0;
|
||||
|
||||
// If Init() sets *aNeedsPerformatScanning to true, then these methods are
|
||||
// called when elements are started and ended, before AppendElementStart
|
||||
// and AppendElementEnd, respectively. They are supposed to be used to
|
||||
// allow the implementer to keep track of whether the element is
|
||||
// preformatted.
|
||||
NS_IMETHOD ScanElementForPreformat(mozilla::dom::Element* aElement) = 0;
|
||||
NS_IMETHOD ForgetElementForPreformat(mozilla::dom::Element* aElement) = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIContentSerializer, NS_ICONTENTSERIALIZER_IID)
|
||||
|
|
|
@ -139,7 +139,8 @@ nsPlainTextSerializer::~nsPlainTextSerializer()
|
|||
NS_IMETHODIMP
|
||||
nsPlainTextSerializer::Init(uint32_t aFlags, uint32_t aWrapColumn,
|
||||
const char* aCharSet, bool aIsCopying,
|
||||
bool aIsWholeDocument)
|
||||
bool aIsWholeDocument,
|
||||
bool* aNeedsPreformatScanning)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// Check if the major control flags are set correctly.
|
||||
|
@ -155,6 +156,7 @@ nsPlainTextSerializer::Init(uint32_t aFlags, uint32_t aWrapColumn,
|
|||
}
|
||||
#endif
|
||||
|
||||
*aNeedsPreformatScanning = true;
|
||||
mFlags = aFlags;
|
||||
mWrapColumn = aWrapColumn;
|
||||
|
||||
|
@ -370,6 +372,20 @@ nsPlainTextSerializer::AppendCDATASection(nsIContent* aCDATASection,
|
|||
return AppendText(aCDATASection, aStartOffset, aEndOffset, aStr);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPlainTextSerializer::ScanElementForPreformat(Element* aElement)
|
||||
{
|
||||
mPreformatStack.push(IsElementPreformatted(aElement));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPlainTextSerializer::ForgetElementForPreformat(Element* aElement)
|
||||
{
|
||||
mPreformatStack.pop();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPlainTextSerializer::AppendElementStart(Element* aElement,
|
||||
Element* aOriginalElement,
|
||||
|
@ -388,7 +404,6 @@ nsPlainTextSerializer::AppendElementStart(Element* aElement,
|
|||
|
||||
if (isContainer) {
|
||||
rv = DoOpenContainer(id);
|
||||
mPreformatStack.push(IsElementPreformatted(mElement));
|
||||
}
|
||||
else {
|
||||
rv = DoAddLeaf(id);
|
||||
|
@ -422,7 +437,6 @@ nsPlainTextSerializer::AppendElementEnd(Element* aElement,
|
|||
rv = NS_OK;
|
||||
if (isContainer) {
|
||||
rv = DoCloseContainer(id);
|
||||
mPreformatStack.pop();
|
||||
}
|
||||
|
||||
mElement = nullptr;
|
||||
|
|
|
@ -44,7 +44,8 @@ public:
|
|||
// nsIContentSerializer
|
||||
NS_IMETHOD Init(uint32_t flags, uint32_t aWrapColumn,
|
||||
const char* aCharSet, bool aIsCopying,
|
||||
bool aIsWholeDocument) override;
|
||||
bool aIsWholeDocument,
|
||||
bool* aNeedsPreformatScanning) override;
|
||||
|
||||
NS_IMETHOD AppendText(nsIContent* aText, int32_t aStartOffset,
|
||||
int32_t aEndOffset, nsAString& aStr) override;
|
||||
|
@ -69,6 +70,9 @@ public:
|
|||
NS_IMETHOD AppendDocumentStart(nsIDocument *aDocument,
|
||||
nsAString& aStr) override;
|
||||
|
||||
NS_IMETHOD ScanElementForPreformat(mozilla::dom::Element* aElement) override;
|
||||
NS_IMETHOD ForgetElementForPreformat(mozilla::dom::Element* aElement) override;
|
||||
|
||||
private:
|
||||
~nsPlainTextSerializer();
|
||||
|
||||
|
|
|
@ -59,8 +59,9 @@ nsXHTMLContentSerializer::~nsXHTMLContentSerializer()
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsXHTMLContentSerializer::Init(uint32_t aFlags, uint32_t aWrapColumn,
|
||||
const char* aCharSet, bool aIsCopying,
|
||||
bool aRewriteEncodingDeclaration)
|
||||
const char* aCharSet, bool aIsCopying,
|
||||
bool aRewriteEncodingDeclaration,
|
||||
bool* aNeedsPreformatScanning)
|
||||
{
|
||||
// The previous version of the HTML serializer did implicit wrapping
|
||||
// when there is no flags, so we keep wrapping in order to keep
|
||||
|
@ -71,7 +72,9 @@ nsXHTMLContentSerializer::Init(uint32_t aFlags, uint32_t aWrapColumn,
|
|||
}
|
||||
|
||||
nsresult rv;
|
||||
rv = nsXMLContentSerializer::Init(aFlags, aWrapColumn, aCharSet, aIsCopying, aRewriteEncodingDeclaration);
|
||||
rv = nsXMLContentSerializer::Init(aFlags, aWrapColumn, aCharSet,
|
||||
aIsCopying, aRewriteEncodingDeclaration,
|
||||
aNeedsPreformatScanning);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mRewriteEncodingDeclaration = aRewriteEncodingDeclaration;
|
||||
|
|
|
@ -29,7 +29,8 @@ class nsXHTMLContentSerializer : public nsXMLContentSerializer {
|
|||
|
||||
NS_IMETHOD Init(uint32_t flags, uint32_t aWrapColumn,
|
||||
const char* aCharSet, bool aIsCopying,
|
||||
bool aRewriteEncodingDeclaration) override;
|
||||
bool aRewriteEncodingDeclaration,
|
||||
bool* aNeedsPreformatScanning) override;
|
||||
|
||||
NS_IMETHOD AppendText(nsIContent* aText,
|
||||
int32_t aStartOffset,
|
||||
|
|
|
@ -76,8 +76,10 @@ NS_IMPL_ISUPPORTS(nsXMLContentSerializer, nsIContentSerializer)
|
|||
NS_IMETHODIMP
|
||||
nsXMLContentSerializer::Init(uint32_t aFlags, uint32_t aWrapColumn,
|
||||
const char* aCharSet, bool aIsCopying,
|
||||
bool aRewriteEncodingDeclaration)
|
||||
bool aRewriteEncodingDeclaration,
|
||||
bool* aNeedsPreformatScanning)
|
||||
{
|
||||
*aNeedsPreformatScanning = false;
|
||||
mPrefixIndex = 0;
|
||||
mColPos = 0;
|
||||
mIndentOverflow = 0;
|
||||
|
|
|
@ -34,7 +34,8 @@ class nsXMLContentSerializer : public nsIContentSerializer {
|
|||
|
||||
NS_IMETHOD Init(uint32_t flags, uint32_t aWrapColumn,
|
||||
const char* aCharSet, bool aIsCopying,
|
||||
bool aRewriteEncodingDeclaration) override;
|
||||
bool aRewriteEncodingDeclaration,
|
||||
bool* aNeedsPreformatScanning) override;
|
||||
|
||||
NS_IMETHOD AppendText(nsIContent* aText, int32_t aStartOffset,
|
||||
int32_t aEndOffset, nsAString& aStr) override;
|
||||
|
@ -66,6 +67,15 @@ class nsXMLContentSerializer : public nsIContentSerializer {
|
|||
NS_IMETHOD AppendDocumentStart(nsIDocument *aDocument,
|
||||
nsAString& aStr) override;
|
||||
|
||||
NS_IMETHOD ScanElementForPreformat(mozilla::dom::Element* aElement) override
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD ForgetElementForPreformat(mozilla::dom::Element* aElement) override
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~nsXMLContentSerializer();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче