Commit graph

33 commits

Author SHA1 Message Date
Andreas Kling
85ac9705ba LibHTML: Add LayoutNode::is_image() and is<LayoutImage> helper 2019-12-18 20:52:36 +01:00
Andreas Kling
6d1c4ae5a9 LibHTML: Implement basic <form> and <input> element support
This patch adds "submit" inputs and default (text box) inputs, as well
as form elements that can be submitted.

Layout of input elements is implemented via a new LayoutWidget class
that allows you to put an arbitrary GWidget in the layout tree.
At the moment, the DOM node sets the initial size of the LayoutWidget,
and then the positioning is done by the normal layout algorithm.

We also now support submitting a <form method="GET">, which does a full
replacing load with a URL based on the form's action + a query string
built from the name/value of input elements within the submitted form.

This is pretty neat! :^)
2019-11-25 21:21:55 +01:00
Andreas Kling
c628ebda0f LibHTML: Use floating point numbers throughout the layout tree 2019-11-18 16:30:18 +01:00
Andreas Kling
f3f0b08d43 LibHTML: Build some foundation for text selection
Add LayoutPosition and LayoutRange classes. The layout tree root node
now has a selection() LayoutRange. It's essentially a start and end
LayoutPosition.

A LayoutPosition is a LayoutNode, and an optional index into that node.
The index is only relevant for text nodes, where it's the character
index into the rendered text.

HtmlView now updates the selection start/end of the LayoutDocument when
clicking and dragging with the left mouse button.

We don't paint the selection yet, and there's no way to copy what's
selected. It only exists as a LayoutRange.
2019-11-05 22:13:26 +01:00
Andreas Kling
715d7a8532 LibHTML: Add a convenient way to get from any layout node to the root 2019-11-04 20:45:47 +01:00
Andreas Kling
c41bae3d54 LibHTML+Browser: Support scrolling to anchor with <a href="#foo">
This patch implements basic support for <a href="#foo"> fragment links.

To figure out where we actually want to scroll to, we have to do
something different based on the layout node's box type. So if it's a
regular LayoutBox we can just use the LayoutBox::position().

However, if it's an inline layout node, we use the position of the
first line box fragment in the containing block contributed by this
layout node or one of its descendants.
2019-10-20 10:07:26 +02:00
Andreas Kling
2305dee455 LibHTML: Add LayoutNode::first_ancestor_of_type<T>() 2019-10-18 10:16:33 +02:00
Andreas Kling
65ad6c35f0 LibHTML: Add typed child/sibling traversal helpers for LayoutNode
Also add some special variants for the table classes, to make it a bit
more pleasant to write table code. :^)
2019-10-18 09:38:12 +02:00
Andreas Kling
b4c2621ed7 LibHTML: Add is<T> helpers for the table-related LayoutNode subclasses 2019-10-17 23:39:31 +02:00
Andreas Kling
5e29238a49 LibHTML: Make "children are inline" flag imperative
Instead of computing whether a block's children are inline based on the
first child, make it an imperatively-set flag.

This gives us some flexibility to ignore things like text nodes inside
a <table>, for example. I'm still unsure what the "correct" way to deal
with those will be. We'll find out sooner or later. :^)
2019-10-17 23:39:31 +02:00
Andreas Kling
4814253589 LibHTML: Introduce LayoutBox and LayoutNodeWithStyleAndBoxModelMetrics
To streamline the layout tree and remove irrelevant data from classes
that don't need it, this patch adds two new LayoutNode subclasses.

LayoutNodeWithStyleAndBoxModelMetrics should be inherited by any layout
node that cares about box model metrics (margin, border, and padding.)
LayoutBox should be inherited by any layout node that can have a rect.

This makes LayoutText significantly smaller (from 140 to 40 bytes) and
clarifies a lot of things about the layout tree.

I'm also adding next_sibling() and previous_sibling() overloads to
LayoutBlock that return a LayoutBlock*. This is okay since blocks only
ever have block siblings.

Do also note that the semantics of is<T> slightly change in this patch:
is<T>(nullptr) now returns true, to facilitate allowing to<T>(nullptr).
2019-10-15 16:48:38 +02:00
Andreas Kling
d14b60533f LibHTML: Add is<T> and to<T> helpers for LayoutNode class family 2019-10-15 14:24:26 +02:00
Andreas Kling
735f02900b LibHTML: Implement basic partial style invalidation
This patch makes it possible to call Node::invalidate_style() and have
that node and all of its ancestors recompute their style.

We then figure out if the new style is visually different from the old
style, and if so do a paint invalidation with set_needs_display().
Note that the "are they visually different" code is very incomplete!

Use this to make hover effects a lot more efficient. They no longer
cause a full relayout+repaint, but only a style invalidation.
Style invalidations are still quite heavy though, and there's a lot of
room for improvement there. :^)
2019-10-14 18:33:23 +02:00
Andreas Kling
3309bdf722 LibHTML: Add some convenient geometry getters on LayoutNode
Add x(), y(), size() and position() and use them around the codebase.
2019-10-13 18:47:16 +02:00
Andreas Kling
44979ad7a5 LibHTML: Fix broken line splitting behavior in LayoutReplaced
Replaced elements will now properly create line breaks when they use up
the available horizontal space.

This fixes an issue with <img>'s lining up instead of breaking.
2019-10-13 18:47:16 +02:00
Andreas Kling
159507f2a6 LibHTML: Move is_ancestor_of() from LayoutNode to TreeNode
This way it becomes available to all the different TreeNode subclasses.
2019-10-09 21:33:34 +02:00
Andreas Kling
fdbad6284c LibHTML: Implement the <blink> element
Just in time for Serenity's 1st birthday, here is the <blink> element!

This patch adds a bunch of different mechanisms to enable partial
repaints of the layout tree (LayoutNode::set_needs_display()))
It also adds LayoutNode::is_visible(), which can be toggled to prevent
a LayoutNode from rendering anything (it still takes up space though.)
2019-10-09 21:25:29 +02:00
Andreas Kling
749e3f0f30 LibHTML: Add LayoutNodeWithStyle class, make LayoutText style-less
Since LayoutText always inherits style, it shouldn't store any style of
its own. This patch adds a LayoutNodeWithStyle class to sit between
LayoutNode and everyone who wants to inherit from LayoutNode except
LayoutText :^)

Since LayoutText can never have children, we also know that the parent
of any LayoutNode is always going to be a LayoutNodeWithStyle.
So this patch makes LayoutNode::parent() return LayoutNodeWithStyle*.
2019-10-07 10:56:44 +02:00
Andreas Kling
15f3e64862 LibHTML: Rename "style_properties" to "style" everywhere 2019-10-07 10:56:44 +02:00
Andreas Kling
ee567cdc3d LibHTML: Implement basic layout for inline <img alt>
LayoutReplaced objects can now participate in inline layout.

It's very hackish, but basically LayoutReplaced will just add itself to
the last line in the containing block.

This patch gets rid of the idea that only LayoutInline subclasses can
be split into lines, by moving the split_into_lines() virtual up to
LayoutNode and overriding it in LayoutReplaced.
2019-10-05 23:29:01 +02:00
Andreas Kling
09dccb3224 LibHTML: Flesh out <img> element with LayoutImage and LayoutReplaced
This patch adds parsing of <img> into HTMLImageElement objects.
It also adds LayoutImage and its parent class LayoutReplaced, which is
going to represent CSS "replaced elements."
2019-10-05 23:29:01 +02:00
Andreas Kling
a7ca719c4e LibHTML: Rename LayoutNode::style_properties() to LayoutNode::style() 2019-10-04 15:56:36 +02:00
Andreas Kling
9c0e9a1a20 LibHTML: Rename ComputedStyle to BoxModelMetrics
There was nothing left in ComputedStyle except the box model metrics,
so this patch gives it a more representative name.

Note that style information is fetched directly from StyleProperties,
which is basically the CSS property name/value pairs that apply to
an element.
2019-10-04 15:50:50 +02:00
Andreas Kling
4e35bbffdd LibHTML: LayoutText should always use parent's style properties
This patch makes StyleProperties heap-allocated and ref-counted so that
a LayoutNode can be without one. The ref-counting also allows anonymous
blocks to share style with their parent block.

LayoutText never needs a StyleProperties, since text always inherits
style from its parent element. This is handled by style_properties().
2019-10-04 12:12:39 +02:00
Andreas Kling
7912592f89 LibHTML: Add inserted_into() and removed_from() TreeNode callbacks
These will be called when a Node or LayoutNode is inserted or removed
from a tree. They get the parent node as an argument.
2019-09-29 17:40:39 +02:00
Andreas Kling
754e6e0f67 LibHTML: Add LayoutNode::document() for easy access
Every LayoutNode indirectly belongs to some Document. For anonymous
LayoutNodes, we simply traverse the parent chain until we find someone
with a Node from which we can get a Document&.
2019-09-29 11:43:33 +02:00
Andreas Kling
3de4b99dc3 LibHTML: Implement naive hit testing
We don't have proper line boxes yet, so we can't easily hit test
inline text.
2019-09-28 23:04:59 +02:00
Sergey Bugaev
235dee8c42 LibHTML: Implement rendering 2019-09-28 18:29:42 +02:00
Sergey Bugaev
fd0aa5dd43 LibHTML: Get rid of the style tree
We now create a layout tree directly from the DOM tree.
This way we don't actually lose text nodes ^)
2019-09-28 18:29:42 +02:00
Andreas Kling
f88c5860df LibHTML: Fetch the box edge values needed for block width computation. 2019-07-24 07:34:07 +02:00
Andreas Kling
1c0669f010 LibDraw: Introduce (formerly known as SharedGraphics.)
Instead of LibGUI and WindowServer building their own copies of the drawing
and graphics code, let's it in a separate LibDraw library.

This avoids building the code twice, and will encourage better separation
of concerns. :^)
2019-07-18 10:18:16 +02:00
Andreas Kling
fc127eb769 LibHTML: Create anonymous blocks around inline children of blocks. 2019-07-08 17:42:23 +02:00
Andreas Kling
04b9dc2d30 Libraries: Create top level directory for libraries.
Things were getting a little crowded in the project root, so this patch
moves the Lib*/ directories into Libraries/.
2019-07-04 16:16:50 +02:00
Renamed from LibHTML/Layout/LayoutNode.h (Browse further)