diff options
Diffstat (limited to 'content/handlers/html/box.h')
-rw-r--r-- | content/handlers/html/box.h | 571 |
1 files changed, 314 insertions, 257 deletions
diff --git a/content/handlers/html/box.h b/content/handlers/html/box.h index 8ab2875a0..df2b99d87 100644 --- a/content/handlers/html/box.h +++ b/content/handlers/html/box.h @@ -1,6 +1,7 @@ /* * Copyright 2005 James Bursa <bursa@users.sourceforge.net> * Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net> + * Copyright 2020 Vincent Sanders <vince@netsurf-browser.org> * * This file is part of NetSurf, http://www.netsurf-browser.org/ * @@ -19,69 +20,8 @@ /** * \file - * Box tree construction and manipulation (interface). + * Box interface. * - * This stage of rendering converts a tree of dom_nodes (produced by libdom) - * to a tree of struct box. The box tree represents the structure of the - * document as given by the CSS display and float properties. - * - * For example, consider the following HTML: - * \code - * <h1>Example Heading</h1> - * <p>Example paragraph <em>with emphasised text</em> etc.</p> \endcode - * - * This would produce approximately the following box tree with default CSS - * rules: - * \code - * BOX_BLOCK (corresponds to h1) - * BOX_INLINE_CONTAINER - * BOX_INLINE "Example Heading" - * BOX_BLOCK (p) - * BOX_INLINE_CONTAINER - * BOX_INLINE "Example paragraph " - * BOX_INLINE "with emphasised text" (em) - * BOX_INLINE "etc." \endcode - * - * Note that the em has been collapsed into the INLINE_CONTAINER. - * - * If these CSS rules were applied: - * \code - * h1 { display: table-cell } - * p { display: table-cell } - * em { float: left; width: 5em } \endcode - * - * then the box tree would instead look like this: - * \code - * BOX_TABLE - * BOX_TABLE_ROW_GROUP - * BOX_TABLE_ROW - * BOX_TABLE_CELL (h1) - * BOX_INLINE_CONTAINER - * BOX_INLINE "Example Heading" - * BOX_TABLE_CELL (p) - * BOX_INLINE_CONTAINER - * BOX_INLINE "Example paragraph " - * BOX_FLOAT_LEFT (em) - * BOX_BLOCK - * BOX_INLINE_CONTAINER - * BOX_INLINE "with emphasised text" - * BOX_INLINE "etc." \endcode - * - * Here implied boxes have been added and a float is present. - * - * A box tree is "normalized" if the following is satisfied: - * \code - * parent permitted child nodes - * BLOCK, INLINE_BLOCK BLOCK, INLINE_CONTAINER, TABLE - * INLINE_CONTAINER INLINE, INLINE_BLOCK, FLOAT_LEFT, FLOAT_RIGHT, BR, TEXT, - * INLINE_END - * INLINE none - * TABLE at least 1 TABLE_ROW_GROUP - * TABLE_ROW_GROUP at least 1 TABLE_ROW - * TABLE_ROW at least 1 TABLE_CELL - * TABLE_CELL BLOCK, INLINE_CONTAINER, TABLE (same as BLOCK) - * FLOAT_(LEFT|RIGHT) exactly 1 BLOCK or TABLE - * \endcode */ #ifndef NETSURF_HTML_BOX_H @@ -89,7 +29,6 @@ #include <limits.h> #include <stdbool.h> -#include <stdio.h> #include <libcss/libcss.h> #include "content/handlers/css/utils.h" @@ -97,9 +36,6 @@ struct content; struct box; struct browser_window; -struct column; -struct object_params; -struct object_param; struct html_content; struct nsurl; struct dom_node; @@ -109,20 +45,36 @@ struct rect; #define UNKNOWN_WIDTH INT_MAX #define UNKNOWN_MAX_WIDTH INT_MAX + typedef void (*box_construct_complete_cb)(struct html_content *c, bool success); -/** Type of a struct box. */ + +/** + * Type of a struct box. + */ typedef enum { - BOX_BLOCK, BOX_INLINE_CONTAINER, BOX_INLINE, - BOX_TABLE, BOX_TABLE_ROW, BOX_TABLE_CELL, + BOX_BLOCK, + BOX_INLINE_CONTAINER, + BOX_INLINE, + BOX_TABLE, + BOX_TABLE_ROW, + BOX_TABLE_CELL, BOX_TABLE_ROW_GROUP, - BOX_FLOAT_LEFT, BOX_FLOAT_RIGHT, - BOX_INLINE_BLOCK, BOX_BR, BOX_TEXT, - BOX_INLINE_END, BOX_NONE + BOX_FLOAT_LEFT, + BOX_FLOAT_RIGHT, + BOX_INLINE_BLOCK, + BOX_BR, + BOX_TEXT, + BOX_INLINE_END, + BOX_NONE, + BOX_FLEX, + BOX_INLINE_FLEX, } box_type; -/** Flags for a struct box. */ +/** + * Flags for a struct box. + */ typedef enum { NEW_LINE = 1 << 0, /* first inline on a new line */ STYLE_OWNED = 1 << 1, /* style is owned by this box */ @@ -139,9 +91,13 @@ typedef enum { IS_REPLACED = 1 << 12 /* box is a replaced element */ } box_flags; -/* Sides of a box */ + +/** + * Sides of a box + */ enum box_side { TOP, RIGHT, BOTTOM, LEFT }; + /** * Container for box border details */ @@ -151,31 +107,190 @@ struct box_border { int width; /**< border-width (pixels) */ }; -/** Node in box tree. All dimensions are in pixels. */ + +/** + * Table column data. + */ +struct column { + /** + * Type of column. + */ + enum { + COLUMN_WIDTH_UNKNOWN, + COLUMN_WIDTH_FIXED, + COLUMN_WIDTH_AUTO, + COLUMN_WIDTH_PERCENT, + COLUMN_WIDTH_RELATIVE + } type; + + /** + * Preferred width of column. Pixels for FIXED, percentage for + * PERCENT, relative units for RELATIVE, unused for AUTO. + */ + int width; + + /** + * Minimum width of content. + */ + int min; + + /** + * Maximum width of content. + */ + int max; + + /** + * Whether all of column's cells are css positioned. + */ + bool positioned; +}; + + +/** + * Linked list of object element parameters. + */ +struct object_param { + char *name; + char *value; + char *type; + char *valuetype; + struct object_param *next; +}; + + +/** + * Parameters for object element and similar elements. + */ +struct object_params { + struct nsurl *data; + char *type; + char *codetype; + struct nsurl *codebase; + struct nsurl *classid; + struct object_param *params; +}; + + +/** + * Node in box tree. All dimensions are in pixels. + */ struct box { - /** Type of box. */ + /** + * Type of box. + */ box_type type; - /** Box flags */ + /** + * Box flags + */ box_flags flags; - /** Computed styles for elements and their pseudo elements. NULL on - * non-element boxes. */ + /** + * DOM node that generated this box or NULL + */ + struct dom_node *node; + + /** + * Computed styles for elements and their pseudo elements. + * NULL on non-element boxes. + */ css_select_results *styles; - /** Style for this box. 0 for INLINE_CONTAINER and FLOAT_*. Pointer into - * a box's 'styles' select results, except for implied boxes, where it - * is a pointer to an owned computed style. */ + /** + * Style for this box. 0 for INLINE_CONTAINER and + * FLOAT_*. Pointer into a box's 'styles' select results, + * except for implied boxes, where it is a pointer to an + * owned computed style. + */ css_computed_style *style; - /** Coordinate of left padding edge relative to parent box, or relative - * to ancestor that contains this box in float_children for FLOAT_. */ + /** + * value of id attribute (or name for anchors) + */ + lwc_string *id; + + + /** + * Next sibling box, or NULL. + */ + struct box *next; + + /** + * Previous sibling box, or NULL. + */ + struct box *prev; + + /** + * First child box, or NULL. + */ + struct box *children; + + /** + * Last child box, or NULL. + */ + struct box *last; + + /** + * Parent box, or NULL. + */ + struct box *parent; + + /** + * INLINE_END box corresponding to this INLINE box, or INLINE + * box corresponding to this INLINE_END box. + */ + struct box *inline_end; + + + /** + * First float child box, or NULL. Float boxes are in the tree + * twice, in this list for the block box which defines the + * area for floats, and also in the standard tree given by + * children, next, prev, etc. + */ + struct box *float_children; + + /** + * Next sibling float box. + */ + struct box *next_float; + + /** + * If box is a float, points to box's containing block + */ + struct box *float_container; + + /** + * Level below which subsequent floats must be cleared. This + * is used only for boxes with float_children + */ + int clear_level; + + /** + * Level below which floats have been placed. + */ + int cached_place_below_level; + + + /** + * Coordinate of left padding edge relative to parent box, or + * relative to ancestor that contains this box in + * float_children for FLOAT_. + */ int x; - /** Coordinate of top padding edge, relative as for x. */ + /** + * Coordinate of top padding edge, relative as for x. + */ int y; - int width; /**< Width of content box (excluding padding etc.). */ - int height; /**< Height of content box (excluding padding etc.). */ + /** + * Width of content box (excluding padding etc.). + */ + int width; + /** + * Height of content box (excluding padding etc.). + */ + int height; /* These four variables determine the maximum extent of a box's * descendants. They are relative to the x,y coordinates of the box. @@ -196,205 +311,147 @@ struct box { int descendant_x1; /**< right edge of descendants */ int descendant_y1; /**< bottom edge of descendants */ - int margin[4]; /**< Margin: TOP, RIGHT, BOTTOM, LEFT. */ - int padding[4]; /**< Padding: TOP, RIGHT, BOTTOM, LEFT. */ - struct box_border border[4]; /**< Border: TOP, RIGHT, BOTTOM, LEFT. */ + /** + * Margin: TOP, RIGHT, BOTTOM, LEFT. + */ + int margin[4]; + + /** + * Padding: TOP, RIGHT, BOTTOM, LEFT. + */ + int padding[4]; - struct scrollbar *scroll_x; /**< Horizontal scroll. */ - struct scrollbar *scroll_y; /**< Vertical scroll. */ + /** + * Border: TOP, RIGHT, BOTTOM, LEFT. + */ + struct box_border border[4]; - /** Width of box taking all line breaks (including margins etc). Must - * be non-negative. */ + /** + * Horizontal scroll. + */ + struct scrollbar *scroll_x; + + /** + * Vertical scroll. + */ + struct scrollbar *scroll_y; + + /** + * Width of box taking all line breaks (including margins + * etc). Must be non-negative. + */ int min_width; - /** Width that would be taken with no line breaks. Must be - * non-negative. */ + + /** + * Width that would be taken with no line breaks. Must be + * non-negative. + */ int max_width; - /**< Byte offset within a textual representation of this content. */ - size_t byte_offset; - char *text; /**< Text, or 0 if none. Unterminated. */ - size_t length; /**< Length of text. */ + /** + * Text, or NULL if none. Unterminated. + */ + char *text; + + /** + * Length of text. + */ + size_t length; - /** Width of space after current text (depends on font and size). */ + /** + * Width of space after current text (depends on font and size). + */ int space; - struct nsurl *href; /**< Link, or 0. */ - const char *target; /**< Link target, or 0. */ - const char *title; /**< Title, or 0. */ - - unsigned int columns; /**< Number of columns for TABLE / TABLE_CELL. */ - unsigned int rows; /**< Number of rows for TABLE only. */ - unsigned int start_column; /**< Start column for TABLE_CELL only. */ - - struct box *next; /**< Next sibling box, or 0. */ - struct box *prev; /**< Previous sibling box, or 0. */ - struct box *children; /**< First child box, or 0. */ - struct box *last; /**< Last child box, or 0. */ - struct box *parent; /**< Parent box, or 0. */ - /** INLINE_END box corresponding to this INLINE box, or INLINE box - * corresponding to this INLINE_END box. */ - struct box *inline_end; + /** + * Byte offset within a textual representation of this content. + */ + size_t byte_offset; - /** First float child box, or 0. Float boxes are in the tree twice, in - * this list for the block box which defines the area for floats, and - * also in the standard tree given by children, next, prev, etc. */ - struct box *float_children; - /** Next sibling float box. */ - struct box *next_float; - /** If box is a float, points to box's containing block */ - struct box *float_container; - /** Level below which subsequent floats must be cleared. - * This is used only for boxes with float_children */ - int clear_level; - /* Level below which floats have been placed. */ - int cached_place_below_level; + /** + * Link, or NULL. + */ + struct nsurl *href; - /** List marker box if this is a list-item, or 0. */ - struct box *list_marker; + /** + * Link target, or NULL. + */ + const char *target; - struct column *col; /**< Array of table column data for TABLE only. */ + /** + * Title, or NULL. + */ + const char *title; - /** Form control data, or 0 if not a form control. */ - struct form_control* gadget; - char *usemap; /** (Image)map to use with this object, or 0 if none */ - lwc_string *id; /**< value of id attribute (or name for anchors) */ + /** + * Number of columns for TABLE / TABLE_CELL. + */ + unsigned int columns; - /** Background image for this box, or 0 if none */ - struct hlcache_handle *background; + /** + * Number of rows for TABLE only. + */ + unsigned int rows; - /** Object in this box (usually an image), or 0 if none. */ - struct hlcache_handle* object; - /** Parameters for the object, or 0. */ - struct object_params *object_params; + /** + * Start column for TABLE_CELL only. + */ + unsigned int start_column; - /** Iframe's browser_window, or NULL if none */ - struct browser_window *iframe; + /** + * Array of table column data for TABLE only. + */ + struct column *col; - struct dom_node *node; /**< DOM node that generated this box or NULL */ -}; + /** + * List item value. + */ + int list_value; -/** Table column data. */ -struct column { - /** Type of column. */ - enum { COLUMN_WIDTH_UNKNOWN, COLUMN_WIDTH_FIXED, - COLUMN_WIDTH_AUTO, COLUMN_WIDTH_PERCENT, - COLUMN_WIDTH_RELATIVE } type; - /** Preferred width of column. Pixels for FIXED, percentage for PERCENT, - * relative units for RELATIVE, unused for AUTO. */ - int width; - /** Minimum width of content. */ - int min; - /** Maximum width of content. */ - int max; - /** Whether all of column's cells are css positioned. */ - bool positioned; -}; + /** + * List marker box if this is a list-item, or NULL. + */ + struct box *list_marker; -/** Parameters for object element and similar elements. */ -struct object_params { - struct nsurl *data; - char *type; - char *codetype; - struct nsurl *codebase; - struct nsurl *classid; - struct object_param *params; -}; -/** Linked list of object element parameters. */ -struct object_param { - char *name; - char *value; - char *type; - char *valuetype; - struct object_param *next; -}; + /** + * Form control data, or NULL if not a form control. + */ + struct form_control* gadget; -/** Frame target names (constant pointers to save duplicating the strings many - * times). We convert _blank to _top for user-friendliness. */ -extern const char *TARGET_SELF; -extern const char *TARGET_PARENT; -extern const char *TARGET_TOP; -extern const char *TARGET_BLANK; - - - -struct box * box_create(css_select_results *styles, css_computed_style *style, - bool style_owned, struct nsurl *href, const char *target, - const char *title, lwc_string *id, void *context); -void box_add_child(struct box *parent, struct box *child); -void box_insert_sibling(struct box *box, struct box *new_box); -void box_unlink_and_free(struct box *box); -void box_free(struct box *box); -void box_free_box(struct box *box); -void box_bounds(struct box *box, struct rect *r); -void box_coords(struct box *box, int *x, int *y); -struct box *box_at_point( - const nscss_len_ctx *len_ctx, - struct box *box, const int x, const int y, - int *box_x, int *box_y); -struct box *box_pick_text_box(struct html_content *html, - int x, int y, int dir, int *dx, int *dy); -struct box *box_find_by_id(struct box *box, lwc_string *id); -bool box_visible(struct box *box); -void box_dump(FILE *stream, struct box *box, unsigned int depth, bool style); -/** - * Extract a URL from a relative link, handling junk like whitespace and - * attempting to read a real URL from "javascript:" links. - * - * \param content html content - * \param dsrel relative URL text taken from page - * \param base base for relative URLs - * \param result updated to target URL on heap, unchanged if extract failed - * \return true on success, false on memory exhaustion - */ -bool box_extract_link(const struct html_content *content, const struct dom_string *dsrel, struct nsurl *base, struct nsurl **result); + /** + * (Image)map to use with this object, or NULL if none + */ + char *usemap; -/** - * Applies the given scroll setup to a box. This includes scroll - * creation/deletion as well as scroll dimension updates. - * - * \param c content in which the box is located - * \param box the box to handle the scrolls for - * \param bottom whether the horizontal scrollbar should be present - * \param right whether the vertical scrollbar should be present - * \return true on success false otherwise - */ -nserror box_handle_scrollbars(struct content *c, struct box *box, - bool bottom, bool right); -bool box_vscrollbar_present(const struct box *box); -bool box_hscrollbar_present(const struct box *box); + /** + * Background image for this box, or NULL if none + */ + struct hlcache_handle *background; -nserror dom_to_box(struct dom_node *n, struct html_content *c, - box_construct_complete_cb cb, void **box_conversion_context); -nserror cancel_dom_to_box(void *box_conversion_context); -bool box_normalise_block( - struct box *block, - const struct box *root, - struct html_content *c); + /** + * Object in this box (usually an image), or NULL if none. + */ + struct hlcache_handle* object; -/** - * Check if layout box is a first child. - * - * \param[in] b Box to check. - * \return true iff box is first child. - */ -static inline bool box_is_first_child(struct box *b) -{ - return (b->parent == NULL || b == b->parent->children); -} + /** + * Parameters for the object, or NULL. + */ + struct object_params *object_params; + + + /** + * Iframe's browser_window, or NULL if none + */ + struct browser_window *iframe; + +}; -/** - * Retrieve the box for a dom node, if there is one - * - * \param node The DOM node - * \return The box if there is one - */ -struct box *box_for_node(struct dom_node *node); #endif |