Bug 1431000 - Introduce nsINode::InsertChildBefore, r=catalinb

This commit is contained in:
Andrea Marchesini 2018-01-25 15:59:42 +01:00
Родитель 2ff99faa2d
Коммит 35c2c8122a
21 изменённых файлов: 212 добавлений и 1 удалений

Просмотреть файл

@ -284,6 +284,13 @@ Attr::ComputeIndexOf(const nsINode* aPossibleChild) const
return -1;
}
nsresult
Attr::InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
Attr::InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify)

Просмотреть файл

@ -64,6 +64,8 @@ public:
virtual uint32_t GetChildCount() const override;
virtual nsIContent *GetChildAt_Deprecated(uint32_t aIndex) const override;
virtual int32_t ComputeIndexOf(const nsINode* aPossibleChild) const override;
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) override;
virtual nsresult InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify) override;
virtual void RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify) override;

Просмотреть файл

@ -1156,6 +1156,19 @@ nsIContent::SetXBLInsertionPoint(nsIContent* aContent)
}
}
nsresult
FragmentOrElement::InsertChildBefore(nsIContent* aKid,
nsIContent* aBeforeThis,
bool aNotify)
{
NS_PRECONDITION(aKid, "null ptr");
int32_t index = aBeforeThis ? ComputeIndexOf(aBeforeThis) : GetChildCount();
MOZ_ASSERT(index >= 0);
return doInsertChildAt(aKid, index, aNotify, mAttrsAndChildren);
}
nsresult
FragmentOrElement::InsertChildAt_Deprecated(nsIContent* aKid,
uint32_t aIndex,

Просмотреть файл

@ -120,6 +120,8 @@ public:
virtual uint32_t GetChildCount() const override;
virtual nsIContent *GetChildAt_Deprecated(uint32_t aIndex) const override;
virtual int32_t ComputeIndexOf(const nsINode* aPossibleChild) const override;
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) override;
virtual nsresult InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify) override;
virtual void RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify) override;

Просмотреть файл

@ -4363,6 +4363,21 @@ nsDocument::GetChildCount() const
return mChildren.ChildCount();
}
nsresult
nsDocument::InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify)
{
if (aKid->IsElement() && GetRootElement()) {
NS_WARNING("Inserting root element when we already have one");
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
int32_t index = aBeforeThis ? ComputeIndexOf(aBeforeThis) : GetChildCount();
MOZ_ASSERT(index >= 0);
return doInsertChildAt(aKid, index, aNotify, mChildren);
}
nsresult
nsDocument::InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify)

Просмотреть файл

@ -557,6 +557,8 @@ public:
virtual nsIContent *GetChildAt_Deprecated(uint32_t aIndex) const override;
virtual int32_t ComputeIndexOf(const nsINode* aPossibleChild) const override;
virtual uint32_t GetChildCount() const override;
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) override;
virtual nsresult InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify) override;
virtual void RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify) override;

Просмотреть файл

@ -651,6 +651,14 @@ nsGenericDOMDataNode::ComputeIndexOf(const nsINode* aPossibleChild) const
return -1;
}
nsresult
nsGenericDOMDataNode::InsertChildBefore(nsIContent* aKid,
nsIContent* aBeforeThis,
bool aNotify)
{
return NS_OK;
}
nsresult
nsGenericDOMDataNode::InsertChildAt_Deprecated(nsIContent* aKid,
uint32_t aIndex,

Просмотреть файл

@ -107,6 +107,8 @@ public:
virtual uint32_t GetChildCount() const override;
virtual nsIContent *GetChildAt_Deprecated(uint32_t aIndex) const override;
virtual int32_t ComputeIndexOf(const nsINode* aPossibleChild) const override;
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) override;
virtual nsresult InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify) override;
virtual void RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify) override;

Просмотреть файл

