mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-22 04:25:13 +00:00
LibWeb: Implement the Element.contentEditable IDL attribute
This commit is contained in:
parent
07e13e9868
commit
7811cf3520
Notes:
sideshowbarker
2024-07-19 04:23:06 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/7811cf35200
4 changed files with 68 additions and 7 deletions
|
@ -495,4 +495,9 @@ const String& Document::compat_mode() const
|
|||
return css1_compat;
|
||||
}
|
||||
|
||||
bool Document::is_editable() const
|
||||
{
|
||||
return m_editable;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <LibWeb/DOM/Element.h>
|
||||
#include <LibWeb/DOM/Text.h>
|
||||
#include <LibWeb/Dump.h>
|
||||
#include <LibWeb/HTML/Parser/HTMLDocumentParser.h>
|
||||
#include <LibWeb/Layout/LayoutBlock.h>
|
||||
#include <LibWeb/Layout/LayoutInline.h>
|
||||
#include <LibWeb/Layout/LayoutListItem.h>
|
||||
|
@ -41,7 +42,6 @@
|
|||
#include <LibWeb/Layout/LayoutTableRow.h>
|
||||
#include <LibWeb/Layout/LayoutTableRowGroup.h>
|
||||
#include <LibWeb/Layout/LayoutTreeBuilder.h>
|
||||
#include <LibWeb/HTML/Parser/HTMLDocumentParser.h>
|
||||
|
||||
namespace Web::DOM {
|
||||
|
||||
|
@ -90,6 +90,11 @@ void Element::set_attribute(const FlyString& name, const String& value)
|
|||
parse_attribute(name, value);
|
||||
}
|
||||
|
||||
void Element::remove_attribute(const FlyString& name)
|
||||
{
|
||||
m_attributes.remove_first_matching([&](auto& attribute) { return attribute.name() == name; });
|
||||
}
|
||||
|
||||
void Element::set_attributes(Vector<Attribute>&& attributes)
|
||||
{
|
||||
m_attributes = move(attributes);
|
||||
|
@ -290,22 +295,62 @@ String Element::inner_html() const
|
|||
return builder.to_string();
|
||||
}
|
||||
|
||||
bool Element::is_editable() const
|
||||
Element::ContentEditableState Element::content_editable_state() const
|
||||
{
|
||||
auto contenteditable = attribute(HTML::AttributeNames::contenteditable);
|
||||
// "true" and the empty string map to the "true" state.
|
||||
if ((!contenteditable.is_null() && contenteditable.is_empty()) || contenteditable.equals_ignoring_case("true"))
|
||||
return true;
|
||||
return ContentEditableState::True;
|
||||
// "false" maps to the "false" state.
|
||||
if (contenteditable.equals_ignoring_case("false"))
|
||||
return false;
|
||||
return ContentEditableState::False;
|
||||
// "inherit", an invalid value, and a missing value all map to the "inherit" state.
|
||||
return parent() && parent()->is_editable();
|
||||
return ContentEditableState::Inherit;
|
||||
}
|
||||
|
||||
bool Document::is_editable() const
|
||||
bool Element::is_editable() const
|
||||
{
|
||||
return m_editable;
|
||||
switch (content_editable_state()) {
|
||||
case ContentEditableState::True:
|
||||
return true;
|
||||
case ContentEditableState::False:
|
||||
return false;
|
||||
case ContentEditableState::Inherit:
|
||||
return parent() && parent()->is_editable();
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
String Element::content_editable() const
|
||||
{
|
||||
switch (content_editable_state()) {
|
||||
case ContentEditableState::True:
|
||||
return "true";
|
||||
case ContentEditableState::False:
|
||||
return "false";
|
||||
case ContentEditableState::Inherit:
|
||||
return "inherit";
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
void Element::set_content_editable(const String& content_editable)
|
||||
{
|
||||
if (content_editable.equals_ignoring_case("inherit")) {
|
||||
remove_attribute(HTML::AttributeNames::contenteditable);
|
||||
return;
|
||||
}
|
||||
if (content_editable.equals_ignoring_case("true")) {
|
||||
set_attribute(HTML::AttributeNames::contenteditable, "true");
|
||||
return;
|
||||
}
|
||||
if (content_editable.equals_ignoring_case("false")) {
|
||||
set_attribute(HTML::AttributeNames::contenteditable, "false");
|
||||
return;
|
||||
}
|
||||
// FIXME: otherwise the attribute setter must throw a "SyntaxError" DOMException.
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ public:
|
|||
String attribute(const FlyString& name) const;
|
||||
String get_attribute(const FlyString& name) const { return attribute(name); }
|
||||
void set_attribute(const FlyString& name, const String& value);
|
||||
void remove_attribute(const FlyString& name);
|
||||
|
||||
void set_attributes(Vector<Attribute>&&);
|
||||
|
||||
|
@ -83,11 +84,20 @@ public:
|
|||
void set_inner_html(StringView);
|
||||
|
||||
virtual bool is_editable() const final;
|
||||
String content_editable() const;
|
||||
void set_content_editable(const String&);
|
||||
|
||||
protected:
|
||||
RefPtr<LayoutNode> create_layout_node(const CSS::StyleProperties* parent_style) override;
|
||||
|
||||
private:
|
||||
enum class ContentEditableState {
|
||||
True,
|
||||
False,
|
||||
Inherit,
|
||||
};
|
||||
ContentEditableState content_editable_state() const;
|
||||
|
||||
Attribute* find_attribute(const FlyString& name);
|
||||
const Attribute* find_attribute(const FlyString& name) const;
|
||||
|
||||
|
|
|
@ -9,5 +9,6 @@ interface Element : Node {
|
|||
[Reflect] attribute DOMString id;
|
||||
[Reflect=class] attribute DOMString className;
|
||||
|
||||
attribute DOMString contentEditable;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue