635 lines
15 KiB
C
635 lines
15 KiB
C
#pragma lib "libhtml.a"
|
|
#pragma src "/sys/src/libhtml"
|
|
|
|
/* UTILS */
|
|
extern uchar* fromStr(Rune* buf, int n, int chset);
|
|
extern Rune* toStr(uchar* buf, int n, int chset);
|
|
|
|
/* Common LEX and BUILD enums */
|
|
|
|
/* Media types */
|
|
enum
|
|
{
|
|
ApplMsword,
|
|
ApplOctets,
|
|
ApplPdf,
|
|
ApplPostscript,
|
|
ApplRtf,
|
|
ApplFramemaker,
|
|
ApplMsexcel,
|
|
ApplMspowerpoint,
|
|
UnknownType,
|
|
Audio32kadpcm,
|
|
AudioBasic,
|
|
ImageCgm,
|
|
ImageG3fax,
|
|
ImageGif,
|
|
ImageIef,
|
|
ImageJpeg,
|
|
ImagePng,
|
|
ImageTiff,
|
|
ImageXBit,
|
|
ImageXBit2,
|
|
ImageXBitmulti,
|
|
ImageXXBitmap,
|
|
ModelVrml,
|
|
MultiDigest,
|
|
MultiMixed,
|
|
TextCss,
|
|
TextEnriched,
|
|
TextHtml,
|
|
TextJavascript,
|
|
TextPlain,
|
|
TextRichtext,
|
|
TextSgml,
|
|
TextTabSeparatedValues,
|
|
TextXml,
|
|
VideoMpeg,
|
|
VideoQuicktime,
|
|
NMEDIATYPES
|
|
};
|
|
|
|
/* HTTP methods */
|
|
enum
|
|
{
|
|
HGet,
|
|
HPost
|
|
};
|
|
|
|
/* Charsets */
|
|
enum
|
|
{
|
|
UnknownCharset,
|
|
US_Ascii,
|
|
ISO_8859_1,
|
|
UTF_8,
|
|
Unicode,
|
|
NCHARSETS
|
|
};
|
|
|
|
/* Frame Target IDs */
|
|
enum {
|
|
FTtop,
|
|
FTself,
|
|
FTparent,
|
|
FTblank
|
|
};
|
|
|
|
/* LEX */
|
|
typedef struct Token Token;
|
|
typedef struct Attr Attr;
|
|
|
|
#pragma incomplete Token
|
|
|
|
/* BUILD */
|
|
|
|
typedef struct Item Item;
|
|
typedef struct Itext Itext;
|
|
typedef struct Irule Irule;
|
|
typedef struct Iimage Iimage;
|
|
typedef struct Iformfield Iformfield;
|
|
typedef struct Itable Itable;
|
|
typedef struct Ifloat Ifloat;
|
|
typedef struct Ispacer Ispacer;
|
|
typedef struct Genattr Genattr;
|
|
typedef struct SEvent SEvent;
|
|
typedef struct Formfield Formfield;
|
|
typedef struct Option Option;
|
|
typedef struct Form Form;
|
|
typedef struct Table Table;
|
|
typedef struct Tablecol Tablecol;
|
|
typedef struct Tablerow Tablerow;
|
|
typedef struct Tablecell Tablecell;
|
|
typedef struct Align Align;
|
|
typedef struct Dimen Dimen;
|
|
typedef struct Anchor Anchor;
|
|
typedef struct DestAnchor DestAnchor;
|
|
typedef struct Map Map;
|
|
typedef struct Area Area;
|
|
typedef struct Background Background;
|
|
typedef struct Kidinfo Kidinfo;
|
|
typedef struct Docinfo Docinfo;
|
|
typedef struct Stack Stack;
|
|
typedef struct Pstate Pstate;
|
|
typedef struct ItemSource ItemSource;
|
|
typedef struct Lay Lay; /* defined in Layout module */
|
|
|
|
#pragma incomplete Lay
|
|
|
|
|
|
/* Alignment types */
|
|
enum {
|
|
ALnone = 0, ALleft, ALcenter, ALright, ALjustify,
|
|
ALchar, ALtop, ALmiddle, ALbottom, ALbaseline,
|
|
};
|
|
|
|
struct Align
|
|
{
|
|
uchar halign; /* one of ALnone, ALleft, etc. */
|
|
uchar valign; /* one of ALnone, ALtop, etc. */
|
|
};
|
|
|
|
/*
|
|
* A Dimen holds a dimension specification, especially for those
|
|
* cases when a number can be followed by a % or a * to indicate
|
|
* percentage of total or relative weight.
|
|
* Dnone means no dimension was specified
|
|
*/
|
|
|
|
/* To fit in a word, use top bits to identify kind, rest for value */
|
|
enum {
|
|
Dnone = 0,
|
|
Dpixels = (1<<29),
|
|
Dpercent = (2<<29),
|
|
Drelative = (3<<29),
|
|
Dkindmask = (3<<29),
|
|
Dspecmask = (~Dkindmask)
|
|
};
|
|
|
|
struct Dimen
|
|
{
|
|
int kindspec; /* kind | spec */
|
|
};
|
|
|
|
/*
|
|
* Background is either an image or a color.
|
|
* If both are set, the image has precedence.
|
|
*/
|
|
struct Background
|
|
{
|
|
Rune* image; /* url */
|
|
int color;
|
|
};
|
|
|
|
|
|
/*
|
|
* There are about a half dozen Item variants.
|
|
* The all look like this at the start (using Plan 9 C's
|
|
* anonymous structure member mechanism),
|
|
* and then the tag field dictates what extra fields there are.
|
|
*/
|
|
struct Item
|
|
{
|
|
Item* next; /* successor in list of items */
|
|
int width; /* width in pixels (0 for floating items) */
|
|
int height; /* height in pixels */
|
|
int ascent; /* ascent (from top to baseline) in pixels */
|
|
int anchorid; /* if nonzero, which anchor we're in */
|
|
int state; /* flags and values (see below) */
|
|
Genattr*genattr; /* generic attributes and events */
|
|
int tag; /* variant discriminator: Itexttag, etc. */
|
|
};
|
|
|
|
/* Item variant tags */
|
|
enum {
|
|
Itexttag,
|
|
Iruletag,
|
|
Iimagetag,
|
|
Iformfieldtag,
|
|
Itabletag,
|
|
Ifloattag,
|
|
Ispacertag
|
|
};
|
|
|
|
struct Itext
|
|
{
|
|
Item; /* (with tag ==Itexttag) */
|
|
Rune* s; /* the characters */
|
|
int fnt; /* style*NumSize+size (see font stuff, below) */
|
|
int fg; /* Pixel (color) for text */
|
|
uchar voff; /* Voffbias+vertical offset from baseline, in pixels (+ve == down) */
|
|
uchar ul; /* ULnone, ULunder, or ULmid */
|
|
};
|
|
|
|
struct Irule
|
|
{
|
|
Item; /* (with tag ==Iruletag) */
|
|
uchar align; /* alignment spec */
|
|
uchar noshade; /* if true, don't shade */
|
|
int size; /* size attr (rule height) */
|
|
int color; /* color attr */
|
|
Dimen wspec; /* width spec */
|
|
};
|
|
|
|
|
|
struct Iimage
|
|
{
|
|
Item; /* (with tag ==Iimagetag) */
|
|
Rune* imsrc; /* image src url */
|
|
int imwidth; /* spec width (actual, if no spec) */
|
|
int imheight; /* spec height (actual, if no spec) */
|
|
Rune* altrep; /* alternate representation, in absence of image */
|
|
Map* map; /* if non-nil, client side map */
|
|
int ctlid; /* if animated */
|
|
uchar align; /* vertical alignment */
|
|
uchar hspace; /* in pixels; buffer space on each side */
|
|
uchar vspace; /* in pixels; buffer space on top and bottom */
|
|
uchar border; /* in pixels: border width to draw around image */
|
|
Iimage* nextimage; /* next in list of document's images */
|
|
void* aux;
|
|
};
|
|
|
|
|
|
struct Iformfield
|
|
{
|
|
Item; /* (with tag ==Iformfieldtag) */
|
|
Formfield*formfield;
|
|
void* aux;
|
|
};
|
|
|
|
|
|
struct Itable
|
|
{
|
|
Item; /* (with tag ==Itabletag) */
|
|
Table* table;
|
|
};
|
|
|
|
|
|
struct Ifloat
|
|
{
|
|
Item; /* (with tag ==Ifloattag) */
|
|
Item* item; /* table or image item that floats */
|
|
int x; /* x coord of top (from right, if ALright) */
|
|
int y; /* y coord of top */
|
|
uchar side; /* margin it floats to: ALleft or ALright */
|
|
uchar infloats; /* true if this has been added to a lay.floats */
|
|
Ifloat* nextfloat; /* in list of floats */
|
|
};
|
|
|
|
|
|
struct Ispacer
|
|
{
|
|
Item; /* (with tag ==Ispacertag) */
|
|
int spkind; /* ISPnull, etc. */
|
|
};
|
|
|
|
/* Item state flags and value fields */
|
|
enum {
|
|
IFbrk = 0x80000000, /* forced break before this item */
|
|
IFbrksp = 0x40000000, /* add 1 line space to break (IFbrk set too) */
|
|
IFnobrk = 0x20000000, /* break not allowed before this item */
|
|
IFcleft = 0x10000000, /* clear left floats (IFbrk set too) */
|
|
IFcright= 0x08000000, /* clear right floats (IFbrk set too) */
|
|
IFwrap = 0x04000000, /* in a wrapping (non-pre) line */
|
|
IFhang = 0x02000000, /* in a hanging (into left indent) item */
|
|
IFrjust = 0x01000000, /* right justify current line */
|
|
IFcjust = 0x00800000, /* center justify current line */
|
|
IFsmap = 0x00400000, /* image is server-side map */
|
|
IFindentshift = 8,
|
|
IFindentmask = (255<<IFindentshift), /* current indent, in tab stops */
|
|
IFhangmask = 255 /* current hang into left indent, in 1/10th tabstops */
|
|
};
|
|
|
|
/* Bias added to Itext's voff field */
|
|
enum { Voffbias = 128 };
|
|
|
|
/* Spacer kinds */
|
|
enum {
|
|
ISPnull, /* 0 height and width */
|
|
ISPvline, /* height and ascent of current font */
|
|
ISPhspace, /* width of space in current font */
|
|
ISPgeneral /* other purposes (e.g., between markers and list) */
|
|
};
|
|
|
|
/* Generic attributes and events (not many elements will have any of these set) */
|
|
struct Genattr
|
|
{
|
|
Rune* id;
|
|
Rune* class;
|
|
Rune* style;
|
|
Rune* title;
|
|
SEvent* events;
|
|
};
|
|
|
|
struct SEvent
|
|
{
|
|
SEvent* next; /* in list of events */
|
|
int type; /* SEonblur, etc. */
|
|
Rune* script;
|
|
};
|
|
|
|
enum {
|
|
SEonblur, SEonchange, SEonclick, SEondblclick,
|
|
SEonfocus, SEonkeypress, SEonkeyup, SEonload,
|
|
SEonmousedown, SEonmousemove, SEonmouseout,
|
|
SEonmouseover, SEonmouseup, SEonreset, SEonselect,
|
|
SEonsubmit, SEonunload,
|
|
Numscriptev
|
|
};
|
|
|
|
/* Form field types */
|
|
enum {
|
|
Ftext,
|
|
Fpassword,
|
|
Fcheckbox,
|
|
Fradio,
|
|
Fsubmit,
|
|
Fhidden,
|
|
Fimage,
|
|
Freset,
|
|
Ffile,
|
|
Fbutton,
|
|
Fselect,
|
|
Ftextarea
|
|
};
|
|
|
|
/* Information about a field in a form */
|
|
struct Formfield
|
|
{
|
|
Formfield*next; /* in list of fields for a form */
|
|
int ftype; /* Ftext, Fpassword, etc. */
|
|
int fieldid; /* serial no. of field within its form */
|
|
Form* form; /* containing form */
|
|
Rune* name; /* name attr */
|
|
Rune* value; /* value attr */
|
|
int size; /* size attr */
|
|
int maxlength; /* maxlength attr */
|
|
int rows; /* rows attr */
|
|
int cols; /* cols attr */
|
|
uchar flags; /* FFchecked, etc. */
|
|
Option* options; /* for Fselect fields */
|
|
Item* image; /* image item, for Fimage fields */
|
|
int ctlid; /* identifies control for this field in layout */
|
|
SEvent* events; /* same as genattr->events of containing item */
|
|
};
|
|
|
|
enum {
|
|
FFchecked = (1<<7),
|
|
FFmultiple = (1<<6)
|
|
};
|
|
|
|
/* Option holds info about an option in a "select" form field */
|
|
struct Option
|
|
{
|
|
Option* next; /* next in list of options for a field */
|
|
int selected; /* true if selected initially */
|
|
Rune* value; /* value attr */
|
|
Rune* display; /* display string */
|
|
};
|
|
|
|
/* Form holds info about a form */
|
|
struct Form
|
|
{
|
|
Form* next; /* in list of forms for document */
|
|
int formid; /* serial no. of form within its doc */
|
|
Rune* name; /* name or id attr (netscape uses name, HTML 4.0 uses id) */
|
|
Rune* action; /* action attr */
|
|
int target; /* target attr as targetid */
|
|
int method; /* HGet or HPost */
|
|
int nfields; /* number of fields */
|
|
Formfield*fields; /* field's forms, in input order */
|
|
};
|
|
|
|
/* Flags used in various table structures */
|
|
enum {
|
|
TFparsing = (1<<7),
|
|
TFnowrap = (1<<6),
|
|
TFisth = (1<<5)
|
|
};
|
|
|
|
|
|
/* Information about a table */
|
|
struct Table
|
|
{
|
|
Table* next; /* next in list of document's tables */
|
|
int tableid; /* serial no. of table within its doc */
|
|
Tablerow*rows; /* array of row specs (list during parsing) */
|
|
int nrow; /* total number of rows */
|
|
Tablecol*cols; /* array of column specs */
|
|
int ncol; /* total number of columns */
|
|
Tablecell*cells; /* list of unique cells */
|
|
int ncell; /* total number of cells */
|
|
Tablecell***grid; /* 2-D array of cells */
|
|
Align align; /* alignment spec for whole table */
|
|
Dimen width; /* width spec for whole table */
|
|
int border; /* border attr */
|
|
int cellspacing; /* cellspacing attr */
|
|
int cellpadding; /* cellpadding attr */
|
|
Background background; /* table background */
|
|
Item* caption; /* linked list of Items, giving caption */
|
|
uchar caption_place; /* ALtop or ALbottom */
|
|
Lay* caption_lay; /* layout of caption */
|
|
int totw; /* total width */
|
|
int toth; /* total height */
|
|
int caph; /* caption height */
|
|
int availw; /* used for previous 3 sizes */
|
|
Token* tabletok; /* token that started the table */
|
|
uchar flags; /* Lchanged, perhaps */
|
|
};
|
|
|
|
|
|
struct Tablecol
|
|
{
|
|
int width;
|
|
Align align;
|
|
Point pos;
|
|
};
|
|
|
|
|
|
struct Tablerow
|
|
{
|
|
Tablerow*next; /* Next in list of rows, during parsing */
|
|
Tablecell*cells; /* Cells in row, linked through nextinrow */
|
|
int height;
|
|
int ascent;
|
|
Align align;
|
|
Background background;
|
|
Point pos;
|
|
uchar flags; /* 0 or TFparsing */
|
|
};
|
|
|
|
/*
|
|
* A Tablecell is one cell of a table.
|
|
* It may span multiple rows and multiple columns.
|
|
* Cells are linked on two lists: the list for all the cells of
|
|
* a document (the next pointers), and the list of all the
|
|
* cells that start in a given row (the nextinrow pointers)
|
|
*/
|
|
struct Tablecell
|
|
{
|
|
Tablecell*next; /* next in list of table's cells */
|
|
Tablecell*nextinrow; /* next in list of row's cells */
|
|
int cellid; /* serial no. of cell within table */
|
|
Item* content; /* contents before layout */
|
|
Lay* lay; /* layout of cell */
|
|
int rowspan; /* number of rows spanned by this cell */
|
|
int colspan; /* number of cols spanned by this cell */
|
|
Align align; /* alignment spec */
|
|
uchar flags; /* TFparsing, TFnowrap, TFisth */
|
|
Dimen wspec; /* suggested width */
|
|
int hspec; /* suggested height */
|
|
Background background; /* cell background */
|
|
int minw; /* minimum possible width */
|
|
int maxw; /* maximum width */
|
|
int ascent; /* cell's ascent */
|
|
int row; /* row of upper left corner */
|
|
int col; /* col of upper left corner */
|
|
Point pos; /* nw corner of cell contents, in cell */
|
|
};
|
|
|
|
/* Anchor is for info about hyperlinks that go somewhere */
|
|
struct Anchor
|
|
{
|
|
Anchor* next; /* next in list of document's anchors */
|
|
int index; /* serial no. of anchor within its doc */
|
|
Rune* name; /* name attr */
|
|
Rune* href; /* href attr */
|
|
int target; /* target attr as targetid */
|
|
};
|
|
|
|
|
|
/* DestAnchor is for info about hyperlinks that are destinations */
|
|
struct DestAnchor
|
|
{
|
|
DestAnchor*next; /* next in list of document's destanchors */
|
|
int index; /* serial no. of anchor within its doc */
|
|
Rune* name; /* name attr */
|
|
Item* item; /* the destination */
|
|
};
|
|
|
|
|
|
/* Maps (client side) */
|
|
struct Map
|
|
{
|
|
Map* next; /* next in list of document's maps */
|
|
Rune* name; /* map name */
|
|
Area* areas; /* list of map areas */
|
|
};
|
|
|
|
|
|
struct Area
|
|
{
|
|
Area* next; /* next in list of a map's areas */
|
|
int shape; /* SHrect, etc. */
|
|
Rune* href; /* associated hypertext link */
|
|
int target; /* associated target frame */
|
|
Dimen* coords; /* array of coords for shape */
|
|
int ncoords; /* size of coords array */
|
|
};
|
|
|
|
/* Area shapes */
|
|
enum {
|
|
SHrect, SHcircle, SHpoly
|
|
};
|
|
|
|
/* Fonts are represented by integers: style*NumSize + size */
|
|
|
|
/* Font styles */
|
|
enum {
|
|
FntR, /* roman */
|
|
FntI, /* italic */
|
|
FntB, /* bold */
|
|
FntT, /* typewriter */
|
|
NumStyle
|
|
};
|
|
|
|
/* Font sizes */
|
|
enum {
|
|
Tiny,
|
|
Small,
|
|
Normal,
|
|
Large,
|
|
Verylarge,
|
|
NumSize
|
|
};
|
|
|
|
enum {
|
|
NumFnt = NumStyle*NumSize,
|
|
DefFnt = FntR*NumSize+Normal,
|
|
};
|
|
|
|
/* Lines are needed through some text items, for underlining or strikethrough */
|
|
enum {
|
|
ULnone, ULunder, ULmid
|
|
};
|
|
|
|
/* Kidinfo flags */
|
|
enum {
|
|
FRnoresize = (1<<0),
|
|
FRnoscroll = (1<<1),
|
|
FRhscroll = (1<<2),
|
|
FRvscroll = (1<<3),
|
|
FRhscrollauto = (1<<4),
|
|
FRvscrollauto = (1<<5)
|
|
};
|
|
|
|
/* Information about child frame or frameset */
|
|
struct Kidinfo
|
|
{
|
|
Kidinfo*next; /* in list of kidinfos for a frameset */
|
|
int isframeset;
|
|
|
|
/* fields for "frame" */
|
|
Rune* src; /* only nil if a "dummy" frame or this is frameset */
|
|
Rune* name; /* always non-empty if this isn't frameset */
|
|
int marginw;
|
|
int marginh;
|
|
int framebd;
|
|
int flags;
|
|
|
|
/* fields for "frameset" */
|
|
Dimen* rows; /* array of row dimensions */
|
|
int nrows; /* length of rows */
|
|
Dimen* cols; /* array of col dimensions */
|
|
int ncols; /* length of cols */
|
|
Kidinfo*kidinfos;
|
|
Kidinfo*nextframeset; /* parsing stack */
|
|
};
|
|
|
|
|
|
/* Document info (global information about HTML page) */
|
|
struct Docinfo
|
|
{
|
|
/* stuff from HTTP headers, doc head, and body tag */
|
|
Rune* src; /* original source of doc */
|
|
Rune* base; /* base URL of doc */
|
|
Rune* doctitle; /* from <title> element */
|
|
Background background; /* background specification */
|
|
Iimage* backgrounditem; /* Image Item for doc background image, or nil */
|
|
int text; /* doc foreground (text) color */
|
|
int link; /* unvisited hyperlink color */
|
|
int vlink; /* visited hyperlink color */
|
|
int alink; /* highlighting hyperlink color */
|
|
int target; /* target frame default */
|
|
int chset; /* ISO_8859, etc. */
|
|
int mediatype; /* TextHtml, etc. */
|
|
int scripttype; /* TextJavascript, etc. */
|
|
int hasscripts; /* true if scripts used */
|
|
Rune* refresh; /* content of <http-equiv=Refresh ...> */
|
|
Kidinfo*kidinfo; /* if a frameset */
|
|
int frameid; /* id of document frame */
|
|
|
|
/* info needed to respond to user actions */
|
|
Anchor* anchors; /* list of href anchors */
|
|
DestAnchor*dests; /* list of destination anchors */
|
|
Form* forms; /* list of forms */
|
|
Table* tables; /* list of tables */
|
|
Map* maps; /* list of maps */
|
|
Iimage* images; /* list of image items (through nextimage links) */
|
|
};
|
|
|
|
extern int dimenkind(Dimen d);
|
|
extern int dimenspec(Dimen d);
|
|
extern void freedocinfo(Docinfo* d);
|
|
extern void freeitems(Item* ithead);
|
|
extern Item* parsehtml(uchar* data, int datalen, Rune* src, int mtype, int chset, Docinfo** pdi);
|
|
extern void printitems(Item* items, char* msg);
|
|
extern int targetid(Rune* s);
|
|
extern Rune* targetname(int targid);
|
|
extern int validitems(Item* i);
|
|
|
|
#pragma varargck type "I" Item*
|
|
|
|
/* Control print output */
|
|
extern int warn;
|
|
extern int dbglex;
|
|
extern int dbgbuild;
|
|
|
|
/*
|
|
* To be provided by caller
|
|
* emalloc and erealloc should not return if can't get memory.
|
|
* emalloc should zero its memory.
|
|
*/
|
|
extern void* emalloc(ulong);
|
|
extern void* erealloc(void* p, ulong size);
|