--- a/config.h.in Wed May 13 13:31:37 2009 -0400
+++ b/config.h.in Thu May 14 23:48:02 2009 +0800
@@ -2,6 +2,9 @@
/* Enable GIF images */
#undef ENABLE_GIF
+
+/* Enable JavaScript */
+#undef ENABLE_JAVASCRIPT
/* Enable JPEG images */
#undef ENABLE_JPEG
@@ -14,6 +17,24 @@
/* Define to 1 if you have the header file. */
#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the `GC_dump' function. */
+#undef HAVE_GC_DUMP
+
+/* Define to 1 if you have the `GC_free' function. */
+#undef HAVE_GC_FREE
+
+/* Define to 1 if you have the `GC_gcollect' function. */
+#undef HAVE_GC_GCOLLECT
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_GC_GC_H
+
+/* Define to 1 if you have the `GC_malloc' function. */
+#undef HAVE_GC_MALLOC
+
+/* Define to 1 if you have the `GC_malloc_atomic' function. */
+#undef HAVE_GC_MALLOC_ATOMIC
/* Define to 1 if you have the `gethostbyname' function. */
#undef HAVE_GETHOSTBYNAME
@@ -35,6 +56,12 @@
/* Define to 1 if you have the header file. */
#undef HAVE_PNG_H
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_SEE_H
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_SEE_SEE_H
/* Define to 1 if you have the `setsockopt' function. */
#undef HAVE_SETSOCKOPT
@@ -102,6 +129,9 @@
/* Version number of package */
#undef VERSION
+/* Define if you have Boehm GC */
+#undef WITH_BOEHM_GC
+
/* Use char pointers for newer libiconv */
#undef inbuf_t
diff -r 468e535f1435 configure.in
--- a/configure.in Wed May 13 13:31:37 2009 -0400
+++ b/configure.in Thu May 14 23:48:02 2009 +0800
@@ -32,6 +32,8 @@ AC_ARG_ENABLE(jpeg, [ --disable-jpeg
enable_jpeg=$enableval, enable_jpeg=yes)
AC_ARG_ENABLE(gif, [ --disable-gif Disable support for GIF images],
enable_gif=$enableval, enable_gif=yes)
+AC_ARG_ENABLE(javascript, [ --disable-javascript Disable support for JavaScript],
+ enable_javascript=$enableval, enable_javascript=yes)
AC_ARG_ENABLE(threaded-dns,[ --disable-threaded-dns Disable the advantage of a reentrant resolver library],
enable_threaded_dns=$enableval, enable_threaded_dns=yes)
AC_ARG_ENABLE(rtfl, [ --enable-rtfl Build with rtfl messages])
@@ -183,6 +185,115 @@ fi
if test "x$jpeg_ok" = "xyes"; then
AC_DEFINE([ENABLE_JPEG], [], [Enable JPEG images])
+fi
+
+dnl ----------------
+dnl Test for libsee
+dnl ----------------
+dnl
+if test "x$enable_javascript" = "xyes"; then
+ AC_MSG_CHECKING([for libsee-config])
+
+dnl Check if the user hasn't set the variable $SEE_CONFIG
+ if test -z "$SEE_CONFIG"; then
+ SEE_CONFIG=`which libsee-config`
+ fi
+
+dnl Check if the libpng-config script was found and is executable
+ if test -n "$SEE_CONFIG" && test -x "$SEE_CONFIG"; then
+ AC_MSG_RESULT([$SEE_CONFIG])
+ see_ok="yes"
+ LIBSEE_CPPFLAGS=`$SEE_CONFIG --cppflags`
+ LIBSEE_LIBS=`$SEE_CONFIG --libs`
+ else
+ AC_MSG_RESULT([missing])
+ see_ok="no"
+ fi
+
+dnl Try to find libpng even though libpng-config wasn't found
+ if test "x$see_ok" = "xno"; then
+ AC_CHECK_HEADERS(see.h see/see.h, see_ok=yes && break, see_ok=no)
+
+ if test "x$see_ok" = "xyes"; then
+ old_libs="$LIBS"
+ AC_CHECK_LIB(see, SEE_interpreter_init, see_ok=yes, see_ok=no)
+ LIBS="$old_libs"
+
+ if test "x$see_ok" = "xyes"; then
+ LIBSEE_LIBS="-lsee"
+ fi
+ fi
+
+ if test "x$see_ok" = "xno"; then
+ AC_MSG_WARN([*** No libsee found. Disabling JavaScript ***])
+ fi
+ fi
+fi
+
+if test "x$see_ok" = "xyes"; then
+
+dnl ------------------------------------------------------------
+dnl external libraries
+dnl
+
+AC_ARG_WITH(boehm-gc,
+ AC_HELP_STRING([--with-boehm-gc],
+ [use Boehm-Weiser garbage collector, default=yes]),
+ [with_boehmgc=$withval], [with_boehmgc=yes])
+ if test x"$with_boehmgc" != x"no"; then
+ save_LIBSEE_LIBS="$LIBSEE_LIBS"
+ save_LIBS="$LIBS"
+ save_LDFLAGS="$LDFLAGS"
+ save_CPPFLAGS="$CPPFLAGS"
+ case "$with_boehmgc" in
+ yes)
+ LIBSEE_LIBS="$LIBSEE_LIBS -lgc"
+ LIBS="$LIBS -lgc"
+ ;;
+ *) LIBSEE_LIBS="$LIBSEE_LIBS -L${with_boehmgc}/lib -lgc"
+ LDFLAGS="$LDFLAGS -L${with_boehmgc}/lib"
+ LIBS="$LIBS -lgc"
+ CPPFLAGS="$CPPFLAGS -I${with_boehmgc}/include"
+ ;;
+ esac
+
+ # The following minimum for Boehm GC support:
+ #
+ # #if WITH_BOEHM_GC
+ # # include
+ # GC_INIT();
+ # GC_MALLOC(...);
+ # GC_dump();
+ # GC_gcollect();
+ # #endif
+
+ have_boehm_gc=yes
+ AC_CHECK_HEADERS([gc/gc.h],,[have_boehm_gc=no])
+ AC_TRY_LINK([#include ],
+ [GC_INIT();
+ GC_MALLOC(1);
+ GC_gcollect();
+ ],,
+ [have_boehm_gc=no])
+ if test x"$have_boehm_gc" = x"yes"; then
+ AC_DEFINE(WITH_BOEHM_GC, [1], [Define if you have Boehm GC])
+ AC_CHECK_FUNCS([GC_malloc GC_gcollect GC_dump GC_malloc_atomic GC_free],
+ ,[have_boehm_gc=no])
+ else
+ LIBSEE_LIBS="$save_LIBSEE_LIBS"
+ CPPFLAGS="$save_CPPFLAGS"
+ fi
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ else
+ have_boehm_gc=no
+ fi
+ AC_MSG_CHECKING([if we can use Boehm GC])
+ AM_CONDITIONAL(WITH_BOEHM_GC, test x"$have_boehm_gc" = x"yes")
+ AC_MSG_RESULT([$have_boehm_gc])
+
+
+ AC_DEFINE([ENABLE_JAVASCRIPT], [], [Enable JavaScript])
fi
dnl -------------
@@ -491,6 +602,8 @@ AC_SUBST(LIBJPEG_CPPFLAGS)
AC_SUBST(LIBJPEG_CPPFLAGS)
AC_SUBST(LIBPNG_LIBS)
AC_SUBST(LIBPNG_CFLAGS)
+AC_SUBST(LIBSEE_LIBS)
+AC_SUBST(LIBSEE_CPPFLAGS)
AC_SUBST(LIBZ_LIBS)
AC_SUBST(LIBSSL_LIBS)
AC_SUBST(LIBPTHREAD_LIBS)
diff -r 468e535f1435 src/Makefile.am
--- a/src/Makefile.am Wed May 13 13:31:37 2009 -0400
+++ b/src/Makefile.am Thu May 14 23:48:02 2009 +0800
@@ -14,7 +14,7 @@ dillo_LDADD = \
../dw/libDw-fltk.a \
../dw/libDw-core.a \
../lout/liblout.a \
- @LIBJPEG_LIBS@ @LIBPNG_LIBS@ @LIBFLTK_LIBS@ @LIBZ_LIBS@ @LIBICONV_LIBS@
+ @LIBJPEG_LIBS@ @LIBPNG_LIBS@ @LIBFLTK_LIBS@ @LIBZ_LIBS@ @LIBICONV_LIBS@ @LIBSEE_LIBS@
dillo_SOURCES = \
dillo.cc \
diff -r 468e535f1435 src/form.cc
--- a/src/form.cc Wed May 13 13:31:37 2009 -0400
+++ b/src/form.cc Thu May 14 23:48:02 2009 +0800
@@ -24,6 +24,8 @@
#include "prefs.h"
#include "nav.h"
#include "uicmd.hh"
+
+#include "capi.h"
using namespace dw;
using namespace dw::core;
@@ -95,6 +97,7 @@ class DilloHtmlForm {
Dstr *x, Dstr *y);
public: //BUG: for now everything is public
+ char *name;
DilloHtmlMethod method;
DilloUrl *action;
DilloHtmlEnc content_type;
@@ -107,7 +110,7 @@ public: //BUG: for now everything is pu
DilloHtmlReceiver *form_receiver;
public:
- DilloHtmlForm (DilloHtml *html,
+ DilloHtmlForm (DilloHtml *html, char *name,
DilloHtmlMethod method, const DilloUrl *action,
DilloHtmlEnc content_type, const char *charset,
bool enabled);
@@ -151,6 +154,7 @@ public: //BUG: for now everything is pu
bool init_val; /* only meaningful for buttons */
Dstr *file_data; /* only meaningful for file inputs.
TODO: may become a list... */
+ char *onclick;
private:
void connectTo(DilloHtmlReceiver *form_receiver);
@@ -159,7 +163,7 @@ private:
public:
DilloHtmlInput (DilloHtmlInputType type, Embed *embed,
- const char *name, const char *init_str, bool init_val);
+ const char *name, const char *init_str, bool init_val, const char *onclick);
~DilloHtmlInput ();
void appendValuesTo(Dlist *values, bool is_active_submit);
void reset();
@@ -194,12 +198,12 @@ private:
* Form API
*/
-DilloHtmlForm *a_Html_form_new (DilloHtml *html, DilloHtmlMethod method,
+DilloHtmlForm *a_Html_form_new (DilloHtml *html, char *name, DilloHtmlMethod method,
const DilloUrl *action,
DilloHtmlEnc content_type, const char *charset,
bool enabled)
{
- return new DilloHtmlForm (html, method, action, content_type, charset, enabled);
+ return new DilloHtmlForm (html, name, method, action, content_type, charset, enabled);
}
void a_Html_form_delete (DilloHtmlForm *form)
@@ -236,11 +240,11 @@ void a_Html_form_display_hiddens2(void *
*/
static void Html_add_input(DilloHtml *html, DilloHtmlInputType type,
Embed *embed, const char *name,
- const char *init_str, bool init_val)
+ const char *init_str, bool init_val, const char *onclick)
{
_MSG("name=[%s] init_str=[%s] init_val=[%d]\n", name, init_str, init_val);
DilloHtmlInput *input = new DilloHtmlInput(type, embed, name, init_str,
- init_val);
+ init_val, onclick);
if (html->InFlags & IN_FORM) {
html->getCurrentForm()->addInput(input, type);
} else {
@@ -292,6 +296,7 @@ static DilloHtmlInput *Html_get_current_
*/
void Html_tag_open_form(DilloHtml *html, const char *tag, int tagsize)
{
+ char *name = 0;
DilloUrl *action;
DilloHtmlMethod method;
DilloHtmlEnc content_type;
@@ -309,6 +314,9 @@ void Html_tag_open_form(DilloHtml *html,
html->InFlags &= ~IN_OPTION;
html->InFlags &= ~IN_TEXTAREA;
+ if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "name"))) {
+ name = dStrdup(attrbuf);
+ }
method = DILLO_HTML_METHOD_GET;
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "method"))) {
if (!dStrcasecmp(attrbuf, "post")) {
@@ -348,7 +356,7 @@ void Html_tag_open_form(DilloHtml *html,
}
if (!charset)
charset = html->charset;
- html->formNew(method, action, content_type, charset);
+ html->formNew(name, method, action, content_type, charset);
dFree(first);
a_Url_free(action);
}
@@ -411,7 +419,7 @@ void Html_tag_open_input(DilloHtml *html
DilloHtmlInputType inp_type;
Resource *resource = NULL;
Embed *embed = NULL;
- char *value, *name, *type, *init_str;
+ char *value, *name, *type, *onclick, *init_str;
const char *attrbuf, *label;
bool init_val = false;
ResourceFactory *factory;
@@ -431,6 +439,7 @@ void Html_tag_open_input(DilloHtml *html
value = a_Html_get_attr_wdef(html, tag, tagsize, "value", NULL);
name = a_Html_get_attr_wdef(html, tag, tagsize, "name", NULL);
type = a_Html_get_attr_wdef(html, tag, tagsize, "type", "");
+ onclick = a_Html_get_attr_wdef(html, tag, tagsize, "onclick", NULL);
init_str = NULL;
inp_type = DILLO_HTML_INPUT_UNKNOWN;
@@ -528,7 +537,7 @@ void Html_tag_open_input(DilloHtml *html
if (inp_type != DILLO_HTML_INPUT_UNKNOWN) {
Html_add_input(html, inp_type, embed, name,
- (init_str) ? init_str : "", init_val);
+ (init_str) ? init_str : "", init_val, onclick);
}
if (embed != NULL && inp_type != DILLO_HTML_INPUT_IMAGE &&
@@ -554,6 +563,8 @@ void Html_tag_open_input(DilloHtml *html
if (init_str != value)
dFree(init_str);
dFree(value);
+ if(onclick)
+ dFree(onclick);
}
/*
@@ -562,6 +573,7 @@ void Html_tag_open_input(DilloHtml *html
*/
void Html_tag_open_isindex(DilloHtml *html, const char *tag, int tagsize)
{
+ char *name = 0;
DilloUrl *action;
Embed *embed;
const char *attrbuf;
@@ -571,12 +583,15 @@ void Html_tag_open_isindex(DilloHtml *ht
return;
}
+ if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "name"))) {
+ name = dStrdup(attrbuf);
+ }
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "action")))
action = a_Html_url_new(html, attrbuf, NULL, 0);
else
action = a_Url_dup(html->base_url);
- html->formNew(DILLO_HTML_METHOD_GET, action, DILLO_HTML_ENC_URLENCODED,
+ html->formNew(name, DILLO_HTML_METHOD_GET, action, DILLO_HTML_ENC_URLENCODED,
html->charset);
html->InFlags |= IN_FORM;
@@ -588,7 +603,7 @@ void Html_tag_open_isindex(DilloHtml *ht
ResourceFactory *factory = HT2LT(html)->getResourceFactory();
EntryResource *entryResource = factory->createEntryResource (20,false,NULL);
embed = new Embed (entryResource);
- Html_add_input(html, DILLO_HTML_INPUT_INDEX, embed, NULL, NULL, FALSE);
+ Html_add_input(html, DILLO_HTML_INPUT_INDEX, embed, NULL, NULL, FALSE, 0);
HT2TB(html)->addWidget (embed, html->styleEngine->backgroundStyle ());
@@ -656,7 +671,7 @@ void Html_tag_open_textarea(DilloHtml *h
/* Readonly or not? */
if (a_Html_get_attr(html, tag, tagsize, "readonly"))
textres->setEditable(false);
- Html_add_input(html, DILLO_HTML_INPUT_TEXTAREA, embed, name, NULL, false);
+ Html_add_input(html, DILLO_HTML_INPUT_TEXTAREA, embed, name, NULL, false, 0);
HT2TB(html)->addWidget (embed, html->styleEngine->backgroundStyle ());
dFree(name);
@@ -744,7 +759,7 @@ void Html_tag_open_select(DilloHtml *htm
HT2TB(html)->addWidget (embed, html->styleEngine->backgroundStyle ());
- Html_add_input(html, type, embed, name, NULL, false);
+ Html_add_input(html, type, embed, name, NULL, false, 0);
a_Html_stash_init(html);
dFree(name);
}
@@ -837,7 +852,7 @@ void Html_tag_open_button(DilloHtml *htm
/* Render the button */
Widget *page;
Embed *embed;
- char *name, *value;
+ char *name, *value, *onclick;
page = new Textblock (prefs.limit_text_width);
page->setStyle (html->styleEngine->backgroundStyle ());
@@ -857,10 +872,13 @@ void Html_tag_open_button(DilloHtml *htm
value = a_Html_get_attr_wdef(html, tag, tagsize, "value", NULL);
name = a_Html_get_attr_wdef(html, tag, tagsize, "name", NULL);
+ onclick = a_Html_get_attr_wdef(html, tag, tagsize, "onclick", NULL);
- Html_add_input(html, inp_type, embed, name, value, FALSE);
+ Html_add_input(html, inp_type, embed, name, value, FALSE, onclick);
dFree(name);
dFree(value);
+ if(onclick)
+ dFree(onclick);
}
dFree(type);
}
@@ -885,11 +903,13 @@ void Html_tag_close_button(DilloHtml *ht
* Constructor
*/
DilloHtmlForm::DilloHtmlForm (DilloHtml *html2,
+ char *name2,
DilloHtmlMethod method2,
const DilloUrl *action2,
DilloHtmlEnc content_type2,
const char *charset, bool enabled)
{
+ name = name2;
html = html2;
method = method2;
action = a_Url_dup(action2);
@@ -907,6 +927,8 @@ DilloHtmlForm::DilloHtmlForm (DilloHtml
*/
DilloHtmlForm::~DilloHtmlForm ()
{
+ if(name)
+ dFree(name);
a_Url_free(action);
dFree(submit_charset);
for (int j = 0; j < inputs->size(); j++)
@@ -937,6 +959,21 @@ void DilloHtmlForm::eventHandler(Resourc
*/
void DilloHtmlForm::submit(DilloHtmlInput *active_input, EventButton *event)
{
+ if(active_input->onclick) {
+ //printf("onclick = %s\n", active_input->onclick);
+ bool bRetVal = false;
+ char *s = active_input->onclick;
+ if(strncasecmp("return ", active_input->onclick, 7) == 0) {
+ s = active_input->onclick + 7;
+ bRetVal = true; /*Enable return value check*/
+ }
+ void *p = a_Html_script_run(html, s);
+ if(bRetVal && p == 0) {
+printf("onClick fail...\n");
+ return;
+ }
+ }
+
DilloUrl *url = buildQueryUrl(active_input);
if (url) {
if (event && event->button == 2) {
@@ -1528,13 +1565,14 @@ void DilloHtmlReceiver::clicked (Resourc
*/
DilloHtmlInput::DilloHtmlInput (DilloHtmlInputType type2, Embed *embed2,
const char *name2, const char *init_str2,
- bool init_val2)
+ bool init_val2, const char *onclick2)
{
type = type2;
embed = embed2;
name = (name2) ? dStrdup(name2) : NULL;
init_str = (init_str2) ? dStrdup(init_str2) : NULL;
init_val = init_val2;
+ onclick = (onclick2) ? dStrdup(onclick2) : NULL;
select = NULL;
switch (type) {
case DILLO_HTML_INPUT_SELECT:
@@ -1558,6 +1596,8 @@ DilloHtmlInput::~DilloHtmlInput ()
dStr_free(file_data, 1);
if (select)
delete select;
+ if (onclick)
+ dFree(onclick);
}
/*
@@ -1936,3 +1976,480 @@ static void Html_option_finish(DilloHtml
a_Html_parse_entities(html, html->Stash->str, html->Stash->len);
}
}
+
+/*
+ * File: dom.cc
+ *
+ * Copyright (C) 2009 Steve Chang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ */
+
+/*
+* Document Object Model
+*/
+
+#if WITH_BOEHM_GC
+# include
+#endif
+
+#include
+
+static struct SEE_interpreter *interp = 0;
+
+/*
+ * Runs the input given by inp, printing any exceptions
+ * to stderr.
+ * This function first establishes a local exception catch context.
+ * Next, it passes the unicode input provider ('inp') to the generic
+ * evaluation procedure SEE_Global_eval which executes the program
+ * text in the ECMAScript global context. This function also examines
+ * the result of the evaluation, being careful to print out exceptions
+ * correctly.
+ * Returns 0 if an exception was uncaught, or 1 if the script ran to
+ * completion.
+ */
+static int
+run_input(struct SEE_input *inp, struct SEE_value *res)
+{
+ struct SEE_value v;
+ SEE_try_context_t ctxt, ctxt2;
+
+ interp->traceback = NULL;
+ SEE_TRY (interp, ctxt) {
+/*
+ if (debugger)
+ debug_eval(interp, debugger, inp, res);
+ else
+*/
+ SEE_Global_eval(interp, inp, res);
+ }
+ if (SEE_CAUGHT(ctxt)) {
+ fprintf(stderr, "exception:\n");
+ SEE_TRY(interp, ctxt2) {
+ SEE_ToString(interp, SEE_CAUGHT(ctxt), &v);
+ fprintf(stderr, " ");
+ SEE_string_fputs(v.u.string, stderr);
+ fprintf(stderr, "\n");
+#ifndef NDEBUG
+ if (ctxt.throw_file)
+ fprintf(stderr, " (thrown from %s:%d)\n",
+ ctxt.throw_file, ctxt.throw_line);
+#endif
+ SEE_PrintContextTraceback(interp, &ctxt, stderr);
+ }
+ if (SEE_CAUGHT(ctxt2)) {
+ /* Exception while printing exception! */
+ fprintf(stderr, "[exception thrown while printing exception");
+ if (ctxt2.throw_file)
+ fprintf(stderr, " at %s:%d",
+ ctxt2.throw_file, ctxt2.throw_line);
+ fprintf(stderr, "]\n");
+ }
+ return 0;
+ }
+ return 1;
+}
+
+class DilloHtmlScript {
+ DilloHtml *html;
+ DilloHtmlScriptType type;
+ DilloUrl *src;
+ char *script;
+ struct SEE_input *input;
+
+public:
+ DilloHtmlScript(DilloHtml *html, DilloHtmlScriptType type, const DilloUrl *src, const char *script);
+ ~DilloHtmlScript();
+
+ void Script(const char *script);
+ void Input();
+};
+
+/*
+ * Called by the network engine to load javascript.
+ */
+
+static void Script_load_callback(int Op, CacheClient_t *Client)
+{
+ _MSG("Script_load_callback: Op=%d\n", Op);
+ if (Op) { /* EOF */
+/*Are we really get javascript ? Maybe some thing below.*/
+/*
+
+
400 Bad Request
+Your request has bad syntax or is inherently impossible to satisfy.
+
+thttpd/2.20c 21nov01
+
+*/
+ DilloHtmlScript *s = (DilloHtmlScript *)Client->CbData;
+ s->Script((const char *)Client->Buf);
+/*
+ printf("Load %s complete\n", a_Url_str(Client->Url));
+ printf("**************************************************\n");
+ printf("%s\n", Client->Buf);
+ printf("**************************************************\n");
+*/
+ }
+}
+
+DilloHtmlScript::DilloHtmlScript(DilloHtml *_html, DilloHtmlScriptType _type, const DilloUrl *_src, const char *_script)
+: html(_html), type(_type), script(NULL)
+{
+ //src = (_src) ? dStrdup(_src) : NULL;
+ src = a_Url_dup(_src);
+ if(_script)
+ Script(_script);
+ else {
+ DilloWeb *Web;
+ int ClientKey;
+ /* Fill a Web structure for the cache query */
+ Web = a_Web_new(src);
+ Web->bw = html->bw;
+ if ((ClientKey = a_Capi_open_url(Web, Script_load_callback, this)) != 0) {
+ a_Bw_add_client(html->bw, ClientKey, 0);
+ a_Bw_add_url(html->bw, src);
+ }
+ }
+}
+
+DilloHtmlScript::~DilloHtmlScript()
+{
+ a_Url_free(src);
+ if(script)
+ dFree(script);
+ if(input)
+ SEE_INPUT_CLOSE(input);
+}
+
+void DilloHtmlScript::Script(const char *_script)
+{
+ if(_script == NULL)
+ return;
+
+ script = dStrdup(_script);
+}
+
+void DilloHtmlScript::Input()
+{
+ input = SEE_input_utf8(interp, script);
+ if(src)
+ input->filename = SEE_intern_ascii(interp, a_Url_str(src));
+ else
+ input->filename = SEE_intern_ascii(interp, "");
+ run_input(input, NULL);
+}
+
+DilloHtmlScript *a_Html_script_new(DilloHtml *html, DilloHtmlScriptType type, const DilloUrl *src, const char *script)
+{
+ return new DilloHtmlScript(html, type, src, script);
+}
+
+/*
+*
+*/
+
+struct method {
+ const char *name;
+ void (*fn)(struct SEE_interpreter *, struct SEE_object *,
+ struct SEE_object *, int, struct SEE_value **,
+ struct SEE_value *);
+ int expected_args;
+};
+/*
+static void
+add_methods(interpreter, object, methods)
+ struct SEE_interpreter *interpreter;
+ struct SEE_object *object;
+ const struct method *methods;
+*/
+static void
+add_methods(struct SEE_interpreter *interpreter,
+ struct SEE_object* object,
+ const struct method *methods)
+{
+ unsigned int i;
+
+ for (i = 0; methods[i].name; i++)
+ SEE_CFUNCTION_PUTA(interpreter, object,
+ methods[i].name, methods[i].fn,
+ methods[i].expected_args, 0);
+}
+
+/*
+ * A write function that prints its output to stdout.
+ * No newline is appended.
+ */
+static void
+document_write(struct SEE_interpreter *interpreter,
+ struct SEE_object *self,
+ struct SEE_object *thisobj,
+ int argc,
+ struct SEE_value **argv,
+ struct SEE_value *res)
+{
+ struct SEE_value v;
+
+ if (argc) {
+ SEE_ToString(interp, argv[0], &v);
+ SEE_string_fputs(v.u.string, stdout);
+ fflush(stdout);
+ }
+ SEE_SET_UNDEFINED(res);
+}
+
+/*
+ * A function that gets forms object by name.
+*/
+static void
+document_getElementById(struct SEE_interpreter *interpreter,
+ struct SEE_object *self,
+ struct SEE_object *thisobj,
+ int argc,
+ struct SEE_value **argv,
+ struct SEE_value *res)
+{
+ struct SEE_value v, s;
+
+ if(thisobj && argc) {
+ SEE_ToString(interp, argv[0], &s);
+ SEE_OBJECT_GET(interp, thisobj, SEE_intern(interp, s.u.string), &v);
+ if (SEE_VALUE_GET_TYPE(&v) == SEE_OBJECT) {
+ SEE_SET_OBJECT(res, v.u.object); /*Object already created, just return it.*/
+ return;
+ }
+ }
+
+ SEE_SET_UNDEFINED(res);
+}
+
+/*
+* Form submit
+*/
+static void
+form_submit(struct SEE_interpreter *interpreter,
+ struct SEE_object *self,
+ struct SEE_object *thisobj,
+ int argc,
+ struct SEE_value **argv,
+ struct SEE_value *res)
+{
+ SEE_SET_UNDEFINED(res);
+}
+
+/*
+* Form reset
+*/
+static void
+form_reset(struct SEE_interpreter *interpreter,
+ struct SEE_object *self,
+ struct SEE_object *thisobj,
+ int argc,
+ struct SEE_value **argv,
+ struct SEE_value *res)
+{
+ DilloHtmlInput *i = (DilloHtmlInput *)thisobj->host_data;
+ i->reset();
+
+ SEE_SET_UNDEFINED(res);
+}
+
+/*
+* Input focus
+*/
+static void
+input_focus(struct SEE_interpreter *interpreter,
+ struct SEE_object *self,
+ struct SEE_object *thisobj,
+ int argc,
+ struct SEE_value **argv,
+ struct SEE_value *res)
+{
+ SEE_SET_UNDEFINED(res);
+}
+
+static void
+global_alert(struct SEE_interpreter *interpreter,
+ struct SEE_object *self,
+ struct SEE_object *thisobj,
+ int argc,
+ struct SEE_value **argv,
+ struct SEE_value *res)
+{
+ SEE_SET_UNDEFINED(res);
+}
+
+/*
+*
+*/
+#if WITH_BOEHM_GC
+# include
+#endif
+
+void a_Dom_setup(DilloHtml *html)
+{
+ static int interp_initialised = 0;
+ static struct SEE_interpreter i;
+
+ #if WITH_BOEHM_GC
+ GC_INIT();
+ #endif
+
+#define INIT_INTERP_ONCE do { \
+ if (!interp_initialised) { \
+ SEE_interpreter_init(&i); \
+ interp_initialised = 1; \
+ } \
+ } while (0)
+
+ INIT_INTERP_ONCE;
+
+ interp = &i;
+
+ SEE_CFUNCTION_PUTA(interp, interp->Global, "alert", global_alert, 1, 0); /*form.length*/
+
+ struct SEE_object *document, *forms;
+ struct SEE_value v;
+
+ document = SEE_Object_new(interp);
+ document->host_data = html;
+ SEE_SET_OBJECT(&v, document);
+ SEE_OBJECT_PUTA(interp, interp->Global, "document", &v, 0);
+
+ static const struct method document_methods[] = {
+ { "write", document_write, 1 },
+ { "getElementById", document_getElementById, 1 },
+ {0}
+ };
+
+ add_methods(interp, document, document_methods);
+
+ /**/
+
+ forms = SEE_Object_new(interp);
+ forms->host_data = html->forms;
+ SEE_SET_OBJECT(&v, forms);
+ SEE_OBJECT_PUTA(interp, document, "forms", &v, 0);
+/*forms.length -> number of forms in a document */
+ SEE_SET_NUMBER(&v, html->forms->size());
+ SEE_OBJECT_PUTA(interp, forms, "length", &v, 0);
+
+
+ if(html->forms) {
+/*Create object according to form name*/
+ int c;
+ for(c=0;c forms->size();c++) {
+ DilloHtmlForm* f = html->forms->get(c);
+ if(!f || !f->name) /*Object MUST exist and have a name*/
+ continue;
+/**/
+ struct SEE_object *form = SEE_Object_new(interp);
+ form->host_data = f;
+ SEE_SET_OBJECT(&v, form);
+ SEE_OBJECT_PUTA(interp, document, f->name, &v, 0);
+/*form.length*/
+ SEE_SET_NUMBER(&v, f->inputs->size());
+ SEE_OBJECT_PUTA(interp, form, "length", &v, 0);
+
+/*form.method*/
+ switch(f->method) {
+ case DILLO_HTML_METHOD_UNKNOWN: SEE_SET_STRING(&v, SEE_string_sprintf(interp, ""));
+ break;
+ case DILLO_HTML_METHOD_GET: SEE_SET_STRING(&v, SEE_string_sprintf(interp, "get"));
+ break;
+ case DILLO_HTML_METHOD_POST: SEE_SET_STRING(&v, SEE_string_sprintf(interp, "post"));
+ break;
+ }
+ SEE_OBJECT_PUTA(interp, form, "method", &v, 0);
+/*form.submit()*/
+ SEE_CFUNCTION_PUTA(interp, form, "submit", form_submit, 0, 0); /*form.submit*/
+/*form.reset()*/
+ SEE_CFUNCTION_PUTA(interp, form, "reset", form_reset, 0, 0); /*form.reset*/
+
+/*Create object according to input name*/
+ lout::misc::SimpleVector *inputs = f->inputs;
+ if(inputs) {
+ int cc;
+ for(cc=0;cc size();cc++) {
+ DilloHtmlInput *i = inputs->get(cc);
+ if(!i || !i->name) /*Object MUST exist and have a name*/
+ continue;
+ struct SEE_object *inp = SEE_Object_new(interp);
+ inp->host_data = i;
+ SEE_SET_OBJECT(&v, inp);
+ SEE_OBJECT_PUTA(interp, form, i->name, &v, 0);
+
+/*input.value*/
+ switch (i->type) {
+ case DILLO_HTML_INPUT_TEXT:
+ case DILLO_HTML_INPUT_PASSWORD:
+ case DILLO_HTML_INPUT_INDEX:
+ case DILLO_HTML_INPUT_HIDDEN: {
+ EntryResource *entryres = (EntryResource*)i->embed->getResource();
+ SEE_SET_STRING(&v, SEE_string_sprintf(interp, "%s", entryres->getText()));
+ } break;
+ default:
+ SEE_SET_STRING(&v, SEE_string_sprintf(interp, ""));
+ break;
+ }
+ SEE_OBJECT_PUTA(interp, inp, "value", &v, 0);
+/*input.focus()*/
+ SEE_CFUNCTION_PUTA(interp, inp, "focus", input_focus, 0, 0);
+ }
+ }
+ }
+ }
+}
+
+/*
+*
+*/
+
+void *a_Html_script_run(DilloHtml *html, const char *script)
+{
+ a_Dom_setup(html);
+
+ int i;
+ for(i=0;i scripts->size();i++) {
+ DilloHtmlScript *s = html->scripts->get(i);
+ s->Input();
+ }
+
+ static struct SEE_value res, rstr;
+ struct SEE_input *input;
+ SEE_string *r;
+
+printf("Run : %s\n", script);
+ input = SEE_input_utf8(interp, script);
+ if (run_input(input, &res)) {
+ printf(" = ");
+ SEE_PrintValue(interp, &res, stdout);
+ printf("\n");
+ }
+
+ SEE_INPUT_CLOSE(input);
+
+ switch(SEE_VALUE_GET_TYPE(&res)) {
+ case SEE_UNDEFINED:
+ case SEE_NULL:
+ case SEE_OBJECT:
+ return 0;
+ case SEE_BOOLEAN:
+ return (void *)res.u.boolean;
+ case SEE_NUMBER:
+ //return (void *)res.u.number;
+ case SEE_STRING:
+ SEE_ToString(interp, &res, &rstr);
+ r = rstr.u.string;
+ break;
+ default:
+ return 0;
+ }
+
+ return r->data;
+}
+
diff -r 468e535f1435 src/form.hh
--- a/src/form.hh Wed May 13 13:31:37 2009 -0400
+++ b/src/form.hh Thu May 14 23:48:02 2009 +0800
@@ -31,6 +31,7 @@ class DilloHtml;
*/
DilloHtmlForm *a_Html_form_new(DilloHtml *html,
+ char *name,
DilloHtmlMethod method,
const DilloUrl *action,
DilloHtmlEnc enc,
@@ -59,4 +60,20 @@ void Html_tag_open_button(DilloHtml *htm
void Html_tag_open_button(DilloHtml *html, const char *tag, int tagsize);
void Html_tag_close_button(DilloHtml *html, int TagIdx);
+/*
+* Script
+*/
+
+void a_Dom_setup(DilloHtml *html);
+
+typedef enum {
+ DILLO_HTML_JAVASCRIPT,
+ DILLO_HTML_VBSCRIPT
+} DilloHtmlScriptType;
+
+class DilloHtmlScript;
+
+DilloHtmlScript *a_Html_script_new(DilloHtml *html, DilloHtmlScriptType type, const DilloUrl *src, const char *script);
+void *a_Html_script_run(DilloHtml *html, const char *script);
+
#endif /* __FORM_HH__ */
diff -r 468e535f1435 src/html.cc
--- a/src/html.cc Wed May 13 13:31:37 2009 -0400
+++ b/src/html.cc Thu May 14 23:48:02 2009 +0800
@@ -40,6 +40,8 @@
#include "html_common.hh"
#include "form.hh"
#include "table.hh"
+
+#include "dom.hh"
#include "dw/textblock.hh"
#include "dw/bullet.hh"
@@ -472,6 +474,7 @@ DilloHtml::DilloHtml(BrowserWindow *p_bw
inputs_outside_form = new misc::SimpleVector (1);
links = new misc::SimpleVector (64);
images = new misc::SimpleVector (16);
+ scripts = new misc::SimpleVector (1);
//a_Dw_image_map_list_init(&maps);
/* Initialize the main widget */
@@ -635,18 +638,28 @@ void DilloHtml::finishParsing(int Client
/*
* Allocate and insert form information.
*/
-int DilloHtml::formNew(DilloHtmlMethod method, const DilloUrl *action,
+int DilloHtml::formNew(char *name, DilloHtmlMethod method, const DilloUrl *action,
DilloHtmlEnc enc, const char *charset)
{
// avoid data loss on repush after CSS stylesheets have been loaded
bool enabled = bw->NumPendingStyleSheets == 0;
- DilloHtmlForm *form = a_Html_form_new (this, method, action,
+ DilloHtmlForm *form = a_Html_form_new (this, name, method, action,
enc, charset, enabled);
int nf = forms->size ();
forms->increase ();
forms->set (nf, form);
_MSG("Html formNew: action=%s nform=%d\n", action, nf);
return forms->size();
+}
+
+int DilloHtml::scriptNew(DilloHtmlScriptType type, const DilloUrl *src, const char *script)
+{
+ DilloHtmlScript *s = a_Html_script_new(this, type, src, script);
+ int ns = scripts->size ();
+ scripts->increase ();
+ scripts->set (ns, s);
+ _MSG("Html scriptNew: src=%s nform=%d\n", a_Url_str(src), ns);
+ return scripts->size();
}
/*
@@ -1624,6 +1637,20 @@ static void Html_tag_close_title(DilloHt
*/
static void Html_tag_open_script(DilloHtml *html, const char *tag, int tagsize)
{
+ const char *attrbuf;
+ attrbuf = a_Html_get_attr(html, tag, tagsize, "language");
+ if(attrbuf) {
+ if(dStristr(attrbuf, "javascript")) {
+ //printf("JavaScript\n");
+
+ DilloUrl *url;
+ if (!(attrbuf = a_Html_get_attr(html, tag, tagsize, "src")) ||
+ !(url = a_Html_url_new(html, attrbuf, NULL, 0)))
+ goto script_done;
+
+ html->scriptNew(DILLO_HTML_JAVASCRIPT, url, 0);
+ }
+ }
+
+script_done:
a_Html_stash_init(html);
S_TOP(html)->parse_mode = DILLO_HTML_PARSE_MODE_VERBATIM;
}
@@ -1633,7 +1660,10 @@ static void Html_tag_open_script(DilloHt
*/
static void Html_tag_close_script(DilloHtml *html, int TagIdx)
{
+ //printf("html->Stash->str = \n%s\n", html->Stash->str);
/* eventually the stash will be sent to an interpreter for parsing */
+ if(html->Stash->str && html->Stash->str != "")
+ html->scriptNew(DILLO_HTML_JAVASCRIPT, 0, html->Stash->str);
}
/*
@@ -3425,7 +3455,7 @@ static void Html_process_tag(DilloHtml *
}
/* Handle HTML, HEAD and BODY. Elements with optional open and close */
- if (!(html->InFlags & IN_BODY) /* && parsing HTML */)
+ if (!(html->InFlags & IN_BODY) && (ni != 54)/* && parsing HTML */)
Html_test_section(html, ni, IsCloseTag);
/* Tag processing */
diff -r 468e535f1435 src/html_common.hh
--- a/src/html_common.hh Wed May 13 13:31:37 2009 -0400
+++ b/src/html_common.hh Thu May 14 23:48:02 2009 +0800
@@ -14,6 +14,8 @@
#include "form.hh"
#include "styleengine.hh"
+
+#include "dom.hh"
/*
* Macros
@@ -196,6 +198,7 @@ public: //BUG: for now everything is pu
lout::misc::SimpleVector *inputs_outside_form;
lout::misc::SimpleVector *links;
lout::misc::SimpleVector *images;
+ lout::misc::SimpleVector *scripts;
dw::ImageMapsList maps;
private:
@@ -210,8 +213,9 @@ public:
void write(char *Buf, int BufSize, int Eof);
int getCurTagLineNumber();
void finishParsing(int ClientKey);
- int formNew(DilloHtmlMethod method, const DilloUrl *action,
+ int formNew(char *name, DilloHtmlMethod method, const DilloUrl *action,
DilloHtmlEnc enc, const char *charset);
+ int scriptNew(DilloHtmlScriptType type, const DilloUrl *src, const char *script);
DilloHtmlForm *getCurrentForm ();
bool_t unloadedImages();
void loadImages (const DilloUrl *pattern);
沒有留言:
張貼留言