This commit completes Phase 3 (Event System) and includes a thorough midpoint review that identified and fixed critical gaps from earlier phases. Major accomplishments: • Complete event system with addEventListener/removeEventListener API • Event dispatch system with preventDefault/stopPropagation support • Click event integration with w3m's existing mouse handling system • Enhanced document.write() from stub to functional implementation • Fixed critical anchor-DOM integration gap from Phase 2 • Comprehensive code review and stub elimination • Full DOM element extraction and JavaScript object conversion • Working noscript tag suppression when JavaScript is enabled Testing verified: • JavaScript execution and DOM manipulation working correctly • document.write() creates DOM elements and displays content properly • noscript content correctly hidden when JavaScript is enabled • Click events integrate properly with w3m's mouse system • No compilation errors or warnings (except minor unused variable) Phase status: Phases 1-3 now complete and fully functional. Remaining stubs are safe and won't cause unexpected behavior. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
133 lines
5.1 KiB
C
133 lines
5.1 KiB
C
/*
|
|
* w3m DOM Implementation Header
|
|
*
|
|
* This file defines the Document Object Model structures and interfaces
|
|
* for JavaScript integration in w3m. It provides a minimal but functional
|
|
* DOM representation that maps to w3m's internal buffer structures.
|
|
*/
|
|
|
|
#ifndef W3M_DOM_H
|
|
#define W3M_DOM_H
|
|
|
|
#ifdef USE_JAVASCRIPT
|
|
|
|
#include "quickjs/quickjs.h"
|
|
#include "w3m_javascript.h"
|
|
|
|
/* Forward declarations */
|
|
struct _Buffer;
|
|
struct Line;
|
|
struct Anchor;
|
|
struct FormItem;
|
|
|
|
/* Simplified DOM Element Structure */
|
|
typedef struct W3MElement {
|
|
char *tagName; /* Element tag name (uppercase) */
|
|
char *id; /* Element ID attribute */
|
|
char *className; /* CSS class names */
|
|
|
|
/* Tree structure */
|
|
struct W3MElement *parent;
|
|
struct W3MElement *firstChild;
|
|
struct W3MElement *lastChild;
|
|
struct W3MElement *nextSibling;
|
|
struct W3MElement *previousSibling;
|
|
|
|
/* w3m mappings */
|
|
struct Line *line; /* Associated line in buffer */
|
|
int line_pos; /* Position within line */
|
|
struct Anchor *anchor; /* If element is interactive */
|
|
struct FormItem *form_item; /* If element is form control */
|
|
|
|
/* Attributes and content */
|
|
struct {
|
|
char **names;
|
|
char **values;
|
|
int count;
|
|
int capacity;
|
|
} attributes;
|
|
|
|
char *textContent; /* Text content of element */
|
|
char *innerHTML; /* HTML content (basic) */
|
|
|
|
/* JavaScript object reference */
|
|
JSValue js_object;
|
|
int js_object_valid;
|
|
} W3MElement;
|
|
|
|
/* Document structure */
|
|
typedef struct W3MDocument {
|
|
W3MElement *documentElement; /* <html> element */
|
|
W3MElement *body; /* <body> element */
|
|
W3MElement *head; /* <head> element */
|
|
Buffer *buffer; /* Associated w3m buffer */
|
|
|
|
char *title; /* Document title */
|
|
char *URL; /* Document URL */
|
|
char *domain; /* Document domain */
|
|
|
|
/* Element collections */
|
|
W3MElement **all_elements; /* All elements in document */
|
|
int element_count;
|
|
int element_capacity;
|
|
|
|
/* JavaScript object reference */
|
|
JSValue js_document;
|
|
} W3MDocument;
|
|
|
|
/* DOM Creation and Management */
|
|
W3MDocument *w3m_dom_create_document(Buffer *buf);
|
|
void w3m_dom_destroy_document(W3MDocument *doc);
|
|
W3MElement *w3m_dom_create_element(const char *tagName);
|
|
void w3m_dom_destroy_element(W3MElement *elem);
|
|
|
|
/* DOM Tree Operations */
|
|
void w3m_dom_append_child(W3MElement *parent, W3MElement *child);
|
|
void w3m_dom_remove_child(W3MElement *parent, W3MElement *child);
|
|
void w3m_dom_insert_before(W3MElement *parent, W3MElement *newChild, W3MElement *referenceChild);
|
|
|
|
/* Element Search and Access */
|
|
W3MElement *w3m_dom_get_element_by_id(W3MDocument *doc, const char *id);
|
|
W3MElement **w3m_dom_get_elements_by_tag_name(W3MDocument *doc, const char *tagName, int *count);
|
|
W3MElement **w3m_dom_get_elements_by_class_name(W3MDocument *doc, const char *className, int *count);
|
|
|
|
/* Attribute Management */
|
|
const char *w3m_dom_get_attribute(W3MElement *elem, const char *name);
|
|
void w3m_dom_set_attribute(W3MElement *elem, const char *name, const char *value);
|
|
void w3m_dom_remove_attribute(W3MElement *elem, const char *name);
|
|
int w3m_dom_has_attribute(W3MElement *elem, const char *name);
|
|
|
|
/* Content Access and Modification */
|
|
char *w3m_dom_get_text_content(W3MElement *elem);
|
|
void w3m_dom_set_text_content(W3MElement *elem, const char *text);
|
|
char *w3m_dom_get_inner_html(W3MElement *elem);
|
|
void w3m_dom_set_inner_html(W3MElement *elem, const char *html);
|
|
|
|
/* Buffer Integration */
|
|
void w3m_dom_build_from_buffer(W3MDocument *doc, Buffer *buf);
|
|
void w3m_dom_update_buffer(W3MDocument *doc);
|
|
W3MElement *w3m_dom_find_element_at_position(W3MDocument *doc, int line_num, int col);
|
|
|
|
/* Internal DOM Management */
|
|
void add_element_to_document(W3MDocument *doc, W3MElement *elem);
|
|
void set_element_buffer_position(W3MElement *elem, Buffer *buf);
|
|
|
|
/* JavaScript Binding */
|
|
void w3m_dom_bind_to_js(W3MJSContext *ctx, W3MDocument *doc);
|
|
JSValue w3m_dom_element_to_js(W3MJSContext *ctx, W3MElement *elem);
|
|
W3MElement *w3m_dom_js_to_element(W3MJSContext *ctx, JSValue val);
|
|
W3MElement *w3m_dom_find_anchor_element(W3MDocument *doc, Anchor *anchor);
|
|
|
|
/* JavaScript DOM API Functions */
|
|
JSValue js_getElementById(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
|
|
JSValue js_getElementsByTagName(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
|
|
JSValue js_createElement(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
|
|
JSValue js_element_getAttribute(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
|
|
JSValue js_element_setAttribute(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
|
|
JSValue js_element_get_textContent(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
|
|
JSValue js_element_set_textContent(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
|
|
JSValue js_document_write(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
|
|
|
|
#endif /* USE_JAVASCRIPT */
|
|
|
|
#endif /* W3M_DOM_H */ |