gecko-dev/dom/html/HTMLPictureElement.cpp
Boris Chiou 3897893bd1 Bug 1694741 - Part 6: Map width/height attributes to the style of img elements. r=emilio
This patch will use the width/height attributes from <source> to override
width/height/aspect-ratio CSS property values of <img> elements.

So basically, we need to introduce an extra nsMappedAttribtue member in
HTMLSourceElement (and it only stores width and height attributes).
And then we use it as an extra declarations (which are generated by
Gecko_GetExtraContentStyleDeclarations()) so we can override the
declarations created from presentation attributes of <img>.

Besides, we need to make sure <img> elements get restyled in the
following cases:
1. width/height attributes is changed in <source> elements
2. <source> is inserted as a <picture>'s child
3. <source> is removed from the child list of <picture>
4. <img> is inserted as a <picture>'s child
5. <img> is removed from the child list of <picture>

We make the responsive source synchronously get updated in the previous patch,
so now we can just restyle the image when updating its responsive source.

Note: We fix the reflection of percentages for width/height attributes in
the next patch.

Differential Revision: https://phabricator.services.mozilla.com/D152586
2022-08-22 20:18:39 +00:00

80 lines
2.9 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/HTMLPictureElement.h"
#include "mozilla/dom/HTMLPictureElementBinding.h"
#include "mozilla/dom/HTMLImageElement.h"
#include "mozilla/dom/HTMLSourceElement.h"
// Expand NS_IMPL_NS_NEW_HTML_ELEMENT(Picture) to add pref check.
nsGenericHTMLElement* NS_NewHTMLPictureElement(
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
mozilla::dom::FromParser aFromParser) {
RefPtr<mozilla::dom::NodeInfo> nodeInfo(aNodeInfo);
auto* nim = nodeInfo->NodeInfoManager();
return new (nim) mozilla::dom::HTMLPictureElement(nodeInfo.forget());
}
namespace mozilla::dom {
HTMLPictureElement::HTMLPictureElement(
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
: nsGenericHTMLElement(std::move(aNodeInfo)) {}
HTMLPictureElement::~HTMLPictureElement() = default;
NS_IMPL_ELEMENT_CLONE(HTMLPictureElement)
void HTMLPictureElement::RemoveChildNode(nsIContent* aKid, bool aNotify) {
MOZ_ASSERT(aKid);
if (auto* img = HTMLImageElement::FromNode(aKid)) {
img->PictureSourceRemoved();
} else if (auto* source = HTMLSourceElement::FromNode(aKid)) {
// Find all img siblings after this <source> to notify them of its demise
nsCOMPtr<nsIContent> nextSibling = source->GetNextSibling();
if (nextSibling && nextSibling->GetParentNode() == this) {
do {
if (auto* img = HTMLImageElement::FromNode(nextSibling)) {
img->PictureSourceRemoved(source);
}
} while ((nextSibling = nextSibling->GetNextSibling()));
}
}
nsGenericHTMLElement::RemoveChildNode(aKid, aNotify);
}
void HTMLPictureElement::InsertChildBefore(nsIContent* aKid,
nsIContent* aBeforeThis,
bool aNotify, ErrorResult& aRv) {
nsGenericHTMLElement::InsertChildBefore(aKid, aBeforeThis, aNotify, aRv);
if (aRv.Failed() || !aKid) {
return;
}
if (auto* img = HTMLImageElement::FromNode(aKid)) {
img->PictureSourceAdded();
} else if (auto* source = HTMLSourceElement::FromNode(aKid)) {
// Find all img siblings after this <source> to notify them of its insertion
nsCOMPtr<nsIContent> nextSibling = source->GetNextSibling();
if (nextSibling && nextSibling->GetParentNode() == this) {
do {
if (auto* img = HTMLImageElement::FromNode(nextSibling)) {
img->PictureSourceAdded(source);
}
} while ((nextSibling = nextSibling->GetNextSibling()));
}
}
}
JSObject* HTMLPictureElement::WrapNode(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return HTMLPictureElement_Binding::Wrap(aCx, this, aGivenProto);
}
} // namespace mozilla::dom