718 lines
18 KiB
C
718 lines
18 KiB
C
/*
|
|
* libwebsockets - small server side websockets and web server implementation
|
|
*
|
|
* Copyright (C) 2010 - 2022 Andy Green <andy@warmcat.com>
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to
|
|
* deal in the Software without restriction, including without limitation the
|
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
* sell copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
* IN THE SOFTWARE.
|
|
*
|
|
* Extremely Lightweight HTML5 Stream Parser, same approach as lecp but for
|
|
* html5.
|
|
*/
|
|
|
|
#if !defined(LHP_MAX_ELEMS_NEST)
|
|
#define LHP_MAX_ELEMS_NEST 32
|
|
#endif
|
|
#if !defined(LHP_MAX_DEPTH)
|
|
#define LHP_MAX_DEPTH 12
|
|
#endif
|
|
#if !defined(LHP_STRING_CHUNK)
|
|
#define LHP_STRING_CHUNK 254
|
|
#endif
|
|
|
|
enum lhp_callbacks {
|
|
|
|
LHPCB_ERR_ATTRIB_SYNTAX = -5,
|
|
LHPCB_ERR_ATTRIB_LEN = -4,
|
|
LHPCB_ERR_OOM = -3,
|
|
LHPCB_ERR_ELEM_DEPTH = -2,
|
|
LHPCB_CONTINUE = -1,
|
|
|
|
LHPCB_CONSTRUCTED = 0,
|
|
LHPCB_DESTRUCTED = 1,
|
|
|
|
LHPCB_COMPLETE = 2,
|
|
LHPCB_FAILED = 3,
|
|
|
|
LHPCB_ELEMENT_START = 4, /* reported at end of <> */
|
|
LHPCB_ELEMENT_END = 5,
|
|
|
|
LHPCB_CONTENT = 6,
|
|
|
|
LHPCB_COMMENT = 7,
|
|
};
|
|
|
|
/*
|
|
* CSS v2.1 full property set, taken from
|
|
*
|
|
* https://www.w3.org/TR/CSS21/propidx.html
|
|
*/
|
|
|
|
typedef enum lcsp_props {
|
|
LCSP_PROP_AZIMUTH,
|
|
LCSP_PROP_BACKGROUND_ATTACHMENT,
|
|
LCSP_PROP_BACKGROUND_COLOR,
|
|
LCSP_PROP_BACKGROUND_IMAGE,
|
|
LCSP_PROP_BACKGROUND_POSITION,
|
|
LCSP_PROP_BACKGROUND_REPEAT,
|
|
LCSP_PROP_BACKGROUND,
|
|
LCSP_PROP_BORDER_COLLAPSE,
|
|
LCSP_PROP_BORDER_COLOR,
|
|
LCSP_PROP_BORDER_SPACING,
|
|
LCSP_PROP_BORDER_STYLE,
|
|
LCSP_PROP_BORDER_TOP,
|
|
LCSP_PROP_BORDER_RIGHT,
|
|
LCSP_PROP_BORDER_BOTTOM,
|
|
LCSP_PROP_BORDER_LEFT,
|
|
LCSP_PROP_BORDER_TOP_COLOR,
|
|
LCSP_PROP_BORDER_RIGHT_COLOR,
|
|
LCSP_PROP_BORDER_BOTTOM_COLOR,
|
|
LCSP_PROP_BORDER_LEFT_COLOR,
|
|
LCSP_PROP_BORDER_TOP_STYLE,
|
|
LCSP_PROP_BORDER_RIGHT_STYLE,
|
|
LCSP_PROP_BORDER_BOTTOM_STYLE,
|
|
LCSP_PROP_BORDER_LEFT_STYLE,
|
|
LCSP_PROP_BORDER_TOP_WIDTH,
|
|
LCSP_PROP_BORDER_RIGHT_WIDTH,
|
|
LCSP_PROP_BORDER_BOTTOM_WIDTH,
|
|
LCSP_PROP_BORDER_LEFT_WIDTH,
|
|
LCSP_PROP_BORDER_WIDTH,
|
|
LCSP_PROP_BORDER_TOP_LEFT_RADIUS,
|
|
LCSP_PROP_BORDER_TOP_RIGHT_RADIUS,
|
|
LCSP_PROP_BORDER_BOTTOM_LEFT_RADIUS,
|
|
LCSP_PROP_BORDER_BOTTOM_RIGHT_RADIUS,
|
|
LCSP_PROP_BORDER_RADIUS,
|
|
LCSP_PROP_BORDER,
|
|
LCSP_PROP_BOTTOM,
|
|
LCSP_PROP_CAPTION_SIDE,
|
|
LCSP_PROP_CLEAR,
|
|
LCSP_PROP_CLIP,
|
|
LCSP_PROP_COLOR,
|
|
LCSP_PROP_CONTENT,
|
|
LCSP_PROP_COUNTER_INCREMENT,
|
|
LCSP_PROP_COUNTER_RESET,
|
|
LCSP_PROP_CUE_AFTER,
|
|
LCSP_PROP_CUE_BEFORE,
|
|
LCSP_PROP_CUE,
|
|
LCSP_PROP_CURSOR,
|
|
LCSP_PROP_DIRECTION,
|
|
LCSP_PROP_DISPLAY,
|
|
LCSP_PROP_ELEVATION,
|
|
LCSP_PROP_EMPTY_CELLS,
|
|
LCSP_PROP_FLOAT,
|
|
LCSP_PROP_FONT_FAMILY,
|
|
LCSP_PROP_FONT_SIZE,
|
|
LCSP_PROP_FONT_STYLE,
|
|
LCSP_PROP_FONT_VARAIANT,
|
|
LCSP_PROP_FONT_WEIGHT,
|
|
LCSP_PROP_FONT,
|
|
LCSP_PROP_HEIGHT,
|
|
LCSP_PROP_LEFT,
|
|
LCSP_PROP_LETTER_SPACING,
|
|
LCSP_PROP_LINE_HEIGHT,
|
|
LCSP_PROP_LIST_STYLE_IMAGE,
|
|
LCSP_PROP_LIST_STYLE_POSITION,
|
|
LCSP_PROP_LIST_STYLE_TYPE,
|
|
LCSP_PROP_LIST_STYLE,
|
|
LCSP_PROP_MARGIN_RIGHT,
|
|
LCSP_PROP_MARGIN_LEFT,
|
|
LCSP_PROP_MARGIN_TOP,
|
|
LCSP_PROP_MARGIN_BOTTOM,
|
|
LCSP_PROP_MARGIN,
|
|
LCSP_PROP_MAX_HEIGHT,
|
|
LCSP_PROP_MAX_WIDTH,
|
|
LCSP_PROP_MIN_HEIGHT,
|
|
LCSP_PROP_MIN_WIDTH,
|
|
LCSP_PROP_ORPHANS,
|
|
LCSP_PROP_OUTLINE_COLOR,
|
|
LCSP_PROP_OUTLINE_STYLE,
|
|
LCSP_PROP_OUTLINE_WIDTH,
|
|
LCSP_PROP_OUTLINE,
|
|
LCSP_PROP_OVERFLOW,
|
|
LCSP_PROP_PADDING_TOP,
|
|
LCSP_PROP_PADDING_RIGHT,
|
|
LCSP_PROP_PADDING_BOTTOM,
|
|
LCSP_PROP_PADDING_LEFT,
|
|
LCSP_PROP_PADDING,
|
|
LCSP_PROP_PAGE_BREAK_AFTER,
|
|
LCSP_PROP_PAGE_BREAK_BEFORE,
|
|
LCSP_PROP_PAGE_BREAK_INSIDE,
|
|
LCSP_PROP_PAUSE_AFTER,
|
|
LCSP_PROP_PAUSE_BEFORE,
|
|
LCSP_PROP_PAUSE,
|
|
LCSP_PROP_PITCH_RANGE,
|
|
LCSP_PROP_PITCH,
|
|
LCSP_PROP_PLAY_DURING,
|
|
LCSP_PROP_POSITION,
|
|
LCSP_PROP_QUOTES,
|
|
LCSP_PROP_RICHNESS,
|
|
LCSP_PROP_RIGHT,
|
|
LCSP_PROP_SPEAK_HEADER,
|
|
LCSP_PROP_SPEAK_NUMERAL,
|
|
LCSP_PROP_SPEAK_PUNCTUATION,
|
|
LCSP_PROP_SPEAK,
|
|
LCSP_PROP_SPEECH_RATE,
|
|
LCSP_PROP_STRESS,
|
|
LCSP_PROP_TABLE_LAYOUT,
|
|
LCSP_PROP_TEXT_ALIGN,
|
|
LCSP_PROP_TEXT_DECORATION,
|
|
LCSP_PROP_TEXT_INDENT,
|
|
LCSP_PROP_TEXT_TRANSFORM,
|
|
LCSP_PROP_TOP,
|
|
LCSP_PROP_UNICODE_BIDI,
|
|
LCSP_PROP_VERTICAL_ALIGN,
|
|
LCSP_PROP_VISIBILITY,
|
|
LCSP_PROP_VOICE_FAMILY,
|
|
LCSP_PROP_VOLUME,
|
|
LCSP_PROP_WHITE_SPACE,
|
|
LCSP_PROP_WIDOWS,
|
|
LCSP_PROP_WIDTH,
|
|
LCSP_PROP_WORD_SPACING,
|
|
LCSP_PROP_Z_INDEX,
|
|
|
|
LCSP_PROP__COUNT /* always last */
|
|
} lcsp_props_t;
|
|
|
|
/*
|
|
* Indexes for the well-known property values
|
|
*/
|
|
|
|
typedef enum {
|
|
LCSP_PROPVAL_ABOVE,
|
|
LCSP_PROPVAL_ABSOLUTE,
|
|
LCSP_PROPVAL_ALWAYS,
|
|
LCSP_PROPVAL_ARMENIAN,
|
|
LCSP_PROPVAL_AUTO,
|
|
LCSP_PROPVAL_AVOID,
|
|
LCSP_PROPVAL_BASELINE,
|
|
LCSP_PROPVAL_BEHIND,
|
|
LCSP_PROPVAL_BELOW,
|
|
LCSP_PROPVAL_BIDI_OVERRIDE,
|
|
LCSP_PROPVAL_BLINK,
|
|
LCSP_PROPVAL_BLOCK,
|
|
LCSP_PROPVAL_BOLD,
|
|
LCSP_PROPVAL_BOLDER,
|
|
LCSP_PROPVAL_BOTH,
|
|
LCSP_PROPVAL_BOTTOM,
|
|
LCSP_PROPVAL_CAPITALIZE,
|
|
LCSP_PROPVAL_CAPTION,
|
|
LCSP_PROPVAL_CENTER,
|
|
LCSP_PROPVAL_CIRCLE,
|
|
LCSP_PROPVAL_CLOSE_QUOTE,
|
|
LCSP_PROPVAL_CODE,
|
|
LCSP_PROPVAL_COLLAPSE,
|
|
LCSP_PROPVAL_CONTINUOUS,
|
|
LCSP_PROPVAL_CROSSHAIR,
|
|
LCSP_PROPVAL_DECIMAL_LEADING_ZERO,
|
|
LCSP_PROPVAL_DECIMAL,
|
|
LCSP_PROPVAL_DIGITS,
|
|
LCSP_PROPVAL_DISC,
|
|
LCSP_PROPVAL_EMBED,
|
|
LCSP_PROPVAL_E_RESIZE,
|
|
LCSP_PROPVAL_FIXED,
|
|
LCSP_PROPVAL_GEORGIAN,
|
|
LCSP_PROPVAL_HELP,
|
|
LCSP_PROPVAL_HIDDEN,
|
|
LCSP_PROPVAL_HIDE,
|
|
LCSP_PROPVAL_HIGH,
|
|
LCSP_PROPVAL_HIGHER,
|
|
LCSP_PROPVAL_ICON,
|
|
LCSP_PROPVAL_INHERIT,
|
|
LCSP_PROPVAL_INLINE,
|
|
LCSP_PROPVAL_INLINE_BLOCK,
|
|
LCSP_PROPVAL_INLINE_TABLE,
|
|
LCSP_PROPVAL_INVERT,
|
|
LCSP_PROPVAL_ITALIC,
|
|
LCSP_PROPVAL_JUSTIFY,
|
|
LCSP_PROPVAL_LEFT,
|
|
LCSP_PROPVAL_LIGHTER,
|
|
LCSP_PROPVAL_LINE_THROUGH,
|
|
LCSP_PROPVAL_LIST_ITEM,
|
|
LCSP_PROPVAL_LOW,
|
|
LCSP_PROPVAL_LOWER,
|
|
LCSP_PROPVAL_LOWER_ALPHA,
|
|
LCSP_PROPVAL_LOWERCASE,
|
|
LCSP_PROPVAL_LOWER_GREEK,
|
|
LCSP_PROPVAL_LOWER_LATIN,
|
|
LCSP_PROPVAL_LOWER_ROMAN,
|
|
LCSP_PROPVAL_LTR,
|
|
LCSP_PROPVAL_MENU,
|
|
LCSP_PROPVAL_MESSAGE_BOX,
|
|
LCSP_PROPVAL_MIDDLE,
|
|
LCSP_PROPVAL_MIX,
|
|
LCSP_PROPVAL_MOVE,
|
|
LCSP_PROPVAL_NE_RESIZE,
|
|
LCSP_PROPVAL_NO_CLOSE_QUOTE,
|
|
LCSP_PROPVAL_NONE,
|
|
LCSP_PROPVAL_NO_OPEN_QUOTE,
|
|
LCSP_PROPVAL_NO_REPEAT,
|
|
LCSP_PROPVAL_NORMAL,
|
|
LCSP_PROPVAL_NOWRAP,
|
|
LCSP_PROPVAL_N_RESIZE,
|
|
LCSP_PROPVAL_NW_RESIZE,
|
|
LCSP_PROPVAL_OBLIQUE,
|
|
LCSP_PROPVAL_ONCE,
|
|
LCSP_PROPVAL_OPEN_QUOTE,
|
|
LCSP_PROPVAL_OUTSIDE,
|
|
LCSP_PROPVAL_OVERLINE,
|
|
LCSP_PROPVAL_POINTER,
|
|
LCSP_PROPVAL_PRE,
|
|
LCSP_PROPVAL_PRE_LINE,
|
|
LCSP_PROPVAL_PRE_WRAP,
|
|
LCSP_PROPVAL_PROGRESS,
|
|
LCSP_PROPVAL_RELATIVE,
|
|
LCSP_PROPVAL_REPEAT,
|
|
LCSP_PROPVAL_REPEAT_X,
|
|
LCSP_PROPVAL_REPEAT_Y,
|
|
LCSP_PROPVAL_RIGHT,
|
|
LCSP_PROPVAL_RTL,
|
|
LCSP_PROPVAL_SCROLL,
|
|
LCSP_PROPVAL_SEPARATE,
|
|
LCSP_PROPVAL_SE_RESIZE,
|
|
LCSP_PROPVAL_SHOW,
|
|
LCSP_PROPVAL_SILENT,
|
|
LCSP_PROPVAL_SMALL_CAPS,
|
|
LCSP_PROPVAL_SMALL_CAPTION,
|
|
LCSP_PROPVAL_SPELL_OUT,
|
|
LCSP_PROPVAL_SQUARE,
|
|
LCSP_PROPVAL_S_RESIZE,
|
|
LCSP_PROPVAL_STATIC,
|
|
LCSP_PROPVAL_STATUS_BAR,
|
|
LCSP_PROPVAL_SUB,
|
|
LCSP_PROPVAL_SUPER,
|
|
LCSP_PROPVAL_SW_RESIZE,
|
|
LCSP_PROPVAL_TABLE,
|
|
LCSP_PROPVAL_TABLE_CAPTION,
|
|
LCSP_PROPVAL_TABLE_CELL,
|
|
LCSP_PROPVAL_TABLE_COLUMN,
|
|
LCSP_PROPVAL_TABLE_COLUMN_GROUP,
|
|
LCSP_PROPVAL_TABLE_FOOTER_GROUP,
|
|
LCSP_PROPVAL_TABLE_HEADER_GROUP,
|
|
LCSP_PROPVAL_TABLE_ROW,
|
|
LCSP_PROPVAL_TABLE_ROW_GROUP,
|
|
LCSP_PROPVAL_TEXT_BOTTOM,
|
|
LCSP_PROPVAL_TEXT_TOP,
|
|
LCSP_PROPVAL_TEXT,
|
|
LCSP_PROPVAL_TOP,
|
|
LCSP_PROPVAL_TRANSPARENT,
|
|
LCSP_PROPVAL_UNDERLINE,
|
|
LCSP_PROPVAL_UPPER_ALPHA,
|
|
LCSP_PROPVAL_UPPERCASE,
|
|
LCSP_PROPVAL_UPPER_LATIN,
|
|
LCSP_PROPVAL_UPPER_ROMAN,
|
|
LCSP_PROPVAL_VISIBLE,
|
|
LCSP_PROPVAL_WAIT,
|
|
LCSP_PROPVAL_W_RESIZE,
|
|
|
|
LCSP_PROPVAL__COUNT /* always last */
|
|
} lcsp_propvals_t;
|
|
|
|
struct lhp_ctx;
|
|
typedef lws_stateful_ret_t (*lhp_callback)(struct lhp_ctx *ctx, char reason);
|
|
|
|
/* html attribute */
|
|
|
|
typedef struct lhp_atr {
|
|
lws_dll2_t list;
|
|
size_t name_len; /* 0 if it is elem tag */
|
|
size_t value_len;
|
|
|
|
/* name+NUL then value+NUL follow */
|
|
} lhp_atr_t;
|
|
|
|
/*
|
|
* In order to lay out the table, we have to incrementally adjust all foregoing
|
|
* DLOs as newer cells change the situation. So we have to keep track of all
|
|
* cell DLOs in a stack of tables until it's all done.
|
|
*/
|
|
|
|
typedef struct {
|
|
lws_dll2_t list; /* ps->table_cols */
|
|
|
|
lws_dll2_owner_t row_dlos; /* lws_dlo_t in column */
|
|
|
|
lws_fx_t height; /* currently computed row height */
|
|
} lhp_table_row_t;
|
|
|
|
typedef struct {
|
|
lws_dll2_t list; /* ps->table_cols */
|
|
|
|
lws_dll2_owner_t col_dlos; /* lws_dlo_t in column */
|
|
|
|
lws_fx_t width; /* currently computed column width */
|
|
} lhp_table_col_t;
|
|
|
|
struct lcsp_atr;
|
|
|
|
#define CCPAS_TOP 0
|
|
#define CCPAS_RIGHT 1
|
|
#define CCPAS_BOTTOM 2
|
|
#define CCPAS_LEFT 3
|
|
|
|
typedef struct lhp_pstack {
|
|
lws_dll2_t list;
|
|
void *user; /* private to the stack level */
|
|
lhp_callback cb;
|
|
|
|
/* static: x,y: offset from parent, w,h: surface size of this object */
|
|
lws_box_t drt;
|
|
|
|
/* dynamic cursor inside drt for progressive child placement */
|
|
lws_fx_t curx;
|
|
lws_fx_t cury;
|
|
lws_fx_t widest;
|
|
lws_fx_t deepest;
|
|
|
|
lws_dlo_t *dlo_set_curx;
|
|
lws_dlo_t *dlo_set_cury;
|
|
|
|
lws_dll2_owner_t atr; /* lhp_atr_t */
|
|
|
|
const lws_display_font_t *f;
|
|
|
|
const struct lcsp_atr *css_background_color;
|
|
const struct lcsp_atr *css_color;
|
|
|
|
const struct lcsp_atr *css_position;
|
|
const struct lcsp_atr *css_display;
|
|
const struct lcsp_atr *css_width;
|
|
const struct lcsp_atr *css_height;
|
|
|
|
const struct lcsp_atr *css_border_radius[4];
|
|
|
|
const struct lcsp_atr *css_pos[4];
|
|
const struct lcsp_atr *css_margin[4];
|
|
const struct lcsp_atr *css_padding[4];
|
|
|
|
uint16_t tr_idx; /* in table */
|
|
uint16_t td_idx; /* in current tr */
|
|
|
|
uint8_t is_block:1; /* children use space in our drt */
|
|
uint8_t is_table:1;
|
|
|
|
/* user layout owns these after initial values set */
|
|
|
|
lws_dlo_t *dlo;
|
|
const lws_display_font_t *font;
|
|
int oi[4];
|
|
int positioned[4];
|
|
int rel_layout_cursor[4];
|
|
uint8_t runon; /* continues same line */
|
|
|
|
} lhp_pstack_t;
|
|
|
|
typedef enum lcsp_css_units {
|
|
LCSP_UNIT_NONE,
|
|
|
|
LCSP_UNIT_NUM, /* u.i */
|
|
|
|
LCSP_UNIT_LENGTH_EM, /* u.i */
|
|
LCSP_UNIT_LENGTH_EX, /* u.i */
|
|
LCSP_UNIT_LENGTH_IN, /* u.i */
|
|
LCSP_UNIT_LENGTH_CM, /* u.i */
|
|
LCSP_UNIT_LENGTH_MM, /* u.i */
|
|
LCSP_UNIT_LENGTH_PT, /* u.i */
|
|
LCSP_UNIT_LENGTH_PC, /* u.i */
|
|
LCSP_UNIT_LENGTH_PX, /* u.i */
|
|
LCSP_UNIT_LENGTH_PERCENT, /* u.i */
|
|
|
|
LCSP_UNIT_ANGLE_ABS_DEG, /* u.i */
|
|
LCSP_UNIT_ANGLE_REL_DEG, /* u.i */
|
|
|
|
LCSP_UNIT_FREQ_HZ, /* u.i */
|
|
|
|
LCSP_UNIT_RGBA, /* u.rgba */
|
|
|
|
LCSP_UNIT_URL, /* string at end of atr */
|
|
LCSP_UNIT_STRING, /* string at end of atr */
|
|
LCSP_UNIT_DATA, /* binary data at end of atr */
|
|
|
|
} lcsp_css_units_t;
|
|
|
|
typedef struct lcsp_atr {
|
|
lws_dll2_t list;
|
|
|
|
int propval; /* lcsp_propvals_t LCSP_PROPVAL_ */
|
|
|
|
size_t value_len; /* for string . url */
|
|
lcsp_css_units_t unit;
|
|
|
|
union {
|
|
lws_fx_t i;
|
|
uint32_t rgba; /* for colours */
|
|
} u;
|
|
|
|
lws_fx_t r;
|
|
|
|
uint8_t op;
|
|
|
|
/* .value_len bytes follow (for strings and blobs) */
|
|
} lcsp_atr_t;
|
|
|
|
/* css definitions like font-weight: */
|
|
typedef struct lcsp_defs {
|
|
lws_dll2_t list;
|
|
lws_dll2_owner_t atrs; /* lcsp_atr_t */
|
|
lcsp_props_t prop; /* lcsp_props_t, LCSP_PROP_* */
|
|
} lcsp_defs_t;
|
|
|
|
typedef struct lcsp_names {
|
|
lws_dll2_t list;
|
|
size_t name_len;
|
|
|
|
/* name + NUL follow */
|
|
} lcsp_names_t;
|
|
|
|
typedef struct lcsp_stanza { /* css stanza, with names and defs */
|
|
lws_dll2_t list;
|
|
|
|
lws_dll2_owner_t names; /* lcsp_names_t */
|
|
lws_dll2_owner_t defs; /* lcsp_defs_t */
|
|
|
|
} lcsp_stanza_t;
|
|
|
|
/*
|
|
* A list of stanza references can easily have to bring in the same stanza
|
|
* multiple times, eg, <div><span class=x><div> won't work unless the div
|
|
* stanzas are listed twice at different places in the list. It means we can't
|
|
* use dll2 directly since the number of references is open-ended.
|
|
*
|
|
* lcsp_stanza_ptr provides indirection that allows multiple listings.
|
|
*/
|
|
|
|
typedef struct lcsp_stanza_ptr {
|
|
lws_dll2_t list;
|
|
|
|
lcsp_stanza_t *stz;
|
|
} lcsp_stanza_ptr_t;
|
|
|
|
typedef struct lcsp_atr_ptr {
|
|
lws_dll2_t list;
|
|
|
|
lcsp_atr_t *atr;
|
|
} lcsp_atr_ptr_t;
|
|
|
|
#define LHP_FLAG_DOCUMENT_END (1 << 0)
|
|
|
|
typedef struct lhp_ctx {
|
|
lws_dll2_owner_t stack; /* lhp_pstack_t */
|
|
|
|
struct lwsac *cssac; /* css allocations all in an ac */
|
|
struct lwsac *cascadeac; /* active_stanzas ac */
|
|
struct lwsac *propatrac; /* prop atr query results ac */
|
|
lws_dll2_owner_t css; /* lcsp_stanza_t (all in ac) */
|
|
|
|
lws_dll2_owner_t *ids;
|
|
|
|
lws_fx_t tf;
|
|
lcsp_css_units_t unit;
|
|
lcsp_stanza_t *stz; /* current stanza getting properties */
|
|
lcsp_defs_t *def; /* current property getting values */
|
|
|
|
lws_dll2_owner_t active_stanzas; /* lcsp_stanza_ptr_t allocated
|
|
* in cascadeac */
|
|
lws_dll2_owner_t active_atr; /* lcsp_atr_ptr_t allocated in
|
|
* propatrac */
|
|
|
|
lws_surface_info_t ic;
|
|
|
|
const char *base_url; /* strdup of https://x.com/y.html */
|
|
sul_cb_t ssevcb; /* callback for ss events */
|
|
lws_sorted_usec_list_t *ssevsul; /* sul to use to resume rz */
|
|
sul_cb_t sshtmlevcb; /* callback for more html parse */
|
|
lws_sorted_usec_list_t *sshtmlevsul; /* sul for more html parse */
|
|
|
|
void *user;
|
|
void *user1;
|
|
const char *tag; /* private */
|
|
size_t tag_len; /* private */
|
|
|
|
int npos;
|
|
int state; /* private */
|
|
int state_css_comm; /* private */
|
|
int nl_temp;
|
|
int temp_count;
|
|
|
|
uint32_t flags;
|
|
uint32_t temp;
|
|
int32_t window; /* 0, or ss item flow control limit */
|
|
|
|
union {
|
|
uint32_t s;
|
|
struct {
|
|
uint32_t first:1;
|
|
uint32_t closing:1;
|
|
uint32_t void_element:1;
|
|
uint32_t doctype:1;
|
|
uint32_t inq:1;
|
|
uint32_t tag_used:1;
|
|
uint32_t arg:1;
|
|
uint32_t default_css:1;
|
|
#define LHP_CSS_PROPVAL_INT_WHOLE 1
|
|
#define LHP_CSS_PROPVAL_INT_FRAC 2
|
|
#define LHP_CSS_PROPVAL_INT_UNIT 3
|
|
uint32_t integer:2;
|
|
uint32_t color:2;
|
|
} f;
|
|
} u;
|
|
|
|
int prop; /* lcsp_props_t */
|
|
int propval; /* lcsp_propvals_t */
|
|
int16_t css_state; /* private */
|
|
int16_t cssval_state; /* private */
|
|
|
|
uint8_t in_body:1;
|
|
uint8_t finish_css:1;
|
|
uint8_t is_css:1;
|
|
uint8_t await_css_done:1;
|
|
|
|
/* at end so we can memset members above it in one go */
|
|
|
|
char buf[LHP_STRING_CHUNK + 1];
|
|
|
|
} lhp_ctx_t;
|
|
|
|
/*
|
|
* lws_lhp_construct() - Construct an lhp context
|
|
*
|
|
* \param ctx: the lhp context to prepare
|
|
* \param cb: the stream parsing callback
|
|
* \param user: opaque user pointer available from the lhp context
|
|
* \param ic: struct with arguments for lhp context
|
|
*
|
|
* The lhp context is allocated by the caller (the size is known).
|
|
* Prepares an lhp context to parse html. Returns 0 for OK, or nonzero if OOM.
|
|
*/
|
|
LWS_VISIBLE LWS_EXTERN int
|
|
lws_lhp_construct(lhp_ctx_t *ctx, lhp_callback cb, void *user,
|
|
const lws_surface_info_t *ic);
|
|
|
|
/*
|
|
* lws_lhp_destruct() - Destroy an lhp context
|
|
*
|
|
* \param ctx: the lhp context to prepare
|
|
*
|
|
* Destroys an lhp context. The lhp context is allocated by the caller (the
|
|
* size is known). But there are suballocations that must be destroyed with
|
|
* this.
|
|
*/
|
|
LWS_VISIBLE LWS_EXTERN void
|
|
lws_lhp_destruct(lhp_ctx_t *ctx);
|
|
|
|
/**
|
|
* lws_lhp_ss_browse() - browse url using SS and parse via lhp to DLOs
|
|
*
|
|
* \param cx: the lws_context
|
|
* \param rs: the user's render state object
|
|
* \param url: the https://x.com/y.xyz URL to browse
|
|
* \param render: the user's linewise render callback (called from \p rs.sul)
|
|
*
|
|
* High level network fetch via SS and render html via lhp / DLO
|
|
*
|
|
* rs->ic must be prepared before calling.
|
|
*
|
|
* Returns nonzero if an early, fatal problem, else returns 0 and continues
|
|
* asynchronously.
|
|
*
|
|
* If rs->box is (0,0,0,0) on entry, it is set to represent the whole display
|
|
* surface. Otherwise if not representing the whole display surface, it
|
|
* indicates partial mode should be used.
|
|
*/
|
|
LWS_VISIBLE LWS_EXTERN int
|
|
lws_lhp_ss_browse(struct lws_context *cx, lws_display_render_state_t *rs,
|
|
const char *url, sul_cb_t render);
|
|
|
|
/**
|
|
* lws_lhp_parse() - parses a chunk of input HTML
|
|
*
|
|
* \p ctx: the parsing context
|
|
* \p buf: pointer to the start of the chunk of html
|
|
* \p len: pointer the number of bytes of html available at *\pbuf
|
|
*
|
|
* Parses up to *len bytes at *buf. On exit, *buf and *len are adjusted
|
|
* according to how much data was used. May return before processing all the
|
|
* input.
|
|
*
|
|
* Returns LWS_SRET_WANT_INPUT if the parsing is stalled on some other async
|
|
* event (eg, fetch of image to find out the dimensions).
|
|
*
|
|
* The lws_lhp_ss_browse() api wraps this.
|
|
*/
|
|
LWS_VISIBLE LWS_EXTERN lws_stateful_ret_t
|
|
lws_lhp_parse(lhp_ctx_t *ctx, const uint8_t **buf, size_t *len);
|
|
|
|
/**
|
|
* lws_css_cascade_get_prop_atr() - create active css atr list for property
|
|
*
|
|
* \p ctx: the parsing context
|
|
* \p prop: the LCSP_PROP_ property to generate the attribute list for
|
|
*
|
|
* Returns NULL if no atr or OOM.
|
|
*
|
|
* Otherwise produces a list of active CSS property attributes walkable via
|
|
* ctx->active_atr, and returns the tail one. For simple attributes where the
|
|
* last definition is the active one, this points to the last definition.
|
|
*/
|
|
LWS_VISIBLE LWS_EXTERN const lcsp_atr_t *
|
|
lws_css_cascade_get_prop_atr(lhp_ctx_t *ctx, lcsp_props_t prop);
|
|
|
|
/**
|
|
* lws_http_rel_to_url() - make absolute url from base and relative
|
|
*
|
|
* \param dest: place to store the result
|
|
* \param len: max length of result including NUL
|
|
* \param base: a reference url including a file part
|
|
* \param rel: the absolute or relative url or path to apply to base
|
|
*
|
|
* Copy the url formof rel into dest, using base to fill in missing context
|
|
*
|
|
* If base is https://x.com/y/z.html
|
|
*
|
|
* a.html -> https://x.com/y/a/html
|
|
* ../b.html -> https://x.com/b.html
|
|
* /c.html -> https://x.com/c.html
|
|
* https://y.com/a.html -> https://y.com/a.html
|
|
*/
|
|
LWS_VISIBLE LWS_EXTERN int
|
|
lws_http_rel_to_url(char *dest, size_t len, const char *base, const char *rel);
|
|
|
|
LWS_VISIBLE LWS_EXTERN lhp_pstack_t *
|
|
lws_css_get_parent_block(lhp_ctx_t *ctx, lhp_pstack_t *ps);
|
|
|
|
LWS_VISIBLE LWS_EXTERN const char *
|
|
lws_css_pstack_name(lhp_pstack_t *ps);
|
|
|
|
LWS_VISIBLE LWS_EXTERN const char *
|
|
lws_html_get_atr(lhp_pstack_t *ps, const char *aname, size_t aname_len);
|
|
|
|
LWS_VISIBLE LWS_EXTERN const lws_fx_t *
|
|
lws_csp_px(const lcsp_atr_t *a, lhp_pstack_t *ps);
|
|
|
|
LWS_VISIBLE LWS_EXTERN void
|
|
lws_lhp_tag_dlo_id(lhp_ctx_t *ctx, lhp_pstack_t *ps, lws_dlo_t *dlo);
|
|
|
|
void
|
|
lhp_set_dlo_padding_margin(lhp_pstack_t *ps, lws_dlo_t *dlo);
|
|
|
|
#define LWS_LHPREF_WIDTH 0
|
|
#define LWS_LHPREF_HEIGHT 1
|
|
#define LWS_LHPREF_NONE 2
|
|
|
|
LWS_VISIBLE LWS_EXTERN int
|
|
lhp_prop_axis(const lcsp_atr_t *a);
|