128 err = dom_node_get_parent_node(n, &
parent);
129 if (err != DOM_NO_ERR)
137 if (err != DOM_NO_ERR)
140 if (
type != DOM_DOCUMENT_NODE)
156 memset(props, 0,
sizeof(*props));
162 dom_node *current_node = n;
164 struct box *parent_box;
169 err = dom_node_get_parent_node(current_node,
176 if (parent_box != NULL) {
185 if (current_node != n)
186 dom_node_unref(current_node);
196 err = dom_node_get_parent_node(current_node,
199 if (current_node != n)
200 dom_node_unref(current_node);
204 if (current_node != n)
205 dom_node_unref(current_node);
246static css_select_results *
248 const css_computed_style *parent_style,
249 const css_computed_style *root_style,
252 dom_string *s = NULL;
253 css_stylesheet *inline_style = NULL;
254 css_select_results *
styles;
260 err = dom_element_get_attribute(n, corestring_dom_style, &s);
261 if (err != DOM_NO_ERR) {
268 (
const uint8_t *) dom_string_data(s),
269 dom_string_byte_length(s),
272 c->
quirks != DOM_DOCUMENT_QUIRKS_MODE_NONE);
276 if (inline_style == NULL)
282 ctx.
quirks = (c->
quirks == DOM_DOCUMENT_QUIRKS_MODE_FULL);
293 if (inline_style != NULL)
294 css_stylesheet_destroy(inline_style);
315 const css_computed_style *
style)
317 struct box *gen = NULL;
318 enum css_display_e computed_display;
319 const css_computed_content_item *c_item;
329 css_computed_content(
style, &c_item) ==
330 CSS_CONTENT_NORMAL) {
337 if (computed_display == CSS_DISPLAY_BLOCK ||
338 computed_display == CSS_DISPLAY_TABLE) {
343 false, NULL, NULL, NULL, NULL,
content->bctx);
372 lwc_string *image_uri;
374 enum css_list_style_type_e list_style_type;
383 list_style_type = css_computed_list_style_type(
box->
style);
386 switch (list_style_type) {
387 case CSS_LIST_STYLE_TYPE_DISC:
389 marker->
text = (
char *)
"\342\200\242";
393 case CSS_LIST_STYLE_TYPE_CIRCLE:
395 marker->
text = (
char *)
"\342\227\213";
399 case CSS_LIST_STYLE_TYPE_SQUARE:
401 marker->
text = (
char *)
"\342\226\252";
408 case CSS_LIST_STYLE_TYPE_NONE:
414 if (css_computed_list_style_image(
box->
style, &image_uri) == CSS_LIST_STYLE_IMAGE_URI &&
415 (image_uri != NULL) &&
447 return css_computed_float(
box->
style) == CSS_FLOAT_LEFT ||
448 css_computed_float(
box->
style) == CSS_FLOAT_RIGHT;
473 dom_string *title0, *s;
474 lwc_string *
id = NULL;
475 enum css_display_e css_display;
476 struct box *
box = NULL, *old_box;
477 css_select_results *
styles = NULL;
478 lwc_string *bgimage_uri;
481 const css_computed_style *root_style = NULL;
483 assert(ctx->
n != NULL);
504 err = dom_element_get_attribute(ctx->
n, corestring_dom_title, &title0);
505 if (err != DOM_NO_ERR)
508 if (title0 != NULL) {
511 dom_string_unref(title0);
520 if (props.
title == NULL)
525 err = dom_element_get_attribute(ctx->
n, corestring_dom_id, &s);
526 if (err != DOM_NO_ERR)
530 err = dom_string_intern(s, &
id);
531 if (err != DOM_NO_ERR)
537 box =
box_create(styles, styles->styles[CSS_PSEUDO_ELEMENT_NONE],
false,
548 err = dom_element_get_attribute(ctx->
n, corestring_dom_colspan, &s);
549 if (err != DOM_NO_ERR)
553 const char *val = dom_string_data(s);
555 if (
'0' <= val[0] && val[0] <=
'9')
561 err = dom_element_get_attribute(ctx->
n, corestring_dom_rowspan, &s);
562 if (err != DOM_NO_ERR)
566 const char *val = dom_string_data(s);
568 if (
'0' <= val[0] && val[0] <=
'9')
569 box->
rows = strtol(val, NULL, 10);
577 if ((css_computed_position(
box->
style) == CSS_POSITION_ABSOLUTE ||
578 css_computed_position(
box->
style) == CSS_POSITION_FIXED) &&
579 (css_display == CSS_DISPLAY_INLINE ||
580 css_display == CSS_DISPLAY_INLINE_BLOCK ||
581 css_display == CSS_DISPLAY_INLINE_TABLE ||
582 css_display == CSS_DISPLAY_INLINE_FLEX)) {
616 convert_children) ==
false) {
623 box->
styles->styles[CSS_PSEUDO_ELEMENT_BEFORE]);
629 css_select_results_destroy(styles);
644 *convert_children =
false;
650 err = dom_node_set_user_data(ctx->
n,
651 corestring_dom___ns_key_box_node_data,
box, NULL,
653 if (err != DOM_NO_ERR)
671 "Box must have containing block.");
674 NULL, NULL, NULL, ctx->
bctx);
684 if (css_computed_background_image(
box->
style, &bgimage_uri) ==
685 CSS_BACKGROUND_IMAGE_IMAGE && bgimage_uri != NULL &&
694 error =
nsurl_create(lwc_string_data(bgimage_uri), &url);
709 if (*convert_children)
722 CSS_DISPLAY_LIST_ITEM) {
742 if (css_computed_float(
box->
style) == CSS_FLOAT_LEFT)
785 err = dom_node_has_child_nodes(n, &has_children);
786 if (err != DOM_NO_ERR)
789 if (has_children ==
false ||
798 NULL, NULL, NULL, NULL,
content->bctx);
810 box->
id == NULL ? NULL :
825 box->
styles->styles[CSS_PSEUDO_ELEMENT_AFTER]);
844 dom_node *
next = NULL;
848 err = dom_node_has_child_nodes(n, &has_children);
849 if (err != DOM_NO_ERR) {
854 if (convert_children && has_children) {
855 err = dom_node_get_first_child(n, &
next);
856 if (err != DOM_NO_ERR) {
862 err = dom_node_get_next_sibling(n, &
next);
863 if (err != DOM_NO_ERR) {
878 dom_node *parent_next = NULL;
880 err = dom_node_get_parent_node(n, &
parent);
881 if (err != DOM_NO_ERR) {
888 err = dom_node_get_next_sibling(
parent,
890 if (err != DOM_NO_ERR) {
896 if (parent_next != NULL) {
897 dom_node_unref(parent_next);
915 err = dom_node_get_parent_node(n, &
parent);
916 if (err != DOM_NO_ERR) {
923 err = dom_node_get_next_sibling(
parent, &
next);
924 if (err != DOM_NO_ERR) {
960 case CSS_TEXT_TRANSFORM_UPPERCASE:
961 for (i = 0; i < len; ++i)
962 if ((
unsigned char) s[i] < 0x80)
965 case CSS_TEXT_TRANSFORM_LOWERCASE:
966 for (i = 0; i < len; ++i)
967 if ((
unsigned char) s[i] < 0x80)
970 case CSS_TEXT_TRANSFORM_CAPITALIZE:
971 if ((
unsigned char) s[0] < 0x80)
973 for (i = 1; i < len; ++i)
974 if ((
unsigned char) s[i] < 0x80 &&
997 assert(ctx->
n != NULL);
1003 err = dom_characterdata_get_data(ctx->
n, &
content);
1004 if (err != DOM_NO_ERR ||
content == NULL)
1008 CSS_WHITE_SPACE_NORMAL ||
1010 CSS_WHITE_SPACE_NOWRAP) {
1022 if (
text[0] ==
' ' &&
text[1] == 0) {
1040 NULL, NULL, NULL, NULL, ctx->
bctx);
1078 CSS_TEXT_TRANSFORM_NONE)
1080 css_computed_text_transform(
1096 size_t text_len = dom_string_byte_length(
content);
1099 enum css_white_space_e white_space =
1103 assert(white_space == CSS_WHITE_SPACE_PRE ||
1104 white_space == CSS_WHITE_SPACE_PRE_LINE ||
1105 white_space == CSS_WHITE_SPACE_PRE_WRAP);
1107 text = malloc(text_len + 1);
1114 text[text_len] =
'\0';
1117 for (i = 0; i < text_len; i++)
1118 if (
text[i] ==
'\t')
1122 CSS_TEXT_TRANSFORM_NONE)
1124 css_computed_text_transform(
1137 if (*current ==
'\n')
1145 size_t len = strcspn(current,
"\r\n");
1147 char old = current[len];
1157 false, NULL, NULL, NULL, NULL,
1197 if (current[0] !=
'\0') {
1200 false, NULL, NULL, NULL, NULL,
1213 if (current[0] ==
'\r' && current[1] ==
'\n')
1234 bool convert_children;
1235 uint32_t num_processed = 0;
1236 const uint32_t max_processed_before_yield = 10;
1239 convert_children =
true;
1241 assert(ctx->
n != NULL);
1245 dom_node_unref(ctx->
n);
1252 while (
next != NULL) {
1256 err = dom_node_get_node_type(
next, &
type);
1257 if (err != DOM_NO_ERR) {
1259 dom_node_unref(
next);
1264 if (
type == DOM_ELEMENT_NODE)
1267 if (
type == DOM_TEXT_NODE) {
1271 dom_node_unref(ctx->
n);
1303 assert(ctx->
n == NULL);
1308 }
while (++num_processed < max_processed_before_yield);
1320 void **box_conversion_context)
1324 assert(box_conversion_context != NULL);
1326 if (c->
bctx == NULL) {
1329 if (c->
bctx == NULL) {
1334 ctx = malloc(
sizeof(*ctx));
1340 ctx->
n = dom_node_ref(
n);
1345 *box_conversion_context = ctx;
1362 dom_node_unref(ctx->
n);
1375 err = dom_node_get_user_data(n, corestring_dom___ns_key_box_node_data,
1377 if (err != DOM_NO_ERR)
1386 const dom_string *dsrel,
1390 char *s, *s1, *apos0 = 0, *apos1 = 0, *quot0 = 0, *quot1 = 0;
1391 unsigned int i, j, end;
1395 rel = dom_string_data(dsrel);
1397 s1 = s = malloc(3 * strlen(rel) + 1);
1404 for (end = strlen(rel);
1408 for (j = 0; i != end; i++) {
1409 if ((
unsigned char) rel[i] < 0x20) {
1411 }
else if (rel[i] ==
' ') {
1421 if (
content->enable_scripting ==
false) {
1423 if (strncmp(s,
"javascript:", 11) == 0) {
1424 apos0 = strchr(s,
'\'');
1426 apos1 = strchr(apos0 + 1,
'\'');
1427 quot0 = strchr(s,
'"');
1429 quot1 = strchr(quot0 + 1,
'"');
1430 if (apos0 && apos1 &&
1431 (!quot0 || !quot1 || apos0 < quot0)) {
1434 }
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.
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.