@ -717,6 +717,29 @@ public:
return isShadowRoot;
}
/**
* Insert a content node before another or at the end.
* This method handles calling BindToTree on the child appropriately.
*
* @param aKid the content to insert
* @param aBeforeThis an existing node. Use nullptr if you want to
* add aKid at the end.
* @param aNotify whether to notify the document (current document for
* nsIContent, and |this| for nsIDocument) that the insert has
* occurred
*
* @throws NS_ERROR_DOM_HIERARCHY_REQUEST_ERR if one attempts to have more
* than one element node as a child of a document. Doing this will also
* assert -- you shouldn't be doing it! Check with
* nsIDocument::GetRootElement() first if you're not sure. Apart from this
* one constraint, this doesn't do any checking on whether aKid is a valid
* child of |this|.
*
* @throws NS_ERROR_OUT_OF_MEMORY in some cases (from BindToTree).
*/
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) = 0;
/**
* Insert a content node at a particular index. This method handles calling
* BindToTree on the child appropriately.

Просмотреть файл

@ -139,6 +139,39 @@ HTMLFieldSetElement::SubmitNamesValues(HTMLFormSubmission* aFormSubmission)
return NS_OK;
}
nsresult
HTMLFieldSetElement::InsertChildBefore(nsIContent* aChild,
nsIContent* aBeforeThis,
bool aNotify)
{
bool firstLegendHasChanged = false;
if (aChild->IsHTMLElement(nsGkAtoms::legend)) {
if (!mFirstLegend) {
mFirstLegend = aChild;
// We do not want to notify the first time mFirstElement is set.
} else {
// If mFirstLegend is before aIndex, we do not change it.
// Otherwise, mFirstLegend is now aChild.
int32_t index = aBeforeThis ? ComputeIndexOf(aBeforeThis) : GetChildCount();
if (index <= ComputeIndexOf(mFirstLegend)) {
mFirstLegend = aChild;
firstLegendHasChanged = true;
}
}
}
nsresult rv =
nsGenericHTMLFormElement::InsertChildBefore(aChild, aBeforeThis, aNotify);
NS_ENSURE_SUCCESS(rv, rv);
if (firstLegendHasChanged) {
NotifyElementsForFirstLegendChange(aNotify);
}
return rv;
}
nsresult
HTMLFieldSetElement::InsertChildAt_Deprecated(nsIContent* aChild,
uint32_t aIndex,

Просмотреть файл

@ -41,6 +41,8 @@ public:
nsIPrincipal* aSubjectPrincipal,
bool aNotify) override;
virtual nsresult InsertChildBefore(nsIContent* aChild, nsIContent* aBeforeThis,
bool aNotify) override;
virtual nsresult InsertChildAt_Deprecated(nsIContent* aChild, uint32_t aIndex,
bool aNotify) override;
virtual void RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify) override;

Просмотреть файл

@ -74,6 +74,21 @@ HTMLOptGroupElement::GetSelect()
return parent;
}
nsresult
HTMLOptGroupElement::InsertChildBefore(nsIContent* aKid,
nsIContent* aBeforeThis,
bool aNotify)
{
int32_t index = aBeforeThis ? ComputeIndexOf(aBeforeThis) : GetChildCount();
SafeOptionListMutation safeMutation(GetSelect(), this, aKid, index, aNotify);
nsresult rv =
nsGenericHTMLElement::InsertChildBefore(aKid, aBeforeThis, aNotify);
if (NS_FAILED(rv)) {
safeMutation.MutationFailed();
}
return rv;
}
nsresult
HTMLOptGroupElement::InsertChildAt_Deprecated(nsIContent* aKid,
uint32_t aIndex,

Просмотреть файл

@ -25,6 +25,8 @@ public:
NS_DECL_ISUPPORTS_INHERITED
// nsINode
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) override;
virtual nsresult InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify) override;
virtual void RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify) override;

Просмотреть файл

@ -82,6 +82,37 @@ HTMLPictureElement::RemoveChildNode(nsIContent* aKid, bool aNotify)
nsGenericHTMLElement::RemoveChildNode(aKid, aNotify);
}
nsresult
HTMLPictureElement::InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify)
{
nsresult rv =
nsGenericHTMLElement::InsertChildBefore(aKid, aBeforeThis, aNotify);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(aKid, rv);
if (aKid->IsHTMLElement(nsGkAtoms::img)) {
HTMLImageElement* img = HTMLImageElement::FromContent(aKid);
if (img) {
img->PictureSourceAdded(aKid->AsContent());
}
} else if (aKid->IsHTMLElement(nsGkAtoms::source)) {
// Find all img siblings after this <source> to notify them of its insertion
nsCOMPtr<nsIContent> nextSibling = aKid->GetNextSibling();
if (nextSibling && nextSibling->GetParentNode() == this) {
do {
HTMLImageElement* img = HTMLImageElement::FromContent(nextSibling);
if (img) {
img->PictureSourceAdded(aKid->AsContent());
}
} while ( (nextSibling = nextSibling->GetNextSibling()) );
}
}
return rv;
}
nsresult
HTMLPictureElement::InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex, bool aNotify)
{

Просмотреть файл

@ -25,7 +25,10 @@ public:
bool aPreallocateChildren) const override;
virtual void RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify) override;
virtual void RemoveChildNode(nsIContent* aKid, bool aNotify) override;
virtual nsresult InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex, bool aNotify) override;
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) override;
virtual nsresult InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify) override;
protected:
virtual ~HTMLPictureElement();

Просмотреть файл

@ -203,6 +203,22 @@ HTMLSelectElement::GetAutocompleteInfo(AutocompleteInfo& aInfo)
true);
}
nsresult
HTMLSelectElement::InsertChildBefore(nsIContent* aKid,
nsIContent* aBeforeThis,
bool aNotify)
{
int32_t index = aBeforeThis ? ComputeIndexOf(aBeforeThis) : GetChildCount();
SafeOptionListMutation safeMutation(this, this, aKid, index, aNotify);
nsresult rv =
nsGenericHTMLFormElementWithState::InsertChildBefore(aKid, aBeforeThis,
aNotify);
if (NS_FAILED(rv)) {
safeMutation.MutationFailed();
}
return rv;
}
nsresult
HTMLSelectElement::InsertChildAt_Deprecated(nsIContent* aKid,
uint32_t aIndex,

Просмотреть файл

@ -291,6 +291,8 @@ public:
EventChainPostVisitor& aVisitor) override;
virtual bool IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable, int32_t* aTabIndex) override;
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) override;
virtual nsresult InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify) override;
virtual void RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify) override;

Просмотреть файл

@ -34,6 +34,23 @@ namespace dom {
//----------------------------------------------------------------------
// nsISupports methods:
nsresult
SVGDocument::InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify)
{
if (aKid->IsElement() && !aKid->IsSVGElement()) {
// We can get here when well formed XML with a non-SVG root element is
// served with the SVG MIME type, for example. In that case we need to load
// the non-SVG UA sheets or else we can get bugs like bug 1016145. Note
// that we have to do this _before_ the XMLDocument::InsertChildBefore,
// since that can try to construct frames, and we need to have the sheets
// loaded by then.
EnsureNonSVGUserAgentStyleSheetsLoaded();
}
return XMLDocument::InsertChildBefore(aKid, aBeforeThis, aNotify);
}
nsresult
SVGDocument::InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify)

Просмотреть файл

@ -29,6 +29,8 @@ public:
mType = eSVG;
}
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) override;
virtual nsresult InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify) override;
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,

Просмотреть файл

@ -81,6 +81,18 @@ NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGSwitchElement)
//----------------------------------------------------------------------
// nsINode methods
nsresult
SVGSwitchElement::InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify)
{
nsresult rv =
SVGSwitchElementBase::InsertChildBefore(aKid, aBeforeThis, aNotify);
if (NS_SUCCEEDED(rv)) {
MaybeInvalidate();
}
return rv;
}
nsresult
SVGSwitchElement::InsertChildAt_Deprecated(nsIContent* aKid,
uint32_t aIndex,

Просмотреть файл

@ -40,6 +40,8 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SVGSwitchElement,
SVGSwitchElementBase)
// nsINode
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) override;
virtual nsresult InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify) override;
virtual void RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify) override;