LibHTML: Add ResourceLoader to support protocol-agnostic URL loading
We now support loading both file:// and http:// URLs. Feel free to visit http://www.serenityos.org/ and enjoy the fancy good times. :^)
This commit is contained in:
parent
3fdc595e0c
commit
3be6d1aff0
Notes:
sideshowbarker
2024-07-19 11:45:12 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/3be6d1aff0b
6 changed files with 89 additions and 18 deletions
|
@ -23,6 +23,7 @@ h1 {
|
||||||
<li><a href="images.html">images</a></li>
|
<li><a href="images.html">images</a></li>
|
||||||
<li><a href="selectors.html">selectors</a></li>
|
<li><a href="selectors.html">selectors</a></li>
|
||||||
<li><a href="link.html">link element</a></li>
|
<li><a href="link.html">link element</a></li>
|
||||||
|
<li><a href="http://www.serenityos.org/">www.serenityos.org</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
|
#include <LibDraw/PNGLoader.h>
|
||||||
#include <LibHTML/CSS/StyleResolver.h>
|
#include <LibHTML/CSS/StyleResolver.h>
|
||||||
#include <LibHTML/DOM/Document.h>
|
#include <LibHTML/DOM/Document.h>
|
||||||
#include <LibHTML/DOM/HTMLImageElement.h>
|
#include <LibHTML/DOM/HTMLImageElement.h>
|
||||||
#include <LibHTML/Layout/LayoutImage.h>
|
#include <LibHTML/Layout/LayoutImage.h>
|
||||||
|
#include <LibHTML/ResourceLoader.h>
|
||||||
|
|
||||||
HTMLImageElement::HTMLImageElement(Document& document, const String& tag_name)
|
HTMLImageElement::HTMLImageElement(Document& document, const String& tag_name)
|
||||||
: HTMLElement(document, tag_name)
|
: HTMLElement(document, tag_name)
|
||||||
|
@ -21,12 +23,15 @@ void HTMLImageElement::parse_attribute(const String& name, const String& value)
|
||||||
void HTMLImageElement::load_image(const String& src)
|
void HTMLImageElement::load_image(const String& src)
|
||||||
{
|
{
|
||||||
URL src_url = document().complete_url(src);
|
URL src_url = document().complete_url(src);
|
||||||
if (src_url.protocol() == "file") {
|
ResourceLoader::the().load(src_url, [this](auto data) {
|
||||||
m_bitmap = GraphicsBitmap::load_from_file(src_url.path());
|
if (data.is_null()) {
|
||||||
} else {
|
dbg() << "HTMLImageElement: Failed to load " << this->src();
|
||||||
// FIXME: Implement! This whole thing should be at a different layer though..
|
return;
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_bitmap = load_png_from_memory(data.data(), data.size());
|
||||||
|
document().invalidate_layout();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
int HTMLImageElement::preferred_width() const
|
int HTMLImageElement::preferred_width() const
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <LibHTML/Layout/LayoutNode.h>
|
#include <LibHTML/Layout/LayoutNode.h>
|
||||||
#include <LibHTML/Parser/HTMLParser.h>
|
#include <LibHTML/Parser/HTMLParser.h>
|
||||||
#include <LibHTML/RenderingContext.h>
|
#include <LibHTML/RenderingContext.h>
|
||||||
|
#include <LibHTML/ResourceLoader.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
HtmlView::HtmlView(GWidget* parent)
|
HtmlView::HtmlView(GWidget* parent)
|
||||||
|
@ -174,19 +175,18 @@ void HtmlView::load(const URL& url)
|
||||||
if (on_load_start)
|
if (on_load_start)
|
||||||
on_load_start(url);
|
on_load_start(url);
|
||||||
|
|
||||||
auto f = CFile::construct();
|
ResourceLoader::the().load(url, [=](auto data) {
|
||||||
f->set_filename(url.path());
|
if (data.is_null()) {
|
||||||
if (!f->open(CIODevice::OpenMode::ReadOnly)) {
|
dbg() << "Load failed!";
|
||||||
dbg() << "HtmlView::load: Error: " << f->error_string();
|
ASSERT_NOT_REACHED();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto html = f->read_all();
|
auto document = parse_html(data, url);
|
||||||
auto document = parse_html(html, url);
|
|
||||||
document->normalize();
|
document->normalize();
|
||||||
|
|
||||||
set_document(document);
|
set_document(document);
|
||||||
|
|
||||||
if (on_title_change)
|
if (on_title_change)
|
||||||
on_title_change(document->title());
|
on_title_change(document->title());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ LIBHTML_OBJS = \
|
||||||
Layout/BoxModelMetrics.o \
|
Layout/BoxModelMetrics.o \
|
||||||
Layout/LineBox.o \
|
Layout/LineBox.o \
|
||||||
Layout/LineBoxFragment.o \
|
Layout/LineBoxFragment.o \
|
||||||
|
ResourceLoader.o \
|
||||||
HtmlView.o \
|
HtmlView.o \
|
||||||
Frame.o \
|
Frame.o \
|
||||||
Dump.o
|
Dump.o
|
||||||
|
|
50
Libraries/LibHTML/ResourceLoader.cpp
Normal file
50
Libraries/LibHTML/ResourceLoader.cpp
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#include <LibCore/CFile.h>
|
||||||
|
#include <LibCore/CHttpJob.h>
|
||||||
|
#include <LibCore/CHttpRequest.h>
|
||||||
|
#include <LibCore/CNetworkResponse.h>
|
||||||
|
#include <LibHTML/ResourceLoader.h>
|
||||||
|
|
||||||
|
ResourceLoader& ResourceLoader::the()
|
||||||
|
{
|
||||||
|
static ResourceLoader* s_the;
|
||||||
|
if (!s_the)
|
||||||
|
s_the = new ResourceLoader;
|
||||||
|
return *s_the;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceLoader::load(const URL& url, Function<void(const ByteBuffer&)> callback)
|
||||||
|
{
|
||||||
|
if (url.protocol() == "file") {
|
||||||
|
auto f = CFile::construct();
|
||||||
|
f->set_filename(url.path());
|
||||||
|
if (!f->open(CIODevice::OpenMode::ReadOnly)) {
|
||||||
|
dbg() << "HtmlView::load: Error: " << f->error_string();
|
||||||
|
callback({});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto data = f->read_all();
|
||||||
|
callback(data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url.protocol() == "http") {
|
||||||
|
CHttpRequest request;
|
||||||
|
request.set_url(url);
|
||||||
|
request.set_method(CHttpRequest::Method::GET);
|
||||||
|
auto job = request.schedule();
|
||||||
|
job->on_finish = [job, callback = move(callback)](bool success) {
|
||||||
|
if (!success) {
|
||||||
|
dbg() << "HTTP job failed!";
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
auto* response = job->response();
|
||||||
|
ASSERT(response);
|
||||||
|
callback(response->payload());
|
||||||
|
};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbg() << "Unimplemented protocol: " << url.protocol();
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
14
Libraries/LibHTML/ResourceLoader.h
Normal file
14
Libraries/LibHTML/ResourceLoader.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/Function.h>
|
||||||
|
#include <AK/URL.h>
|
||||||
|
|
||||||
|
class ResourceLoader {
|
||||||
|
public:
|
||||||
|
static ResourceLoader& the();
|
||||||
|
|
||||||
|
void load(const URL&, Function<void(const ByteBuffer&)>);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ResourceLoader() {}
|
||||||
|
};
|
Loading…
Add table
Reference in a new issue