129 err = dom_node_get_parent_node(n, &
parent);
130 if (err != DOM_NO_ERR)
138 if (err != DOM_NO_ERR)
141 if (
type != DOM_DOCUMENT_NODE)
157 memset(props, 0,
sizeof(*props));
163 dom_node *current_node = n;
165 struct box *parent_box;
170 err = dom_node_get_parent_node(current_node,
177 if (parent_box != NULL) {
186 if (current_node != n)
187 dom_node_unref(current_node);
197 err = dom_node_get_parent_node(current_node,
200 if (current_node != n)
201 dom_node_unref(current_node);
205 if (current_node != n)
206 dom_node_unref(current_node);
247static css_select_results *
249 const css_computed_style *parent_style,
250 const css_computed_style *root_style,
253 dom_string *s = NULL;
254 css_stylesheet *inline_style = NULL;
255 css_select_results *
styles;
261 err = dom_element_get_attribute(n, corestring_dom_style, &s);
262 if (err != DOM_NO_ERR) {
269 (
const uint8_t *) dom_string_data(s),
270 dom_string_byte_length(s),
273 c->
quirks != DOM_DOCUMENT_QUIRKS_MODE_NONE);
277 if (inline_style == NULL)
283 ctx.
quirks = (c->
quirks == DOM_DOCUMENT_QUIRKS_MODE_FULL);
294 if (inline_style != NULL)
295 css_stylesheet_destroy(inline_style);
316 const css_computed_style *
style)
318 struct box *gen = NULL;
319 enum css_display_e computed_display;
320 const css_computed_content_item *c_item;
330 css_computed_content(
style, &c_item) ==
331 CSS_CONTENT_NORMAL) {
338 if (computed_display == CSS_DISPLAY_BLOCK ||
339 computed_display == CSS_DISPLAY_TABLE) {
344 false, NULL, NULL, NULL, NULL,
content->bctx);
373 lwc_string *image_uri;
375 enum css_list_style_type_e list_style_type;
384 list_style_type = css_computed_list_style_type(
box->
style);
387 switch (list_style_type) {
388 case CSS_LIST_STYLE_TYPE_DISC:
390 marker->
text = (
char *)
"\342\200\242";
394 case CSS_LIST_STYLE_TYPE_CIRCLE:
396 marker->
text = (
char *)
"\342\227\213";
400 case CSS_LIST_STYLE_TYPE_SQUARE:
402 marker->
text = (
char *)
"\342\226\252";
409 case CSS_LIST_STYLE_TYPE_NONE:
415 if (css_computed_list_style_image(
box->
style, &image_uri) == CSS_LIST_STYLE_IMAGE_URI &&
416 (image_uri != NULL) &&
448 return css_computed_float(
box->
style) == CSS_FLOAT_LEFT ||
449 css_computed_float(
box->
style) == CSS_FLOAT_RIGHT;
474 dom_string *title0, *s;
475 lwc_string *
id = NULL;
476 enum css_display_e css_display;
477 struct box *
box = NULL, *old_box;
478 css_select_results *
styles = NULL;
479 lwc_string *bgimage_uri;
482 const css_computed_style *root_style = NULL;
484 assert(ctx->
n != NULL);
505 err = dom_element_get_attribute(ctx->
n, corestring_dom_title, &title0);
506 if (err != DOM_NO_ERR)
509 if (title0 != NULL) {
512 dom_string_unref(title0);
521 if (props.
title == NULL)
526 err = dom_element_get_attribute(ctx->
n, corestring_dom_id, &s);
527 if (err != DOM_NO_ERR)
531 err = dom_string_intern(s, &
id);
532 if (err != DOM_NO_ERR)
538 box =
box_create(styles, styles->styles[CSS_PSEUDO_ELEMENT_NONE],
false,
549 err = dom_element_get_attribute(ctx->
n, corestring_dom_colspan, &s);
550 if (err != DOM_NO_ERR)
554 const char *val = dom_string_data(s);
557 if (
'0' <= val[0] && val[0] <=
'9')
563 err = dom_element_get_attribute(ctx->
n, corestring_dom_rowspan, &s);
564 if (err != DOM_NO_ERR)
568 const char *val = dom_string_data(s);
571 if (
'0' <= val[0] && val[0] <=
'9')
580 if ((css_computed_position(
box->
style) == CSS_POSITION_ABSOLUTE ||
581 css_computed_position(
box->
style) == CSS_POSITION_FIXED) &&
582 (css_display == CSS_DISPLAY_INLINE ||
583 css_display == CSS_DISPLAY_INLINE_BLOCK ||
584 css_display == CSS_DISPLAY_INLINE_TABLE ||
585 css_display == CSS_DISPLAY_INLINE_FLEX)) {
619 convert_children) ==
false) {
626 box->
styles->styles[CSS_PSEUDO_ELEMENT_BEFORE]);
632 css_select_results_destroy(styles);
647 *convert_children =
false;
653 err = dom_node_set_user_data(ctx->
n,
654 corestring_dom___ns_key_box_node_data,
box, NULL,
656 if (err != DOM_NO_ERR)
674 "Box must have containing block.");
677 NULL, NULL, NULL, ctx->
bctx);
687 if (css_computed_background_image(
box->
style, &bgimage_uri) ==
688 CSS_BACKGROUND_IMAGE_IMAGE && bgimage_uri != NULL &&
697 error =
nsurl_create(lwc_string_data(bgimage_uri), &url);
712 if (*convert_children)
725 CSS_DISPLAY_LIST_ITEM) {
745 if (css_computed_float(
box->
style) == CSS_FLOAT_LEFT)
788 err = dom_node_has_child_nodes(n, &has_children);
789 if (err != DOM_NO_ERR)
792 if (has_children ==
false ||
801 NULL, NULL, NULL, NULL,
content->bctx);
813 box->
id == NULL ? NULL :
828 box->
styles->styles[CSS_PSEUDO_ELEMENT_AFTER]);
847 dom_node *
next = NULL;
851 err = dom_node_has_child_nodes(n, &has_children);
852 if (err != DOM_NO_ERR) {
857 if (convert_children && has_children) {
858 err = dom_node_get_first_child(n, &
next);
859 if (err != DOM_NO_ERR) {
865 err = dom_node_get_next_sibling(n, &
next);
866 if (err != DOM_NO_ERR) {
881 dom_node *parent_next = NULL;
883 err = dom_node_get_parent_node(n, &
parent);
884 if (err != DOM_NO_ERR) {
891 err = dom_node_get_next_sibling(
parent,
893 if (err != DOM_NO_ERR) {
899 if (parent_next != NULL) {
900 dom_node_unref(parent_next);
918 err = dom_node_get_parent_node(n, &
parent);
919 if (err != DOM_NO_ERR) {
926 err = dom_node_get_next_sibling(
parent, &
next);
927 if (err != DOM_NO_ERR) {
963 case CSS_TEXT_TRANSFORM_UPPERCASE:
964 for (i = 0; i < len; ++i)
965 if ((
unsigned char) s[i] < 0x80)
968 case CSS_TEXT_TRANSFORM_LOWERCASE:
969 for (i = 0; i < len; ++i)
970 if ((
unsigned char) s[i] < 0x80)
973 case CSS_TEXT_TRANSFORM_CAPITALIZE:
974 if ((
unsigned char) s[0] < 0x80)
976 for (i = 1; i < len; ++i)
977 if ((
unsigned char) s[i] < 0x80 &&
1000 assert(ctx->
n != NULL);
1006 err = dom_characterdata_get_data(ctx->
n, &
content);
1007 if (err != DOM_NO_ERR ||
content == NULL)
1011 CSS_WHITE_SPACE_NORMAL ||
1013 CSS_WHITE_SPACE_NOWRAP) {
1025 if (
text[0] ==
' ' &&
text[1] == 0) {
1043 NULL, NULL, NULL, NULL, ctx->
bctx);
1081 CSS_TEXT_TRANSFORM_NONE)
1083 css_computed_text_transform(
1099 size_t text_len = dom_string_byte_length(
content);
1102 enum css_white_space_e white_space =
1106 assert(white_space == CSS_WHITE_SPACE_PRE ||
1107 white_space == CSS_WHITE_SPACE_PRE_LINE ||
1108 white_space == CSS_WHITE_SPACE_PRE_WRAP);
1110 text = malloc(text_len + 1);
1117 text[text_len] =
'\0';
1120 for (i = 0; i < text_len; i++)
1121 if (
text[i] ==
'\t')
1125 CSS_TEXT_TRANSFORM_NONE)
1127 css_computed_text_transform(
1140 if (*current ==
'\n')
1148 size_t len = strcspn(current,
"\r\n");
1150 char old = current[len];
1160 false, NULL, NULL, NULL, NULL,
1200 if (current[0] !=
'\0') {
1203 false, NULL, NULL, NULL, NULL,
1216 if (current[0] ==
'\r' && current[1] ==
'\n')
1237 bool convert_children;
1238 uint32_t num_processed = 0;
1239 const uint32_t max_processed_before_yield = 10;
1242 convert_children =
true;
1244 assert(ctx->
n != NULL);
1248 dom_node_unref(ctx->
n);
1255 while (
next != NULL) {
1259 err = dom_node_get_node_type(
next, &
type);
1260 if (err != DOM_NO_ERR) {
1262 dom_node_unref(
next);
1267 if (
type == DOM_ELEMENT_NODE)
1270 if (
type == DOM_TEXT_NODE) {
1274 dom_node_unref(ctx->
n);
1306 assert(ctx->
n == NULL);
1311 }
while (++num_processed < max_processed_before_yield);
1323 void **box_conversion_context)
1327 assert(box_conversion_context != NULL);
1329 if (c->
bctx == NULL) {
1332 if (c->
bctx == NULL) {
1337 ctx = malloc(
sizeof(*ctx));
1343 ctx->
n = dom_node_ref(
n);
1348 *box_conversion_context = ctx;
1365 dom_node_unref(ctx->
n);
1378 err = dom_node_get_user_data(n, corestring_dom___ns_key_box_node_data,
1380 if (err != DOM_NO_ERR)
1389 const dom_string *dsrel,
1393 char *s, *s1, *apos0 = 0, *apos1 = 0, *quot0 = 0, *quot1 = 0;
1394 unsigned int i, j, end;
1398 rel = dom_string_data(dsrel);
1400 s1 = s = malloc(3 * strlen(rel) + 1);
1407 for (end = strlen(rel);
1411 for (j = 0; i != end; i++) {
1412 if ((
unsigned char) rel[i] < 0x20) {
1414 }
else if (rel[i] ==
' ') {
1424 if (
content->enable_scripting ==
false) {
1426 if (strncmp(s,
"javascript:", 11) == 0) {
1427 apos0 = strchr(s,
'\'');
1429 apos1 = strchr(apos0 + 1,
'\'');
1430 quot0 = strchr(s,
'"');
1432 quot1 = strchr(quot0 + 1,
'"');
1433 if (apos0 && apos1 &&
1434 (!quot0 || !quot1 || apos0 < quot0)) {
1437 }
else if (quot0 && quot1) {
Helpers for ASCII string handling.
static char ascii_to_lower(char c)
Convert an upper case character to lower case.
static char ascii_to_upper(char c)
Convert a lower case character to upper case.
static bool ascii_is_space(char c)
Test whether a character is a whitespace character.
void(* box_construct_complete_cb)(struct html_content *c, bool success)
box_type
Type of a struct box.
static void box_construct_element_after(dom_node *n, html_content *content)
Complete construction of the box tree for an element.
static bool box__is_flex(const struct box *box)
static const box_type box_map[]
static bool box_construct_text(struct box_construct_ctx *ctx)
Construct the box tree for an XML text node.
static bool box__style_is_float(const struct box *box)
nserror dom_to_box(dom_node *n, html_content *c, box_construct_complete_cb cb, void **box_conversion_context)
Construct a box tree from a dom and html content.
static void box_extract_properties(dom_node *n, struct box_construct_props *props)
Extract transient construction properties.
static dom_node * next_node(dom_node *n, html_content *content, bool convert_children)
Find the next node in the DOM tree, completing element construction where appropriate.
struct box * box_for_node(dom_node *n)
Retrieve the box for a dom node, if there is one.
static css_select_results * box_get_style(html_content *c, const css_computed_style *parent_style, const css_computed_style *root_style, dom_node *n)
Get the style for an element.
static bool box_is_root(dom_node *n)
determine if a box is the root node
static void box_text_transform(char *s, unsigned int len, enum css_text_transform_e tt)
Apply the CSS text-transform property to given text for its ASCII chars.
bool box_extract_link(const html_content *content, const dom_string *dsrel, nsurl *base, nsurl **result)
static bool box__containing_block_is_flex(const struct box_construct_props *props)
static bool box_construct_marker(struct box *box, const char *title, struct box_construct_ctx *ctx, struct box *parent)
Construct a list marker box.
nserror cancel_dom_to_box(void *box_conversion_context)
aborts any ongoing box construction
static void convert_xml_to_box(struct box_construct_ctx *ctx)
Convert an ELEMENT node to a box tree fragment, then schedule conversion of the next ELEMENT node.
static void box_construct_generate(dom_node *n, html_content *content, struct box *box, const css_computed_style *style)
Construct the box required for a generated element.
static bool box_construct_element(struct box_construct_ctx *ctx, bool *convert_children)
Construct the box tree for an XML element.
static const content_type image_types
HTML Box tree construction interface.
struct box * box_create(css_select_results *styles, css_computed_style *style, bool style_owned, nsurl *href, const char *target, const char *title, lwc_string *id, void *context)
Create a box tree node.
void box_add_child(struct box *parent, struct box *child)
Add a child to a box tree node.
Box tree manipulation interface.
bool box_normalise_block(struct box *block, const struct box *root, html_content *c)
Ensure the box tree is correctly nested by adding and removing nodes.
HTML Box tree normalise interface.
bool convert_special_elements(dom_node *node, html_content *content, struct box *box, bool *convert_children)
call an elements special conversion handler
HTML Box tree construction special element conversion interface.
static uint8_t ns_computed_display(const css_computed_style *style, bool root)
Temporary helper wrappers for for libcss computed style getter, while we don't support all values of ...
static uint8_t ns_computed_display_static(const css_computed_style *style)
Temporary helper wrappers for for libcss computed style getter, while we don't support all values of ...
bool html_fetch_object(html_content *c, nsurl *url, struct box *box, content_type permitted_types, bool background)
Start a fetch for an object required by a page.
HTML content object interface.
content_type
The type of a content.
@ CONTENT_IMAGE
All images.
Useful interned string pointers (interface).
nserror
Enumeration of error codes.
@ NSERROR_NOMEM
Memory exhaustion.
static struct directory * root
struct netsurf_table * guit
The global interface table.
Interface to core interface table.
Interface to platform-specific miscellaneous browser operation table.
NetSurf URL handling (interface).
nserror nsurl_create(const char *const url_s, nsurl **url)
Create a NetSurf URL object from a URL string.
void nsurl_unref(nsurl *url)
Drop a reference to a NetSurf URL object.
const char * nsurl_access(const nsurl *url)
Access a NetSurf URL object as a string.
nserror nsurl_join(const nsurl *base, const char *rel, nsurl **joined)
Join a base url to a relative link part, creating a new NetSurf URL object.
struct nsurl nsurl
NetSurf URL object.
Private data for text/html content.
css_select_results * nscss_get_style(nscss_select_ctx *ctx, dom_node *n, const css_media *media, const css_unit_ctx *unit_len_ctx, const css_stylesheet *inline_style)
Get style selection results for an element.
css_stylesheet * nscss_create_inline_style(const uint8_t *data, size_t len, const char *charset, const char *url, bool allow_quirks)
Create an inline style.
static css_error parent_node(void *pw, void *node, void **parent)
Callback to retrieve the parent of a node.
Interface to utility string handling.
char * squash_whitespace(const char *s)
Replace consecutive whitespace with a single space.
Context for box tree construction.
box_construct_complete_cb cb
Callback to invoke on completion.
struct box * root_box
Root box in the tree.
dom_node * n
Current node to process.
html_content * content
Content we're constructing for.
Transient properties for construction of current node.
struct nsurl * href
Current link target, or NULL if none.
bool node_is_root
Whether the current node is the root of the DOM tree.
struct box * containing_block
Identity of the current block-level container.
const char * target
Current frame target, or NULL if none.
struct box * inline_container
Current container for inlines, or NULL if none.
const css_computed_style * parent_style
Style from which to inherit, or NULL if none.
const char * title
Current title attribute, or NULL if none.
struct box * parent
Parent box, or NULL.
lwc_string * id
value of id attribute (or name for anchors)
const char * title
Title, or NULL.
struct box * inline_end
INLINE_END box corresponding to this INLINE box, or INLINE box corresponding to this INLINE_END box.
struct box * prev
Previous sibling box, or NULL.
struct box * list_marker
List marker box if this is a list-item, or NULL.
const char * target
Link target, or NULL.
css_select_results * styles
Computed styles for elements and their pseudo elements.
struct box * last
Last child box, or NULL.
struct box * next
Next sibling box, or NULL.
box_type type
Type of box.
struct nsurl * href
Link, or NULL.
css_computed_style * style
Style for this box.
size_t length
Length of text.
char * text
Text, or NULL if none.
box_flags flags
Box flags.
int space
Width of space after current text (depends on font and size).
struct form_control * gadget
Form control data, or NULL if not a form control.
unsigned int rows
Number of rows for TABLE only.
struct dom_node * node
DOM node that generated this box or NULL.
unsigned int columns
Number of columns for TABLE / TABLE_CELL.
Content which corresponds to a single URL.
nserror(* schedule)(int t, void(*callback)(void *p), void *p)
Schedule a callback.
Data specific to CONTENT_HTML.
dom_document_quirks_mode quirks
Quirkyness of document.
int * bctx
A talloc context purely for the render box tree.
char * encoding
Encoding of source, NULL if unknown.
struct nsurl * base_url
Base URL (may be a copy of content->url).
css_select_ctx * select_ctx
Style selection media specification.
css_unit_ctx unit_len_ctx
CSS length conversion context for document.
struct box * layout
Box tree, or NULL.
struct gui_misc_table * misc
Browser table.
const css_computed_style * parent_style
const css_computed_style * root_style
char * talloc_strdup(const void *t, const char *p)
#define talloc_zero(ctx, type)
Option reading and saving interface.
#define nsoption_bool(OPTION)
Get the value of a boolean option.
Interface to a number of general purpose functionality.
#define clamp(x, low, high)
static nserror text(const struct redraw_context *ctx, const struct plot_font_style *fstyle, int x, int y, const char *text, size_t length)
Text plotting.