mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 10:28:10 +00:00
LibWeb: Implement Attribute closer to the spec and with an IDL file
Note our Attribute class is what the spec refers to as just "Attr". The main differences between the existing implementation and the spec are just that the spec defines more fields. Attributes can contain namespace URIs and prefixes. However, note that these are not parsed in HTML documents unless the document content-type is XML. So for now, these are initialized to null. Web pages are able to set the namespace via JavaScript (setAttributeNS), so these fields may be filled in when the corresponding APIs are implemented. The main change to be aware of is that an attribute is a node. This has implications on how attributes are stored in the Element class. Nodes are non-copyable and non-movable because these constructors are deleted by the EventTarget base class. This means attributes cannot be stored in a Vector or HashMap as these containers assume copyability / movability. So for now, the Vector holding attributes is changed to hold RefPtrs to attributes instead. This might change when attribute storage is implemented according to the spec (by way of NamedNodeMap).
This commit is contained in:
parent
8d27292fac
commit
e01dfaac9a
11 changed files with 106 additions and 42 deletions
|
@ -926,6 +926,8 @@ static bool is_wrappable_type(IDL::Type const& type)
|
||||||
return true;
|
return true;
|
||||||
if (type.name == "Selection")
|
if (type.name == "Selection")
|
||||||
return true;
|
return true;
|
||||||
|
if (type.name == "Attribute")
|
||||||
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1628,6 +1630,7 @@ void generate_implementation(IDL::Interface const& interface)
|
||||||
#include <LibJS/Runtime/Value.h>
|
#include <LibJS/Runtime/Value.h>
|
||||||
#include <LibWeb/Bindings/@prototype_class@.h>
|
#include <LibWeb/Bindings/@prototype_class@.h>
|
||||||
#include <LibWeb/Bindings/@wrapper_class@.h>
|
#include <LibWeb/Bindings/@wrapper_class@.h>
|
||||||
|
#include <LibWeb/Bindings/AttributeWrapper.h>
|
||||||
#include <LibWeb/Bindings/CSSRuleListWrapper.h>
|
#include <LibWeb/Bindings/CSSRuleListWrapper.h>
|
||||||
#include <LibWeb/Bindings/CSSRuleWrapper.h>
|
#include <LibWeb/Bindings/CSSRuleWrapper.h>
|
||||||
#include <LibWeb/Bindings/CSSRuleWrapperFactory.h>
|
#include <LibWeb/Bindings/CSSRuleWrapperFactory.h>
|
||||||
|
@ -2836,6 +2839,7 @@ void generate_prototype_implementation(IDL::Interface const& interface)
|
||||||
#include <LibWeb/Bindings/@prototype_class@.h>
|
#include <LibWeb/Bindings/@prototype_class@.h>
|
||||||
#include <LibWeb/Bindings/@wrapper_class@.h>
|
#include <LibWeb/Bindings/@wrapper_class@.h>
|
||||||
#include <LibWeb/Bindings/AbortSignalWrapper.h>
|
#include <LibWeb/Bindings/AbortSignalWrapper.h>
|
||||||
|
#include <LibWeb/Bindings/AttributeWrapper.h>
|
||||||
#include <LibWeb/Bindings/CSSRuleListWrapper.h>
|
#include <LibWeb/Bindings/CSSRuleListWrapper.h>
|
||||||
#include <LibWeb/Bindings/CSSRuleWrapper.h>
|
#include <LibWeb/Bindings/CSSRuleWrapper.h>
|
||||||
#include <LibWeb/Bindings/CSSRuleWrapperFactory.h>
|
#include <LibWeb/Bindings/CSSRuleWrapperFactory.h>
|
||||||
|
|
|
@ -54,6 +54,8 @@ set(SOURCES
|
||||||
Cookie/ParsedCookie.cpp
|
Cookie/ParsedCookie.cpp
|
||||||
DOM/AbortController.cpp
|
DOM/AbortController.cpp
|
||||||
DOM/AbortSignal.cpp
|
DOM/AbortSignal.cpp
|
||||||
|
DOM/Attribute.cpp
|
||||||
|
DOM/Attribute.idl
|
||||||
DOM/CharacterData.cpp
|
DOM/CharacterData.cpp
|
||||||
DOM/CharacterData.idl
|
DOM/CharacterData.idl
|
||||||
DOM/Comment.cpp
|
DOM/Comment.cpp
|
||||||
|
@ -366,6 +368,7 @@ libweb_js_wrapper(CSS/MediaQueryListEvent)
|
||||||
libweb_js_wrapper(CSS/Screen)
|
libweb_js_wrapper(CSS/Screen)
|
||||||
libweb_js_wrapper(CSS/StyleSheet)
|
libweb_js_wrapper(CSS/StyleSheet)
|
||||||
libweb_js_wrapper(CSS/StyleSheetList)
|
libweb_js_wrapper(CSS/StyleSheetList)
|
||||||
|
libweb_js_wrapper(DOM/Attribute)
|
||||||
libweb_js_wrapper(DOM/AbortController)
|
libweb_js_wrapper(DOM/AbortController)
|
||||||
libweb_js_wrapper(DOM/AbortSignal)
|
libweb_js_wrapper(DOM/AbortSignal)
|
||||||
libweb_js_wrapper(DOM/CharacterData)
|
libweb_js_wrapper(DOM/CharacterData)
|
||||||
|
|
24
Userland/Libraries/LibWeb/DOM/Attribute.cpp
Normal file
24
Userland/Libraries/LibWeb/DOM/Attribute.cpp
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, Tim Flynn <trflynn89@pm.me>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <LibWeb/DOM/Attribute.h>
|
||||||
|
#include <LibWeb/DOM/Document.h>
|
||||||
|
|
||||||
|
namespace Web::DOM {
|
||||||
|
|
||||||
|
NonnullRefPtr<Attribute> Attribute::create(Document& document, FlyString local_name, String value)
|
||||||
|
{
|
||||||
|
return adopt_ref(*new Attribute(document, move(local_name), move(value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Attribute::Attribute(Document& document, FlyString local_name, String value)
|
||||||
|
: Node(document, NodeType::ATTRIBUTE_NODE)
|
||||||
|
, m_qualified_name(move(local_name), {}, {})
|
||||||
|
, m_value(move(value))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -7,25 +7,42 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/FlyString.h>
|
#include <AK/FlyString.h>
|
||||||
|
#include <LibWeb/DOM/Node.h>
|
||||||
|
#include <LibWeb/QualifiedName.h>
|
||||||
|
|
||||||
namespace Web::DOM {
|
namespace Web::DOM {
|
||||||
|
|
||||||
class Attribute {
|
// https://dom.spec.whatwg.org/#attr
|
||||||
|
class Attribute final : public Node {
|
||||||
public:
|
public:
|
||||||
Attribute(const FlyString& name, const String& value)
|
using WrapperType = Bindings::AttributeWrapper;
|
||||||
: m_name(name)
|
|
||||||
, m_value(value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
const FlyString& name() const { return m_name; }
|
static NonnullRefPtr<Attribute> create(Document&, FlyString local_name, String value);
|
||||||
const String& value() const { return m_value; }
|
|
||||||
|
|
||||||
void set_value(const String& value) { m_value = value; }
|
virtual ~Attribute() override = default;
|
||||||
|
|
||||||
|
virtual FlyString node_name() const override { return name(); }
|
||||||
|
|
||||||
|
FlyString const& namespace_uri() const { return m_qualified_name.namespace_(); }
|
||||||
|
FlyString const& prefix() const { return m_qualified_name.prefix(); }
|
||||||
|
FlyString const& local_name() const { return m_qualified_name.local_name(); }
|
||||||
|
String const& name() const { return m_qualified_name.as_string(); }
|
||||||
|
|
||||||
|
String const& value() const { return m_value; }
|
||||||
|
void set_value(String value) { m_value = move(value); }
|
||||||
|
|
||||||
|
Element const* owner_element() const { return m_owner_element; }
|
||||||
|
void set_owner_element(Element const* owner_element) { m_owner_element = owner_element; }
|
||||||
|
|
||||||
|
// Always returns true: https://dom.spec.whatwg.org/#dom-attr-specified
|
||||||
|
constexpr bool specified() const { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FlyString m_name;
|
Attribute(Document&, FlyString local_name, String value);
|
||||||
|
|
||||||
|
QualifiedName m_qualified_name;
|
||||||
String m_value;
|
String m_value;
|
||||||
|
Element const* m_owner_element { nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
12
Userland/Libraries/LibWeb/DOM/Attribute.idl
Normal file
12
Userland/Libraries/LibWeb/DOM/Attribute.idl
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[Exposed=Window]
|
||||||
|
interface Attribute : Node {
|
||||||
|
readonly attribute DOMString? namespaceURI;
|
||||||
|
readonly attribute DOMString? prefix;
|
||||||
|
readonly attribute DOMString localName;
|
||||||
|
readonly attribute DOMString name;
|
||||||
|
[CEReactions] attribute DOMString value;
|
||||||
|
|
||||||
|
readonly attribute Element? ownerElement;
|
||||||
|
|
||||||
|
readonly attribute boolean specified;
|
||||||
|
};
|
|
@ -49,8 +49,8 @@ Element::~Element()
|
||||||
Attribute* Element::find_attribute(const FlyString& name)
|
Attribute* Element::find_attribute(const FlyString& name)
|
||||||
{
|
{
|
||||||
for (auto& attribute : m_attributes) {
|
for (auto& attribute : m_attributes) {
|
||||||
if (attribute.name() == name)
|
if (attribute->name() == name)
|
||||||
return &attribute;
|
return attribute;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -58,8 +58,8 @@ Attribute* Element::find_attribute(const FlyString& name)
|
||||||
const Attribute* Element::find_attribute(const FlyString& name) const
|
const Attribute* Element::find_attribute(const FlyString& name) const
|
||||||
{
|
{
|
||||||
for (auto& attribute : m_attributes) {
|
for (auto& attribute : m_attributes) {
|
||||||
if (attribute.name() == name)
|
if (attribute->name() == name)
|
||||||
return &attribute;
|
return attribute;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ ExceptionOr<void> Element::set_attribute(const FlyString& name, const String& va
|
||||||
if (auto* attribute = find_attribute(name))
|
if (auto* attribute = find_attribute(name))
|
||||||
attribute->set_value(value);
|
attribute->set_value(value);
|
||||||
else
|
else
|
||||||
m_attributes.empend(name, value);
|
m_attributes.append(Attribute::create(document(), name, value));
|
||||||
|
|
||||||
parse_attribute(name, value);
|
parse_attribute(name, value);
|
||||||
return {};
|
return {};
|
||||||
|
@ -92,7 +92,7 @@ void Element::remove_attribute(const FlyString& name)
|
||||||
{
|
{
|
||||||
CSS::StyleInvalidator style_invalidator(document());
|
CSS::StyleInvalidator style_invalidator(document());
|
||||||
|
|
||||||
m_attributes.remove_first_matching([&](auto& attribute) { return attribute.name() == name; });
|
m_attributes.remove_first_matching([&](auto& attribute) { return attribute->name() == name; });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Element::has_class(const FlyString& class_name, CaseSensitivity case_sensitivity) const
|
bool Element::has_class(const FlyString& class_name, CaseSensitivity case_sensitivity) const
|
||||||
|
|
|
@ -67,7 +67,7 @@ public:
|
||||||
void for_each_attribute(Callback callback) const
|
void for_each_attribute(Callback callback) const
|
||||||
{
|
{
|
||||||
for (auto& attribute : m_attributes)
|
for (auto& attribute : m_attributes)
|
||||||
callback(attribute.name(), attribute.value());
|
callback(attribute->name(), attribute->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has_class(const FlyString&, CaseSensitivity = CaseSensitivity::CaseSensitive) const;
|
bool has_class(const FlyString&, CaseSensitivity = CaseSensitivity::CaseSensitive) const;
|
||||||
|
@ -132,7 +132,7 @@ private:
|
||||||
|
|
||||||
QualifiedName m_qualified_name;
|
QualifiedName m_qualified_name;
|
||||||
String m_html_uppercased_qualified_name;
|
String m_html_uppercased_qualified_name;
|
||||||
Vector<Attribute> m_attributes;
|
Vector<NonnullRefPtr<Attribute>> m_attributes;
|
||||||
|
|
||||||
RefPtr<CSS::CSSStyleDeclaration> m_inline_style;
|
RefPtr<CSS::CSSStyleDeclaration> m_inline_style;
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@ class UnsetStyleValue;
|
||||||
namespace Web::DOM {
|
namespace Web::DOM {
|
||||||
class AbortController;
|
class AbortController;
|
||||||
class AbortSignal;
|
class AbortSignal;
|
||||||
|
class Attribute;
|
||||||
class CharacterData;
|
class CharacterData;
|
||||||
class Comment;
|
class Comment;
|
||||||
class CustomEvent;
|
class CustomEvent;
|
||||||
|
@ -290,6 +291,7 @@ class URLSearchParamsIterator;
|
||||||
namespace Web::Bindings {
|
namespace Web::Bindings {
|
||||||
class AbortControllerWrapper;
|
class AbortControllerWrapper;
|
||||||
class AbortSignalWrapper;
|
class AbortSignalWrapper;
|
||||||
|
class AttributeWrapper;
|
||||||
class CanvasRenderingContext2DWrapper;
|
class CanvasRenderingContext2DWrapper;
|
||||||
class CharacterDataWrapper;
|
class CharacterDataWrapper;
|
||||||
class CloseEventWrapper;
|
class CloseEventWrapper;
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include <AK/StringView.h>
|
#include <AK/StringView.h>
|
||||||
#include <AK/Utf8View.h>
|
#include <AK/Utf8View.h>
|
||||||
#include <LibTextCodec/Decoder.h>
|
#include <LibTextCodec/Decoder.h>
|
||||||
|
#include <LibWeb/DOM/Attribute.h>
|
||||||
|
#include <LibWeb/DOM/Document.h>
|
||||||
#include <LibWeb/HTML/Parser/HTMLEncodingDetection.h>
|
#include <LibWeb/HTML/Parser/HTMLEncodingDetection.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
@ -94,7 +96,7 @@ Optional<String> extract_character_encoding_from_meta_element(String const& stri
|
||||||
return TextCodec::get_standardized_encoding(encoding);
|
return TextCodec::get_standardized_encoding(encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<DOM::Attribute> prescan_get_attribute(const ByteBuffer& input, size_t& position)
|
RefPtr<DOM::Attribute> prescan_get_attribute(DOM::Document& document, const ByteBuffer& input, size_t& position)
|
||||||
{
|
{
|
||||||
if (!prescan_skip_whitespace_and_slashes(input, position))
|
if (!prescan_skip_whitespace_and_slashes(input, position))
|
||||||
return {};
|
return {};
|
||||||
|
@ -109,7 +111,7 @@ Optional<DOM::Attribute> prescan_get_attribute(const ByteBuffer& input, size_t&
|
||||||
} else if (input[position] == '\t' || input[position] == '\n' || input[position] == '\f' || input[position] == '\r' || input[position] == ' ')
|
} else if (input[position] == '\t' || input[position] == '\n' || input[position] == '\f' || input[position] == '\r' || input[position] == ' ')
|
||||||
goto spaces;
|
goto spaces;
|
||||||
else if (input[position] == '/' || input[position] == '>')
|
else if (input[position] == '/' || input[position] == '>')
|
||||||
return DOM::Attribute(attribute_name.to_string(), "");
|
return DOM::Attribute::create(document, attribute_name.to_string(), "");
|
||||||
else
|
else
|
||||||
attribute_name.append_as_lowercase(input[position]);
|
attribute_name.append_as_lowercase(input[position]);
|
||||||
++position;
|
++position;
|
||||||
|
@ -121,7 +123,7 @@ spaces:
|
||||||
if (!prescan_skip_whitespace_and_slashes(input, position))
|
if (!prescan_skip_whitespace_and_slashes(input, position))
|
||||||
return {};
|
return {};
|
||||||
if (input[position] != '=')
|
if (input[position] != '=')
|
||||||
return DOM::Attribute(attribute_name.to_string(), "");
|
return DOM::Attribute::create(document, attribute_name.to_string(), "");
|
||||||
++position;
|
++position;
|
||||||
|
|
||||||
value:
|
value:
|
||||||
|
@ -134,13 +136,13 @@ value:
|
||||||
++position;
|
++position;
|
||||||
for (; !prescan_should_abort(input, position); ++position) {
|
for (; !prescan_should_abort(input, position); ++position) {
|
||||||
if (input[position] == quote_character)
|
if (input[position] == quote_character)
|
||||||
return DOM::Attribute(attribute_name.to_string(), attribute_value.to_string());
|
return DOM::Attribute::create(document, attribute_name.to_string(), attribute_value.to_string());
|
||||||
else
|
else
|
||||||
attribute_value.append_as_lowercase(input[position]);
|
attribute_value.append_as_lowercase(input[position]);
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
} else if (input[position] == '>')
|
} else if (input[position] == '>')
|
||||||
return DOM::Attribute(attribute_name.to_string(), "");
|
return DOM::Attribute::create(document, attribute_name.to_string(), "");
|
||||||
else
|
else
|
||||||
attribute_value.append_as_lowercase(input[position]);
|
attribute_value.append_as_lowercase(input[position]);
|
||||||
|
|
||||||
|
@ -150,7 +152,7 @@ value:
|
||||||
|
|
||||||
for (; !prescan_should_abort(input, position); ++position) {
|
for (; !prescan_should_abort(input, position); ++position) {
|
||||||
if (input[position] == '\t' || input[position] == '\n' || input[position] == '\f' || input[position] == '\r' || input[position] == ' ' || input[position] == '>')
|
if (input[position] == '\t' || input[position] == '\n' || input[position] == '\f' || input[position] == '\r' || input[position] == ' ' || input[position] == '>')
|
||||||
return DOM::Attribute(attribute_name.to_string(), attribute_value.to_string());
|
return DOM::Attribute::create(document, attribute_name.to_string(), attribute_value.to_string());
|
||||||
else
|
else
|
||||||
attribute_value.append_as_lowercase(input[position]);
|
attribute_value.append_as_lowercase(input[position]);
|
||||||
}
|
}
|
||||||
|
@ -158,7 +160,7 @@ value:
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/parsing.html#prescan-a-byte-stream-to-determine-its-encoding
|
// https://html.spec.whatwg.org/multipage/parsing.html#prescan-a-byte-stream-to-determine-its-encoding
|
||||||
Optional<String> run_prescan_byte_stream_algorithm(const ByteBuffer& input)
|
Optional<String> run_prescan_byte_stream_algorithm(DOM::Document& document, const ByteBuffer& input)
|
||||||
{
|
{
|
||||||
// https://html.spec.whatwg.org/multipage/parsing.html#prescan-a-byte-stream-to-determine-its-encoding
|
// https://html.spec.whatwg.org/multipage/parsing.html#prescan-a-byte-stream-to-determine-its-encoding
|
||||||
|
|
||||||
|
@ -194,24 +196,24 @@ Optional<String> run_prescan_byte_stream_algorithm(const ByteBuffer& input)
|
||||||
Optional<String> charset {};
|
Optional<String> charset {};
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
auto attribute = prescan_get_attribute(input, position);
|
auto attribute = prescan_get_attribute(document, input, position);
|
||||||
if (!attribute.has_value())
|
if (!attribute)
|
||||||
break;
|
break;
|
||||||
if (attribute_list.contains_slow(attribute.value().name()))
|
if (attribute_list.contains_slow(attribute->name()))
|
||||||
continue;
|
continue;
|
||||||
auto& attribute_name = attribute.value().name();
|
auto& attribute_name = attribute->name();
|
||||||
attribute_list.append(attribute.value().name());
|
attribute_list.append(attribute->name());
|
||||||
|
|
||||||
if (attribute_name == "http-equiv") {
|
if (attribute_name == "http-equiv") {
|
||||||
got_pragma = attribute.value().value() == "content-type";
|
got_pragma = attribute->value() == "content-type";
|
||||||
} else if (attribute_name == "content") {
|
} else if (attribute_name == "content") {
|
||||||
auto encoding = extract_character_encoding_from_meta_element(attribute.value().value());
|
auto encoding = extract_character_encoding_from_meta_element(attribute->value());
|
||||||
if (encoding.has_value() && !charset.has_value()) {
|
if (encoding.has_value() && !charset.has_value()) {
|
||||||
charset = encoding.value();
|
charset = encoding.value();
|
||||||
need_pragma = true;
|
need_pragma = true;
|
||||||
}
|
}
|
||||||
} else if (attribute_name == "charset") {
|
} else if (attribute_name == "charset") {
|
||||||
auto maybe_charset = TextCodec::get_standardized_encoding(attribute.value().value());
|
auto maybe_charset = TextCodec::get_standardized_encoding(attribute->value());
|
||||||
if (maybe_charset.has_value()) {
|
if (maybe_charset.has_value()) {
|
||||||
charset = Optional<String> { maybe_charset };
|
charset = Optional<String> { maybe_charset };
|
||||||
need_pragma = { false };
|
need_pragma = { false };
|
||||||
|
@ -231,7 +233,7 @@ Optional<String> run_prescan_byte_stream_algorithm(const ByteBuffer& input)
|
||||||
&& ((input[position + 1] == '/' && isalpha(input[position + 2])) || isalpha(input[position + 1]))) {
|
&& ((input[position + 1] == '/' && isalpha(input[position + 2])) || isalpha(input[position + 1]))) {
|
||||||
position += 2;
|
position += 2;
|
||||||
prescan_skip_whitespace_and_slashes(input, position);
|
prescan_skip_whitespace_and_slashes(input, position);
|
||||||
while (prescan_get_attribute(input, position).has_value()) { };
|
while (prescan_get_attribute(document, input, position)) { };
|
||||||
} else if (!prescan_should_abort(input, position + 1) && input[position] == '<' && (input[position + 1] == '!' || input[position + 1] == '/' || input[position + 1] == '?')) {
|
} else if (!prescan_should_abort(input, position + 1) && input[position] == '<' && (input[position + 1] == '!' || input[position + 1] == '/' || input[position + 1] == '?')) {
|
||||||
position += 2;
|
position += 2;
|
||||||
while (input[position] != '>') {
|
while (input[position] != '>') {
|
||||||
|
@ -247,7 +249,7 @@ Optional<String> run_prescan_byte_stream_algorithm(const ByteBuffer& input)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/parsing.html#determining-the-character-encoding
|
// https://html.spec.whatwg.org/multipage/parsing.html#determining-the-character-encoding
|
||||||
String run_encoding_sniffing_algorithm(const ByteBuffer& input)
|
String run_encoding_sniffing_algorithm(DOM::Document& document, const ByteBuffer& input)
|
||||||
{
|
{
|
||||||
if (input.size() >= 2) {
|
if (input.size() >= 2) {
|
||||||
if (input[0] == 0xFE && input[1] == 0xFF) {
|
if (input[0] == 0xFE && input[1] == 0xFF) {
|
||||||
|
@ -265,7 +267,7 @@ String run_encoding_sniffing_algorithm(const ByteBuffer& input)
|
||||||
// at any later step in this algorithm.
|
// at any later step in this algorithm.
|
||||||
// FIXME: If the transport layer specifies a character encoding, and it is supported.
|
// FIXME: If the transport layer specifies a character encoding, and it is supported.
|
||||||
|
|
||||||
auto optional_encoding = run_prescan_byte_stream_algorithm(input);
|
auto optional_encoding = run_prescan_byte_stream_algorithm(document, input);
|
||||||
if (optional_encoding.has_value()) {
|
if (optional_encoding.has_value()) {
|
||||||
return optional_encoding.value();
|
return optional_encoding.value();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#include <AK/Optional.h>
|
#include <AK/Optional.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
#include <LibWeb/DOM/Attribute.h>
|
#include <LibWeb/Forward.h>
|
||||||
|
|
||||||
namespace Web::HTML {
|
namespace Web::HTML {
|
||||||
|
|
||||||
|
@ -16,8 +16,8 @@ bool prescan_should_abort(const ByteBuffer& input, const size_t& position);
|
||||||
bool prescan_is_whitespace_or_slash(const u8& byte);
|
bool prescan_is_whitespace_or_slash(const u8& byte);
|
||||||
bool prescan_skip_whitespace_and_slashes(const ByteBuffer& input, size_t& position);
|
bool prescan_skip_whitespace_and_slashes(const ByteBuffer& input, size_t& position);
|
||||||
Optional<String> extract_character_encoding_from_meta_element(String const&);
|
Optional<String> extract_character_encoding_from_meta_element(String const&);
|
||||||
Optional<DOM::Attribute> prescan_get_attribute(const ByteBuffer& input, size_t& position);
|
RefPtr<DOM::Attribute> prescan_get_attribute(DOM::Document&, const ByteBuffer& input, size_t& position);
|
||||||
Optional<String> run_prescan_byte_stream_algorithm(const ByteBuffer& input);
|
Optional<String> run_prescan_byte_stream_algorithm(DOM::Document&, const ByteBuffer& input);
|
||||||
String run_encoding_sniffing_algorithm(const ByteBuffer& input);
|
String run_encoding_sniffing_algorithm(DOM::Document&, const ByteBuffer& input);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2810,7 +2810,7 @@ void HTMLParser::handle_in_frameset(HTMLToken& token)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token.is_end_of_file()) {
|
if (token.is_end_of_file()) {
|
||||||
//FIXME: If the current node is not the root html element, then this is a parse error.
|
// FIXME: If the current node is not the root html element, then this is a parse error.
|
||||||
|
|
||||||
stop_parsing();
|
stop_parsing();
|
||||||
return;
|
return;
|
||||||
|
@ -3162,7 +3162,7 @@ NonnullOwnPtr<HTMLParser> HTMLParser::create_with_uncertain_encoding(DOM::Docume
|
||||||
{
|
{
|
||||||
if (document.has_encoding())
|
if (document.has_encoding())
|
||||||
return make<HTMLParser>(document, input, document.encoding().value());
|
return make<HTMLParser>(document, input, document.encoding().value());
|
||||||
auto encoding = run_encoding_sniffing_algorithm(input);
|
auto encoding = run_encoding_sniffing_algorithm(document, input);
|
||||||
dbgln("The encoding sniffing algorithm returned encoding '{}'", encoding);
|
dbgln("The encoding sniffing algorithm returned encoding '{}'", encoding);
|
||||||
return make<HTMLParser>(document, input, encoding);
|
return make<HTMLParser>(document, input, encoding);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue