mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-24 02:12:09 -05:00
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
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="selectors.html">selectors</a></li>
|
||||
<li><a href="link.html">link element</a></li>
|
||||
<li><a href="http://www.serenityos.org/">www.serenityos.org</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#include <LibDraw/PNGLoader.h>
|
||||
#include <LibHTML/CSS/StyleResolver.h>
|
||||
#include <LibHTML/DOM/Document.h>
|
||||
#include <LibHTML/DOM/HTMLImageElement.h>
|
||||
#include <LibHTML/Layout/LayoutImage.h>
|
||||
#include <LibHTML/ResourceLoader.h>
|
||||
|
||||
HTMLImageElement::HTMLImageElement(Document& document, const String& 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)
|
||||
{
|
||||
URL src_url = document().complete_url(src);
|
||||
if (src_url.protocol() == "file") {
|
||||
m_bitmap = GraphicsBitmap::load_from_file(src_url.path());
|
||||
} else {
|
||||
// FIXME: Implement! This whole thing should be at a different layer though..
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
ResourceLoader::the().load(src_url, [this](auto data) {
|
||||
if (data.is_null()) {
|
||||
dbg() << "HTMLImageElement: Failed to load " << this->src();
|
||||
return;
|
||||
}
|
||||
|
||||
m_bitmap = load_png_from_memory(data.data(), data.size());
|
||||
document().invalidate_layout();
|
||||
});
|
||||
}
|
||||
|
||||
int HTMLImageElement::preferred_width() const
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <LibHTML/Layout/LayoutNode.h>
|
||||
#include <LibHTML/Parser/HTMLParser.h>
|
||||
#include <LibHTML/RenderingContext.h>
|
||||
#include <LibHTML/ResourceLoader.h>
|
||||
#include <stdio.h>
|
||||
|
||||
HtmlView::HtmlView(GWidget* parent)
|
||||
|
@ -174,19 +175,18 @@ void HtmlView::load(const URL& url)
|
|||
if (on_load_start)
|
||||
on_load_start(url);
|
||||
|
||||
auto f = CFile::construct();
|
||||
f->set_filename(url.path());
|
||||
if (!f->open(CIODevice::OpenMode::ReadOnly)) {
|
||||
dbg() << "HtmlView::load: Error: " << f->error_string();
|
||||
return;
|
||||
}
|
||||
ResourceLoader::the().load(url, [=](auto data) {
|
||||
if (data.is_null()) {
|
||||
dbg() << "Load failed!";
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
auto html = f->read_all();
|
||||
auto document = parse_html(html, url);
|
||||
document->normalize();
|
||||
auto document = parse_html(data, url);
|
||||
document->normalize();
|
||||
|
||||
set_document(document);
|
||||
set_document(document);
|
||||
|
||||
if (on_title_change)
|
||||
on_title_change(document->title());
|
||||
if (on_title_change)
|
||||
on_title_change(document->title());
|
||||
});
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ LIBHTML_OBJS = \
|
|||
Layout/BoxModelMetrics.o \
|
||||
Layout/LineBox.o \
|
||||
Layout/LineBoxFragment.o \
|
||||
ResourceLoader.o \
|
||||
HtmlView.o \
|
||||
Frame.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