LibWeb: Use dimension image source for images
Fixes tiny images on Wikipedia
This commit is contained in:
parent
31cbe2061a
commit
b8f31179b2
5 changed files with 83 additions and 14 deletions
|
|
@ -78,6 +78,7 @@
|
|||
#include <LibWeb/DOM/ShadowRoot.h>
|
||||
#include <LibWeb/HTML/HTMLBRElement.h>
|
||||
#include <LibWeb/HTML/HTMLHtmlElement.h>
|
||||
#include <LibWeb/HTML/HTMLImageElement.h>
|
||||
#include <LibWeb/HTML/HTMLSlotElement.h>
|
||||
#include <LibWeb/HTML/Parser/HTMLParser.h>
|
||||
#include <LibWeb/Layout/Node.h>
|
||||
|
|
@ -1274,8 +1275,11 @@ GC::Ref<CascadedProperties> StyleComputer::compute_cascaded_values(DOM::Abstract
|
|||
auto& element = abstract_element.element();
|
||||
element.apply_presentational_hints(cascaded_properties);
|
||||
if (element.supports_dimension_attributes()) {
|
||||
apply_dimension_attribute(cascaded_properties, element, HTML::AttributeNames::width, CSS::PropertyID::Width);
|
||||
apply_dimension_attribute(cascaded_properties, element, HTML::AttributeNames::height, CSS::PropertyID::Height);
|
||||
auto const& dimension_source = is<HTML::HTMLImageElement>(element)
|
||||
? static_cast<HTML::HTMLImageElement const&>(element).dimension_attribute_source()
|
||||
: element;
|
||||
apply_dimension_attribute(cascaded_properties, dimension_source, HTML::AttributeNames::width, CSS::PropertyID::Width);
|
||||
apply_dimension_attribute(cascaded_properties, dimension_source, HTML::AttributeNames::height, CSS::PropertyID::Height);
|
||||
}
|
||||
|
||||
// SVG presentation attributes are parsed as CSS values, so we need to handle potential custom properties here.
|
||||
|
|
|
|||
|
|
@ -102,9 +102,26 @@ void HTMLImageElement::visit_edges(Cell::Visitor& visitor)
|
|||
visitor.visit(m_current_request);
|
||||
visitor.visit(m_pending_request);
|
||||
visitor.visit(m_document_observer);
|
||||
visitor.visit(m_dimension_attribute_source);
|
||||
visit_lazy_loading_element(visitor);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/embedded-content.html#concept-img-dimension-attribute-source
|
||||
DOM::Element const& HTMLImageElement::dimension_attribute_source() const
|
||||
{
|
||||
if (m_dimension_attribute_source)
|
||||
return *m_dimension_attribute_source;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void HTMLImageElement::set_dimension_attribute_source(DOM::Element const* source)
|
||||
{
|
||||
if (m_dimension_attribute_source.ptr() != source) {
|
||||
m_dimension_attribute_source = source;
|
||||
set_needs_style_update(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool HTMLImageElement::is_presentational_hint(FlyString const& name) const
|
||||
{
|
||||
if (Base::is_presentational_hint(name))
|
||||
|
|
@ -1290,25 +1307,22 @@ static void update_the_source_set(DOM::Element& element)
|
|||
// 8. If child has a type attribute, and its value is an unknown or unsupported MIME type, continue to the next child.
|
||||
if (child->has_attribute(HTML::AttributeNames::type)) {
|
||||
auto mime_type = child->get_attribute_value(HTML::AttributeNames::type);
|
||||
if (is<HTMLImageElement>(element)) {
|
||||
if (!is_supported_image_type(mime_type))
|
||||
continue;
|
||||
}
|
||||
|
||||
// FIXME: Implement this step for link elements
|
||||
if (!is_supported_image_type(mime_type))
|
||||
continue;
|
||||
}
|
||||
|
||||
// FIXME: 9. If child has width or height attributes, set el's dimension attribute source to child.
|
||||
// Otherwise, set el's dimension attribute source to el.
|
||||
// 9. If child has width or height attributes, set el's dimension attribute source to child.
|
||||
// Otherwise, set el's dimension attribute source to el.
|
||||
if (child->has_attribute(HTML::AttributeNames::width) || child->has_attribute(HTML::AttributeNames::height))
|
||||
img->set_dimension_attribute_source(child);
|
||||
else
|
||||
img->set_dimension_attribute_source(nullptr);
|
||||
|
||||
// 10. Normalize the source densities of source set.
|
||||
source_set.normalize_source_densities(element);
|
||||
|
||||
// 11. Set el's source set to source set.
|
||||
if (auto* image_element = as_if<HTMLImageElement>(element))
|
||||
image_element->set_source_set(move(source_set));
|
||||
else if (is<HTMLLinkElement>(element))
|
||||
TODO();
|
||||
img->set_source_set(move(source_set));
|
||||
|
||||
// 12. Return.
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -92,6 +92,10 @@ public:
|
|||
|
||||
void set_source_set(SourceSet);
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-element:dimension-attribute-source
|
||||
DOM::Element const& dimension_attribute_source() const;
|
||||
void set_dimension_attribute_source(DOM::Element const*);
|
||||
|
||||
ImageRequest& current_request() { return *m_current_request; }
|
||||
ImageRequest const& current_request() const { return *m_current_request; }
|
||||
|
||||
|
|
@ -168,6 +172,10 @@ private:
|
|||
|
||||
CSSPixelSize m_last_seen_viewport_size;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-element:dimension-attribute-source
|
||||
// Each img element has a dimension attribute source, which must initially be the img element itself.
|
||||
GC::Ptr<DOM::Element const> m_dimension_attribute_source;
|
||||
|
||||
u64 m_update_the_image_data_count { 0 };
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
with source dimensions: 200x100
|
||||
without source dimensions: 50x50
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../include.js"></script>
|
||||
<script>
|
||||
asyncTest((done) => {
|
||||
const picture = document.createElement("picture");
|
||||
const source = document.createElement("source");
|
||||
source.media = "(min-width: 1px)";
|
||||
source.srcset = "../../../Assets/120.png";
|
||||
source.width = 200;
|
||||
source.height = 100;
|
||||
const img = document.createElement("img");
|
||||
img.src = "../../../Assets/120.png";
|
||||
img.width = 25;
|
||||
img.height = 25;
|
||||
picture.appendChild(source);
|
||||
picture.appendChild(img);
|
||||
document.body.appendChild(picture);
|
||||
img.onload = function() {
|
||||
println("with source dimensions: " + img.clientWidth + "x" + img.clientHeight);
|
||||
picture.remove();
|
||||
|
||||
// Test without source dimensions (should use img dimensions)
|
||||
const picture2 = document.createElement("picture");
|
||||
const source2 = document.createElement("source");
|
||||
source2.media = "(min-width: 1px)";
|
||||
source2.srcset = "../../../Assets/120.png";
|
||||
const img2 = document.createElement("img");
|
||||
img2.src = "../../../Assets/120.png";
|
||||
img2.width = 50;
|
||||
img2.height = 50;
|
||||
picture2.appendChild(source2);
|
||||
picture2.appendChild(img2);
|
||||
document.body.appendChild(picture2);
|
||||
img2.onload = function() {
|
||||
println("without source dimensions: " + img2.clientWidth + "x" + img2.clientHeight);
|
||||
picture2.remove();
|
||||
done();
|
||||
};
|
||||
};
|
||||
});
|
||||
</script>
|
||||
Loading…
Reference in a new issue