Update identifier map entries and notify if they get removed.

This commit is contained in:
Fedor 2019-12-25 15:47:36 +03:00
parent 5ded7266d9
commit b630797d1e
4 changed files with 81 additions and 6 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

@ -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