diff options
author | Andreas Kling <kling@serenityos.org> | 2020-03-25 18:53:20 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-03-25 18:53:20 +0100 |
commit | 68b04d5c78612ea03d1df0014c107340f817b6d7 (patch) | |
tree | 9fd43582dde886960d61af3c20b9cf99869b10a3 /Libraries/LibWeb/DOM | |
parent | 632cc53e2c02b05993458115baeb44cf6a0702ec (diff) | |
download | serenity-68b04d5c78612ea03d1df0014c107340f817b6d7.zip |
LibWeb: Implement getting and setting element.innerHTML
Getting the innerHTML property will recurse through the subtree inside
the element and serialize it into a string as it goes.
Setting it will parse the set value as an HTML fragment. It will then
remove all current children of the element and replace them with all
the children inside the parsed fragment.
Setting element.innerHTML will currently force a complete rebuild of
the document's layout tree.
This is pretty neat! :^)
Diffstat (limited to 'Libraries/LibWeb/DOM')
-rw-r--r-- | Libraries/LibWeb/DOM/Element.cpp | 52 | ||||
-rw-r--r-- | Libraries/LibWeb/DOM/Element.h | 5 |
2 files changed, 55 insertions, 2 deletions
diff --git a/Libraries/LibWeb/DOM/Element.cpp b/Libraries/LibWeb/DOM/Element.cpp index b7ebb004b1..3f5e93be41 100644 --- a/Libraries/LibWeb/DOM/Element.cpp +++ b/Libraries/LibWeb/DOM/Element.cpp @@ -24,11 +24,15 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <LibWeb/CSS/StyleResolver.h> -#include <LibWeb/CSS/PropertyID.h> +#include <AK/StringBuilder.h> #include <LibWeb/CSS/Length.h> +#include <LibWeb/CSS/PropertyID.h> +#include <LibWeb/CSS/StyleResolver.h> #include <LibWeb/DOM/Document.h> +#include <LibWeb/DOM/DocumentFragment.h> #include <LibWeb/DOM/Element.h> +#include <LibWeb/DOM/Text.h> +#include <LibWeb/Dump.h> #include <LibWeb/Layout/LayoutBlock.h> #include <LibWeb/Layout/LayoutInline.h> #include <LibWeb/Layout/LayoutListItem.h> @@ -36,6 +40,7 @@ #include <LibWeb/Layout/LayoutTableCell.h> #include <LibWeb/Layout/LayoutTableRow.h> #include <LibWeb/Layout/LayoutTreeBuilder.h> +#include <LibWeb/Parser/HTMLParser.h> namespace Web { @@ -218,4 +223,47 @@ NonnullRefPtr<StyleProperties> Element::computed_style() return properties; } +void Element::set_inner_html(StringView markup) +{ + auto fragment = parse_html_fragment(document(), markup); + remove_all_children(); + if (!fragment) + return; + while (RefPtr<Node> child = fragment->first_child()) { + fragment->remove_child(*child); + append_child(*child); + } + + set_needs_style_update(true); + document().schedule_style_update(); + document().invalidate_layout(); +} + +String Element::inner_html() const +{ + StringBuilder builder; + + Function<void(const Node&)> recurse = [&](auto& node) { + for (auto* child = node.first_child(); child; child = child->next_sibling()) { + if (child->is_element()) { + builder.append('<'); + builder.append(to<Element>(*child).tag_name()); + builder.append('>'); + + recurse(*child); + + builder.append("</"); + builder.append(to<Element>(*child).tag_name()); + builder.append('>'); + } + if (child->is_text()) { + builder.append(to<Text>(*child).data()); + } + } + }; + recurse(*this); + + return builder.to_string(); +} + } diff --git a/Libraries/LibWeb/DOM/Element.h b/Libraries/LibWeb/DOM/Element.h index b23ac2c454..f1602d4b07 100644 --- a/Libraries/LibWeb/DOM/Element.h +++ b/Libraries/LibWeb/DOM/Element.h @@ -55,6 +55,8 @@ private: class Element : public ParentNode { public: + using WrapperType = Bindings::ElementWrapper; + Element(Document&, const FlyString& tag_name); virtual ~Element() override; @@ -88,6 +90,9 @@ public: const StyleProperties* resolved_style() const { return m_resolved_style.ptr(); } NonnullRefPtr<StyleProperties> computed_style(); + String inner_html() const; + void set_inner_html(StringView); + private: RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override; |