Skip to content

Commit 69749b0

Browse files
trflynn89awesomekling
authored andcommitted
LibWeb: Begin supporting non-image HTMLObjectElement data representation
We currently only supported loading image data from an HTMLObjectElement node. This adds (some) support for non-image data. A big FIXME is to actually paint that data. We will need to make FrameBox and NestedBrowsingContextPaintable work with HTMLObjectElement for this (they currently only work with HTMLIFrameElement).
1 parent f733385 commit 69749b0

File tree

2 files changed

+52
-19
lines changed

2 files changed

+52
-19
lines changed

Userland/Libraries/LibWeb/HTML/HTMLObjectElement.cpp

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@
1515
namespace Web::HTML {
1616

1717
HTMLObjectElement::HTMLObjectElement(DOM::Document& document, DOM::QualifiedName qualified_name)
18-
: HTMLElement(document, move(qualified_name))
18+
: BrowsingContextContainer(document, move(qualified_name))
1919
{
2020
}
2121

2222
HTMLObjectElement::~HTMLObjectElement() = default;
2323

2424
void HTMLObjectElement::parse_attribute(const FlyString& name, const String& value)
2525
{
26-
HTMLElement::parse_attribute(name, value);
26+
BrowsingContextContainer::parse_attribute(name, value);
2727

2828
if (name == HTML::AttributeNames::data)
2929
queue_element_task_to_run_object_representation_steps();
@@ -38,10 +38,20 @@ String HTMLObjectElement::data() const
3838

3939
RefPtr<Layout::Node> HTMLObjectElement::create_layout_node(NonnullRefPtr<CSS::StyleProperties> style)
4040
{
41-
if (m_should_show_fallback_content)
42-
return HTMLElement::create_layout_node(move(style));
43-
if (m_image_loader.has_value() && m_image_loader->has_image())
44-
return adopt_ref(*new Layout::ImageBox(document(), *this, move(style), *m_image_loader));
41+
switch (m_representation) {
42+
case Representation::Children:
43+
return BrowsingContextContainer::create_layout_node(move(style));
44+
case Representation::NestedBrowsingContext:
45+
// FIXME: Actually paint the nested browsing context's document, similar to how iframes are painted with FrameBox and NestedBrowsingContextPaintable.
46+
return nullptr;
47+
case Representation::Image:
48+
if (m_image_loader.has_value() && m_image_loader->has_image())
49+
return adopt_ref(*new Layout::ImageBox(document(), *this, move(style), *m_image_loader));
50+
break;
51+
default:
52+
break;
53+
}
54+
4555
return nullptr;
4656
}
4757

@@ -161,17 +171,31 @@ void HTMLObjectElement::run_object_representation_handler_steps(StringView resou
161171
// If plugins are being sandboxed, then jump to the step below labeled fallback.
162172
// Otherwise, the user agent should use the plugin that supports resource type and pass the content of the resource to that plugin. If the plugin reports an error, then jump to the step below labeled fallback.
163173

164-
// * FIXME: If the resource type is an XML MIME type, or if the resource type does not start with "image/"
165-
// If the object element's nested browsing context is null, then create a new nested browsing context for the element.
166-
// If the URL of the given resource does not match about:blank, then navigate the element's nested browsing context to that resource, with historyHandling set to "replace" and the source browsing context set to the object element's node document's browsing context. (The data attribute of the object element doesn't get updated if the browsing context gets further navigated to other locations.)
167-
// The object element represents its nested browsing context.
174+
// * If the resource type is an XML MIME type, or if the resource type does not start with "image/"
175+
// FIXME: Handle XML MIME types.
176+
if (!resource_type.starts_with("image/"sv)) {
177+
// If the object element's nested browsing context is null, then create a new nested browsing context for the element.
178+
if (!m_nested_browsing_context)
179+
create_new_nested_browsing_context();
180+
181+
// If the URL of the given resource does not match about:blank, then navigate the element's nested browsing context to that resource, with historyHandling set to "replace" and the source browsing context set to the object element's node document's browsing context. (The data attribute of the object element doesn't get updated if the browsing context gets further navigated to other locations.)
182+
if (auto const& url = resource()->url(); url != "about:blank"sv)
183+
m_nested_browsing_context->loader().load(url, FrameLoader::Type::IFrame);
184+
185+
// The object element represents its nested browsing context.
186+
m_representation = Representation::NestedBrowsingContext;
187+
run_object_representation_completed_steps();
188+
}
168189

169190
// * If the resource type starts with "image/", and support for images has not been disabled
170-
if (resource_type.starts_with("image/"sv)) {
191+
// FIXME: Handle disabling image support.
192+
else if (resource_type.starts_with("image/"sv)) {
171193
// FIXME: If the object element's nested browsing context is non-null, then it must be discarded and then set to null.
172194

173195
// Apply the image sniffing rules to determine the type of the image.
174196
// The object element represents the specified image.
197+
m_representation = Representation::Image;
198+
175199
// If the image cannot be rendered, e.g. because it is malformed or in an unsupported format, jump to the step below labeled fallback.
176200
if (!resource()->has_encoded_data())
177201
return run_object_representation_fallback_steps();
@@ -191,11 +215,12 @@ void HTMLObjectElement::run_object_representation_completed_steps()
191215
{
192216
// 4.10. The element's contents are not part of what the object element represents.
193217
// 4.11. If the object element does not represent its nested browsing context, then once the resource is completely loaded, queue an element task on the DOM manipulation task source given the object element to fire an event named load at the element.
194-
queue_an_element_task(HTML::Task::Source::DOMManipulation, [&]() {
195-
dispatch_event(DOM::Event::create(HTML::EventNames::load));
196-
});
218+
if (m_representation != Representation::NestedBrowsingContext) {
219+
queue_an_element_task(HTML::Task::Source::DOMManipulation, [&]() {
220+
dispatch_event(DOM::Event::create(HTML::EventNames::load));
221+
});
222+
}
197223

198-
m_should_show_fallback_content = false;
199224
update_layout_and_child_objects();
200225

201226
// 4.12. Return.
@@ -205,7 +230,7 @@ void HTMLObjectElement::run_object_representation_completed_steps()
205230
void HTMLObjectElement::run_object_representation_fallback_steps()
206231
{
207232
// 6. Fallback: The object element represents the element's children, ignoring any leading param element children. This is the element's fallback content. If the element has an instantiated plugin, then unload it. If the element's nested browsing context is non-null, then it must be discarded and then set to null.
208-
m_should_show_fallback_content = true;
233+
m_representation = Representation::Children;
209234
update_layout_and_child_objects();
210235
}
211236

Userland/Libraries/LibWeb/HTML/HTMLObjectElement.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,25 @@
88

99
#include <LibCore/Forward.h>
1010
#include <LibGfx/Forward.h>
11+
#include <LibWeb/HTML/BrowsingContextContainer.h>
1112
#include <LibWeb/HTML/FormAssociatedElement.h>
1213
#include <LibWeb/HTML/HTMLElement.h>
1314
#include <LibWeb/Loader/ImageLoader.h>
1415

1516
namespace Web::HTML {
1617

1718
class HTMLObjectElement final
18-
: public HTMLElement
19+
: public BrowsingContextContainer
1920
, public FormAssociatedElement
2021
, public ResourceClient {
21-
FORM_ASSOCIATED_ELEMENT(HTMLElement, HTMLObjectElement)
22+
FORM_ASSOCIATED_ELEMENT(BrowsingContextContainer, HTMLObjectElement)
23+
24+
enum class Representation {
25+
Unknown,
26+
Image,
27+
NestedBrowsingContext,
28+
Children,
29+
};
2230

2331
public:
2432
using WrapperType = Bindings::HTMLObjectElementWrapper;
@@ -52,8 +60,8 @@ class HTMLObjectElement final
5260
virtual void resource_did_load() override;
5361
virtual void resource_did_fail() override;
5462

63+
Representation m_representation { Representation::Unknown };
5564
Optional<ImageLoader> m_image_loader;
56-
bool m_should_show_fallback_content { false };
5765
};
5866

5967
}

0 commit comments

Comments
 (0)