📄 stack.c
字号:
/* HTML elements stack *//* $Id: stack.c,v 1.28.2.2 2005/04/05 21:08:41 jonas Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "elinks.h"#include "document/document.h"#include "document/html/parser/stack.h"#include "document/html/parser/parse.h"#include "document/html/parser.h"#include "document/html/renderer.h"#include "protocol/uri.h"#include "util/conv.h"#include "util/error.h"#include "util/lists.h"#include "util/memdebug.h"#include "util/memory.h"#include "util/string.h"/* Unsafe macros */#include "document/html/internal.h"#if 0voiddump_html_stack(void){ struct html_element *element; DBG("HTML stack debug:"); foreach (element, html_context.stack) { DBG("&name/len:%p:%d name:%.*s type:%d", element->name, element->namelen, element->namelen, element->name, element->type); } WDBG("Did you enjoy it?");}#endifstruct html_element *search_html_stack(unsigned char *name){ struct html_element *element; int namelen; assert(name && *name); namelen = strlen(name);#if 0 /* Debug code. Please keep. */ dump_html_stack();#endif foreach (element, html_context.stack) { if (element == &html_top) continue; /* skip the top element */ if (strlcasecmp(element->name, element->namelen, name, namelen)) continue; return element; } return NULL;}voidkill_html_stack_item(struct html_element *e){#ifdef CONFIG_ECMASCRIPT unsigned char *onload = NULL;#endif assert(e); if_assert_failed return; assertm((void *) e != &html_context.stack, "trying to free bad html element"); if_assert_failed return; assertm(e->type != ELEMENT_IMMORTAL, "trying to kill unkillable element"); if_assert_failed return;#ifdef CONFIG_ECMASCRIPT /* As our another tiny l33t extension, we allow the onLoad attribute for * any element, executing it when that element is fully loaded. */ if (e->options) onload = get_attr_val(e->options, "onLoad"); if (html_context.part && html_context.part->document && onload && *onload && *onload != '^') { /* XXX: The following expression alone amounts two #includes. */ add_to_string_list(&html_context.part->document->onload_snippets, onload, -1); } if (onload) mem_free(onload);#endif mem_free_if(e->attr.link); mem_free_if(e->attr.target); mem_free_if(e->attr.image); mem_free_if(e->attr.title); mem_free_if(e->attr.select); mem_free_if(e->attr.onclick); mem_free_if(e->attr.ondblclick); mem_free_if(e->attr.onmouseover); mem_free_if(e->attr.onhover); mem_free_if(e->attr.onfocus); mem_free_if(e->attr.onmouseout); mem_free_if(e->attr.onblur); del_from_list(e); mem_free(e);#if 0 if (list_empty(html_context.stack) || !html_context.stack.next) { DBG("killing last element"); }#endif}voidhtml_stack_dup(enum html_element_type type){ struct html_element *e; struct html_element *ep = html_context.stack.next; assertm(ep && (void *) ep != &html_context.stack, "html stack empty"); if_assert_failed return; e = mem_alloc(sizeof(*e)); if (!e) return; copy_struct(e, ep); if (ep->attr.link) e->attr.link = stracpy(ep->attr.link); if (ep->attr.target) e->attr.target = stracpy(ep->attr.target); if (ep->attr.image) e->attr.image = stracpy(ep->attr.image); if (ep->attr.title) e->attr.title = stracpy(ep->attr.title); if (ep->attr.select) e->attr.select = stracpy(ep->attr.select); /* We don't want to propagate these. */ /* XXX: For sure? --pasky */ e->attr.onclick = e->attr.ondblclick = e->attr.onmouseover = e->attr.onhover = e->attr.onfocus = e->attr.onmouseout = e->attr.onblur = NULL;#if 0 if (e->name) { if (e->attr.link) set_mem_comment(e->attr.link, e->name, e->namelen); if (e->attr.target) set_mem_comment(e->attr.target, e->name, e->namelen); if (e->attr.image) set_mem_comment(e->attr.image, e->name, e->namelen); if (e->attr.title) set_mem_comment(e->attr.title, e->name, e->namelen); if (e->attr.select) set_mem_comment(e->attr.select, e->name, e->namelen); }#endif e->name = e->options = NULL; e->namelen = 0; e->type = type; add_to_list(html_context.stack, e);}static voidkill_element(int ls, struct html_element *e){ int l = 0; while ((void *) e != &html_context.stack) { if (ls && e == html_context.stack.next) break; if (e->linebreak > l) l = e->linebreak; e = e->prev; kill_html_stack_item(e->next); } ln_break(l, html_context.line_break_f, html_context.part);}voidkill_html_stack_until(int ls, ...){ struct html_element *e = &html_top; if (ls) e = e->next; while ((void *) e != &html_context.stack) { int sk = 0; va_list arg; va_start(arg, ls); while (1) { unsigned char *s = va_arg(arg, unsigned char *); int slen; if (!s) break; slen = strlen(s); if (!slen) { sk++; continue; } if (strlcasecmp(e->name, e->namelen, s, slen)) continue; if (!sk) { if (e->type < ELEMENT_KILLABLE) break; va_end(arg); kill_element(ls, e); return; } else if (sk == 1) { va_end(arg); e = e->prev; kill_element(ls, e); return; } else { break; } } va_end(arg); if (e->type < ELEMENT_KILLABLE || (!strlcasecmp(e->name, e->namelen, "TABLE", 5))) break; if (e->namelen == 2 && toupper(e->name[0]) == 'T') { unsigned char c = toupper(e->name[1]); if (c == 'D' || c == 'H' || c == 'R') break; } e = e->next; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -