Bug 1374999 - stylo: Iterate over manually created editor NAC. r?bholley
MozReview-Commit-ID: 1CiWVfYbxaJ
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -10263,16 +10263,22 @@ nsContentUtils::AppendNativeAnonymousChi
AutoTArray<nsIFrame::OwnedAnonBox, 8> ownedAnonBoxes;
primaryFrame->AppendOwnedAnonBoxes(ownedAnonBoxes);
for (nsIFrame::OwnedAnonBox& box : ownedAnonBoxes) {
MOZ_ASSERT(box.mAnonBoxFrame->GetContent() == aContent);
AppendNativeAnonymousChildrenFromFrame(box.mAnonBoxFrame, aKids, aFlags);
}
}
+ // Get manually created NAC (editor resize handles, etc.).
+ if (auto nac = static_cast<ManualNAC*>(
+ aContent->GetProperty(nsGkAtoms::manualNACProperty))) {
+ aKids.AppendElements(*nac);
+ }
+
// The root scroll frame is not the primary frame of the root element.
// Detect and handle this case.
if (!(aFlags & nsIContent::eSkipDocumentLevelNativeAnonymousContent) &&
aContent == aContent->OwnerDoc()->GetRootElement()) {
AppendDocumentLevelNativeAnonymousContentTo(aContent->OwnerDoc(), aKids);
}
}
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -190,16 +190,22 @@ struct EventNameMapping
// True if mAtom is possibly used by special SVG/SMIL events, but
// mMessage is eUnidentifiedEvent. See EventNameList.h
bool mMaybeSpecialSVGorSMILEvent;
};
typedef bool (*CallOnRemoteChildFunction) (mozilla::dom::TabParent* aTabParent,
void* aArg);
+namespace mozilla {
+// 16 seems to be the maximum number of manual NAC nodes that editor
+// creates for a given element.
+typedef AutoTArray<mozilla::dom::Element*,16> ManualNAC;
+}
+
class nsContentUtils
{
friend class nsAutoScriptBlockerSuppressNodeRemoved;
typedef mozilla::dom::Element Element;
typedef mozilla::TimeDuration TimeDuration;
public:
static nsresult Init();
--- a/dom/base/nsGkAtomList.h
+++ b/dom/base/nsGkAtomList.h
@@ -2156,16 +2156,17 @@ GK_ATOM(transitionsOfBeforeProperty, "Tr
GK_ATOM(transitionsOfAfterProperty, "TransitionsOfAfterProperty") // FrameTransitions*
GK_ATOM(genConInitializerProperty, "QuoteNodeProperty")
GK_ATOM(labelMouseDownPtProperty, "LabelMouseDownPtProperty")
GK_ATOM(lockedStyleStates, "lockedStyleStates")
GK_ATOM(apzCallbackTransform, "apzCallbackTransform")
GK_ATOM(restylableAnonymousNode, "restylableAnonymousNode")
GK_ATOM(paintRequestTime, "PaintRequestTime")
GK_ATOM(pseudoProperty, "PseudoProperty") // CSSPseudoElementType
+GK_ATOM(manualNACProperty, "ManualNACProperty") // ManualNAC*
// Languages for lang-specific transforms
GK_ATOM(Japanese, "ja")
GK_ATOM(Chinese, "zh-CN")
GK_ATOM(Taiwanese, "zh-TW")
GK_ATOM(HongKongChinese, "zh-HK")
GK_ATOM(Unicode, "x-unicode")
--- a/editor/libeditor/HTMLAnonymousNodeEditor.cpp
+++ b/editor/libeditor/HTMLAnonymousNodeEditor.cpp
@@ -221,16 +221,26 @@ HTMLEditor::CreateAnonymousElement(nsIAt
nsresult rv =
newContent->BindToTree(doc, parentContent, parentContent, true);
if (NS_FAILED(rv)) {
newContent->UnbindFromTree();
return nullptr;
}
}
+ // Record the NAC on the element, so that AllChildrenIterator can find it.
+ auto nac = static_cast<ManualNAC*>(
+ parentContent->GetProperty(nsGkAtoms::manualNACProperty));
+ if (!nac) {
+ nac = new ManualNAC();
+ parentContent->SetProperty(nsGkAtoms::manualNACProperty, nac,
+ nsINode::DeleteProperty<ManualNAC>);
+ }
+ nac->AppendElement(newContent);
+
ElementDeletionObserver* observer =
new ElementDeletionObserver(newContent, parentContent);
NS_ADDREF(observer); // NodeWillBeDestroyed releases.
parentContent->AddMutationObserver(observer);
newContent->AddMutationObserver(observer);
#ifdef DEBUG
// Editor anonymous content gets passed to PostRecreateFramesFor... which
@@ -298,16 +308,26 @@ HTMLEditor::DeleteRefToAnonymousNode(nsI
docObserver->ContentRemoved(aContent->GetComposedDoc(),
aParentContent, aContent, -1,
aContent->GetPreviousSibling());
if (document) {
docObserver->EndUpdate(document, UPDATE_CONTENT_MODEL);
}
}
}
+
+ // Remove reference from the parent element.
+ auto nac = static_cast<mozilla::ManualNAC*>(
+ aParentContent->GetProperty(nsGkAtoms::manualNACProperty));
+ MOZ_ASSERT(nac);
+ nac->RemoveElement(aContent);
+ if (nac->IsEmpty()) {
+ aParentContent->DeleteProperty(nsGkAtoms::manualNACProperty);
+ }
+
aContent->UnbindFromTree();
}
// The following method is mostly called by a selection listener. When a
// selection change is notified, the method is called to check if resizing
// handles, a grabber and/or inline table editing UI need to be displayed
// or refreshed
NS_IMETHODIMP