summaryrefslogtreecommitdiff
path: root/Libraries/LibWeb/DOM/Element.cpp
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-03-25 18:53:20 +0100
committerAndreas Kling <kling@serenityos.org>2020-03-25 18:53:20 +0100
commit68b04d5c78612ea03d1df0014c107340f817b6d7 (patch)
tree9fd43582dde886960d61af3c20b9cf99869b10a3 /Libraries/LibWeb/DOM/Element.cpp
parent632cc53e2c02b05993458115baeb44cf6a0702ec (diff)
downloadserenity-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.cpp52
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();
+}
+
}