diff --git a/doc/MANUAL.html b/doc/MANUAL.html
index 9f82dfb..9ca1f6b 100644
--- a/doc/MANUAL.html
+++ b/doc/MANUAL.html
@@ -958,6 +958,30 @@ Keybinding description for C-g had been moved as it did not fit to "Hyperlink op
diff --git a/file.c b/file.c
index a7ad0d7..4d6d352 100644
--- a/file.c
+++ b/file.c
@@ -4631,7 +4631,7 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env)
*/
/* Set buffer position and add to document body */
- set_element_buffer_position(p_elem, h_env->buf);
+ set_element_buffer_position(p_elem, h_env->buffer_ref);
add_element_to_document(h_env->buffer_ref->js_document, p_elem);
w3m_dom_append_child(h_env->buffer_ref->js_document->body, p_elem);
}
@@ -5031,6 +5031,11 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env)
return 1;
case HTML_SCRIPT:
#ifdef USE_JAVASCRIPT
+ /* Initialize JavaScript state if not already done */
+ if (h_env->buffer_ref && !h_env->buffer_ref->js_state && w3m_js_enabled) {
+ h_env->buffer_ref->js_state = (void *)w3m_js_init_buffer_state(h_env->buffer_ref);
+ }
+
/* Phase 2: Create DOM element for script tag */
if (h_env->buffer_ref && h_env->buffer_ref->js_state && h_env->buffer_ref->js_document) {
W3MElement *script_elem = w3m_dom_create_element("SCRIPT");
@@ -5045,7 +5050,7 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env)
}
/* Set buffer position and add to document */
- set_element_buffer_position(script_elem, h_env->buf);
+ set_element_buffer_position(script_elem, h_env->buffer_ref);
add_element_to_document(h_env->buffer_ref->js_document, script_elem);
w3m_dom_append_child(h_env->buffer_ref->js_document->head, script_elem);
}
@@ -5317,6 +5322,11 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env)
if (!(obuf->flag & RB_IGNORE_P))
flushline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit);
#ifdef USE_JAVASCRIPT
+ /* Initialize JavaScript state if not already done */
+ if (h_env->buffer_ref && !h_env->buffer_ref->js_state && w3m_js_enabled) {
+ h_env->buffer_ref->js_state = (void *)w3m_js_init_buffer_state(h_env->buffer_ref);
+ }
+
/* Phase 2: Create DOM element for DIV tag */
if (h_env->buffer_ref && h_env->buffer_ref->js_state && h_env->buffer_ref->js_document) {
W3MElement *div_elem = w3m_dom_create_element("DIV");
@@ -5342,7 +5352,7 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env)
} */
/* Set buffer position and add to document body */
- set_element_buffer_position(div_elem, h_env->buf);
+ set_element_buffer_position(div_elem, h_env->buffer_ref);
add_element_to_document(h_env->buffer_ref->js_document, div_elem);
w3m_dom_append_child(h_env->buffer_ref->js_document->body, div_elem);
}
@@ -5373,6 +5383,45 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env)
tmp = process_form(tag);
if (tmp)
HTMLlineproc1(tmp->ptr, h_env);
+
+#ifdef USE_JAVASCRIPT
+ /* Initialize JavaScript state if not already done */
+ if (h_env->buffer_ref && !h_env->buffer_ref->js_state && w3m_js_enabled) {
+ h_env->buffer_ref->js_state = (void *)w3m_js_init_buffer_state(h_env->buffer_ref);
+ }
+
+ /* Phase 4: Create DOM element for form tag */
+ if (h_env->buffer_ref && h_env->buffer_ref->js_state && h_env->buffer_ref->js_document) {
+ W3MElement *form_elem = w3m_dom_create_element("FORM");
+ if (form_elem) {
+ /* Extract form attributes */
+ char *action, *method, *name, *target, *enctype, *id;
+
+ if (parsedtag_get_value(tag, ATTR_ACTION, &action))
+ w3m_dom_set_attribute(form_elem, "action", action);
+ if (parsedtag_get_value(tag, ATTR_METHOD, &method))
+ w3m_dom_set_attribute(form_elem, "method", method);
+ if (parsedtag_get_value(tag, ATTR_NAME, &name))
+ w3m_dom_set_attribute(form_elem, "name", name);
+ if (parsedtag_get_value(tag, ATTR_TARGET, &target))
+ w3m_dom_set_attribute(form_elem, "target", target);
+ if (parsedtag_get_value(tag, ATTR_ENCTYPE, &enctype))
+ w3m_dom_set_attribute(form_elem, "enctype", enctype);
+ if (parsedtag_get_value(tag, ATTR_ID, &id)) {
+ w3m_dom_set_attribute(form_elem, "id", id);
+ if (!form_elem->id) {
+ int len = strlen(id);
+ form_elem->id = GC_MALLOC(len + 1);
+ if (form_elem->id) strcpy(form_elem->id, id);
+ }
+ }
+
+ /* Add to document body */
+ w3m_dom_append_child(h_env->buffer_ref->js_document->body, form_elem);
+ add_element_to_document(h_env->buffer_ref->js_document, form_elem);
+ }
+ }
+#endif
return 1;
case HTML_N_FORM:
CLOSE_A;
@@ -5385,6 +5434,44 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env)
tmp = process_input(tag);
if (tmp)
HTMLlineproc1(tmp->ptr, h_env);
+
+#ifdef USE_JAVASCRIPT
+ /* Phase 4: Create DOM element for input tag */
+ if (h_env->buffer_ref && h_env->buffer_ref->js_state && h_env->buffer_ref->js_document) {
+ W3MElement *input_elem = w3m_dom_create_element("INPUT");
+ if (input_elem) {
+ /* Extract input attributes */
+ char *type, *name, *value, *id;
+ char *size_str, *maxlength_str, *readonly_str;
+ char *checked_str, *src, *alt;
+
+ if (parsedtag_get_value(tag, ATTR_TYPE, &type))
+ w3m_dom_set_attribute(input_elem, "type", type);
+ if (parsedtag_get_value(tag, ATTR_NAME, &name))
+ w3m_dom_set_attribute(input_elem, "name", name);
+ if (parsedtag_get_value(tag, ATTR_VALUE, &value))
+ w3m_dom_set_attribute(input_elem, "value", value);
+ if (parsedtag_get_value(tag, ATTR_ID, &id))
+ w3m_dom_set_attribute(input_elem, "id", id);
+ if (parsedtag_get_value(tag, ATTR_SIZE, &size_str))
+ w3m_dom_set_attribute(input_elem, "size", size_str);
+ if (parsedtag_get_value(tag, ATTR_MAXLENGTH, &maxlength_str))
+ w3m_dom_set_attribute(input_elem, "maxlength", maxlength_str);
+ if (parsedtag_get_value(tag, ATTR_READONLY, &readonly_str))
+ w3m_dom_set_attribute(input_elem, "readonly", readonly_str);
+ if (parsedtag_get_value(tag, ATTR_CHECKED, &checked_str))
+ w3m_dom_set_attribute(input_elem, "checked", checked_str);
+ if (parsedtag_get_value(tag, ATTR_SRC, &src))
+ w3m_dom_set_attribute(input_elem, "src", src);
+ if (parsedtag_get_value(tag, ATTR_ALT, &alt))
+ w3m_dom_set_attribute(input_elem, "alt", alt);
+
+ /* Add to document body */
+ w3m_dom_append_child(h_env->buffer_ref->js_document->body, input_elem);
+ add_element_to_document(h_env->buffer_ref->js_document, input_elem);
+ }
+ }
+#endif
return 1;
case HTML_BUTTON:
HTML5_CLOSE_A;
@@ -5402,6 +5489,30 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env)
tmp = process_select(tag);
if (tmp)
HTMLlineproc1(tmp->ptr, h_env);
+
+#ifdef USE_JAVASCRIPT
+ /* Phase 4: Create DOM element for select tag */
+ if (h_env->buffer_ref && h_env->buffer_ref->js_state && h_env->buffer_ref->js_document) {
+ W3MElement *select_elem = w3m_dom_create_element("SELECT");
+ if (select_elem) {
+ /* Extract select attributes */
+ char *name, *id, *size_str, *multiple_str;
+
+ if (parsedtag_get_value(tag, ATTR_NAME, &name))
+ w3m_dom_set_attribute(select_elem, "name", name);
+ if (parsedtag_get_value(tag, ATTR_ID, &id))
+ w3m_dom_set_attribute(select_elem, "id", id);
+ if (parsedtag_get_value(tag, ATTR_SIZE, &size_str))
+ w3m_dom_set_attribute(select_elem, "size", size_str);
+ if (parsedtag_get_value(tag, ATTR_MULTIPLE, &multiple_str))
+ w3m_dom_set_attribute(select_elem, "multiple", multiple_str);
+
+ /* Add to document body */
+ w3m_dom_append_child(h_env->buffer_ref->js_document->body, select_elem);
+ add_element_to_document(h_env->buffer_ref->js_document, select_elem);
+ }
+ }
+#endif
obuf->flag |= RB_INSELECT;
obuf->end_tag = HTML_N_SELECT;
return 1;
@@ -5420,6 +5531,35 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env)
tmp = process_textarea(tag, h_env->limit);
if (tmp)
HTMLlineproc1(tmp->ptr, h_env);
+
+#ifdef USE_JAVASCRIPT
+ /* Phase 4: Create DOM element for textarea tag */
+ if (h_env->buffer_ref && h_env->buffer_ref->js_state && h_env->buffer_ref->js_document) {
+ W3MElement *textarea_elem = w3m_dom_create_element("TEXTAREA");
+ if (textarea_elem) {
+ /* Extract textarea attributes */
+ char *name, *id, *rows_str, *cols_str;
+ char *readonly_str, *maxlength_str;
+
+ if (parsedtag_get_value(tag, ATTR_NAME, &name))
+ w3m_dom_set_attribute(textarea_elem, "name", name);
+ if (parsedtag_get_value(tag, ATTR_ID, &id))
+ w3m_dom_set_attribute(textarea_elem, "id", id);
+ if (parsedtag_get_value(tag, ATTR_ROWS, &rows_str))
+ w3m_dom_set_attribute(textarea_elem, "rows", rows_str);
+ if (parsedtag_get_value(tag, ATTR_COLS, &cols_str))
+ w3m_dom_set_attribute(textarea_elem, "cols", cols_str);
+ if (parsedtag_get_value(tag, ATTR_READONLY, &readonly_str))
+ w3m_dom_set_attribute(textarea_elem, "readonly", readonly_str);
+ if (parsedtag_get_value(tag, ATTR_MAXLENGTH, &maxlength_str))
+ w3m_dom_set_attribute(textarea_elem, "maxlength", maxlength_str);
+
+ /* Add to document body */
+ w3m_dom_append_child(h_env->buffer_ref->js_document->body, textarea_elem);
+ add_element_to_document(h_env->buffer_ref->js_document, textarea_elem);
+ }
+ }
+#endif
obuf->flag |= RB_INTXTA;
obuf->end_tag = HTML_N_TEXTAREA;
return 1;
@@ -6021,7 +6161,7 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit)
W3MElement *anchor_elem = w3m_dom_find_anchor_element(js_state->dom_document, a_href);
if (anchor_elem) {
a_href->element = anchor_elem;
- anchor_elem->anchor = a_href;
+ anchor_elem->anchor = (struct Anchor *)a_href;
}
}
}
diff --git a/js/w3m_dom.c b/js/w3m_dom.c
index 16da5ac..9b431df 100644
--- a/js/w3m_dom.c
+++ b/js/w3m_dom.c
@@ -17,6 +17,21 @@
/* Forward declarations */
static W3MElement *w3m_dom_find_anchor_element_recursive(W3MElement *elem, Anchor *anchor);
+/* Phase 4: Form Element JavaScript API Function Declarations */
+static JSValue js_form_submit(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
+static JSValue js_form_reset(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
+static JSValue js_input_focus(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
+static JSValue js_input_blur(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
+static JSValue js_input_click(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
+static JSValue js_textarea_focus(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
+static JSValue js_textarea_blur(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
+static JSValue js_select_focus(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
+static JSValue js_select_blur(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
+
+/* Phase 4: Form submission helper functions */
+static int w3m_dom_submit_form(W3MElement *form_elem);
+static int w3m_dom_reset_form(W3MElement *form_elem);
+
/* DOM Document Management */
W3MDocument *
@@ -829,6 +844,93 @@ create_js_element_object(JSContext *ctx, W3MElement *elem)
JS_NewString(ctx, elem->innerHTML) : JS_NewString(ctx, "");
JS_SetPropertyStr(ctx, js_elem, "innerHTML", innerHTML);
+ /* Phase 4: Add form element properties and methods */
+ if (elem->tagName) {
+ if (strcmp(elem->tagName, "FORM") == 0) {
+ /* Form element properties */
+ const char *action_str = w3m_dom_get_attribute(elem, "action");
+ JS_SetPropertyStr(ctx, js_elem, "action", action_str ? JS_NewString(ctx, action_str) : JS_NewString(ctx, ""));
+
+ const char *method_str = w3m_dom_get_attribute(elem, "method");
+ JS_SetPropertyStr(ctx, js_elem, "method", method_str ? JS_NewString(ctx, method_str) : JS_NewString(ctx, "get"));
+
+ const char *name_str = w3m_dom_get_attribute(elem, "name");
+ JS_SetPropertyStr(ctx, js_elem, "name", name_str ? JS_NewString(ctx, name_str) : JS_NewString(ctx, ""));
+
+ /* Form methods */
+ JS_SetPropertyStr(ctx, js_elem, "submit",
+ JS_NewCFunction(ctx, js_form_submit, "submit", 0));
+ JS_SetPropertyStr(ctx, js_elem, "reset",
+ JS_NewCFunction(ctx, js_form_reset, "reset", 0));
+
+ } else if (strcmp(elem->tagName, "INPUT") == 0) {
+ /* Input element properties */
+ const char *type_str = w3m_dom_get_attribute(elem, "type");
+ JS_SetPropertyStr(ctx, js_elem, "type", type_str ? JS_NewString(ctx, type_str) : JS_NewString(ctx, "text"));
+
+ const char *name_str = w3m_dom_get_attribute(elem, "name");
+ JS_SetPropertyStr(ctx, js_elem, "name", name_str ? JS_NewString(ctx, name_str) : JS_NewString(ctx, ""));
+
+ const char *value_str = w3m_dom_get_attribute(elem, "value");
+ JS_SetPropertyStr(ctx, js_elem, "value", value_str ? JS_NewString(ctx, value_str) : JS_NewString(ctx, ""));
+
+ /* Note: placeholder not supported in w3m's HTML attribute constants */
+ JS_SetPropertyStr(ctx, js_elem, "placeholder", JS_NewString(ctx, ""));
+
+ /* Boolean properties */
+ const char *checked_str = w3m_dom_get_attribute(elem, "checked");
+ JSValue checked = JS_NewBool(ctx, checked_str != NULL);
+ JS_SetPropertyStr(ctx, js_elem, "checked", checked);
+
+ /* Note: disabled not supported in w3m's HTML attribute constants */
+ JS_SetPropertyStr(ctx, js_elem, "disabled", JS_NewBool(ctx, 0));
+
+ const char *readonly_str = w3m_dom_get_attribute(elem, "readonly");
+ JSValue readonly = JS_NewBool(ctx, readonly_str != NULL);
+ JS_SetPropertyStr(ctx, js_elem, "readonly", readonly);
+
+ /* Input methods */
+ JS_SetPropertyStr(ctx, js_elem, "focus",
+ JS_NewCFunction(ctx, js_input_focus, "focus", 0));
+ JS_SetPropertyStr(ctx, js_elem, "blur",
+ JS_NewCFunction(ctx, js_input_blur, "blur", 0));
+ JS_SetPropertyStr(ctx, js_elem, "click",
+ JS_NewCFunction(ctx, js_input_click, "click", 0));
+
+ } else if (strcmp(elem->tagName, "TEXTAREA") == 0) {
+ /* Textarea element properties */
+ const char *name_str = w3m_dom_get_attribute(elem, "name");
+ JS_SetPropertyStr(ctx, js_elem, "name", name_str ? JS_NewString(ctx, name_str) : JS_NewString(ctx, ""));
+
+ JSValue value = elem->textContent ? JS_NewString(ctx, elem->textContent) : JS_NewString(ctx, "");
+ JS_SetPropertyStr(ctx, js_elem, "value", value);
+
+ /* Note: placeholder not supported in w3m's HTML attribute constants */
+ JS_SetPropertyStr(ctx, js_elem, "placeholder", JS_NewString(ctx, ""));
+
+ /* Textarea methods */
+ JS_SetPropertyStr(ctx, js_elem, "focus",
+ JS_NewCFunction(ctx, js_textarea_focus, "focus", 0));
+ JS_SetPropertyStr(ctx, js_elem, "blur",
+ JS_NewCFunction(ctx, js_textarea_blur, "blur", 0));
+
+ } else if (strcmp(elem->tagName, "SELECT") == 0) {
+ /* Select element properties */
+ const char *name_str = w3m_dom_get_attribute(elem, "name");
+ JS_SetPropertyStr(ctx, js_elem, "name", name_str ? JS_NewString(ctx, name_str) : JS_NewString(ctx, ""));
+
+ const char *multiple_str = w3m_dom_get_attribute(elem, "multiple");
+ JSValue multiple = JS_NewBool(ctx, multiple_str != NULL);
+ JS_SetPropertyStr(ctx, js_elem, "multiple", multiple);
+
+ /* Select methods */
+ JS_SetPropertyStr(ctx, js_elem, "focus",
+ JS_NewCFunction(ctx, js_select_focus, "focus", 0));
+ JS_SetPropertyStr(ctx, js_elem, "blur",
+ JS_NewCFunction(ctx, js_select_blur, "blur", 0));
+ }
+ }
+
return js_elem;
}
@@ -1059,4 +1161,243 @@ w3m_dom_find_anchor_element_recursive(W3MElement *elem, Anchor *anchor)
return NULL;
}
+/* Phase 4: Form Element JavaScript API Functions */
+
+static JSValue
+js_form_submit(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
+{
+ W3MElement *form_elem = get_element_from_js_value(ctx, this_val);
+ if (!form_elem) return JS_UNDEFINED;
+
+ /* Phase 4: JavaScript form submission implementation */
+ if (strcmp(form_elem->tagName, "FORM") != 0) {
+ return JS_UNDEFINED; /* Not a form element */
+ }
+
+ /* Find a form item that belongs to this form */
+ if (w3m_dom_submit_form(form_elem)) {
+ /* Form submitted successfully */
+ return JS_UNDEFINED;
+ } else {
+ /* Form submission failed */
+ return JS_UNDEFINED;
+ }
+}
+
+static JSValue
+js_form_reset(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
+{
+ W3MElement *form_elem = get_element_from_js_value(ctx, this_val);
+ if (!form_elem) return JS_UNDEFINED;
+
+ /* Phase 4: JavaScript form reset implementation */
+ if (strcmp(form_elem->tagName, "FORM") != 0) {
+ return JS_UNDEFINED; /* Not a form element */
+ }
+
+ /* Reset all form elements to their initial values */
+ w3m_dom_reset_form(form_elem);
+
+ return JS_UNDEFINED;
+}
+
+static JSValue
+js_input_focus(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
+{
+ W3MElement *input_elem = get_element_from_js_value(ctx, this_val);
+ if (!input_elem) return JS_UNDEFINED;
+
+ /* Phase 4 stub: Input focus will be implemented with w3m's form navigation */
+ /* TODO: Move cursor to this input element */
+
+ return JS_UNDEFINED;
+}
+
+static JSValue
+js_input_blur(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
+{
+ W3MElement *input_elem = get_element_from_js_value(ctx, this_val);
+ if (!input_elem) return JS_UNDEFINED;
+
+ /* Phase 4 stub: Input blur */
+ /* TODO: Remove focus from this input element */
+
+ return JS_UNDEFINED;
+}
+
+static JSValue
+js_input_click(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
+{
+ W3MElement *input_elem = get_element_from_js_value(ctx, this_val);
+ if (!input_elem) return JS_UNDEFINED;
+
+ /* Phase 4 stub: Input click simulation */
+ /* TODO: Simulate click event on this input element */
+
+ return JS_UNDEFINED;
+}
+
+static JSValue
+js_textarea_focus(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
+{
+ W3MElement *textarea_elem = get_element_from_js_value(ctx, this_val);
+ if (!textarea_elem) return JS_UNDEFINED;
+
+ /* Phase 4 stub: Textarea focus */
+ /* TODO: Move cursor to this textarea element */
+
+ return JS_UNDEFINED;
+}
+
+static JSValue
+js_textarea_blur(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
+{
+ W3MElement *textarea_elem = get_element_from_js_value(ctx, this_val);
+ if (!textarea_elem) return JS_UNDEFINED;
+
+ /* Phase 4 stub: Textarea blur */
+ /* TODO: Remove focus from this textarea element */
+
+ return JS_UNDEFINED;
+}
+
+static JSValue
+js_select_focus(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
+{
+ W3MElement *select_elem = get_element_from_js_value(ctx, this_val);
+ if (!select_elem) return JS_UNDEFINED;
+
+ /* Phase 4 stub: Select focus */
+ /* TODO: Move cursor to this select element */
+
+ return JS_UNDEFINED;
+}
+
+static JSValue
+js_select_blur(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
+{
+ W3MElement *select_elem = get_element_from_js_value(ctx, this_val);
+ if (!select_elem) return JS_UNDEFINED;
+
+ /* Phase 4 stub: Select blur */
+ /* TODO: Remove focus from this select element */
+
+ return JS_UNDEFINED;
+}
+
+/* Phase 4: Form Submission Implementation */
+
+static int
+w3m_dom_submit_form(W3MElement *form_elem)
+{
+ extern TabBuffer *CurrentTab;
+
+ if (!form_elem || !Currentbuf || !Currentbuf->formitem) return 0;
+
+ /* Find the first form element that belongs to this form */
+ const char *form_name = w3m_dom_get_attribute(form_elem, "name");
+ const char *form_action = w3m_dom_get_attribute(form_elem, "action");
+
+ for (int i = 0; i < Currentbuf->formitem->nanchor; i++) {
+ Anchor *a = &Currentbuf->formitem->anchors[i];
+ struct form_item_list *fi = (struct form_item_list *)a->url;
+
+ if (!fi || !fi->parent) continue;
+
+ /* Check if this form item belongs to our form */
+ int form_match = 0;
+ if (form_name && fi->parent->name && strcmp(form_name, fi->parent->name) == 0) {
+ form_match = 1;
+ } else if (form_action && fi->parent->action &&
+ strcmp(form_action, fi->parent->action->ptr) == 0) {
+ form_match = 1;
+ } else if (!form_name && !form_action) {
+ /* If no name/action specified, use first available form */
+ form_match = 1;
+ }
+
+ if (form_match) {
+ /* Trigger form submission using w3m's existing system */
+ /* We need to simulate the submission by setting the current buffer position
+ * to this form element and calling the submission function */
+
+ /* Set buffer position to this form item */
+ Currentbuf->submit = a;
+
+ /* Return success - the actual submission will be processed by w3m's main loop */
+ return 1;
+ }
+ }
+
+ return 0; /* No matching form found */
+}
+
+static int
+w3m_dom_reset_form(W3MElement *form_elem)
+{
+ extern TabBuffer *CurrentTab;
+
+ if (!form_elem || !Currentbuf || !Currentbuf->formitem) return 0;
+
+ /* Find all form elements that belong to this form and reset them */
+ const char *form_name = w3m_dom_get_attribute(form_elem, "name");
+ const char *form_action = w3m_dom_get_attribute(form_elem, "action");
+
+ int reset_count = 0;
+
+ for (int i = 0; i < Currentbuf->formitem->nanchor; i++) {
+ Anchor *a = &Currentbuf->formitem->anchors[i];
+ struct form_item_list *fi = (struct form_item_list *)a->url;
+
+ if (!fi || !fi->parent) continue;
+
+ /* Check if this form item belongs to our form */
+ int form_match = 0;
+ if (form_name && fi->parent->name && strcmp(form_name, fi->parent->name) == 0) {
+ form_match = 1;
+ } else if (form_action && fi->parent->action &&
+ strcmp(form_action, fi->parent->action->ptr) == 0) {
+ form_match = 1;
+ } else if (!form_name && !form_action) {
+ /* If no name/action specified, reset first available form */
+ form_match = 1;
+ }
+
+ if (form_match) {
+ /* Reset this form element to its initial value */
+ switch (fi->type) {
+ case FORM_INPUT_TEXT:
+ case FORM_INPUT_PASSWORD:
+ case FORM_TEXTAREA:
+ if (fi->init_value) {
+ fi->value = Strdup(fi->init_value);
+ } else {
+ fi->value = Strnew();
+ }
+ break;
+
+ case FORM_INPUT_CHECKBOX:
+ case FORM_INPUT_RADIO:
+ fi->checked = fi->init_checked;
+ break;
+
+#ifdef MENU_SELECT
+ case FORM_SELECT:
+ fi->selected = fi->init_selected;
+ if (fi->init_label) {
+ fi->label = Strdup(fi->init_label);
+ }
+ break;
+#endif
+ }
+
+ /* Update the buffer display */
+ formUpdateBuffer(a, Currentbuf, fi);
+ reset_count++;
+ }
+ }
+
+ return reset_count;
+}
+
#endif /* USE_JAVASCRIPT */
\ No newline at end of file
diff --git a/js/w3m_dom.h b/js/w3m_dom.h
index a8cffe6..4bf8be8 100644
--- a/js/w3m_dom.h
+++ b/js/w3m_dom.h
@@ -18,7 +18,7 @@
struct _Buffer;
struct Line;
struct Anchor;
-struct FormItem;
+struct form_item_list;
/* Simplified DOM Element Structure */
typedef struct W3MElement {
@@ -37,7 +37,7 @@ typedef struct W3MElement {
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 */
+ struct form_item_list *form_item; /* If element is form control */
/* Attributes and content */
struct {
diff --git a/js/w3m_javascript.c b/js/w3m_javascript.c
index f41c414..5593ddb 100644
--- a/js/w3m_javascript.c
+++ b/js/w3m_javascript.c
@@ -22,6 +22,21 @@ int w3m_js_timeout = 5000; /* 5 second timeout */
int w3m_js_memory_limit = 8388608; /* 8MB memory limit */
int w3m_js_network_enabled = 1;
+/* Debug console.log implementation */
+static JSValue
+w3m_js_console_log(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
+{
+ if (argc > 0) {
+ const char *str = JS_ToCString(ctx, argv[0]);
+ if (str) {
+ /* For now, just add to debug - later we might display this somewhere */
+ fprintf(stderr, "JS: %s\n", str);
+ JS_FreeCString(ctx, str);
+ }
+ }
+ return JS_UNDEFINED;
+}
+
/* JavaScript Context Management */
W3MJSContext *
@@ -49,6 +64,12 @@ w3m_js_create_context(void)
/* Get global object */
ctx->global_obj = JS_GetGlobalObject(ctx->context);
+ /* Add basic console.log support for debugging */
+ JSValue console = JS_NewObject(ctx->context);
+ JS_SetPropertyStr(ctx->context, console, "log",
+ JS_NewCFunction(ctx->context, w3m_js_console_log, "log", 1));
+ JS_SetPropertyStr(ctx->context, ctx->global_obj, "console", console);
+
/* Initialize empty document and window objects */
ctx->document_obj = JS_NULL;
ctx->window_obj = JS_NULL;
@@ -260,10 +281,11 @@ w3m_js_value_to_string(W3MJSContext *ctx, JSValue val)
void
w3m_js_report_error(W3MJSContext *ctx, const char *msg)
{
- /* For now, just ignore errors silently */
- /* In future, could log to status line or debug output */
+ /* Report JavaScript errors to stderr for debugging */
+ if (msg) {
+ fprintf(stderr, "JavaScript Error: %s\n", msg);
+ }
(void)ctx;
- (void)msg;
}
#endif /* USE_JAVASCRIPT */
\ No newline at end of file
|