Merge remote-tracking branch 'origin/master' into custom

This commit is contained in:
Roy Tam 2019-12-06 22:48:12 +08:00
commit bf6cd1e010
10 changed files with 146 additions and 49 deletions

View file

@ -395,6 +395,21 @@ nsIdentifierMapEntry::FireChangeCallbacks(Element* aOldElement,
} }
} }
void
nsIdentifierMapEntry::ClearAndNotify()
{
Element* currentElement = mIdContentList.SafeElementAt(0);
mIdContentList.Clear();
if (currentElement) {
FireChangeCallbacks(currentElement, nullptr);
}
mNameContentList = nullptr;
if (mImageElement) {
SetImageElement(nullptr);
}
mChangeCallbacks = nullptr;
}
namespace { namespace {
struct PositionComparator struct PositionComparator
@ -1422,12 +1437,12 @@ nsDocument::~nsDocument()
delete mSubDocuments; delete mSubDocuments;
mSubDocuments = nullptr; mSubDocuments = nullptr;
nsAutoScriptBlocker scriptBlocker;
// Destroy link map now so we don't waste time removing // Destroy link map now so we don't waste time removing
// links one by one // links one by one
DestroyElementMaps(); DestroyElementMaps();
nsAutoScriptBlocker scriptBlocker;
for (uint32_t indx = mChildren.ChildCount(); indx-- != 0; ) { for (uint32_t indx = mChildren.ChildCount(); indx-- != 0; ) {
mChildren.ChildAt(indx)->UnbindFromTree(); mChildren.ChildAt(indx)->UnbindFromTree();
mChildren.RemoveChildAt(indx); mChildren.RemoveChildAt(indx);
@ -1972,15 +1987,16 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
delete mSubDocuments; delete mSubDocuments;
mSubDocuments = nullptr; mSubDocuments = nullptr;
// Destroy link map now so we don't waste time removing
// links one by one
DestroyElementMaps();
bool oldVal = mInUnlinkOrDeletion; bool oldVal = mInUnlinkOrDeletion;
mInUnlinkOrDeletion = true; mInUnlinkOrDeletion = true;
uint32_t count = mChildren.ChildCount(); uint32_t count = mChildren.ChildCount();
{ // Scope for update { // Scope for update
MOZ_AUTO_DOC_UPDATE(this, UPDATE_CONTENT_MODEL, true); MOZ_AUTO_DOC_UPDATE(this, UPDATE_CONTENT_MODEL, true);
// Destroy link map now so we don't waste time removing
// links one by one
DestroyElementMaps();
for (int32_t i = int32_t(count) - 1; i >= 0; i--) { for (int32_t i = int32_t(count) - 1; i >= 0; i--) {
nsCOMPtr<nsIContent> content = mChildren.ChildAt(i); nsCOMPtr<nsIContent> content = mChildren.ChildAt(i);
@ -8955,7 +8971,14 @@ nsDocument::DestroyElementMaps()
mStyledLinksCleared = true; mStyledLinksCleared = true;
#endif #endif
mStyledLinks.Clear(); mStyledLinks.Clear();
// Notify ID change listeners before clearing the identifier map.
for (auto iter = mIdentifierMap.Iter(); !iter.Done(); iter.Next()) {
iter.Get()->ClearAndNotify();
}
mIdentifierMap.Clear(); mIdentifierMap.Clear();
++mExpandoAndGeneration.generation; ++mExpandoAndGeneration.generation;
} }

View file

@ -216,6 +216,11 @@ public:
void RemoveContentChangeCallback(nsIDocument::IDTargetObserver aCallback, void RemoveContentChangeCallback(nsIDocument::IDTargetObserver aCallback,
void* aData, bool aForImage); void* aData, bool aForImage);
/**
* Remove all elements and notify change listeners.
*/
void ClearAndNotify();
void Traverse(nsCycleCollectionTraversalCallback* aCallback); void Traverse(nsCycleCollectionTraversalCallback* aCallback);
struct ChangeCallback { struct ChangeCallback {

View file

@ -53,7 +53,6 @@ static int32_t GetUnicharStringWidth(const char16_t* pwcs, int32_t n);
// Someday may want to make this non-const: // Someday may want to make this non-const:
static const uint32_t TagStackSize = 500; static const uint32_t TagStackSize = 500;
static const uint32_t OLStackSize = 100;
nsresult nsresult
NS_NewPlainTextSerializer(nsIContentSerializer** aSerializer) NS_NewPlainTextSerializer(nsIContentSerializer** aSerializer)
@ -100,10 +99,6 @@ nsPlainTextSerializer::nsPlainTextSerializer()
mTagStackIndex = 0; mTagStackIndex = 0;
mIgnoreAboveIndex = (uint32_t)kNotFound; mIgnoreAboveIndex = (uint32_t)kNotFound;
// initialize the OL stack, where numbers for ordered lists are kept
mOLStack = new int32_t[OLStackSize];
mOLStackIndex = 0;
mULCount = 0; mULCount = 0;
mIgnoredChildNodeLevel = 0; mIgnoredChildNodeLevel = 0;
@ -112,7 +107,6 @@ nsPlainTextSerializer::nsPlainTextSerializer()
nsPlainTextSerializer::~nsPlainTextSerializer() nsPlainTextSerializer::~nsPlainTextSerializer()
{ {
delete[] mTagStack; delete[] mTagStack;
delete[] mOLStack;
NS_WARNING_ASSERTION(mHeadLevel == 0, "Wrong head level!"); NS_WARNING_ASSERTION(mHeadLevel == 0, "Wrong head level!");
} }
@ -189,6 +183,8 @@ nsPlainTextSerializer::Init(uint32_t aFlags, uint32_t aWrapColumn,
// XXX We should let the caller decide whether to do this or not // XXX We should let the caller decide whether to do this or not
mFlags &= ~nsIDocumentEncoder::OutputNoFramesContent; mFlags &= ~nsIDocumentEncoder::OutputNoFramesContent;
MOZ_ASSERT(mOLStack.IsEmpty());
return NS_OK; return NS_OK;
} }
@ -438,6 +434,8 @@ nsPlainTextSerializer::AppendDocumentStart(nsIDocument *aDocument,
return NS_OK; return NS_OK;
} }
int32_t kOlStackDummyValue = 0;
nsresult nsresult
nsPlainTextSerializer::DoOpenContainer(nsIAtom* aTag) nsPlainTextSerializer::DoOpenContainer(nsIAtom* aTag)
{ {
@ -616,44 +614,45 @@ nsPlainTextSerializer::DoOpenContainer(nsIAtom* aTag)
} }
else if (aTag == nsGkAtoms::ul) { else if (aTag == nsGkAtoms::ul) {
// Indent here to support nested lists, which aren't included in li :-( // Indent here to support nested lists, which aren't included in li :-(
EnsureVerticalSpace(mULCount + mOLStackIndex == 0 ? 1 : 0); EnsureVerticalSpace(IsInOLOrUL() ? 0 : 1);
// Must end the current line before we change indention // Must end the current line before we change indention
mIndent += kIndentSizeList; mIndent += kIndentSizeList;
mULCount++; mULCount++;
} }
else if (aTag == nsGkAtoms::ol) { else if (aTag == nsGkAtoms::ol) {
EnsureVerticalSpace(mULCount + mOLStackIndex == 0 ? 1 : 0); EnsureVerticalSpace(IsInOLOrUL() ? 0 : 1);
if (mFlags & nsIDocumentEncoder::OutputFormatted) { if (mFlags & nsIDocumentEncoder::OutputFormatted) {
// Must end the current line before we change indention // Must end the current line before we change indention
if (mOLStackIndex < OLStackSize) { nsAutoString startAttr;
nsAutoString startAttr; int32_t startVal = 1;
int32_t startVal = 1; if (NS_SUCCEEDED(GetAttributeValue(nsGkAtoms::start, startAttr))) {
if (NS_SUCCEEDED(GetAttributeValue(nsGkAtoms::start, startAttr))) { nsresult rv = NS_OK;
nsresult rv = NS_OK; startVal = startAttr.ToInteger(&rv);
startVal = startAttr.ToInteger(&rv); if (NS_FAILED(rv)) {
if (NS_FAILED(rv)) startVal = 1;
startVal = 1;
} }
mOLStack[mOLStackIndex++] = startVal;
} }
mOLStack.AppendElement(startVal);
} else { } else {
mOLStackIndex++; mOLStack.AppendElement(kOlStackDummyValue);
} }
mIndent += kIndentSizeList; // see ul mIndent += kIndentSizeList; // see ul
} }
else if (aTag == nsGkAtoms::li && else if (aTag == nsGkAtoms::li &&
(mFlags & nsIDocumentEncoder::OutputFormatted)) { (mFlags & nsIDocumentEncoder::OutputFormatted)) {
if (mTagStackIndex > 1 && IsInOL()) { if (mTagStackIndex > 1 && IsInOL()) {
if (mOLStackIndex > 0) { if (!mOLStack.IsEmpty()) {
nsAutoString valueAttr; nsAutoString valueAttr;
if (NS_SUCCEEDED(GetAttributeValue(nsGkAtoms::value, valueAttr))) { if (NS_SUCCEEDED(GetAttributeValue(nsGkAtoms::value, valueAttr))) {
nsresult rv = NS_OK; nsresult rv = NS_OK;
int32_t valueAttrVal = valueAttr.ToInteger(&rv); int32_t valueAttrVal = valueAttr.ToInteger(&rv);
if (NS_SUCCEEDED(rv)) if (NS_SUCCEEDED(rv)) {
mOLStack[mOLStackIndex-1] = valueAttrVal; mOLStack.LastElement() = valueAttrVal;
}
} }
// This is what nsBulletFrame does for OLs: // This is what nsBulletFrame does for OLs:
mInIndentString.AppendInt(mOLStack[mOLStackIndex-1]++, 10); mInIndentString.AppendInt(mOLStack.LastElement(), 10);
mOLStack.LastElement()++;
} }
else { else {
mInIndentString.Append(char16_t('#')); mInIndentString.Append(char16_t('#'));
@ -878,7 +877,8 @@ nsPlainTextSerializer::DoCloseContainer(nsIAtom* aTag)
else if (aTag == nsGkAtoms::ul) { else if (aTag == nsGkAtoms::ul) {
FlushLine(); FlushLine();
mIndent -= kIndentSizeList; mIndent -= kIndentSizeList;
if (--mULCount + mOLStackIndex == 0) { --mULCount;
if (!IsInOLOrUL()) {
mFloatingLines = 1; mFloatingLines = 1;
mLineBreakDue = true; mLineBreakDue = true;
} }
@ -886,9 +886,9 @@ nsPlainTextSerializer::DoCloseContainer(nsIAtom* aTag)
else if (aTag == nsGkAtoms::ol) { else if (aTag == nsGkAtoms::ol) {
FlushLine(); // Doing this after decreasing OLStackIndex would be wrong. FlushLine(); // Doing this after decreasing OLStackIndex would be wrong.
mIndent -= kIndentSizeList; mIndent -= kIndentSizeList;
NS_ASSERTION(mOLStackIndex, "Wrong OLStack level!"); NS_ASSERTION(!mOLStack.IsEmpty(), "Wrong OLStack level!");
mOLStackIndex--; mOLStack.RemoveElementAt(mOLStack.Length() - 1);
if (mULCount + mOLStackIndex == 0) { if (!IsInOLOrUL()) {
mFloatingLines = 1; mFloatingLines = 1;
mLineBreakDue = true; mLineBreakDue = true;
} }
@ -1861,6 +1861,10 @@ nsPlainTextSerializer::IsInOL()
return false; return false;
} }
bool nsPlainTextSerializer::IsInOLOrUL() const {
return (mULCount > 0) || !mOLStack.IsEmpty();
}
/* /*
@return 0 = no header, 1 = h1, ..., 6 = h6 @return 0 = no header, 1 = h1, ..., 6 = h6
*/ */

View file

@ -81,6 +81,7 @@ private:
void Write(const nsAString& aString); void Write(const nsAString& aString);
bool IsInPre(); bool IsInPre();
bool IsInOL(); bool IsInOL();
bool IsInOLOrUL() const;
bool IsCurrentNodeConverted(); bool IsCurrentNodeConverted();
bool MustSuppressLeaf(); bool MustSuppressLeaf();
@ -218,8 +219,7 @@ private:
uint32_t mIgnoreAboveIndex; uint32_t mIgnoreAboveIndex;
// The stack for ordered lists // The stack for ordered lists
int32_t *mOLStack; AutoTArray<int32_t, 100> mOLStack;
uint32_t mOLStackIndex;
uint32_t mULCount; uint32_t mULCount;

View file

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="en">
<title>canvas filters: remove referenced filter element through document.open()</title>
<body onload="loaded()">
<canvas id="canvas" width="10" height="10"></canvas>
<svg height="0">
<filter id="filter">
<feFlood flood-color="red"/>
</filter>
</svg>
<script>
function loaded() {
var ctx = document.getElementById('canvas').getContext('2d');
ctx.filter = 'url(#filter)';
ctx.fillRect(0, 0, 10, 10); // do a draw first to work around bug 1287316
document.open();
// The document.open() call removed #filter from the document. So the filter
// reference should now be invalid, and the rect should be drawn without a
// filter applied, resulting in black.
ctx.fillRect(0, 0, 10, 10);
try {
var data = ctx.getImageData(0, 0, 1, 1).data;
if (data[0] == 0 && data[1] == 0 && data[2] == 0 && data[3] == 255) {
// Successfully painted black.
document.write('PASS');
} else {
// Painted something else, like red.
document.write('FAIL');
}
} catch (e) {
document.write('getImageData failed');
}
document.close();
}
</script>

View file

@ -6,6 +6,7 @@ default-preferences pref(canvas.filters.enabled,true)
fuzzy-if(azureSkia,1,1500) == global-alpha.html global-alpha-ref.html fuzzy-if(azureSkia,1,1500) == global-alpha.html global-alpha-ref.html
== global-composite-operation.html global-composite-operation-ref.html == global-composite-operation.html global-composite-operation-ref.html
== liveness.html ref.html == liveness.html ref.html
== liveness-document-open.html data:text/html,PASS
== multiple-drop-shadows.html shadow-ref.html == multiple-drop-shadows.html shadow-ref.html
== shadow.html shadow-ref.html == shadow.html shadow-ref.html
== subregion-fill-paint.html subregion-ref.html == subregion-fill-paint.html subregion-ref.html

View file

@ -310,9 +310,10 @@ PluginInstanceChild::InternalGetNPObjectForValue(NPNVariable aValue,
switch (aValue) { switch (aValue) {
case NPNVWindowNPObject: case NPNVWindowNPObject:
if (!(actor = mCachedWindowActor)) { if (!(actor = mCachedWindowActor)) {
result = NPERR_GENERIC_ERROR;
PPluginScriptableObjectChild* actorProtocol; PPluginScriptableObjectChild* actorProtocol;
CallNPN_GetValue_NPNVWindowNPObject(&actorProtocol, &result); if (CallNPN_GetValue_NPNVWindowNPObject(&actorProtocol, &result) &&
if (result == NPERR_NO_ERROR) { result == NPERR_NO_ERROR) {
actor = mCachedWindowActor = actor = mCachedWindowActor =
static_cast<PluginScriptableObjectChild*>(actorProtocol); static_cast<PluginScriptableObjectChild*>(actorProtocol);
NS_ASSERTION(actor, "Null actor!"); NS_ASSERTION(actor, "Null actor!");
@ -324,10 +325,10 @@ PluginInstanceChild::InternalGetNPObjectForValue(NPNVariable aValue,
case NPNVPluginElementNPObject: case NPNVPluginElementNPObject:
if (!(actor = mCachedElementActor)) { if (!(actor = mCachedElementActor)) {
result = NPERR_GENERIC_ERROR;
PPluginScriptableObjectChild* actorProtocol; PPluginScriptableObjectChild* actorProtocol;
CallNPN_GetValue_NPNVPluginElementNPObject(&actorProtocol, if (CallNPN_GetValue_NPNVPluginElementNPObject(&actorProtocol, &result) &&
&result); result == NPERR_NO_ERROR) {
if (result == NPERR_NO_ERROR) {
actor = mCachedElementActor = actor = mCachedElementActor =
static_cast<PluginScriptableObjectChild*>(actorProtocol); static_cast<PluginScriptableObjectChild*>(actorProtocol);
NS_ASSERTION(actor, "Null actor!"); NS_ASSERTION(actor, "Null actor!");
@ -338,6 +339,7 @@ PluginInstanceChild::InternalGetNPObjectForValue(NPNVariable aValue,
break; break;
default: default:
result = NPERR_GENERIC_ERROR;
NS_NOTREACHED("Don't know what to do with this value type!"); NS_NOTREACHED("Don't know what to do with this value type!");
} }
@ -434,6 +436,7 @@ PluginInstanceChild::NPN_GetValue(NPNVariable aVar,
case NPNVWindowNPObject: // Intentional fall-through case NPNVWindowNPObject: // Intentional fall-through
case NPNVPluginElementNPObject: { case NPNVPluginElementNPObject: {
NPObject* object; NPObject* object;
*((NPObject**)aValue) = nullptr;
NPError result = InternalGetNPObjectForValue(aVar, &object); NPError result = InternalGetNPObjectForValue(aVar, &object);
if (result == NPERR_NO_ERROR) { if (result == NPERR_NO_ERROR) {
*((NPObject**)aValue) = object; *((NPObject**)aValue) = object;

View file

@ -7525,7 +7525,8 @@ nsTextFrame::GetCharacterRectsInRange(int32_t aInOffset,
gfxSkipCharsIterator nextIter(iter); gfxSkipCharsIterator nextIter(iter);
nextIter.AdvanceOriginal(1); nextIter.AdvanceOriginal(1);
if (!nextIter.IsOriginalCharSkipped() && if (!nextIter.IsOriginalCharSkipped() &&
!mTextRun->IsClusterStart(nextIter.GetSkippedOffset())) { !mTextRun->IsClusterStart(nextIter.GetSkippedOffset()) &&
nextIter.GetOriginalOffset() < kContentEnd) {
FindClusterEnd(mTextRun, kContentEnd, &nextIter); FindClusterEnd(mTextRun, kContentEnd, &nextIter);
} }

View file

@ -271,6 +271,7 @@ public:
PACResolver() PACResolver()
: mStatus(NS_ERROR_FAILURE) : mStatus(NS_ERROR_FAILURE)
, mMutex("PACResolver::Mutex")
{ {
} }
@ -279,9 +280,15 @@ public:
nsIDNSRecord *record, nsIDNSRecord *record,
nsresult status) override nsresult status) override
{ {
if (mTimer) { nsCOMPtr<nsITimer> timer;
mTimer->Cancel(); {
mTimer = nullptr; MutexAutoLock lock(mMutex);
timer.swap(mTimer);
mRequest = nullptr;
}
if (timer) {
timer->Cancel();
} }
mRequest = nullptr; mRequest = nullptr;
@ -293,9 +300,15 @@ public:
// nsITimerCallback // nsITimerCallback
NS_IMETHOD Notify(nsITimer *timer) override NS_IMETHOD Notify(nsITimer *timer) override
{ {
if (mRequest) nsCOMPtr<nsICancelable> request;
mRequest->Cancel(NS_ERROR_NET_TIMEOUT); {
mTimer = nullptr; MutexAutoLock lock(mMutex);
request.swap(mRequest);
mTimer = nullptr;
}
if (request) {
request->Cancel(NS_ERROR_NET_TIMEOUT);
}
return NS_OK; return NS_OK;
} }
@ -303,6 +316,7 @@ public:
nsCOMPtr<nsICancelable> mRequest; nsCOMPtr<nsICancelable> mRequest;
nsCOMPtr<nsIDNSRecord> mResponse; nsCOMPtr<nsIDNSRecord> mResponse;
nsCOMPtr<nsITimer> mTimer; nsCOMPtr<nsITimer> mTimer;
Mutex mMutex;
private: private:
~PACResolver() {} ~PACResolver() {}

View file

@ -806,7 +806,7 @@ void GetHTMLCharset(guchar * data, int32_t dataLength, nsCString& str)
static void static void
DispatchSelectionNotifyEvent(GtkWidget *widget, XEvent *xevent) DispatchSelectionNotifyEvent(GtkWidget *widget, XEvent *xevent)
{ {
GdkEvent event; GdkEvent event = {};
event.selection.type = GDK_SELECTION_NOTIFY; event.selection.type = GDK_SELECTION_NOTIFY;
event.selection.window = gtk_widget_get_window(widget); event.selection.window = gtk_widget_get_window(widget);
event.selection.selection = gdk_x11_xatom_to_atom(xevent->xselection.selection); event.selection.selection = gdk_x11_xatom_to_atom(xevent->xselection.selection);
@ -822,7 +822,7 @@ DispatchPropertyNotifyEvent(GtkWidget *widget, XEvent *xevent)
{ {
GdkWindow *window = gtk_widget_get_window(widget); GdkWindow *window = gtk_widget_get_window(widget);
if ((gdk_window_get_events(window)) & GDK_PROPERTY_CHANGE_MASK) { if ((gdk_window_get_events(window)) & GDK_PROPERTY_CHANGE_MASK) {
GdkEvent event; GdkEvent event = {};
event.property.type = GDK_PROPERTY_NOTIFY; event.property.type = GDK_PROPERTY_NOTIFY;
event.property.window = window; event.property.window = window;
event.property.atom = gdk_x11_xatom_to_atom(xevent->xproperty.atom); event.property.atom = gdk_x11_xatom_to_atom(xevent->xproperty.atom);