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 {
struct PositionComparator
@ -1422,12 +1437,12 @@ nsDocument::~nsDocument()
delete mSubDocuments;
mSubDocuments = nullptr;
nsAutoScriptBlocker scriptBlocker;
// Destroy link map now so we don't waste time removing
// links one by one
DestroyElementMaps();
nsAutoScriptBlocker scriptBlocker;
for (uint32_t indx = mChildren.ChildCount(); indx-- != 0; ) {
mChildren.ChildAt(indx)->UnbindFromTree();
mChildren.RemoveChildAt(indx);
@ -1972,15 +1987,16 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
delete mSubDocuments;
mSubDocuments = nullptr;
// Destroy link map now so we don't waste time removing
// links one by one
DestroyElementMaps();
bool oldVal = mInUnlinkOrDeletion;
mInUnlinkOrDeletion = true;
uint32_t count = mChildren.ChildCount();
{ // Scope for update
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--) {
nsCOMPtr<nsIContent> content = mChildren.ChildAt(i);
@ -8955,7 +8971,14 @@ nsDocument::DestroyElementMaps()
mStyledLinksCleared = true;
#endif
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();
++mExpandoAndGeneration.generation;
}

View file

@ -216,6 +216,11 @@ public:
void RemoveContentChangeCallback(nsIDocument::IDTargetObserver aCallback,
void* aData, bool aForImage);
/**
* Remove all elements and notify change listeners.
*/
void ClearAndNotify();
void Traverse(nsCycleCollectionTraversalCallback* aCallback);
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:
static const uint32_t TagStackSize = 500;
static const uint32_t OLStackSize = 100;
nsresult
NS_NewPlainTextSerializer(nsIContentSerializer** aSerializer)
@ -100,10 +99,6 @@ nsPlainTextSerializer::nsPlainTextSerializer()
mTagStackIndex = 0;
mIgnoreAboveIndex = (uint32_t)kNotFound;
// initialize the OL stack, where numbers for ordered lists are kept
mOLStack = new int32_t[OLStackSize];
mOLStackIndex = 0;
mULCount = 0;
mIgnoredChildNodeLevel = 0;
@ -112,7 +107,6 @@ nsPlainTextSerializer::nsPlainTextSerializer()
nsPlainTextSerializer::~nsPlainTextSerializer()
{
delete[] mTagStack;
delete[] mOLStack;
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
mFlags &= ~nsIDocumentEncoder::OutputNoFramesContent;
MOZ_ASSERT(mOLStack.IsEmpty());
return NS_OK;
}
@ -438,6 +434,8 @@ nsPlainTextSerializer::AppendDocumentStart(nsIDocument *aDocument,
return NS_OK;
}
int32_t kOlStackDummyValue = 0;
nsresult
nsPlainTextSerializer::DoOpenContainer(nsIAtom* aTag)
{
@ -616,44 +614,45 @@ nsPlainTextSerializer::DoOpenContainer(nsIAtom* aTag)
}
else if (aTag == nsGkAtoms::ul) {
// Indent here to support nested lists, which aren't included in li :-(
EnsureVerticalSpace(mULCount + mOLStackIndex == 0 ? 1 : 0);
// Must end the current line before we change indention
EnsureVerticalSpace(IsInOLOrUL() ? 0 : 1);
// Must end the current line before we change indention
mIndent += kIndentSizeList;
mULCount++;
}
else if (aTag == nsGkAtoms::ol) {
EnsureVerticalSpace(mULCount + mOLStackIndex == 0 ? 1 : 0);
EnsureVerticalSpace(IsInOLOrUL() ? 0 : 1);
if (mFlags & nsIDocumentEncoder::OutputFormatted) {
// Must end the current line before we change indention
if (mOLStackIndex < OLStackSize) {
nsAutoString startAttr;
int32_t startVal = 1;
if (NS_SUCCEEDED(GetAttributeValue(nsGkAtoms::start, startAttr))) {
nsresult rv = NS_OK;
startVal = startAttr.ToInteger(&rv);
if (NS_FAILED(rv))
startVal = 1;
nsAutoString startAttr;
int32_t startVal = 1;
if (NS_SUCCEEDED(GetAttributeValue(nsGkAtoms::start, startAttr))) {
nsresult rv = NS_OK;
startVal = startAttr.ToInteger(&rv);
if (NS_FAILED(rv)) {
startVal = 1;
}
mOLStack[mOLStackIndex++] = startVal;
}
mOLStack.AppendElement(startVal);
} else {
mOLStackIndex++;
mOLStack.AppendElement(kOlStackDummyValue);
}
mIndent += kIndentSizeList; // see ul
}
else if (aTag == nsGkAtoms::li &&
(mFlags & nsIDocumentEncoder::OutputFormatted)) {
if (mTagStackIndex > 1 && IsInOL()) {
if (mOLStackIndex > 0) {
if (!mOLStack.IsEmpty()) {
nsAutoString valueAttr;
if (NS_SUCCEEDED(GetAttributeValue(nsGkAtoms::value, valueAttr))) {
nsresult rv = NS_OK;
int32_t valueAttrVal = valueAttr.ToInteger(&rv);
if (NS_SUCCEEDED(rv))
mOLStack[mOLStackIndex-1] = valueAttrVal;
if (NS_SUCCEEDED(rv)) {
mOLStack.LastElement() = valueAttrVal;
}
}
// This is what nsBulletFrame does for OLs:
mInIndentString.AppendInt(mOLStack[mOLStackIndex-1]++, 10);
mInIndentString.AppendInt(mOLStack.LastElement(), 10);
mOLStack.LastElement()++;
}
else {
mInIndentString.Append(char16_t('#'));
@ -878,7 +877,8 @@ nsPlainTextSerializer::DoCloseContainer(nsIAtom* aTag)
else if (aTag == nsGkAtoms::ul) {
FlushLine();
mIndent -= kIndentSizeList;
if (--mULCount + mOLStackIndex == 0) {
--mULCount;
if (!IsInOLOrUL()) {
mFloatingLines = 1;
mLineBreakDue = true;
}
@ -886,9 +886,9 @@ nsPlainTextSerializer::DoCloseContainer(nsIAtom* aTag)
else if (aTag == nsGkAtoms::ol) {
FlushLine(); // Doing this after decreasing OLStackIndex would be wrong.
mIndent -= kIndentSizeList;
NS_ASSERTION(mOLStackIndex, "Wrong OLStack level!");
mOLStackIndex--;
if (mULCount + mOLStackIndex == 0) {
NS_ASSERTION(!mOLStack.IsEmpty(), "Wrong OLStack level!");
mOLStack.RemoveElementAt(mOLStack.Length() - 1);
if (!IsInOLOrUL()) {
mFloatingLines = 1;
mLineBreakDue = true;
}
@ -1861,6 +1861,10 @@ nsPlainTextSerializer::IsInOL()
return false;
}
bool nsPlainTextSerializer::IsInOLOrUL() const {
return (mULCount > 0) || !mOLStack.IsEmpty();
}
/*
@return 0 = no header, 1 = h1, ..., 6 = h6
*/

View file

@ -81,6 +81,7 @@ private:
void Write(const nsAString& aString);
bool IsInPre();
bool IsInOL();
bool IsInOLOrUL() const;
bool IsCurrentNodeConverted();
bool MustSuppressLeaf();
@ -218,8 +219,7 @@ private:
uint32_t mIgnoreAboveIndex;
// The stack for ordered lists
int32_t *mOLStack;
uint32_t mOLStackIndex;
AutoTArray<int32_t, 100> mOLStack;
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
== global-composite-operation.html global-composite-operation-ref.html
== liveness.html ref.html
== liveness-document-open.html data:text/html,PASS
== multiple-drop-shadows.html shadow-ref.html
== shadow.html shadow-ref.html
== subregion-fill-paint.html subregion-ref.html

View file

@ -310,9 +310,10 @@ PluginInstanceChild::InternalGetNPObjectForValue(NPNVariable aValue,
switch (aValue) {
case NPNVWindowNPObject:
if (!(actor = mCachedWindowActor)) {
result = NPERR_GENERIC_ERROR;
PPluginScriptableObjectChild* actorProtocol;
CallNPN_GetValue_NPNVWindowNPObject(&actorProtocol, &result);
if (result == NPERR_NO_ERROR) {
if (CallNPN_GetValue_NPNVWindowNPObject(&actorProtocol, &result) &&
result == NPERR_NO_ERROR) {
actor = mCachedWindowActor =
static_cast<PluginScriptableObjectChild*>(actorProtocol);
NS_ASSERTION(actor, "Null actor!");
@ -324,10 +325,10 @@ PluginInstanceChild::InternalGetNPObjectForValue(NPNVariable aValue,
case NPNVPluginElementNPObject:
if (!(actor = mCachedElementActor)) {
result = NPERR_GENERIC_ERROR;
PPluginScriptableObjectChild* actorProtocol;
CallNPN_GetValue_NPNVPluginElementNPObject(&actorProtocol,
&result);
if (result == NPERR_NO_ERROR) {
if (CallNPN_GetValue_NPNVPluginElementNPObject(&actorProtocol, &result) &&
result == NPERR_NO_ERROR) {
actor = mCachedElementActor =
static_cast<PluginScriptableObjectChild*>(actorProtocol);
NS_ASSERTION(actor, "Null actor!");
@ -338,6 +339,7 @@ PluginInstanceChild::InternalGetNPObjectForValue(NPNVariable aValue,
break;
default:
result = NPERR_GENERIC_ERROR;
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 NPNVPluginElementNPObject: {
NPObject* object;
*((NPObject**)aValue) = nullptr;
NPError result = InternalGetNPObjectForValue(aVar, &object);
if (result == NPERR_NO_ERROR) {
*((NPObject**)aValue) = object;

View file

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

View file

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

View file

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