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/Element.cpp | |
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/Element.cpp')
-rw-r--r-- | Libraries/LibWeb/DOM/Element.cpp | 52 |
1 files changed, 50 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(); +} + } |