mirror of
https://github.com/rkd77/elinks.git
synced 2025-02-02 15:09:23 -05:00
Merge with git+ssh://pasky.or.cz/srv/git/elinks.git
This commit is contained in:
commit
f15c0a2677
@ -48,6 +48,9 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
|
|||||||
INSTALL_DATA = @INSTALL_DATA@
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||||
|
|
||||||
|
TEST_LIB=$(top_srcdir)/test/libtest.sh
|
||||||
|
export TEST_LIB
|
||||||
|
|
||||||
host = @host@
|
host = @host@
|
||||||
|
|
||||||
ASCIIDOC = @ASCIIDOC@
|
ASCIIDOC = @ASCIIDOC@
|
||||||
@ -139,6 +142,7 @@ CONFIG_RISCOS = @CONFIG_RISCOS@
|
|||||||
CONFIG_RUBY = @CONFIG_RUBY@
|
CONFIG_RUBY = @CONFIG_RUBY@
|
||||||
CONFIG_SCANNER = @CONFIG_SCANNER@
|
CONFIG_SCANNER = @CONFIG_SCANNER@
|
||||||
CONFIG_SCRIPTING = @CONFIG_SCRIPTING@
|
CONFIG_SCRIPTING = @CONFIG_SCRIPTING@
|
||||||
|
CONFIG_SEE = @CONFIG_SEE@
|
||||||
CONFIG_SHA1 = @CONFIG_SHA1@
|
CONFIG_SHA1 = @CONFIG_SHA1@
|
||||||
CONFIG_SMALL = @CONFIG_SMALL@
|
CONFIG_SMALL = @CONFIG_SMALL@
|
||||||
CONFIG_SMB = @CONFIG_SMB@
|
CONFIG_SMB = @CONFIG_SMB@
|
||||||
|
83
Makefile.lib
83
Makefile.lib
@ -33,8 +33,8 @@ mcmd = @$(if $($(mquiet)cmd_$(1)),echo $($(mquiet)cmd_$(1)) &&) $(cmd_$(1))
|
|||||||
ecmd = @$(if $($(mquiet)cmd_$(1)),printf "%-38s " $($(mquiet)cmd_$(1)) &&) $(cmd_$(1))
|
ecmd = @$(if $($(mquiet)cmd_$(1)),printf "%-38s " $($(mquiet)cmd_$(1)) &&) $(cmd_$(1))
|
||||||
|
|
||||||
quiet_cmd_compile = ' [$(CC_COLOR)CC$(END_COLOR)] $(RELPATH)$@'
|
quiet_cmd_compile = ' [$(CC_COLOR)CC$(END_COLOR)] $(RELPATH)$@'
|
||||||
masq_cmd_compile = $(COMPILE) -c $<
|
masq_cmd_compile = $(COMPILE) -o $(@) -c $< $(2)
|
||||||
cmd_compile = $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
|
cmd_compile = $(COMPILE) -o $(@) -Wp,-MD,.deps/$(*F).pp -c $< $(2)
|
||||||
|
|
||||||
# Rule to compile a set of .o files into one .o file
|
# Rule to compile a set of .o files into one .o file
|
||||||
quiet_cmd_ld_objs = " [$(LD_COLOR)LD$(END_COLOR)] $(RELPATH)$@"
|
quiet_cmd_ld_objs = " [$(LD_COLOR)LD$(END_COLOR)] $(RELPATH)$@"
|
||||||
@ -43,7 +43,7 @@ quiet_cmd_ld_objs = " [$(LD_COLOR)LD$(END_COLOR)] $(RELPATH)$@"
|
|||||||
`test -e $(subdir)/lib.o && echo $(subdir)/lib.o`)
|
`test -e $(subdir)/lib.o && echo $(subdir)/lib.o`)
|
||||||
|
|
||||||
quiet_cmd_link = ' [$(LINK_COLOR)LINK$(END_COLOR)] $(RELPATH)$@'
|
quiet_cmd_link = ' [$(LINK_COLOR)LINK$(END_COLOR)] $(RELPATH)$@'
|
||||||
cmd_link = $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
|
cmd_link = $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(2) $(LIBS)
|
||||||
|
|
||||||
quiet_cmd_sparse = ' [SPARSE] $(RELPATH)$(2)'
|
quiet_cmd_sparse = ' [SPARSE] $(RELPATH)$(2)'
|
||||||
cmd_sparse = $(SPARSE) $(DEFS) $(INCLUDES) $(AM_CFLAGS) $(CFLAGS) $(SPARSE_FLAGS) $(2)
|
cmd_sparse = $(SPARSE) $(DEFS) $(INCLUDES) $(AM_CFLAGS) $(CFLAGS) $(SPARSE_FLAGS) $(2)
|
||||||
@ -125,12 +125,15 @@ CLEAN += $(PROG)
|
|||||||
|
|
||||||
all-default: $(LIB_O) $(PROGS) $(MAN1) $(MAN5)
|
all-default: $(LIB_O) $(PROGS) $(MAN1) $(MAN5)
|
||||||
|
|
||||||
|
# Ensure that Makefiles in subdirs are created before we recursive into them
|
||||||
|
init-recursive: init-default
|
||||||
|
|
||||||
init-default:
|
init-default:
|
||||||
@$(foreach subdir,$(sort $(SUBDIRS)), \
|
@$(foreach subdir,$(sort $(SUBDIRS)), \
|
||||||
$(MKINSTALLDIRS) $(subdir) >/dev/null; \
|
$(MKINSTALLDIRS) $(subdir) >/dev/null; \
|
||||||
echo 'include $(SRC)/$(RELPATH)/$(subdir)/Makefile' > $(subdir)/Makefile;)
|
echo 'include $(SRC)/$(RELPATH)/$(subdir)/Makefile' > $(subdir)/Makefile;)
|
||||||
|
|
||||||
clean-default:
|
clean-default: clean-test
|
||||||
@-test -z "$(CLEAN)" || $(RM) $(CLEAN)
|
@-test -z "$(CLEAN)" || $(RM) $(CLEAN)
|
||||||
|
|
||||||
cleanall-default: clean-default
|
cleanall-default: clean-default
|
||||||
@ -141,6 +144,40 @@ ifneq ($(SPARSE),)
|
|||||||
$(call ncmd,sparse,$(file));)
|
$(call ncmd,sparse,$(file));)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# Auto-testing infrastructure
|
||||||
|
#
|
||||||
|
|
||||||
|
clean-test:
|
||||||
|
test-default:
|
||||||
|
|
||||||
|
ifdef TEST_PROGS
|
||||||
|
TESTDEPS-$(CONFIG_DEBUG) += $(top_builddir)/src/util/memdebug.o
|
||||||
|
TESTDEPS += $(TESTDEPS-yes)
|
||||||
|
|
||||||
|
TESTS = $(wildcard $(srcdir)test-*)
|
||||||
|
|
||||||
|
$(TEST_PROGS): $(TESTDEPS)
|
||||||
|
$(call cmd,link,$@.o)
|
||||||
|
|
||||||
|
# We cannot use $$@.o in the rule above so ensure that all test programs are
|
||||||
|
# built before linking.
|
||||||
|
$(TESTS): $(addsuffix .o,$(TEST_PROGS)) $(TEST_PROGS)
|
||||||
|
@echo "*** $(notdir $@) ***"; \
|
||||||
|
$(call shellquote,$(SHELL)) $@ $(TEST_OPTS)
|
||||||
|
|
||||||
|
test-default: $(TESTS)
|
||||||
|
|
||||||
|
clean-test:
|
||||||
|
@rm -fr trash
|
||||||
|
|
||||||
|
CLEAN += $(TEST_PROGS) $(addsuffix .o,$(TEST_PROGS))
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: $(TESTS)
|
||||||
|
.NOPARALLEL:
|
||||||
|
|
||||||
# sparse is architecture-neutral, which means that we need to tell it
|
# sparse is architecture-neutral, which means that we need to tell it
|
||||||
# explicitly what architecture to check for. Fix this up for yours..
|
# explicitly what architecture to check for. Fix this up for yours..
|
||||||
SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
|
SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
|
||||||
@ -163,29 +200,41 @@ endif
|
|||||||
|
|
||||||
# Recursion:
|
# Recursion:
|
||||||
|
|
||||||
.PHONY: all-recursive install-recursive clean-recursive cleanall-recursive init-recursive check-recursive
|
RULES = all install clean cleanall init check test
|
||||||
|
RECRULES = $(addsuffix -recursive,$(RULES))
|
||||||
|
|
||||||
all-recursive install-recursive clean-recursive cleanall-recursive init-recursive check-recursive:
|
.PHONY: $(RECRULES)
|
||||||
|
|
||||||
|
# The -recursive rules decend all subdirs.
|
||||||
|
$(RECRULES):
|
||||||
ifdef SUBDIRS
|
ifdef SUBDIRS
|
||||||
@$(foreach subdir,$(sort $(SUBDIRS)), \
|
@$(foreach subdir,$(sort $(SUBDIRS)), \
|
||||||
$(call ncmd,recmake,$(subdir),$(subst -recursive,,$@)) || exit 1;)
|
$(call ncmd,recmake,$(subdir),$(subst -recursive,,$@)) || exit 1;)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
all: all-recursive all-default all-local
|
# Setup the default sub commands dependency. First decend subdirs then do all
|
||||||
install: install-recursive install-default install-local
|
# the default stuff and finally do any local hooks.
|
||||||
check: check-recursive check-default check-local
|
recdeps = $1-recursive $1-default $1-local
|
||||||
clean: clean-recursive clean-default clean-local
|
all: $(call recdeps,all)
|
||||||
|
check: $(call recdeps,check)
|
||||||
|
cleanall: $(call recdeps,cleanall)
|
||||||
|
clean: $(call recdeps,clean)
|
||||||
|
init: $(call recdeps,init)
|
||||||
|
install: $(call recdeps,install)
|
||||||
|
test: $(call recdeps,test)
|
||||||
|
|
||||||
cleanall: cleanall-recursive cleanall-default
|
# Dummy rules for local hooks
|
||||||
init: init-default init-recursive
|
$(addsuffix -local,$(RULES)):
|
||||||
|
|
||||||
all-local:
|
|
||||||
install-local:
|
|
||||||
clean-local:
|
|
||||||
check-local:
|
|
||||||
|
|
||||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||||
.NOEXPORT:
|
.NOEXPORT:
|
||||||
|
|
||||||
|
# Shell quote;
|
||||||
|
# Result of this needs to be placed inside ''
|
||||||
|
# XXX: Placed here because Vim cannot highlight things right afterwards
|
||||||
|
shq = $(subst ','\'',$(1))
|
||||||
|
# This has surrounding ''
|
||||||
|
shellquote = '$(call shq,$(1))'
|
||||||
|
|
||||||
# vim:syntax=make
|
# vim:syntax=make
|
||||||
|
1102
Unicode/entities.lnx
1102
Unicode/entities.lnx
File diff suppressed because it is too large
Load Diff
1060
Unicode/entities.txt
Normal file
1060
Unicode/entities.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -2,18 +2,27 @@
|
|||||||
|
|
||||||
echo
|
echo
|
||||||
echo Generating entity table.
|
echo Generating entity table.
|
||||||
(
|
|
||||||
cat entities.lnx | grep '^[ ]*{"' | sort >tmp
|
sed -n '/^[^#]/,$p' < entities.txt | while read line; do \
|
||||||
|
name=$(echo "$line" | cut -f 1); \
|
||||||
|
code=$(echo "$line" | cut -f 3); \
|
||||||
|
desc=$(echo "$line" | cut -f 4 | sed 's/# //'); \
|
||||||
|
test "$code" = "0x????" && continue
|
||||||
|
printf "\t{ %-12s %s }, /* %-46s */\n" \
|
||||||
|
"\"$name\"," "$code" "$desc"; \
|
||||||
|
done | LC_ALL=C sort > tmp
|
||||||
N=`cat tmp | wc -l`
|
N=`cat tmp | wc -l`
|
||||||
echo '/* Automatically generated by gen-ent */'
|
|
||||||
echo
|
cat > ../src/intl/entity.inc <<EOF
|
||||||
echo 'struct entity { char *s; unicode_val_T c; } entities ['`expr $N + 1`'] = {'
|
/* Automatically generated by gen-ent */
|
||||||
cat tmp
|
|
||||||
echo ' {NULL, 0}'
|
struct entity { char *s; unicode_val_T c; } entities [$(expr $N + 1)] = {
|
||||||
echo '};'
|
$(cat tmp)
|
||||||
echo
|
{ NULL, 0 }
|
||||||
echo '#define N_ENTITIES' $N
|
};
|
||||||
) > ../src/intl/entity.inc
|
|
||||||
|
#define N_ENTITIES $N
|
||||||
|
EOF
|
||||||
rm -f tmp
|
rm -f tmp
|
||||||
echo Done.
|
echo Done.
|
||||||
echo
|
echo
|
||||||
|
51
configure.in
51
configure.in
@ -496,6 +496,55 @@ if test "$CONFIG_WIN32" = yes; then
|
|||||||
EL_CONFIG_WIN32
|
EL_CONFIG_WIN32
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl ===================================================================
|
||||||
|
dnl Check for SEE (Simple Ecmascript Engine)
|
||||||
|
dnl ===================================================================
|
||||||
|
AC_ARG_WITH(see, [ --with-see enable Simple Ecmascript Engine (SEE) support],
|
||||||
|
[ if test "x$withval" != xno; then enable_see=yes; fi ])
|
||||||
|
|
||||||
|
# The following is probably bad, ugly and so on. Stolen from Guile's (1.4)
|
||||||
|
# SEE_FLAGS but I really don't want to require people to have Guile in order
|
||||||
|
# to compile CVS. Also, the macro seems to be really stupid regarding searching
|
||||||
|
# for Guile in $PATH etc. --pasky
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([for SEE])
|
||||||
|
|
||||||
|
if test "$enable_see" = "yes"; then
|
||||||
|
AC_MSG_RESULT(yes);
|
||||||
|
## Based on the SEE_FLAGS macro.
|
||||||
|
|
||||||
|
if test -d "$withval"; then
|
||||||
|
SEE_PATH="$withval:$PATH"
|
||||||
|
else
|
||||||
|
SEE_PATH="$PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_PATH_PROG(SEE_CONFIG, libsee-config, no, $SEE_PATH)
|
||||||
|
|
||||||
|
## First, let's just see if we can find Guile at all.
|
||||||
|
if test "$SEE_CONFIG" != no; then
|
||||||
|
cf_result="yes";
|
||||||
|
|
||||||
|
SEE_LIBS="`$SEE_CONFIG --libs`"
|
||||||
|
SEE_CFLAGS="`$SEE_CONFIG --cppflags`"
|
||||||
|
LIBS="$SEE_LIBS $LIBS"
|
||||||
|
CPPFLAGS="$CPPFLAGS $SEE_CFLAGS"
|
||||||
|
EL_CONFIG(CONFIG_SEE, [SEE])
|
||||||
|
AC_SUBST(SEE_CFLAGS)
|
||||||
|
AC_SUBST(CONFIG_SEE)
|
||||||
|
disable_spidermonkey=yes
|
||||||
|
else
|
||||||
|
if test -n "$withval" && test "x$withval" != xno; then
|
||||||
|
AC_MSG_ERROR([SEE not found])
|
||||||
|
else
|
||||||
|
AC_MSG_WARN([SEE support disabled])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(no);
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
dnl ===================================================================
|
dnl ===================================================================
|
||||||
dnl Check for SpiderMonkey, optional even if installed.
|
dnl Check for SpiderMonkey, optional even if installed.
|
||||||
dnl ===================================================================
|
dnl ===================================================================
|
||||||
@ -550,7 +599,7 @@ fi
|
|||||||
|
|
||||||
AC_SUBST(CONFIG_SPIDERMONKEY)
|
AC_SUBST(CONFIG_SPIDERMONKEY)
|
||||||
|
|
||||||
EL_CONFIG_DEPENDS(CONFIG_ECMASCRIPT, [CONFIG_SPIDERMONKEY], [ECMAScript (JavaScript)])
|
EL_CONFIG_DEPENDS(CONFIG_ECMASCRIPT, [CONFIG_SEE CONFIG_SPIDERMONKEY], [ECMAScript (JavaScript)])
|
||||||
|
|
||||||
|
|
||||||
dnl ===================================================================
|
dnl ===================================================================
|
||||||
|
@ -934,8 +934,6 @@ B<dia> <I<dialect>> <I<URL>> (or current url)
|
|||||||
|
|
||||||
Dialects: I<redneck>, I<jive>, I<cockney>, I<fudd>, I<bork>, I<moron>, I<piglatin>, or I<hacker>
|
Dialects: I<redneck>, I<jive>, I<cockney>, I<fudd>, I<bork>, I<moron>, I<piglatin>, or I<hacker>
|
||||||
|
|
||||||
=back
|
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
############################################################################
|
############################################################################
|
||||||
# the Dialectizer (dia <dialect> <url>)
|
# the Dialectizer (dia <dialect> <url>)
|
||||||
@ -1070,6 +1068,8 @@ using the search engine defined by the 'search' configuration option if
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
|
||||||
=head1 FOLLOW URL HOOK
|
=head1 FOLLOW URL HOOK
|
||||||
|
|
||||||
@ -1081,8 +1081,6 @@ I<Developer's usage>: The function I<follow_url_hook> is called when the hook
|
|||||||
is triggered, taking the target URL as its only argument. It returns the final
|
is triggered, taking the target URL as its only argument. It returns the final
|
||||||
target URL.
|
target URL.
|
||||||
|
|
||||||
=back
|
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
################################################################################
|
################################################################################
|
||||||
### follow_url_hook ############################################################
|
### follow_url_hook ############################################################
|
||||||
@ -1133,6 +1131,8 @@ Translates any I<nntp:> or I<news:> URLs to Google Groups HTTP URLs.
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
|
||||||
=head1 PRE FORMAT HTML HOOK
|
=head1 PRE FORMAT HTML HOOK
|
||||||
|
|
||||||
@ -1151,8 +1151,6 @@ I<Developer's usage>: The function I<pre_format_html_hook> is called when the
|
|||||||
hook is triggered, taking the document's URL and the HTML source as its two
|
hook is triggered, taking the document's URL and the HTML source as its two
|
||||||
arguments. It returns the rewritten HTML code.
|
arguments. It returns the rewritten HTML code.
|
||||||
|
|
||||||
=back
|
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
################################################################################
|
################################################################################
|
||||||
### pre_format_html_hook #######################################################
|
### pre_format_html_hook #######################################################
|
||||||
@ -1242,6 +1240,8 @@ content-type:text/html.
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
|
||||||
=head1 PROXY FOR HOOK
|
=head1 PROXY FOR HOOK
|
||||||
|
|
||||||
@ -1256,8 +1256,6 @@ I<Developer's usage>: The function I<proxy_for_hook> is called when the hook is
|
|||||||
triggered, taking the target URL as its only argument. It returns the proxy
|
triggered, taking the target URL as its only argument. It returns the proxy
|
||||||
URL, empty string to use no proxy or I<undef> to use the default proxy URL.
|
URL, empty string to use no proxy or I<undef> to use the default proxy URL.
|
||||||
|
|
||||||
=back
|
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
################################################################################
|
################################################################################
|
||||||
### proxy_for_hook #############################################################
|
### proxy_for_hook #############################################################
|
||||||
@ -1281,6 +1279,8 @@ Prevents proxy usage for local files and C<http://localhost>.
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
|
||||||
=head1 QUIT HOOK
|
=head1 QUIT HOOK
|
||||||
|
|
||||||
@ -1294,8 +1294,6 @@ I<Developer's usage>: The function I<quit_hook> is called when the hook is
|
|||||||
triggered, taking no arguments nor returning anything. ('cause, you know, what
|
triggered, taking no arguments nor returning anything. ('cause, you know, what
|
||||||
would be the point?)
|
would be the point?)
|
||||||
|
|
||||||
=back
|
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
################################################################################
|
################################################################################
|
||||||
### quit_hook ##################################################################
|
### quit_hook ##################################################################
|
||||||
@ -1367,6 +1365,8 @@ A few words of wisdom from ELinks the Sage.
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
|
||||||
=head1 SEE ALSO
|
=head1 SEE ALSO
|
||||||
|
|
||||||
|
146
doc/Makefile
146
doc/Makefile
@ -14,6 +14,7 @@ TXT_DIR = $(top_srcdir)/doc/txt
|
|||||||
|
|
||||||
DOC_DIRS = \
|
DOC_DIRS = \
|
||||||
$(HTML_DIR) \
|
$(HTML_DIR) \
|
||||||
|
$(HTML_DIR)/api \
|
||||||
$(MAN_DIR)/man1 \
|
$(MAN_DIR)/man1 \
|
||||||
$(MAN_DIR)/man5 \
|
$(MAN_DIR)/man5 \
|
||||||
$(TXT_DIR) \
|
$(TXT_DIR) \
|
||||||
@ -48,77 +49,51 @@ ELINKS = $(top_builddir)/src/elinks
|
|||||||
KBDBIND = $(top_srcdir)/src/config/kbdbind.c
|
KBDBIND = $(top_srcdir)/src/config/kbdbind.c
|
||||||
FEATURES = $(top_srcdir)/features.conf
|
FEATURES = $(top_srcdir)/features.conf
|
||||||
|
|
||||||
|
### Locale env vars to override system one to ensure commands
|
||||||
|
# using elinks binary will generate texts in english
|
||||||
|
#
|
||||||
|
LOCALES = LC_ALL=C LANGUAGE=en
|
||||||
|
|
||||||
### Scripts
|
### Scripts
|
||||||
#
|
#
|
||||||
|
|
||||||
|
CODE2DOC = $(top_srcdir)/doc/tools/code2doc
|
||||||
HELP2DOC = $(top_srcdir)/doc/tools/help2doc
|
HELP2DOC = $(top_srcdir)/doc/tools/help2doc
|
||||||
IMPORT_FEATURES_CONF = $(top_srcdir)/doc/tools/import-features.conf
|
IMPORT_FEATURES_CONF = $(top_srcdir)/doc/tools/import-features.conf
|
||||||
MAKE_ELINKS_MANPAGE = $(top_srcdir)/doc/tools/make-elinks-manpage
|
MAKE_ELINKS_MANPAGE = $(top_srcdir)/doc/tools/make-elinks-manpage
|
||||||
MAKE_ELINKSKEYS_MANPAGE = $(top_srcdir)/doc/tools/make-elinkskeys-manpage
|
MAKE_ELINKSKEYS_MANPAGE = $(top_srcdir)/doc/tools/make-elinkskeys-manpage
|
||||||
|
|
||||||
ifeq ($(CONFIG_ASCIIDOC),yes)
|
HTML_DOCS-$(CONFIG_ASCIIDOC) += \
|
||||||
HTML_DOCS_WITH_ASCIIDOC = \
|
api/dom.html \
|
||||||
$(HTML_DIR)/elinks.1.html \
|
elinks.1.html \
|
||||||
$(HTML_DIR)/elinkskeys.5.html \
|
elinkskeys.5.html \
|
||||||
$(HTML_DIR)/hacking.html \
|
hacking.html \
|
||||||
$(HTML_DIR)/manual.html
|
manual.html
|
||||||
endif
|
|
||||||
|
|
||||||
|
HTML_DOCS-$(CONFIG_XMLTO) += \
|
||||||
|
manual.html-chunked
|
||||||
|
|
||||||
|
HTML_DOCS-$(CONFIG_POD2HTML) += \
|
||||||
|
perl.html \
|
||||||
|
perl-hooks.html
|
||||||
|
|
||||||
|
MAN_DOCS-$(CONFIG_XMLTO) += \
|
||||||
|
man1/elinks.1.in \
|
||||||
|
man5/elinkskeys.5
|
||||||
|
|
||||||
# Only jw is used for generating PDF.
|
# Only jw is used for generating PDF.
|
||||||
ifeq ($(CONFIG_XMLTO),yes)
|
PDF_DOCS-$(CONFIG_JW) += \
|
||||||
HTML_DOCS_WITH_XMLTO = \
|
manual.pdf
|
||||||
$(HTML_DIR)/manual.html-chunked
|
|
||||||
|
|
||||||
MAN_DOCS_WITH_XMLTO = \
|
MAN_DOCS += man5/elinks.conf.5
|
||||||
$(MAN_DIR)/man1/elinks.1.in \
|
|
||||||
$(MAN_DIR)/man5/elinkskeys.5
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Only jw is used for generating PDF.
|
MAN_DOCS += $(MAN_DOCS-yes)
|
||||||
ifeq ($(CONFIG_JW),yes)
|
HTML_DOCS += $(HTML_DOCS-yes)
|
||||||
PDF_DOCS_WITH_JW = \
|
PDF_DOCS += $(PDF_DOCS-yes)
|
||||||
$(PDF_DIR)/manual.pdf
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_POD2HTML),yes)
|
man-docs: doc-dirs $(addprefix $(MAN_DIR)/,$(MAN_DOCS))
|
||||||
HTML_DOCS_WITH_POD2HTML = \
|
html-docs: doc-dirs $(addprefix $(HTML_DIR)/,$(HTML_DOCS))
|
||||||
$(HTML_DIR)/perl.html \
|
pdf-docs: doc-dirs $(addprefix $(PDF_DIR)/,$(PDF_DOCS))
|
||||||
$(HTML_DIR)/perl-hooks.html
|
|
||||||
endif
|
|
||||||
|
|
||||||
MAN_DOCS_WITH_SHELL = $(MAN_DIR)/man5/elinks.conf.5
|
|
||||||
|
|
||||||
MAN_DOCS = \
|
|
||||||
$(MAN_DOCS_WITH_SHELL)
|
|
||||||
$(MAN_DOCS_WITH_ASCIIDOC)
|
|
||||||
|
|
||||||
HTML_DOCS = \
|
|
||||||
$(HTML_DOCS_WITH_ASCIIDOC) \
|
|
||||||
$(HTML_DOCS_WITH_POD2HTML) \
|
|
||||||
$(HTML_DOCS_WITH_JW)
|
|
||||||
|
|
||||||
PDF_DOCS = \
|
|
||||||
$(PDF_DOCS_WITH_JW)
|
|
||||||
|
|
||||||
html-asciidoc-yes: doc-dirs $(HTML_DOCS_WITH_ASCIIDOC)
|
|
||||||
html-asciidoc-no:
|
|
||||||
|
|
||||||
html-pod2html-yes: doc-dirs $(HTML_DOCS_WITH_POD2HTML)
|
|
||||||
html-pod2html-no:
|
|
||||||
|
|
||||||
html-xmlto-yes: doc-dirs $(HTML_DOCS_WITH_XMLTO)
|
|
||||||
html-xmlto-no:
|
|
||||||
|
|
||||||
man-xmlto-yes: doc-dirs $(MAN_DOCS_WITH_XMLTO)
|
|
||||||
man-xmlto-no:
|
|
||||||
|
|
||||||
pdf-jw-yes: doc-dirs $(PDF_DOCS_WITH_JW)
|
|
||||||
pdf-jw-no:
|
|
||||||
|
|
||||||
man-docs: man-xmlto-$(CONFIG_XMLTO) $(MAN_DOCS_WITH_SHELL)
|
|
||||||
html-docs: html-asciidoc-$(CONFIG_ASCIIDOC) html-xmlto-$(CONFIG_XMLTO) html-pod2html-$(CONFIG_POD2HTML)
|
|
||||||
pdf-docs: pdf-jw-$(CONFIG_JW)
|
|
||||||
|
|
||||||
all-docs: man-docs html-docs pdf-docs
|
all-docs: man-docs html-docs pdf-docs
|
||||||
|
|
||||||
@ -135,36 +110,40 @@ clean-local:
|
|||||||
|
|
||||||
# Autogenerated asciidoc files.
|
# Autogenerated asciidoc files.
|
||||||
|
|
||||||
$(TXT_DIR)/import-features.conf.txt: $(FEATURES) doc-dirs $(IMPORT_FEATURES_CONF)
|
$(TXT_DIR)/import-features.conf.txt: $(FEATURES) $(IMPORT_FEATURES_CONF)
|
||||||
$(IMPORT_FEATURES_CONF) > $@
|
$(IMPORT_FEATURES_CONF) > $@
|
||||||
|
|
||||||
$(TXT_DIR)/elinks.1.%.txt: $(MAKE_ELINKS_MANPAGE) doc-dirs $(ELINKS)
|
$(TXT_DIR)/elinks.1.%.txt: $(MAKE_ELINKS_MANPAGE) $(ELINKS) $(HELP2DOC) Makefile
|
||||||
$(MAKE_ELINKS_MANPAGE) $@ $(ELINKS) $(HELP2DOC) > $@
|
$(LOCALES) $(MAKE_ELINKS_MANPAGE) $@ $(ELINKS) $(HELP2DOC) > $@
|
||||||
|
|
||||||
$(TXT_DIR)/elinkskeys.5.%.txt: $(MAKE_ELINKSKEYS_MANPAGE) doc-dirs $(KBDBIND)
|
$(TXT_DIR)/elinkskeys.5.%.txt: $(MAKE_ELINKSKEYS_MANPAGE) $(KBDBIND) Makefile
|
||||||
$(MAKE_ELINKSKEYS_MANPAGE) $@ $(KBDBIND) > $@
|
$(LOCALES) $(MAKE_ELINKSKEYS_MANPAGE) $@ $(KBDBIND) > $@
|
||||||
|
|
||||||
|
|
||||||
# Man Pages
|
# Man Pages
|
||||||
|
|
||||||
$(XML_DIR)/%.man.xml: $(TXT_DIR)/%.man.txt doc-dirs
|
$(XML_DIR)/%.man.xml: $(TXT_DIR)/%.man.txt
|
||||||
$(ASCIIDOC) -b docbook -d manpage -o $@ $<
|
$(ASCIIDOC) -b docbook -d manpage -o $@ $<
|
||||||
|
|
||||||
$(MAN_DIR)/man1/elinks.1.in: $(XML_DIR)/elinks.1.man.xml doc-dirs
|
$(MAN_DIR)/man1/elinks.1.in: $(XML_DIR)/elinks.1.man.xml
|
||||||
$(XMLTO) -o $(MAN_DIR)/man1 man $<
|
$(XMLTO) -o $(MAN_DIR)/man1 man $<
|
||||||
mv $(MAN_DIR)/man1/elinks.1 $@
|
sed 's/^\.TH "ELINKS" 1 .*/.TH "ELINKS" 1 "The ELinks text-browser" "$(shell date -I)" "The ELinks text-browser"/' \
|
||||||
|
< $(MAN_DIR)/man1/elinks.1 > $@
|
||||||
|
rm $(MAN_DIR)/man1/elinks.1
|
||||||
|
|
||||||
$(MAN_DIR)/man5/elinkskeys.5: $(XML_DIR)/elinkskeys.5.man.xml doc-dirs
|
$(MAN_DIR)/man5/elinkskeys.5: $(XML_DIR)/elinkskeys.5.man.xml
|
||||||
$(XMLTO) -o $(MAN_DIR)/man5 man $<
|
$(XMLTO) -o $(MAN_DIR)/man5 man $<
|
||||||
sed -e 's/\\fI\\fR'\''/\\fI\\'\''\\fR/' < $@ > $@.tmp
|
sed -e 's/\\fI\\fR'\''/\\fI\\'\''\\fR/' < $@ > $@.tmp
|
||||||
mv $@.tmp $@
|
sed 's/^\.TH "ELINKSKEYS" 5 .*/.TH "ELINKSKEYS" 5 "ELinks keybindings" "$(shell date -I)" "ELinks keybindings"/' \
|
||||||
|
< $@.tmp > $@
|
||||||
|
rm $@.tmp
|
||||||
|
|
||||||
$(MAN_DIR)/man5/elinks.conf.5: doc-dirs $(ELINKS)
|
$(MAN_DIR)/man5/elinks.conf.5: $(ELINKS) $(HELP2DOC) Makefile
|
||||||
$(HELP2DOC) --elinks=$(ELINKS) --elinksconf > $@
|
$(LOCALES) $(HELP2DOC) --elinks=$(ELINKS) --elinksconf > $@
|
||||||
|
|
||||||
# XHTML/CSS Man Pages
|
# XHTML/CSS Man Pages
|
||||||
|
|
||||||
$(HTML_DIR)/%.html: $(TXT_DIR)/%.html.txt doc-dirs
|
$(HTML_DIR)/%.html: $(TXT_DIR)/%.html.txt
|
||||||
$(ASCIIDOC) -b xhtml11 -d manpage -o $@ $<
|
$(ASCIIDOC) -b xhtml11 -d manpage -o $@ $<
|
||||||
|
|
||||||
# The Manual
|
# The Manual
|
||||||
@ -174,28 +153,39 @@ MANUAL_EXTRA_FILES = \
|
|||||||
$(TXT_DIR)/elinks.1.html.txt \
|
$(TXT_DIR)/elinks.1.html.txt \
|
||||||
$(TXT_DIR)/elinkskeys.5.html.txt
|
$(TXT_DIR)/elinkskeys.5.html.txt
|
||||||
|
|
||||||
$(HTML_DIR)/manual.html: $(MANUAL_FILES) doc-dirs $(MANUAL_EXTRA_FILES)
|
$(HTML_DIR)/manual.html: $(MANUAL_FILES) $(MANUAL_EXTRA_FILES)
|
||||||
$(ASCIIDOC) -b xhtml11 -d book -o $@ -n $<
|
$(ASCIIDOC) -b xhtml11 -d book -o $@ -n $<
|
||||||
|
|
||||||
$(HTML_DIR)/hacking.html: $(top_srcdir)/doc/hacking.txt doc-dirs
|
$(HTML_DIR)/hacking.html: $(top_srcdir)/doc/hacking.txt
|
||||||
$(ASCIIDOC) -b xhtml11 -d book -o $@ -n $<
|
$(ASCIIDOC) -b xhtml11 -d book -o $@ -n $<
|
||||||
|
|
||||||
$(HTML_DIR)/dev-intro.html: $(top_srcdir)/doc/dev-intro.txt doc-dirs
|
$(HTML_DIR)/dev-intro.html: $(top_srcdir)/doc/dev-intro.txt
|
||||||
$(ASCIIDOC) -b xhtml11 -d book -o $@ -n $<
|
$(ASCIIDOC) -b xhtml11 -d book -o $@ -n $<
|
||||||
|
|
||||||
$(XML_DIR)/manual.xml: $(MANUAL_FILES) doc-dirs $(MANUAL_EXTRA_FILES)
|
$(XML_DIR)/manual.xml: $(MANUAL_FILES) $(MANUAL_EXTRA_FILES)
|
||||||
$(ASCIIDOC) -b docbook -d book -o $@ $<
|
$(ASCIIDOC) -b docbook -d book -o $@ $<
|
||||||
|
|
||||||
$(HTML_DIR)/manual.html-chunked: $(XML_DIR)/manual.xml doc-dirs
|
$(HTML_DIR)/manual.html-chunked: $(XML_DIR)/manual.xml
|
||||||
$(XMLTO) -o $@ html $<
|
$(XMLTO) -o $@ html $<
|
||||||
|
|
||||||
$(PDF_DIR)/manual.pdf: $(XML_DIR)/manual.xml doc-dirs
|
$(PDF_DIR)/manual.pdf: $(XML_DIR)/manual.xml
|
||||||
$(JW) -o $(PDF_DIR) -b pdf $<
|
$(JW) -o $(PDF_DIR) -b pdf $<
|
||||||
|
|
||||||
$(HTML_DIR)/perl.html: $(top_srcdir)/doc/perl.pod doc-dirs
|
$(HTML_DIR)/perl.html: $(top_srcdir)/doc/perl.pod
|
||||||
$(POD2HTML) --outfile=$@ < $<
|
$(POD2HTML) --outfile=$@ < $<
|
||||||
|
|
||||||
$(HTML_DIR)/perl-hooks.html: $(top_srcdir)/contrib/perl/hooks.pl doc-dirs
|
$(HTML_DIR)/perl-hooks.html: $(top_srcdir)/contrib/perl/hooks.pl
|
||||||
$(POD2HTML) --outfile=$@ < $<
|
$(POD2HTML) --outfile=$@ < $<
|
||||||
|
|
||||||
|
## API Docs
|
||||||
|
#
|
||||||
|
|
||||||
|
DOM_API = \
|
||||||
|
$(top_srcdir)/src/dom/scanner.h \
|
||||||
|
$(top_srcdir)/src/dom/stack.h \
|
||||||
|
$(top_srcdir)/src/dom/sgml/parser.h
|
||||||
|
|
||||||
|
$(HTML_DIR)/api/dom.html: $(DOM_API)
|
||||||
|
$(CODE2DOC) $(DOM_API) | $(ASCIIDOC) -f code2doc.conf -b xhtml11 -d book -o $@ -n -
|
||||||
|
|
||||||
include $(top_srcdir)/Makefile.lib
|
include $(top_srcdir)/Makefile.lib
|
||||||
|
@ -220,6 +220,3 @@ in the future. So far, we have had no reports from our users that anyone wants
|
|||||||
to switch their bookmarks format frequently, so this is not too high on our
|
to switch their bookmarks format frequently, so this is not too high on our
|
||||||
TODO list. So be sure to tell us if you would like this process to be
|
TODO list. So be sure to tell us if you would like this process to be
|
||||||
simplified rather sooner than later.
|
simplified rather sooner than later.
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
55
doc/code2doc.conf
Normal file
55
doc/code2doc.conf
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
[specialwords]
|
||||||
|
emphasizedwords=\bAsciiDoc\b
|
||||||
|
monospacedwords=\basciidoc\(1\)
|
||||||
|
|
||||||
|
[id-inlinemacro]
|
||||||
|
<a id="{0}" href="#{0}">{0}</a>
|
||||||
|
|
||||||
|
[enum-inlinemacro]
|
||||||
|
<a id="{target}">enum {target}: {0}</a>
|
||||||
|
|
||||||
|
[func-inlinemacro]
|
||||||
|
<a id="{target}">{target}(): {0}</a>
|
||||||
|
|
||||||
|
[struct-inlinemacro]
|
||||||
|
<a id="{target}">struct {target}: {0}</a>
|
||||||
|
|
||||||
|
[macro-inlinemacro]
|
||||||
|
<a id="{target}">struct {target}: {0}</a>
|
||||||
|
|
||||||
|
[typedef-inlinemacro]
|
||||||
|
<a id="{target}">typedef {target}: {0}</a>
|
||||||
|
|
||||||
|
[ref-inlinemacro]
|
||||||
|
<a href="{target}#{0}">{0}</a>
|
||||||
|
|
||||||
|
[replacements]
|
||||||
|
(^|[^-])--($|[^-])=\1--\2
|
||||||
|
|
||||||
|
[tags]
|
||||||
|
ilisttext=|
|
||||||
|
olisttext=|
|
||||||
|
vlisttext=|
|
||||||
|
qlisttext=|
|
||||||
|
colisttext=|
|
||||||
|
|
||||||
|
[tags]
|
||||||
|
title1=<h1>|</h1>
|
||||||
|
title2=<h2>|</h2>
|
||||||
|
title3=<h3>|</h3>
|
||||||
|
|
||||||
|
[literalparagraph]
|
||||||
|
<table border="1" class="code"><tr><td><pre>
|
||||||
|
|
|
||||||
|
</pre></td></tr></table>
|
||||||
|
|
||||||
|
[listingblock]
|
||||||
|
<p><b>{title}</b></p>
|
||||||
|
<table border="1" class="code"><tr><td><pre>
|
||||||
|
|
|
||||||
|
</pre></td></tr></table>
|
||||||
|
|
||||||
|
[noteblock]
|
||||||
|
<div><p><b>{title}</b></p>
|
||||||
|
|
|
||||||
|
</div>
|
@ -120,6 +120,3 @@ that there are no SpiderMonkey references outside of
|
|||||||
ECMAScript backend, go ahead - you will just need to write an autoconf
|
ECMAScript backend, go ahead - you will just need to write an autoconf
|
||||||
detection for it and tie it to `src/ecmascript/ecmascript.c`, which should be
|
detection for it and tie it to `src/ecmascript/ecmascript.c`, which should be
|
||||||
easy. We await your patches eagerly.
|
easy. We await your patches eagerly.
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
@ -99,6 +99,3 @@ Also, perhaps wider scale of commands should be implemented in ex-mode. The
|
|||||||
code is extremely flexible and it is very trivial to make another ex-mode
|
code is extremely flexible and it is very trivial to make another ex-mode
|
||||||
command handler, it's just that no one has done it yet ;-). Also, more actions
|
command handler, it's just that no one has done it yet ;-). Also, more actions
|
||||||
should be able to take arguments.
|
should be able to take arguments.
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
12
doc/faq.txt
12
doc/faq.txt
@ -101,14 +101,6 @@ One mebibyte 1 MiB = 2^20 B = 1 048 576 B
|
|||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
[[Christmas]]
|
|
||||||
Why are stable releases made at Christmas?
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
It is suspected that this yearly present has become a tradition because pasky
|
|
||||||
worships the Christmas spirit. ;-)
|
|
||||||
|
|
||||||
|
|
||||||
[[get-256-colours]]
|
[[get-256-colours]]
|
||||||
How can I get 256 colors?
|
How can I get 256 colors?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -150,7 +142,3 @@ The new ELinks versions (from 0.9.0 on) send:
|
|||||||
You should therefore check against something like /^ELinks[\/ ]/, since more
|
You should therefore check against something like /^ELinks[\/ ]/, since more
|
||||||
fields can be added inside the parenthesis in subsequent versions. Note that
|
fields can be added inside the parenthesis in subsequent versions. Note that
|
||||||
users can change their User-Agent through the options system.
|
users can change their User-Agent through the options system.
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
@ -31,8 +31,3 @@ pizza, some close location of yourself recommended), we accept drinks, nice
|
|||||||
books, CDs with interesting things, computer equipment and accessories, PDAs,
|
books, CDs with interesting things, computer equipment and accessories, PDAs,
|
||||||
pens + pencils + erasers, and last but not least money. Contact the maintainer,
|
pens + pencils + erasers, and last but not least money. Contact the maintainer,
|
||||||
he'll split the stuff properly amongst himself and other developers >:).
|
he'll split the stuff properly amongst himself and other developers >:).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
@ -5,8 +5,6 @@ Welcome, mere mortal, to the realm of evil unindented code, heaps of one or
|
|||||||
two-letter variables, seas of gotos accompanied with 30-letters labels in Czech
|
two-letter variables, seas of gotos accompanied with 30-letters labels in Czech
|
||||||
language with absolutely no meaning, welcome to the realm of ELinks code!
|
language with absolutely no meaning, welcome to the realm of ELinks code!
|
||||||
|
|
||||||
[We're going to extend this file slowly, basing on daily practice ;]
|
|
||||||
|
|
||||||
Don't take this file as a law. We may or may not be right in these issues.
|
Don't take this file as a law. We may or may not be right in these issues.
|
||||||
|
|
||||||
Motto: I didn't expect someone to look at the source, so it's unreadable.
|
Motto: I didn't expect someone to look at the source, so it's unreadable.
|
||||||
@ -620,6 +618,22 @@ typedef int (some_func_T)(void *);
|
|||||||
typedef long long our_long_T;
|
typedef long long our_long_T;
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Please use mode_t and S_I???? macros instead of numeric modes
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.Use:
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
mode_t mode = S_IRWXU | S_IRGRP | S_IROTH;
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
.Instead of:
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
int mode = 0744;
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Note that S_IREAD, S_IWRITE and S_IEXEC are obsolete, you should use S_IRUSR,
|
||||||
|
S_IWUSR, S_IXUSR instead.
|
||||||
|
|
||||||
|
|
||||||
Patches
|
Patches
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
@ -681,6 +695,3 @@ to compile or execute in one of these modes, then rework it.
|
|||||||
|
|
||||||
|
|
||||||
Happy hacking!
|
Happy hacking!
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
@ -74,6 +74,3 @@ include::ecmascript.txt[]
|
|||||||
include::txt/import-features.conf.txt[]
|
include::txt/import-features.conf.txt[]
|
||||||
|
|
||||||
endif::installation-webpage[]
|
endif::installation-webpage[]
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
@ -359,7 +359,3 @@ everything is marked TODO!
|
|||||||
- Insert mode in text-input form-fields.
|
- Insert mode in text-input form-fields.
|
||||||
|
|
||||||
- Menu searching.
|
- Menu searching.
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
@ -559,6 +559,3 @@ More ideas
|
|||||||
- More things are possible, I'm sure. If you have an idea that requires
|
- More things are possible, I'm sure. If you have an idea that requires
|
||||||
another hook or function, contact me (Peter Wang) and I'll see what I can
|
another hook or function, contact me (Peter Wang) and I'll see what I can
|
||||||
do.
|
do.
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
@ -124,6 +124,3 @@ audio/mpeg; xmms '%s'; test=test -n "$DISPLAY";
|
|||||||
application/pdf; xpdf '%s'; test=test -n "$DISPLAY";
|
application/pdf; xpdf '%s'; test=test -n "$DISPLAY";
|
||||||
application/postscript; ps2ascii %s ; copiousoutput
|
application/postscript; ps2ascii %s ; copiousoutput
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
.el .ne 3
|
.el .ne 3
|
||||||
.IP "\\$1" \\$2
|
.IP "\\$1" \\$2
|
||||||
..
|
..
|
||||||
.TH "ELINKS" 1 "" "" ""
|
.TH "ELINKS" 1 "The ELinks text-browser" "2006-01-10" "The ELinks text-browser"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
elinks \- lynx-like alternative character mode WWW browser
|
elinks \- lynx-like alternative character mode WWW browser
|
||||||
.SH "SYNOPSIS"
|
.SH "SYNOPSIS"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
.\" elinks.conf.5
|
.\" elinks.conf.5
|
||||||
.\"
|
.\"
|
||||||
.\" Generated by help2doc (Revision: 1.19) on 09 August 05 using output from ELinks version 0.11.CVS.
|
.\" Generated by help2doc (Revision: 1.19) on 2006-01-10 using output from ELinks version 0.12.GIT.
|
||||||
.\"
|
.\"
|
||||||
.\" Copyleft (c) 2002-2004 The ELinks project
|
.\" Copyleft (c) 2002-2004 The ELinks project
|
||||||
.\"
|
.\"
|
||||||
@ -8,7 +8,7 @@
|
|||||||
.\" General Public License. <www.gnu.org/licenses/gpl.html>
|
.\" General Public License. <www.gnu.org/licenses/gpl.html>
|
||||||
.\"
|
.\"
|
||||||
.\" Process this file with groff -man -Tascii elinks.conf.5
|
.\" Process this file with groff -man -Tascii elinks.conf.5
|
||||||
.TH ELINKS.CONF 5 \"09 August 05\"
|
.TH ELINKS.CONF 5 "ELinks configuration file" "2006-01-10" "ELinks configuration file"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
elinks.conf \- ELinks configuration file
|
elinks.conf \- ELinks configuration file
|
||||||
@ -50,7 +50,7 @@ set document.browse.margin_width = 3
|
|||||||
# Default document codepage.
|
# Default document codepage.
|
||||||
set document.codepage.assume = "ISO-8859-1"
|
set document.codepage.assume = "ISO-8859-1"
|
||||||
# User defined protocol handlers
|
# User defined protocol handlers
|
||||||
set protocol.user.mailto.unix = "mutt %h -s \"%s\""
|
set protocol.user.mailto.unix = "mutt %h -s \e\*(lq%s\e\*(rq"
|
||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.SS Bookmarks (bookmarks)
|
.SS Bookmarks (bookmarks)
|
||||||
@ -313,8 +313,8 @@ are always inserted into a selected text field.
|
|||||||
\f3document.browse.forms.editor\f2 <str>\f1 (default: "")
|
\f3document.browse.forms.editor\f2 <str>\f1 (default: "")
|
||||||
Path to the executable that ELinks should launch when the user
|
Path to the executable that ELinks should launch when the user
|
||||||
requests to edit a textarea with an external editor.
|
requests to edit a textarea with an external editor.
|
||||||
.TP
|
If this is blank, ELinks will use the value of the environmental
|
||||||
\f3variable\f2 $EDITOR.\f1 (variable $EDITOR. If $EDITOR is empty or not set, ELinks will then)
|
variable $EDITOR. If $EDITOR is empty or not set, ELinks will then
|
||||||
default to "vi".
|
default to "vi".
|
||||||
.TP
|
.TP
|
||||||
\f3document.browse.forms.show_formhist\f2 [0|1]\f1 (default: 0)
|
\f3document.browse.forms.show_formhist\f2 [0|1]\f1 (default: 0)
|
||||||
@ -459,6 +459,9 @@ The TABINDEX attribute in HTML elements specifies the order
|
|||||||
in which links should receive focus when using the keyboard
|
in which links should receive focus when using the keyboard
|
||||||
to navigating the document.
|
to navigating the document.
|
||||||
.TP
|
.TP
|
||||||
|
\f3document.browse.links.missing_fragment\f2 [0|1]\f1 (default: 1)
|
||||||
|
Open a message box when document has no tag with given id.
|
||||||
|
.TP
|
||||||
\f3document.browse.links.number_keys_select_link\f2 <num>\f1 (default: 1)
|
\f3document.browse.links.number_keys_select_link\f2 <num>\f1 (default: 1)
|
||||||
Number keys select links rather than specify command prefixes. This
|
Number keys select links rather than specify command prefixes. This
|
||||||
is a tristate:
|
is a tristate:
|
||||||
@ -675,11 +678,10 @@ Default directory color.
|
|||||||
See document.browse.links.color_dirs option.
|
See document.browse.links.color_dirs option.
|
||||||
.TP
|
.TP
|
||||||
\f3document.colors.increase_contrast\f2 [0|1]\f1 (default: 1)
|
\f3document.colors.increase_contrast\f2 [0|1]\f1 (default: 1)
|
||||||
Setting this option to 0 will increase the contrast
|
Increase the contrast between the foreground and background colors
|
||||||
between the foreground and background colors to ensure
|
to ensure readability. For example it disallows dark colors on a
|
||||||
readability. For example it disallows dark colors on a
|
black background. Note, this is different from ensuring the contrast
|
||||||
black background. Note, this is different from ensuring
|
with the ensure_contrast option.
|
||||||
the contrast with the ensure_contrast option.
|
|
||||||
.TP
|
.TP
|
||||||
\f3document.colors.ensure_contrast\f2 [0|1]\f1 (default: 1)
|
\f3document.colors.ensure_contrast\f2 [0|1]\f1 (default: 1)
|
||||||
Makes sure that the back- and foreground color are never equal.
|
Makes sure that the back- and foreground color are never equal.
|
||||||
@ -877,6 +879,7 @@ A rule for passing URI to an external command.
|
|||||||
The format is:
|
The format is:
|
||||||
%c in the string means the current URL
|
%c in the string means the current URL
|
||||||
%% in the string means '%'
|
%% in the string means '%'
|
||||||
|
Do _not_ put single- or double-quotes around %c.
|
||||||
.SS ECMAScript (ecmascript)
|
.SS ECMAScript (ecmascript)
|
||||||
ECMAScript options.
|
ECMAScript options.
|
||||||
.TP
|
.TP
|
||||||
@ -886,6 +889,10 @@ Whether to run those scripts inside of documents.
|
|||||||
\f3ecmascript.error_reporting\f2 [0|1]\f1 (default: 0)
|
\f3ecmascript.error_reporting\f2 [0|1]\f1 (default: 0)
|
||||||
Open a message box when a script reports an error.
|
Open a message box when a script reports an error.
|
||||||
.TP
|
.TP
|
||||||
|
\f3ecmascript.ignore_noscript\f2 [0|1]\f1 (default: 0)
|
||||||
|
Whether to ignore content enclosed by the <noscript> tag
|
||||||
|
when ECMAScript is enabled.
|
||||||
|
.TP
|
||||||
\f3ecmascript.max_exec_time\f2 <num>\f1 (default: 5)
|
\f3ecmascript.max_exec_time\f2 <num>\f1 (default: 5)
|
||||||
Maximum execution time in seconds for a script.
|
Maximum execution time in seconds for a script.
|
||||||
.PD
|
.PD
|
||||||
@ -1045,6 +1052,13 @@ What IP address to report to the tracker. If set to ""
|
|||||||
no IP address will be sent and the tracker will automatically
|
no IP address will be sent and the tracker will automatically
|
||||||
determine an appropriate IP address.
|
determine an appropriate IP address.
|
||||||
.TP
|
.TP
|
||||||
|
\f3protocol.bittorrent.tracker.key\f2 <str>\f1 (default: "")
|
||||||
|
An additional identification that is not shared with any users.
|
||||||
|
It is intended to allow a client to prove their identity should
|
||||||
|
their IP address change. It is an optional parameter, but some
|
||||||
|
trackers require this parameter. If set to "" no user key will
|
||||||
|
be sent to the tracker.
|
||||||
|
.TP
|
||||||
\f3protocol.bittorrent.tracker.numwant\f2 <num>\f1 (default: 50)
|
\f3protocol.bittorrent.tracker.numwant\f2 <num>\f1 (default: 50)
|
||||||
The maximum number of peers to request from the tracker.
|
The maximum number of peers to request from the tracker.
|
||||||
Set to 0 to use the server default.
|
Set to 0 to use the server default.
|
||||||
@ -1337,7 +1351,7 @@ disable use of the default template rewrite rule.
|
|||||||
Enable dumb prefixes - simple URI abbreviations which can
|
Enable dumb prefixes - simple URI abbreviations which can
|
||||||
be written to the Goto URL dialog instead of actual URIs - i.e.
|
be written to the Goto URL dialog instead of actual URIs - i.e.
|
||||||
if you write 'elinks' there, you are directed to
|
if you write 'elinks' there, you are directed to
|
||||||
http://elinks.or.cz/.
|
http://elinks.cz/.
|
||||||
.TP
|
.TP
|
||||||
\f3protocol.rewrite.enable-smart\f2 [0|1]\f1 (default: 1)
|
\f3protocol.rewrite.enable-smart\f2 [0|1]\f1 (default: 1)
|
||||||
Enable smart prefixes - URI templates triggered by writing
|
Enable smart prefixes - URI templates triggered by writing
|
||||||
@ -2139,6 +2153,9 @@ on the command line or when requested by the goto-url-home action.
|
|||||||
Set to "" if the environment variable WWW_HOME should be used
|
Set to "" if the environment variable WWW_HOME should be used
|
||||||
as homepage URI instead.
|
as homepage URI instead.
|
||||||
.TP
|
.TP
|
||||||
|
\f3ui.sessions.keep_session_active\f2 [0|1]\f1 (default: 0)
|
||||||
|
Keep the session active even if the last terminal exits.
|
||||||
|
.TP
|
||||||
\f3ui.sessions.snapshot\f2 [0|1]\f1 (default: 0)
|
\f3ui.sessions.snapshot\f2 [0|1]\f1 (default: 0)
|
||||||
Automatically save a snapshot of all tabs periodically.
|
Automatically save a snapshot of all tabs periodically.
|
||||||
This will periodically bookmark the tabs of each terminal in a separate folder
|
This will periodically bookmark the tabs of each terminal in a separate folder
|
||||||
@ -2225,7 +2242,7 @@ in an xterm-like terminal. This way the document's title is
|
|||||||
shown on the window titlebar.
|
shown on the window titlebar.
|
||||||
.SH "DOCUMENT INFO"
|
.SH "DOCUMENT INFO"
|
||||||
.PP
|
.PP
|
||||||
Generated by help2doc (Revision: 1.19) on 09 August 05 using output from ELinks version 0.11.CVS.
|
Generated by help2doc (Revision: 1.19) on 2006-01-10 using output from ELinks version 0.12.GIT.
|
||||||
help2doc is distributed with ELinks under the terms of the GPL.
|
help2doc is distributed with ELinks under the terms of the GPL.
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.BR elinks (1),
|
.BR elinks (1),
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
.el .ne 3
|
.el .ne 3
|
||||||
.IP "\\$1" \\$2
|
.IP "\\$1" \\$2
|
||||||
..
|
..
|
||||||
.TH "ELINKSKEYS" 5 "" "" ""
|
.TH "ELINKSKEYS" 5 "ELinks keybindings" "2006-01-10" "ELinks keybindings"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
elinkskeys \- keybindings for ELinks
|
elinkskeys \- keybindings for ELinks
|
||||||
.SH "SYNOPSIS"
|
.SH "SYNOPSIS"
|
||||||
@ -258,6 +258,10 @@ Follow the current link, forcing reload of the target\&.
|
|||||||
link\-menu
|
link\-menu
|
||||||
Open the link context menu\&.
|
Open the link context menu\&.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
link\-form\-menu
|
||||||
|
Open the form fields menu\&.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
lua\-console
|
lua\-console
|
||||||
Open a Lua console\&.
|
Open a Lua console\&.
|
||||||
|
@ -84,6 +84,3 @@ did not quit your ELinks _completely_ --- if you run multiple ELinks
|
|||||||
instances under a single user on a single system, they "join" together and
|
instances under a single user on a single system, they "join" together and
|
||||||
you must quit (or kill) them all to get rid of the damn thing. But that's a
|
you must quit (or kill) them all to get rid of the damn thing. But that's a
|
||||||
different story.
|
different story.
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
@ -178,6 +178,3 @@ Just enter set mime.type.class.name = "handler", replacing class with the
|
|||||||
class for the mime type, name with the specific name within that class, and
|
class for the mime type, name with the specific name within that class, and
|
||||||
handler with the name for the handler you want to assign to the MIME type.
|
handler with the name for the handler you want to assign to the MIME type.
|
||||||
E.g. you may want to have set mime.type.image.jpeg = "image_viewer".
|
E.g. you may want to have set mime.type.image.jpeg = "image_viewer".
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
@ -83,6 +83,3 @@ example, by running:
|
|||||||
|
|
||||||
new tabs containing `slashdot.org`, `freshmeat.net` and a Google search of elinks
|
new tabs containing `slashdot.org`, `freshmeat.net` and a Google search of elinks
|
||||||
will be opened.
|
will be opened.
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
@ -90,6 +90,3 @@ Whow ! Around 200kb :)
|
|||||||
- it disables fastfind feature, reducing performance, but also reducing a lot
|
- it disables fastfind feature, reducing performance, but also reducing a lot
|
||||||
memory usage, and a bit the executable size.
|
memory usage, and a bit the executable size.
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
@ -110,6 +110,3 @@ bookmark therein the currently displayed document of each tab:
|
|||||||
- As a mean of crash protection, tabs can periodically be saved so that it is
|
- As a mean of crash protection, tabs can periodically be saved so that it is
|
||||||
later possible to reconstruct opened tabs. In case of a clean shutdown
|
later possible to reconstruct opened tabs. In case of a clean shutdown
|
||||||
periodically saved tabs will be removed.
|
periodically saved tabs will be removed.
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
@ -163,6 +163,3 @@ GNU Screen is VT100-compatible, so select 'VT 100 frames'. GNU Screen also
|
|||||||
supports colors just fine, so select '16 colors', or, if you are running Screen
|
supports colors just fine, so select '16 colors', or, if you are running Screen
|
||||||
within a terminal emulator that supports 256 colors and you have compiled both
|
within a terminal emulator that supports 256 colors and you have compiled both
|
||||||
Screen and ELinks to support it, choose '256 colors'.
|
Screen and ELinks to support it, choose '256 colors'.
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
112
doc/tools/code2doc
Executable file
112
doc/tools/code2doc
Executable file
@ -0,0 +1,112 @@
|
|||||||
|
#!/usr/bin/perl -w
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use diagnostics;
|
||||||
|
use Getopt::Std;
|
||||||
|
|
||||||
|
my $HELP = "Usage: $0 [FILE]...
|
||||||
|
Parses [FILE], outputing the result to stdout.";
|
||||||
|
|
||||||
|
sub usage {
|
||||||
|
print "@_\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
our($opt_h, $opt_v, $title, $body, $indent, $idpath, $inblock);
|
||||||
|
|
||||||
|
getopts("hv") or usage($HELP);
|
||||||
|
$opt_v and usage("Copyleft (c) 2006, Russ Rowan (See `COPYING')");
|
||||||
|
usage($HELP) if $opt_h or @ARGV < 1;
|
||||||
|
|
||||||
|
sub put_section {
|
||||||
|
if ($title) {
|
||||||
|
print "\n$title\n";
|
||||||
|
$_ = $title;
|
||||||
|
s/[^-]/-/g;
|
||||||
|
print "$_\n" if not $indent;
|
||||||
|
}
|
||||||
|
if ($body) {
|
||||||
|
$_ = $body;
|
||||||
|
s/#newline#/$indent/g;
|
||||||
|
print "$_\n";
|
||||||
|
}
|
||||||
|
$title = $body = undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
$idpath = $title = $body = "";
|
||||||
|
while (<>)
|
||||||
|
{
|
||||||
|
my $end = s/\s*\*+\//\n/ ? 'yes' : undef;
|
||||||
|
|
||||||
|
if ($end and /[^=]*[\s*](\w+)[\s:,;].*\/\*:\s*(.*)/) {
|
||||||
|
# Implicit id for enum values and struct members.
|
||||||
|
print "\nid:[$idpath$1]::\n\t$2\n";
|
||||||
|
|
||||||
|
} elsif ($inblock) {
|
||||||
|
# Redo the indentation, preserve empty lines.
|
||||||
|
s/^(\s|\*)*//;
|
||||||
|
s/^$/\n/;
|
||||||
|
$body .= "#newline#" . $_;
|
||||||
|
|
||||||
|
} elsif (s/\s*\/\*\*+\s*(.*)/$1/) {
|
||||||
|
# Found magic header; flush, record title and set indentation.
|
||||||
|
put_section;
|
||||||
|
$title = "$1";
|
||||||
|
$indent = /::/ ? "\t" : "";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
next if not ($title or $body) or /^\s$/;
|
||||||
|
|
||||||
|
my $orig_title = $title;
|
||||||
|
|
||||||
|
if (not /^#define\s/) {
|
||||||
|
while (not /(struct|enum|typedef|[^=])*[\s*](\w+).*[\[:,;{]/) {
|
||||||
|
$_ .= <>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/struct\s+(\w+)\s*{/) {
|
||||||
|
$title = "struct:$1" . "[$title]";
|
||||||
|
$idpath = "$1.";
|
||||||
|
|
||||||
|
} elsif (/enum\s+(\w+)\s*{/) {
|
||||||
|
$title = "enum:$1" . "[$title]";
|
||||||
|
$idpath = "";
|
||||||
|
|
||||||
|
} elsif (/#define\s+(\w+)[(]/) {
|
||||||
|
$title = "func:$1" . "[$title]";
|
||||||
|
$idpath = "";
|
||||||
|
|
||||||
|
} elsif (/#define\s+(\w+)/) {
|
||||||
|
$title = "macro:$1" . "[$title]";
|
||||||
|
$idpath = "";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (/typedef/) {
|
||||||
|
if (/.*\(\*(\w+)\)\(/) {
|
||||||
|
$title = "typedef:$1" . "[$title]";
|
||||||
|
} elsif (/typedef.*\s(\w+);/) {
|
||||||
|
$title = "typedef:$1" . "[$title]";
|
||||||
|
}
|
||||||
|
$idpath = "";
|
||||||
|
} else {
|
||||||
|
if (/.*[\s*](\w+)\(/) {
|
||||||
|
$title = "func:$1" . "[$title]";
|
||||||
|
$idpath = "";
|
||||||
|
} elsif (/.*\(\*(\w+)\)\(/) {
|
||||||
|
$body = "#newline#" . $title if not $body;
|
||||||
|
$title = "id:[$idpath$1]::";
|
||||||
|
$indent = "\t";
|
||||||
|
} elsif (/[^=]*[\s*](\w+)[\[\s,:;]/) {
|
||||||
|
$body = "#newline#" . $title if not $body;
|
||||||
|
$title = "id:[$idpath$1]::";
|
||||||
|
$indent = "\t";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
put_section if $orig_title ne $title;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
$inblock = $end ? undef : 'yes';
|
||||||
|
}
|
@ -27,6 +27,7 @@ END_OF_USAGE
|
|||||||
# Option handling {{{1
|
# Option handling {{{1
|
||||||
|
|
||||||
command=
|
command=
|
||||||
|
filter=cat
|
||||||
prev_option=
|
prev_option=
|
||||||
|
|
||||||
for option
|
for option
|
||||||
@ -41,10 +42,12 @@ do
|
|||||||
case "$option" in
|
case "$option" in
|
||||||
--cmdoptions)
|
--cmdoptions)
|
||||||
command="$elinks -long-help"
|
command="$elinks -long-help"
|
||||||
|
filter="sed 0,/^Options:/d"
|
||||||
backend="cmdoptions"
|
backend="cmdoptions"
|
||||||
;;
|
;;
|
||||||
--elinksconf)
|
--elinksconf)
|
||||||
command="$elinks -config-help"
|
command="$elinks -config-help"
|
||||||
|
filter="sed 0,/^Configuration/d"
|
||||||
backend="elinksconf"
|
backend="elinksconf"
|
||||||
;;
|
;;
|
||||||
-)
|
-)
|
||||||
@ -64,7 +67,7 @@ then
|
|||||||
usage "No backend defined"
|
usage "No backend defined"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
date_string=`date +"%d %B %y"`
|
date_string=`date -I`
|
||||||
script_version=`echo "\\$Revision: 1.19 $" | sed -e 's/\\$\(.*\) \\$/\1/'`
|
script_version=`echo "\\$Revision: 1.19 $" | sed -e 's/\\$\(.*\) \\$/\1/'`
|
||||||
elinks_version="`$elinks -version | head -n 1 | sed -e 's/ELinks \([0-9][^ ]*\).*/\1/'`"
|
elinks_version="`$elinks -version | head -n 1 | sed -e 's/ELinks \([0-9][^ ]*\).*/\1/'`"
|
||||||
script_info="Generated by `basename $0` ($script_version) on $date_string"
|
script_info="Generated by `basename $0` ($script_version) on $date_string"
|
||||||
@ -168,7 +171,7 @@ print_elinksconf_header()
|
|||||||
.\" General Public License. <www.gnu.org/licenses/gpl.html>
|
.\" General Public License. <www.gnu.org/licenses/gpl.html>
|
||||||
.\"
|
.\"
|
||||||
.\" Process this file with groff -man -Tascii elinks.conf.5
|
.\" Process this file with groff -man -Tascii elinks.conf.5
|
||||||
.TH ELINKS.CONF 5 \"$date_string\"
|
.TH ELINKS.CONF 5 "ELinks configuration file" "$date_string" "ELinks configuration file"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
elinks.conf \- ELinks configuration file
|
elinks.conf \- ELinks configuration file
|
||||||
@ -210,7 +213,7 @@ set document.browse.margin_width = 3
|
|||||||
# Default document codepage.
|
# Default document codepage.
|
||||||
set document.codepage.assume = "ISO-8859-1"
|
set document.codepage.assume = "ISO-8859-1"
|
||||||
# User defined protocol handlers
|
# User defined protocol handlers
|
||||||
set protocol.user.mailto.unix = "mutt %h -s \"%s\""
|
set protocol.user.mailto.unix = "mutt %h -s \e\*(lq%s\e\*(rq"
|
||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
__END__
|
__END__
|
||||||
@ -227,7 +230,6 @@ print_elinksconf_footer()
|
|||||||
echo "$dist_info"
|
echo "$dist_info"
|
||||||
echo ".SH \"SEE ALSO\""
|
echo ".SH \"SEE ALSO\""
|
||||||
echo ".BR elinks (1),"
|
echo ".BR elinks (1),"
|
||||||
echo ".BR elinksmanual (1),"
|
|
||||||
echo ".BR elinkskeys (5)"
|
echo ".BR elinkskeys (5)"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,7 +287,7 @@ use_log=
|
|||||||
|
|
||||||
$print_header
|
$print_header
|
||||||
|
|
||||||
$command | while read line
|
$command | $filter | while read line
|
||||||
do
|
do
|
||||||
if test -n "$parse_description"
|
if test -n "$parse_description"
|
||||||
then
|
then
|
||||||
@ -323,7 +325,7 @@ do
|
|||||||
case "$line" in
|
case "$line" in
|
||||||
Features:*)
|
Features:*)
|
||||||
;;
|
;;
|
||||||
[A-Z]*:*[a-z]*)
|
[A-Z]*:" ("*[a-z]*)
|
||||||
parse_description=1
|
parse_description=1
|
||||||
title="`echo $line | sed -e 's/\([A-Z]*\):.*/\1/'`"
|
title="`echo $line | sed -e 's/\([A-Z]*\):.*/\1/'`"
|
||||||
path="`echo $line | sed -e 's/.*: (\([a-z_].*\))/\1/'`"
|
path="`echo $line | sed -e 's/.*: (\([a-z_].*\))/\1/'`"
|
||||||
|
@ -87,6 +87,3 @@ advanced CVSweb and Debian package database URI prefixes implemented in the
|
|||||||
sample Lua hooks file. The one disadvantage to this is that you must have Lua
|
sample Lua hooks file. The one disadvantage to this is that you must have Lua
|
||||||
scripting enabled in order to make use of it, and many users don't have Lua
|
scripting enabled in order to make use of it, and many users don't have Lua
|
||||||
installed.
|
installed.
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
@ -11,6 +11,8 @@ MSGMERGE = msgmerge
|
|||||||
# xgettext)
|
# xgettext)
|
||||||
POTFILES_ABS_LIST = potfiles.list
|
POTFILES_ABS_LIST = potfiles.list
|
||||||
|
|
||||||
|
POTFILES_REL = $(shell find $(top_srcdir)/src/ -name '*.[ch]' -o -name options.inc -o -name 'actions-*.inc' | sort)
|
||||||
|
|
||||||
quiet_cmd_gmsgfmt = ' [$(PO_COLOR)GMSGFMT$(END_COLOR)] $(RELPATH)$(@)'
|
quiet_cmd_gmsgfmt = ' [$(PO_COLOR)GMSGFMT$(END_COLOR)] $(RELPATH)$(@)'
|
||||||
cmd_gmsgfmt = rm -f -- "$@" && $(GMSGFMT) --statistics -o "$@" -- "$<"
|
cmd_gmsgfmt = rm -f -- "$@" && $(GMSGFMT) --statistics -o "$@" -- "$<"
|
||||||
|
|
||||||
@ -45,7 +47,7 @@ all-local: $(CATALOGS)
|
|||||||
# This pulls in _all_ .c and .h files in the src directory. Even files that has
|
# This pulls in _all_ .c and .h files in the src directory. Even files that has
|
||||||
# not been added to the git repo. Beware of junk entries!
|
# not been added to the git repo. Beware of junk entries!
|
||||||
|
|
||||||
$(srcdir)$(POTFILES_ABS_LIST):
|
$(srcdir)$(POTFILES_ABS_LIST): $(POTFILES_REL)
|
||||||
@( cd $(top_srcdir); \
|
@( cd $(top_srcdir); \
|
||||||
find src/ -type f -name '*.[ch]' -o -name options.inc -o -name 'actions-*.inc' | sort ) \
|
find src/ -type f -name '*.[ch]' -o -name options.inc -o -name 'actions-*.inc' | sort ) \
|
||||||
> $(srcdir)$(POTFILES_ABS_LIST)
|
> $(srcdir)$(POTFILES_ABS_LIST)
|
||||||
@ -67,7 +69,7 @@ $(srcdir)$(PACKAGE).pot: $(srcdir)$(POTFILES_ABS_LIST)
|
|||||||
# either <lang> or <lang>.po when calling make. Example: make update-po PO=is
|
# either <lang> or <lang>.po when calling make. Example: make update-po PO=is
|
||||||
|
|
||||||
update-po: Makefile $(srcdir)$(PACKAGE).pot
|
update-po: Makefile $(srcdir)$(PACKAGE).pot
|
||||||
@test -n "$(srcdir)" && cd $(srcdir)
|
@test -z "$(srcdir)" || cd $(srcdir)
|
||||||
@$(foreach lang,$(basename $(if $(strip $(PO)),$(PO),$(GMOFILES))), \
|
@$(foreach lang,$(basename $(if $(strip $(PO)),$(PO),$(GMOFILES))), \
|
||||||
echo -n "$(lang): "; \
|
echo -n "$(lang): "; \
|
||||||
if $(MSGMERGE) $(srcdir)$(lang).po $(srcdir)$(PACKAGE).pot -o $(lang).new.po; then \
|
if $(MSGMERGE) $(srcdir)$(lang).po $(srcdir)$(PACKAGE).pot -o $(lang).new.po; then \
|
||||||
|
144
po/fr.po
144
po/fr.po
@ -1,13 +1,13 @@
|
|||||||
# French ELinks translation.
|
# French ELinks translation.
|
||||||
# Fabrice Haberer-Proust <fric@gmx.li>
|
# Fabrice Haberer-Proust <fric@gmx.li>
|
||||||
# Laurent Monin <zas@norz.org>, 2001 - 2005
|
# Laurent Monin <zas@norz.org>, 2001 - 2006
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: ELinks 0.11.GIT\n"
|
"Project-Id-Version: ELinks 0.12.GIT\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2006-01-01 17:49+0100\n"
|
"POT-Creation-Date: 2006-01-10 23:00+0100\n"
|
||||||
"PO-Revision-Date: 2006-01-01 17:50+0100\n"
|
"PO-Revision-Date: 2006-01-10 23:01+0100\n"
|
||||||
"Last-Translator: Laurent Monin <zas@norz.org>\n"
|
"Last-Translator: Laurent Monin <zas@norz.org>\n"
|
||||||
"Language-Team: French <zas@norz.org>\n"
|
"Language-Team: French <zas@norz.org>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@ -15,21 +15,21 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n>1;\n"
|
"Plural-Forms: nplurals=2; plural=n>1;\n"
|
||||||
|
|
||||||
#: src/bfu/hierbox.c:329
|
#: src/bfu/hierbox.c:338
|
||||||
msgid "Close"
|
msgid "Close"
|
||||||
msgstr "Fermer"
|
msgstr "Fermer"
|
||||||
|
|
||||||
#. | MSGBOX_SCROLLABLE
|
#. | MSGBOX_SCROLLABLE
|
||||||
#: src/bfu/hierbox.c:425 src/bfu/hierbox.c:434 src/dialogs/document.c:43
|
#: src/bfu/hierbox.c:434 src/bfu/hierbox.c:443 src/dialogs/document.c:43
|
||||||
#: src/dialogs/document.c:240
|
#: src/dialogs/document.c:240
|
||||||
msgid "Info"
|
msgid "Info"
|
||||||
msgstr "Info"
|
msgstr "Info"
|
||||||
|
|
||||||
#: src/bfu/hierbox.c:426
|
#: src/bfu/hierbox.c:435
|
||||||
msgid "Press space to expand this folder."
|
msgid "Press space to expand this folder."
|
||||||
msgstr "Pressez espace pour déployer le dossier."
|
msgstr "Pressez espace pour déployer le dossier."
|
||||||
|
|
||||||
#: src/bfu/hierbox.c:437 src/bfu/inpfield.c:254 src/bfu/msgbox.c:172
|
#: src/bfu/hierbox.c:446 src/bfu/inpfield.c:254 src/bfu/msgbox.c:172
|
||||||
#: src/bfu/msgbox.c:189 src/config/dialogs.c:57 src/config/dialogs.c:391
|
#: src/bfu/msgbox.c:189 src/config/dialogs.c:57 src/config/dialogs.c:391
|
||||||
#: src/cookies/dialogs.c:354 src/dialogs/edit.c:97 src/dialogs/info.c:133
|
#: src/cookies/dialogs.c:354 src/dialogs/edit.c:97 src/dialogs/info.c:133
|
||||||
#: src/dialogs/options.c:210 src/dialogs/options.c:290 src/mime/dialogs.c:129
|
#: src/dialogs/options.c:210 src/dialogs/options.c:290 src/mime/dialogs.c:129
|
||||||
@ -40,57 +40,57 @@ msgid "~OK"
|
|||||||
msgstr "~OK"
|
msgstr "~OK"
|
||||||
|
|
||||||
#. cant_delete_item
|
#. cant_delete_item
|
||||||
#: src/bfu/hierbox.c:548
|
#: src/bfu/hierbox.c:557
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Sorry, but the item \"%s\" cannot be deleted."
|
msgid "Sorry, but the item \"%s\" cannot be deleted."
|
||||||
msgstr "Désolé, mais l'item \"%s\" ne peut être supprimé."
|
msgstr "Désolé, mais l'item \"%s\" ne peut être supprimé."
|
||||||
|
|
||||||
#. cant_delete_used_item
|
#. cant_delete_used_item
|
||||||
#: src/bfu/hierbox.c:551
|
#: src/bfu/hierbox.c:560
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Sorry, but the item \"%s\" is being used by something else."
|
msgid "Sorry, but the item \"%s\" is being used by something else."
|
||||||
msgstr "Désolé, mais l'item \"%s\" est actuellement utilisé ailleurs."
|
msgstr "Désolé, mais l'item \"%s\" est actuellement utilisé ailleurs."
|
||||||
|
|
||||||
#. cant_delete_folder
|
#. cant_delete_folder
|
||||||
#: src/bfu/hierbox.c:554 src/bookmarks/dialogs.c:119
|
#: src/bfu/hierbox.c:563 src/bookmarks/dialogs.c:119
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Sorry, but the folder \"%s\" cannot be deleted."
|
msgid "Sorry, but the folder \"%s\" cannot be deleted."
|
||||||
msgstr "Désolé, mais le dossier \"%s\" ne peut être supprimé."
|
msgstr "Désolé, mais le dossier \"%s\" ne peut être supprimé."
|
||||||
|
|
||||||
#. cant_delete_used_folder
|
#. cant_delete_used_folder
|
||||||
#: src/bfu/hierbox.c:557 src/bookmarks/dialogs.c:121
|
#: src/bfu/hierbox.c:566 src/bookmarks/dialogs.c:121
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Sorry, but the folder \"%s\" is being used by something else."
|
msgid "Sorry, but the folder \"%s\" is being used by something else."
|
||||||
msgstr "Désolé, mais le dossier \"%s\" est actuellement utilisé ailleurs."
|
msgstr "Désolé, mais le dossier \"%s\" est actuellement utilisé ailleurs."
|
||||||
|
|
||||||
#. delete_marked_items_title
|
#. delete_marked_items_title
|
||||||
#: src/bfu/hierbox.c:560
|
#: src/bfu/hierbox.c:569
|
||||||
msgid "Delete marked items"
|
msgid "Delete marked items"
|
||||||
msgstr "Supprimer les items marqués"
|
msgstr "Supprimer les items marqués"
|
||||||
|
|
||||||
#. delete_marked_items
|
#. delete_marked_items
|
||||||
#: src/bfu/hierbox.c:563
|
#: src/bfu/hierbox.c:572
|
||||||
msgid "Delete marked items?"
|
msgid "Delete marked items?"
|
||||||
msgstr "Supprimer les items marqués ?"
|
msgstr "Supprimer les items marqués ?"
|
||||||
|
|
||||||
#. delete_folder_title
|
#. delete_folder_title
|
||||||
#: src/bfu/hierbox.c:566 src/bookmarks/dialogs.c:127
|
#: src/bfu/hierbox.c:575 src/bookmarks/dialogs.c:127
|
||||||
msgid "Delete folder"
|
msgid "Delete folder"
|
||||||
msgstr "Supprimer un dossier"
|
msgstr "Supprimer un dossier"
|
||||||
|
|
||||||
#. delete_folder
|
#. delete_folder
|
||||||
#: src/bfu/hierbox.c:569
|
#: src/bfu/hierbox.c:578
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Delete the folder \"%s\" and its content?"
|
msgid "Delete the folder \"%s\" and its content?"
|
||||||
msgstr "Supprimer le dossier \"%s\" et son contenu ?"
|
msgstr "Supprimer le dossier \"%s\" et son contenu ?"
|
||||||
|
|
||||||
#. delete_item_title
|
#. delete_item_title
|
||||||
#: src/bfu/hierbox.c:572
|
#: src/bfu/hierbox.c:581
|
||||||
msgid "Delete item"
|
msgid "Delete item"
|
||||||
msgstr "Supprimer un item"
|
msgstr "Supprimer un item"
|
||||||
|
|
||||||
#. delete_item
|
#. delete_item
|
||||||
#: src/bfu/hierbox.c:575
|
#: src/bfu/hierbox.c:584
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Delete \"%s\"?\n"
|
"Delete \"%s\"?\n"
|
||||||
@ -102,45 +102,45 @@ msgstr ""
|
|||||||
"%s"
|
"%s"
|
||||||
|
|
||||||
#. clear_all_items_title
|
#. clear_all_items_title
|
||||||
#: src/bfu/hierbox.c:578
|
#: src/bfu/hierbox.c:587
|
||||||
msgid "Clear all items"
|
msgid "Clear all items"
|
||||||
msgstr "Effacer tous les items"
|
msgstr "Effacer tous les items"
|
||||||
|
|
||||||
#. clear_all_items
|
#. clear_all_items
|
||||||
#: src/bfu/hierbox.c:581
|
#: src/bfu/hierbox.c:590
|
||||||
msgid "Do you really want to remove all items?"
|
msgid "Do you really want to remove all items?"
|
||||||
msgstr "Êtes-vous sûr de vouloir effacer tous les items ?"
|
msgstr "Êtes-vous sûr de vouloir effacer tous les items ?"
|
||||||
|
|
||||||
#: src/bfu/hierbox.c:638
|
#: src/bfu/hierbox.c:647
|
||||||
msgid "Delete error"
|
msgid "Delete error"
|
||||||
msgstr "Erreur de suppression"
|
msgstr "Erreur de suppression"
|
||||||
|
|
||||||
#: src/bfu/hierbox.c:741 src/bfu/hierbox.c:770 src/bfu/hierbox.c:783
|
#: src/bfu/hierbox.c:750 src/bfu/hierbox.c:779 src/bfu/hierbox.c:792
|
||||||
#: src/bfu/hierbox.c:848 src/config/dialogs.c:832 src/dialogs/menu.c:126
|
#: src/bfu/hierbox.c:857 src/config/dialogs.c:832 src/dialogs/menu.c:126
|
||||||
#: src/formhist/formhist.c:418 src/mime/dialogs.c:69 src/session/task.c:272
|
#: src/formhist/formhist.c:418 src/mime/dialogs.c:69 src/session/task.c:272
|
||||||
#: src/terminal/tab.c:191 src/terminal/tab.c:227
|
#: src/terminal/tab.c:191 src/terminal/tab.c:227
|
||||||
msgid "~Yes"
|
msgid "~Yes"
|
||||||
msgstr "~Oui"
|
msgstr "~Oui"
|
||||||
|
|
||||||
#: src/bfu/hierbox.c:742 src/bfu/hierbox.c:771 src/bfu/hierbox.c:784
|
#: src/bfu/hierbox.c:751 src/bfu/hierbox.c:780 src/bfu/hierbox.c:793
|
||||||
#: src/bfu/hierbox.c:849 src/config/dialogs.c:833 src/dialogs/menu.c:127
|
#: src/bfu/hierbox.c:858 src/config/dialogs.c:833 src/dialogs/menu.c:127
|
||||||
#: src/formhist/formhist.c:419 src/mime/dialogs.c:70 src/session/task.c:273
|
#: src/formhist/formhist.c:419 src/mime/dialogs.c:70 src/session/task.c:273
|
||||||
#: src/terminal/tab.c:192 src/terminal/tab.c:228
|
#: src/terminal/tab.c:192 src/terminal/tab.c:228
|
||||||
msgid "~No"
|
msgid "~No"
|
||||||
msgstr "~Non"
|
msgstr "~Non"
|
||||||
|
|
||||||
#: src/bfu/hierbox.c:917 src/bfu/hierbox.c:948 src/viewer/text/search.c:1013
|
#: src/bfu/hierbox.c:926 src/bfu/hierbox.c:957 src/viewer/text/search.c:1013
|
||||||
#: src/viewer/text/search.c:1021 src/viewer/text/search.c:1037
|
#: src/viewer/text/search.c:1021 src/viewer/text/search.c:1037
|
||||||
#: src/viewer/text/search.c:1612
|
#: src/viewer/text/search.c:1612
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Chercher"
|
msgstr "Chercher"
|
||||||
|
|
||||||
#: src/bfu/hierbox.c:919 src/viewer/text/search.c:1014
|
#: src/bfu/hierbox.c:928 src/viewer/text/search.c:1014
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Search string '%s' not found"
|
msgid "Search string '%s' not found"
|
||||||
msgstr "Chaîne recherchée '%s' introuvable"
|
msgstr "Chaîne recherchée '%s' introuvable"
|
||||||
|
|
||||||
#: src/bfu/hierbox.c:948 src/config/dialogs.c:168 src/config/dialogs.c:357
|
#: src/bfu/hierbox.c:957 src/config/dialogs.c:168 src/config/dialogs.c:357
|
||||||
#: src/config/dialogs.c:504 src/cookies/dialogs.c:34 src/cookies/dialogs.c:348
|
#: src/config/dialogs.c:504 src/cookies/dialogs.c:34 src/cookies/dialogs.c:348
|
||||||
#: src/dialogs/edit.c:91 src/dialogs/edit.c:93 src/scripting/lua/core.c:373
|
#: src/dialogs/edit.c:91 src/dialogs/edit.c:93 src/scripting/lua/core.c:373
|
||||||
#: src/scripting/lua/core.c:374 src/scripting/lua/core.c:454
|
#: src/scripting/lua/core.c:374 src/scripting/lua/core.c:454
|
||||||
@ -173,7 +173,7 @@ msgstr "Cha
|
|||||||
#: src/dialogs/options.c:291 src/mime/dialogs.c:130
|
#: src/dialogs/options.c:291 src/mime/dialogs.c:130
|
||||||
#: src/protocol/auth/dialogs.c:111 src/protocol/bittorrent/dialogs.c:801
|
#: src/protocol/auth/dialogs.c:111 src/protocol/bittorrent/dialogs.c:801
|
||||||
#: src/scripting/lua/core.c:378 src/scripting/lua/core.c:458
|
#: src/scripting/lua/core.c:378 src/scripting/lua/core.c:458
|
||||||
#: src/session/download.c:544 src/session/download.c:1121
|
#: src/session/download.c:544 src/session/download.c:1143
|
||||||
#: src/viewer/text/search.c:1594
|
#: src/viewer/text/search.c:1594
|
||||||
msgid "~Cancel"
|
msgid "~Cancel"
|
||||||
msgstr "~Annuler"
|
msgstr "~Annuler"
|
||||||
@ -187,7 +187,7 @@ msgid "Digital clock in the status bar."
|
|||||||
msgstr "Horloge digitale dans la barre de status."
|
msgstr "Horloge digitale dans la barre de status."
|
||||||
|
|
||||||
#: src/bfu/leds.c:77 src/bfu/leds.c:94 src/config/options.inc:1118
|
#: src/bfu/leds.c:77 src/bfu/leds.c:94 src/config/options.inc:1118
|
||||||
#: src/config/options.inc:1125 src/ecmascript/ecmascript.c:40
|
#: src/config/options.inc:1125 src/ecmascript/ecmascript.c:39
|
||||||
#: src/globhist/globhist.c:63 src/mime/backend/mailcap.c:93
|
#: src/globhist/globhist.c:63 src/mime/backend/mailcap.c:93
|
||||||
#: src/mime/backend/mimetypes.c:52 src/network/ssl/ssl.c:80
|
#: src/mime/backend/mimetypes.c:52 src/network/ssl/ssl.c:80
|
||||||
msgid "Enable"
|
msgid "Enable"
|
||||||
@ -1837,7 +1837,7 @@ msgstr "Impossible d'ajouter une option ici."
|
|||||||
|
|
||||||
#: src/config/dialogs.c:531 src/config/dialogs.c:943 src/cookies/dialogs.c:424
|
#: src/config/dialogs.c:531 src/config/dialogs.c:943 src/cookies/dialogs.c:424
|
||||||
#: src/dialogs/options.c:212 src/formhist/dialogs.c:213
|
#: src/dialogs/options.c:212 src/formhist/dialogs.c:213
|
||||||
#: src/protocol/bittorrent/dialogs.c:788 src/session/download.c:1105
|
#: src/protocol/bittorrent/dialogs.c:788 src/session/download.c:1127
|
||||||
msgid "Sa~ve"
|
msgid "Sa~ve"
|
||||||
msgstr "Enre~gistrer"
|
msgstr "Enre~gistrer"
|
||||||
|
|
||||||
@ -2305,14 +2305,12 @@ msgstr "Editeur externe"
|
|||||||
msgid ""
|
msgid ""
|
||||||
"Path to the executable that ELinks should launch when the user\n"
|
"Path to the executable that ELinks should launch when the user\n"
|
||||||
"requests to edit a textarea with an external editor.\n"
|
"requests to edit a textarea with an external editor.\n"
|
||||||
"\n"
|
|
||||||
"If this is blank, ELinks will use the value of the environmental\n"
|
"If this is blank, ELinks will use the value of the environmental\n"
|
||||||
"variable $EDITOR. If $EDITOR is empty or not set, ELinks will then\n"
|
"variable $EDITOR. If $EDITOR is empty or not set, ELinks will then\n"
|
||||||
"default to \"vi\"."
|
"default to \"vi\"."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Chemin du programme qu'ELinks doit lancer quand l'utilisateur\n"
|
"Chemin du programme qu'ELinks doit lancer quand l'utilisateur\n"
|
||||||
"demande à éditer un champ de texte avec un éditeur externe.\n"
|
"demande à éditer un champ de texte avec un éditeur externe.\n"
|
||||||
"\n"
|
|
||||||
"Si vide, ELinks utilisera la valeur de la variable d'environnement\n"
|
"Si vide, ELinks utilisera la valeur de la variable d'environnement\n"
|
||||||
"$EDITOR. Si $EDITOR est vide ou non configurée, ELinks utilisera\n"
|
"$EDITOR. Si $EDITOR est vide ou non configurée, ELinks utilisera\n"
|
||||||
"\"vi\" par défaut."
|
"\"vi\" par défaut."
|
||||||
@ -3357,15 +3355,13 @@ msgid ""
|
|||||||
"The format is:\n"
|
"The format is:\n"
|
||||||
"%c in the string means the current URL\n"
|
"%c in the string means the current URL\n"
|
||||||
"%% in the string means '%'\n"
|
"%% in the string means '%'\n"
|
||||||
"\n"
|
|
||||||
"Do _not_ put single- or double-quotes around %c."
|
"Do _not_ put single- or double-quotes around %c."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Règle de passage d'URI à une commande externe.\n"
|
"Règle de passage d'URI à une commande externe.\n"
|
||||||
"Le format est:\n"
|
"Le format est:\n"
|
||||||
"%c dans la chaîne signifie URL courante\n"
|
"%c dans la chaîne signifie URL courante\n"
|
||||||
"%% dans la chaîne signifie '%'\n"
|
"%% dans la chaîne signifie '%'\n"
|
||||||
"\n"
|
"Ne mettez pas de simples ou doubles guillemets autour de %c."
|
||||||
"Ne mettez pas de simples ou doubles quotes autour de %c."
|
|
||||||
|
|
||||||
#. Keep options in alphabetical order.
|
#. Keep options in alphabetical order.
|
||||||
#: src/config/options.inc:740
|
#: src/config/options.inc:740
|
||||||
@ -4674,7 +4670,7 @@ msgid ""
|
|||||||
"\n"
|
"\n"
|
||||||
"(C) 1999 - 2002 Mikulas Patocka\n"
|
"(C) 1999 - 2002 Mikulas Patocka\n"
|
||||||
"(C) 2001 - 2004 Petr Baudis\n"
|
"(C) 2001 - 2004 Petr Baudis\n"
|
||||||
"(C) 2002 - 2005 Jonas Fonseca\n"
|
"(C) 2002 - 2006 Jonas Fonseca\n"
|
||||||
"and others\n"
|
"and others\n"
|
||||||
"\n"
|
"\n"
|
||||||
"This program is free software; you can redistribute it and/or modify it "
|
"This program is free software; you can redistribute it and/or modify it "
|
||||||
@ -4685,7 +4681,7 @@ msgstr ""
|
|||||||
"\n"
|
"\n"
|
||||||
"(C) 1999 - 2002 Mikulas Patocka\n"
|
"(C) 1999 - 2002 Mikulas Patocka\n"
|
||||||
"(C) 2001 - 2004 Petr Baudis\n"
|
"(C) 2001 - 2004 Petr Baudis\n"
|
||||||
"(C) 2002 - 2005 Jonas Fonseca\n"
|
"(C) 2002 - 2006 Jonas Fonseca\n"
|
||||||
"et d'autres\n"
|
"et d'autres\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Ce programme est un logiciel libre; vous pouvez le redistribuer et/ou le "
|
"Ce programme est un logiciel libre; vous pouvez le redistribuer et/ou le "
|
||||||
@ -5362,31 +5358,31 @@ msgstr ""
|
|||||||
"Laisser à \"\" pour utiliser le style initial du document."
|
"Laisser à \"\" pour utiliser le style initial du document."
|
||||||
|
|
||||||
#. name:
|
#. name:
|
||||||
#: src/ecmascript/ecmascript.c:36 src/ecmascript/ecmascript.c:201
|
#: src/ecmascript/ecmascript.c:35 src/ecmascript/ecmascript.c:137
|
||||||
msgid "ECMAScript"
|
msgid "ECMAScript"
|
||||||
msgstr "ECMAScript"
|
msgstr "ECMAScript"
|
||||||
|
|
||||||
#: src/ecmascript/ecmascript.c:38
|
#: src/ecmascript/ecmascript.c:37
|
||||||
msgid "ECMAScript options."
|
msgid "ECMAScript options."
|
||||||
msgstr "Options d'ECMAScript."
|
msgstr "Options d'ECMAScript."
|
||||||
|
|
||||||
#: src/ecmascript/ecmascript.c:42
|
#: src/ecmascript/ecmascript.c:41
|
||||||
msgid "Whether to run those scripts inside of documents."
|
msgid "Whether to run those scripts inside of documents."
|
||||||
msgstr "Exécuter ou non ces scripts présents dans les documents."
|
msgstr "Exécuter ou non ces scripts présents dans les documents."
|
||||||
|
|
||||||
#: src/ecmascript/ecmascript.c:44
|
#: src/ecmascript/ecmascript.c:43
|
||||||
msgid "Script error reporting"
|
msgid "Script error reporting"
|
||||||
msgstr "Rapport d'erreur de script"
|
msgstr "Rapport d'erreur de script"
|
||||||
|
|
||||||
#: src/ecmascript/ecmascript.c:46
|
#: src/ecmascript/ecmascript.c:45
|
||||||
msgid "Open a message box when a script reports an error."
|
msgid "Open a message box when a script reports an error."
|
||||||
msgstr "Ouvrir une boîte de message quand un script produit une erreur."
|
msgstr "Ouvrir une boîte de message quand un script produit une erreur."
|
||||||
|
|
||||||
#: src/ecmascript/ecmascript.c:48
|
#: src/ecmascript/ecmascript.c:47
|
||||||
msgid "Ignore <noscript> content"
|
msgid "Ignore <noscript> content"
|
||||||
msgstr "Ignorer le contenu de <noscript>"
|
msgstr "Ignorer le contenu de <noscript>"
|
||||||
|
|
||||||
#: src/ecmascript/ecmascript.c:50
|
#: src/ecmascript/ecmascript.c:49
|
||||||
msgid ""
|
msgid ""
|
||||||
"Whether to ignore content enclosed by the <noscript> tag\n"
|
"Whether to ignore content enclosed by the <noscript> tag\n"
|
||||||
"when ECMAScript is enabled."
|
"when ECMAScript is enabled."
|
||||||
@ -5394,38 +5390,29 @@ msgstr ""
|
|||||||
"Ignorer ou non le contenu du tag <noscript> quand ECMAScript\n"
|
"Ignorer ou non le contenu du tag <noscript> quand ECMAScript\n"
|
||||||
"est actif."
|
"est actif."
|
||||||
|
|
||||||
#: src/ecmascript/ecmascript.c:53
|
#: src/ecmascript/ecmascript.c:52
|
||||||
msgid "Maximum execution time"
|
msgid "Maximum execution time"
|
||||||
msgstr "Temps maximal d'exécution"
|
msgstr "Temps maximal d'exécution"
|
||||||
|
|
||||||
#: src/ecmascript/ecmascript.c:55
|
#: src/ecmascript/ecmascript.c:54
|
||||||
msgid "Maximum execution time in seconds for a script."
|
msgid "Maximum execution time in seconds for a script."
|
||||||
msgstr "Temps maximal pour l'exécution d'un script, en secondes."
|
msgstr "Temps maximal pour l'exécution d'un script, en secondes."
|
||||||
|
|
||||||
#: src/ecmascript/ecmascript.c:57
|
#: src/ecmascript/ecmascript.c:56
|
||||||
msgid "Pop-up window blocking"
|
msgid "Pop-up window blocking"
|
||||||
msgstr "Blocage des fenêtres Javascript (popups)"
|
msgstr "Blocage des fenêtres Javascript (popups)"
|
||||||
|
|
||||||
#: src/ecmascript/ecmascript.c:59
|
#: src/ecmascript/ecmascript.c:58
|
||||||
msgid "Whether to disallow scripts to open new windows or tabs."
|
msgid "Whether to disallow scripts to open new windows or tabs."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Interdire ou non l'ouverture de fenêtres ou d'onglets\n"
|
"Interdire ou non l'ouverture de fenêtres ou d'onglets\n"
|
||||||
"par les scripts."
|
"par les scripts."
|
||||||
|
|
||||||
#: src/ecmascript/spidermonkey.c:92
|
#: src/ecmascript/ecmascript.c:126
|
||||||
#, c-format
|
|
||||||
msgid "A script embedded in the current document raised the following%s%s%s%s"
|
|
||||||
msgstr "Un script contenu dans le document courant a provoqué%s%s%s%s"
|
|
||||||
|
|
||||||
#: src/ecmascript/spidermonkey.c:108
|
|
||||||
msgid "JavaScript Error"
|
|
||||||
msgstr "Erreur Javascript"
|
|
||||||
|
|
||||||
#: src/ecmascript/spidermonkey.c:127
|
|
||||||
msgid "JavaScript Emergency"
|
msgid "JavaScript Emergency"
|
||||||
msgstr "Alerte JavaScript"
|
msgstr "Alerte JavaScript"
|
||||||
|
|
||||||
#: src/ecmascript/spidermonkey.c:129
|
#: src/ecmascript/ecmascript.c:128
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"A script embedded in the current document was running\n"
|
"A script embedded in the current document was running\n"
|
||||||
@ -5438,10 +5425,19 @@ msgstr ""
|
|||||||
"qu'il y a un bogue dans ce script et que cela aurait pû\n"
|
"qu'il y a un bogue dans ce script et que cela aurait pû\n"
|
||||||
"bloquer ELinks, l'exécution du script a donc été interrompue."
|
"bloquer ELinks, l'exécution du script a donc été interrompue."
|
||||||
|
|
||||||
#: src/ecmascript/spidermonkey/window.c:286
|
#: src/ecmascript/see/window.c:242 src/ecmascript/spidermonkey/window.c:286
|
||||||
msgid "JavaScript Alert"
|
msgid "JavaScript Alert"
|
||||||
msgstr "Alerte JavaScript"
|
msgstr "Alerte JavaScript"
|
||||||
|
|
||||||
|
#: src/ecmascript/spidermonkey.c:162
|
||||||
|
#, c-format
|
||||||
|
msgid "A script embedded in the current document raised the following%s%s%s%s"
|
||||||
|
msgstr "Un script contenu dans le document courant a provoqué%s%s%s%s"
|
||||||
|
|
||||||
|
#: src/ecmascript/spidermonkey.c:178
|
||||||
|
msgid "JavaScript Error"
|
||||||
|
msgstr "Erreur Javascript"
|
||||||
|
|
||||||
#: src/formhist/dialogs.c:67
|
#: src/formhist/dialogs.c:67
|
||||||
msgid "Forms are never saved for this URL."
|
msgid "Forms are never saved for this URL."
|
||||||
msgstr "Les formulaires ne sont jamais sauvés pour cette URL."
|
msgstr "Les formulaires ne sont jamais sauvés pour cette URL."
|
||||||
@ -5983,12 +5979,12 @@ msgstr ""
|
|||||||
"ici à la place de '.')."
|
"ici à la place de '.')."
|
||||||
|
|
||||||
#. name:
|
#. name:
|
||||||
#: src/mime/backend/default.c:227
|
#: src/mime/backend/default.c:228
|
||||||
msgid "Option system"
|
msgid "Option system"
|
||||||
msgstr "Système de configuration"
|
msgstr "Système de configuration"
|
||||||
|
|
||||||
#. name:
|
#. name:
|
||||||
#: src/mime/backend/mailcap.c:89 src/mime/backend/mailcap.c:668
|
#: src/mime/backend/mailcap.c:89 src/mime/backend/mailcap.c:674
|
||||||
msgid "Mailcap"
|
msgid "Mailcap"
|
||||||
msgstr "Mailcap"
|
msgstr "Mailcap"
|
||||||
|
|
||||||
@ -7128,7 +7124,7 @@ msgstr "Que voulez-vous faire avec le fichier '%s' ?"
|
|||||||
msgid "Information about the torrent"
|
msgid "Information about the torrent"
|
||||||
msgstr "Informations sur le torrent"
|
msgstr "Informations sur le torrent"
|
||||||
|
|
||||||
#: src/protocol/bittorrent/dialogs.c:763 src/session/download.c:1017
|
#: src/protocol/bittorrent/dialogs.c:763 src/session/download.c:1039
|
||||||
msgid "What to do?"
|
msgid "What to do?"
|
||||||
msgstr "Que faire ?"
|
msgstr "Que faire ?"
|
||||||
|
|
||||||
@ -7136,11 +7132,11 @@ msgstr "Que faire ?"
|
|||||||
msgid "Down~load"
|
msgid "Down~load"
|
||||||
msgstr "Té~lécharger"
|
msgstr "Té~lécharger"
|
||||||
|
|
||||||
#: src/protocol/bittorrent/dialogs.c:791 src/session/download.c:1111
|
#: src/protocol/bittorrent/dialogs.c:791 src/session/download.c:1133
|
||||||
msgid "~Display"
|
msgid "~Display"
|
||||||
msgstr "A~fficher"
|
msgstr "A~fficher"
|
||||||
|
|
||||||
#: src/protocol/bittorrent/dialogs.c:795 src/session/download.c:1115
|
#: src/protocol/bittorrent/dialogs.c:795 src/session/download.c:1137
|
||||||
msgid "Show ~header"
|
msgid "Show ~header"
|
||||||
msgstr "~Montrer les en-têtes"
|
msgstr "~Montrer les en-têtes"
|
||||||
|
|
||||||
@ -7840,11 +7836,11 @@ msgid "Scripting"
|
|||||||
msgstr "Scripting"
|
msgstr "Scripting"
|
||||||
|
|
||||||
#: src/session/download.c:234 src/session/download.c:331
|
#: src/session/download.c:234 src/session/download.c:331
|
||||||
#: src/session/download.c:498 src/session/download.c:590
|
#: src/session/download.c:498 src/session/download.c:593
|
||||||
msgid "Download error"
|
msgid "Download error"
|
||||||
msgstr "Erreur de téléchargement"
|
msgstr "Erreur de téléchargement"
|
||||||
|
|
||||||
#: src/session/download.c:235 src/session/download.c:591
|
#: src/session/download.c:235 src/session/download.c:594
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Could not create file '%s':\n"
|
"Could not create file '%s':\n"
|
||||||
@ -7900,30 +7896,30 @@ msgstr "Ecraser le fichier ~original"
|
|||||||
msgid "~Resume download of the original file"
|
msgid "~Resume download of the original file"
|
||||||
msgstr "~Reprendre le téléchargement du fichier original"
|
msgstr "~Reprendre le téléchargement du fichier original"
|
||||||
|
|
||||||
#: src/session/download.c:1020
|
#: src/session/download.c:1042
|
||||||
msgid "Unknown type"
|
msgid "Unknown type"
|
||||||
msgstr "Type inconnu"
|
msgstr "Type inconnu"
|
||||||
|
|
||||||
#: src/session/download.c:1037
|
#: src/session/download.c:1059
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "What would you like to do with the file '%s' (type: %s%s%s)?"
|
msgid "What would you like to do with the file '%s' (type: %s%s%s)?"
|
||||||
msgstr "Que voulez-vous faire avec le fichier '%s' (type: %s%s%s) ?"
|
msgstr "Que voulez-vous faire avec le fichier '%s' (type: %s%s%s) ?"
|
||||||
|
|
||||||
#: src/session/download.c:1067
|
#: src/session/download.c:1089
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid "Program ('%' will be replaced by the filename)"
|
msgid "Program ('%' will be replaced by the filename)"
|
||||||
msgstr "Programme ('%' sera remplacé par le nom du fichier)"
|
msgstr "Programme ('%' sera remplacé par le nom du fichier)"
|
||||||
|
|
||||||
#: src/session/download.c:1071
|
#: src/session/download.c:1093
|
||||||
msgid "Block the terminal"
|
msgid "Block the terminal"
|
||||||
msgstr "Bloquer le terminal"
|
msgstr "Bloquer le terminal"
|
||||||
|
|
||||||
#: src/session/download.c:1077
|
#: src/session/download.c:1099
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "The file will be opened with the program '%s'."
|
msgid "The file will be opened with the program '%s'."
|
||||||
msgstr "Le fichier sera ouvert avec le programme '%s'."
|
msgstr "Le fichier sera ouvert avec le programme '%s'."
|
||||||
|
|
||||||
#: src/session/download.c:1098
|
#: src/session/download.c:1120
|
||||||
msgid "~Open"
|
msgid "~Open"
|
||||||
msgstr "~Ouvrir"
|
msgstr "~Ouvrir"
|
||||||
|
|
||||||
|
@ -157,13 +157,15 @@ hierbox_ev_kbd(struct dialog_data *dlg_data)
|
|||||||
selected = box->sel;
|
selected = box->sel;
|
||||||
action_id = kbd_action(KEYMAP_MENU, ev, NULL);
|
action_id = kbd_action(KEYMAP_MENU, ev, NULL);
|
||||||
|
|
||||||
if (action_id == ACT_MENU_SELECT) {
|
switch (action_id) {
|
||||||
|
case ACT_MENU_SELECT:
|
||||||
if (!selected) return EVENT_PROCESSED;
|
if (!selected) return EVENT_PROCESSED;
|
||||||
if (selected->type != BI_FOLDER)
|
if (selected->type != BI_FOLDER)
|
||||||
return EVENT_NOT_PROCESSED;
|
return EVENT_NOT_PROCESSED;
|
||||||
selected->expanded = !selected->expanded;
|
selected->expanded = !selected->expanded;
|
||||||
|
break;
|
||||||
|
|
||||||
} else if (action_id == ACT_MENU_UNEXPAND) {
|
case ACT_MENU_UNEXPAND:
|
||||||
/* Recursively unexpand all folders */
|
/* Recursively unexpand all folders */
|
||||||
if (!selected) return EVENT_PROCESSED;
|
if (!selected) return EVENT_PROCESSED;
|
||||||
|
|
||||||
@ -173,8 +175,9 @@ hierbox_ev_kbd(struct dialog_data *dlg_data)
|
|||||||
* whole parent folder will be closed. */
|
* whole parent folder will be closed. */
|
||||||
if (list_empty(selected->child)
|
if (list_empty(selected->child)
|
||||||
|| !selected->expanded) {
|
|| !selected->expanded) {
|
||||||
struct listbox_item *root = box->ops->get_root(selected);
|
struct listbox_item *root;
|
||||||
|
|
||||||
|
root = box->ops->get_root(selected);
|
||||||
if (root) {
|
if (root) {
|
||||||
listbox_sel(widget_data, root);
|
listbox_sel(widget_data, root);
|
||||||
}
|
}
|
||||||
@ -182,23 +185,25 @@ hierbox_ev_kbd(struct dialog_data *dlg_data)
|
|||||||
} else if (selected->type == BI_FOLDER) {
|
} else if (selected->type == BI_FOLDER) {
|
||||||
recursively_set_expanded(selected, 0);
|
recursively_set_expanded(selected, 0);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
} else if (action_id == ACT_MENU_EXPAND) {
|
case ACT_MENU_EXPAND:
|
||||||
/* Recursively expand all folders */
|
/* Recursively expand all folders */
|
||||||
|
|
||||||
if (!selected || selected->type != BI_FOLDER)
|
if (!selected || selected->type != BI_FOLDER)
|
||||||
return EVENT_PROCESSED;
|
return EVENT_PROCESSED;
|
||||||
|
|
||||||
recursively_set_expanded(selected, 1);
|
recursively_set_expanded(selected, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
} else if (action_id == ACT_MENU_SEARCH) {
|
case ACT_MENU_SEARCH:
|
||||||
if (!box->ops->match)
|
if (!box->ops->match)
|
||||||
return EVENT_NOT_PROCESSED;
|
return EVENT_NOT_PROCESSED;
|
||||||
|
|
||||||
push_hierbox_search_button(dlg_data, NULL);
|
push_hierbox_search_button(dlg_data, NULL);
|
||||||
return EVENT_PROCESSED;
|
return EVENT_PROCESSED;
|
||||||
|
|
||||||
} else {
|
default:
|
||||||
return EVENT_NOT_PROCESSED;
|
return EVENT_NOT_PROCESSED;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -230,7 +235,9 @@ hierbox_ev_init(struct dialog_data *dlg_data)
|
|||||||
litem->visible = 1;
|
litem->visible = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EVENT_NOT_PROCESSED; /* FIXME: is this correct ? --Zas */
|
/* Return this so that the generic dialog code will run and initialise
|
||||||
|
* the widgets and stuff. */
|
||||||
|
return EVENT_NOT_PROCESSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static widget_handler_status_T
|
static widget_handler_status_T
|
||||||
@ -254,7 +261,9 @@ hierbox_ev_abort(struct dialog_data *dlg_data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return EVENT_NOT_PROCESSED; /* FIXME: is this correct ? --Zas */
|
/* Return this so that the generic dialog code will run and initialise
|
||||||
|
* the widgets and stuff. */
|
||||||
|
return EVENT_NOT_PROCESSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -312,7 +321,7 @@ hierbox_browser(struct hierbox_browser *browser, struct session *ses)
|
|||||||
dlg->udata = ses;
|
dlg->udata = ses;
|
||||||
dlg->udata2 = browser;
|
dlg->udata2 = browser;
|
||||||
|
|
||||||
add_dlg_listbox(dlg, 12, listbox_data);
|
add_dlg_listbox(dlg, listbox_data);
|
||||||
|
|
||||||
for (button = 0; button < browser->buttons_size; button++) {
|
for (button = 0; button < browser->buttons_size; button++) {
|
||||||
struct hierbox_browser_button *but = &browser->buttons[button];
|
struct hierbox_browser_button *but = &browser->buttons[button];
|
||||||
|
@ -121,52 +121,9 @@ refresh_hotkeys(struct terminal *term, struct menu *menu)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns true if key (upcased) matches one of the hotkeys in menu */
|
|
||||||
static int
|
|
||||||
is_hotkey(struct menu_item *item, unsigned char key, struct terminal *term)
|
|
||||||
{
|
|
||||||
unsigned char *text;
|
|
||||||
int key_pos;
|
|
||||||
|
|
||||||
assert(item);
|
|
||||||
if_assert_failed return 0;
|
|
||||||
|
|
||||||
if (!mi_has_left_text(item)) return 0;
|
|
||||||
|
|
||||||
text = item->text;
|
|
||||||
if (mi_text_translate(item)) text = _(text, term);
|
|
||||||
if (!text || !*text) return 0;
|
|
||||||
|
|
||||||
key_pos = item->hotkey_pos;
|
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG
|
|
||||||
if (key_pos < 0) key_pos = -key_pos;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return (key_pos && (toupper(text[key_pos]) == key));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns true if key (upcased) matches first letter of menu item left text. */
|
|
||||||
static int
|
|
||||||
is_not_so_hotkey(struct menu_item *item, unsigned char key, struct terminal *term)
|
|
||||||
{
|
|
||||||
unsigned char *text;
|
|
||||||
|
|
||||||
assert(item);
|
|
||||||
if_assert_failed return 0;
|
|
||||||
|
|
||||||
if (!mi_has_left_text(item)) return 0;
|
|
||||||
|
|
||||||
text = item->text;
|
|
||||||
if (mi_text_translate(item)) text = _(text, term);
|
|
||||||
if (!text || !*text) return 0;
|
|
||||||
|
|
||||||
return (toupper(*text) == key);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
check_hotkeys_common(struct menu *menu, unsigned char hotkey, struct terminal *term,
|
check_hotkeys_common(struct menu *menu, unsigned char hotkey, struct terminal *term,
|
||||||
int (*func)(struct menu_item *, unsigned char, struct terminal *))
|
int check_mode)
|
||||||
{
|
{
|
||||||
unsigned char key = toupper(hotkey);
|
unsigned char key = toupper(hotkey);
|
||||||
int i = menu->selected;
|
int i = menu->selected;
|
||||||
@ -179,9 +136,37 @@ check_hotkeys_common(struct menu *menu, unsigned char hotkey, struct terminal *t
|
|||||||
|
|
||||||
start = i;
|
start = i;
|
||||||
do {
|
do {
|
||||||
|
struct menu_item *item;
|
||||||
|
unsigned char *text;
|
||||||
|
int found;
|
||||||
|
|
||||||
if (++i == menu->size) i = 0;
|
if (++i == menu->size) i = 0;
|
||||||
|
|
||||||
if (func(&menu->items[i], key, term)) {
|
item = &menu->items[i];
|
||||||
|
|
||||||
|
if (!mi_has_left_text(item)) continue;
|
||||||
|
|
||||||
|
text = item->text;
|
||||||
|
if (mi_text_translate(item)) text = _(text, term);
|
||||||
|
if (!text || !*text) continue;
|
||||||
|
|
||||||
|
if (check_mode == 0) {
|
||||||
|
/* Does the key (upcased) matches one of the
|
||||||
|
* hotkeys in menu ? */
|
||||||
|
int key_pos = item->hotkey_pos;
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG
|
||||||
|
if (key_pos < 0) key_pos = -key_pos;
|
||||||
|
#endif
|
||||||
|
found = (key_pos && (toupper(text[key_pos]) == key));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* Does the key (upcased) matches first letter
|
||||||
|
* of menu item left text ? */
|
||||||
|
found = (toupper(*text) == key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
menu->selected = i;
|
menu->selected = i;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -195,7 +180,7 @@ check_hotkeys_common(struct menu *menu, unsigned char hotkey, struct terminal *t
|
|||||||
int
|
int
|
||||||
check_hotkeys(struct menu *menu, unsigned char key, struct terminal *term)
|
check_hotkeys(struct menu *menu, unsigned char key, struct terminal *term)
|
||||||
{
|
{
|
||||||
return check_hotkeys_common(menu, key, term, is_hotkey);
|
return check_hotkeys_common(menu, key, term, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Search if first letter of an entry in menu matches the key (caseless comp.).
|
/* Search if first letter of an entry in menu matches the key (caseless comp.).
|
||||||
@ -205,5 +190,5 @@ check_hotkeys(struct menu *menu, unsigned char key, struct terminal *term)
|
|||||||
int
|
int
|
||||||
check_not_so_hot_keys(struct menu *menu, unsigned char key, struct terminal *term)
|
check_not_so_hot_keys(struct menu *menu, unsigned char key, struct terminal *term)
|
||||||
{
|
{
|
||||||
return check_hotkeys_common(menu, key, term, is_not_so_hotkey);
|
return check_hotkeys_common(menu, key, term, 1);
|
||||||
}
|
}
|
||||||
|
@ -321,7 +321,7 @@ save_input_history(struct input_history *history, unsigned char *filename)
|
|||||||
history_file = straconcat(elinks_home, filename, NULL);
|
history_file = straconcat(elinks_home, filename, NULL);
|
||||||
if (!history_file) return -1;
|
if (!history_file) return -1;
|
||||||
|
|
||||||
ssi = secure_open(history_file, 0177);
|
ssi = secure_open(history_file);
|
||||||
mem_free(history_file);
|
mem_free(history_file);
|
||||||
if (!ssi) return -1;
|
if (!ssi) return -1;
|
||||||
|
|
||||||
|
@ -24,14 +24,12 @@
|
|||||||
#define VERTICAL_LISTBOX_MARGIN 3
|
#define VERTICAL_LISTBOX_MARGIN 3
|
||||||
|
|
||||||
void
|
void
|
||||||
add_dlg_listbox(struct dialog *dlg, int height, void *box_data)
|
add_dlg_listbox(struct dialog *dlg, void *box_data)
|
||||||
{
|
{
|
||||||
struct widget *widget = &dlg->widgets[dlg->number_of_widgets++];
|
struct widget *widget = &dlg->widgets[dlg->number_of_widgets++];
|
||||||
|
|
||||||
widget->type = WIDGET_LISTBOX;
|
widget->type = WIDGET_LISTBOX;
|
||||||
widget->data = box_data;
|
widget->data = box_data;
|
||||||
|
|
||||||
widget->info.listbox.height = height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct listbox_data *
|
struct listbox_data *
|
||||||
|
@ -11,12 +11,8 @@ struct terminal;
|
|||||||
struct uri;
|
struct uri;
|
||||||
struct widget_data;
|
struct widget_data;
|
||||||
|
|
||||||
struct widget_info_listbox {
|
|
||||||
int height;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
void add_dlg_listbox(struct dialog *dlg, void *box_data);
|
||||||
void add_dlg_listbox(struct dialog *dlg, int height, void *box_data);
|
|
||||||
|
|
||||||
enum listbox_match {
|
enum listbox_match {
|
||||||
LISTBOX_MATCH_OK,
|
LISTBOX_MATCH_OK,
|
||||||
|
@ -42,7 +42,6 @@ struct widget {
|
|||||||
union {
|
union {
|
||||||
struct widget_info_checkbox checkbox;
|
struct widget_info_checkbox checkbox;
|
||||||
struct widget_info_field field;
|
struct widget_info_field field;
|
||||||
struct widget_info_listbox listbox;
|
|
||||||
struct widget_info_button button;
|
struct widget_info_button button;
|
||||||
struct widget_info_text text;
|
struct widget_info_text text;
|
||||||
} info;
|
} info;
|
||||||
|
@ -94,7 +94,7 @@ bookmarks_write(struct list_head *bookmarks_list)
|
|||||||
file_name = straconcat(elinks_home, file_name, NULL);
|
file_name = straconcat(elinks_home, file_name, NULL);
|
||||||
if (!file_name) return;
|
if (!file_name) return;
|
||||||
|
|
||||||
ssi = secure_open(file_name, 0177);
|
ssi = secure_open(file_name);
|
||||||
mem_free(file_name);
|
mem_free(file_name);
|
||||||
if (!ssi) return;
|
if (!ssi) return;
|
||||||
|
|
||||||
|
@ -805,7 +805,7 @@ write_config_file(unsigned char *prefix, unsigned char *name,
|
|||||||
config_file = straconcat(prefix, slash, name, NULL);
|
config_file = straconcat(prefix, slash, name, NULL);
|
||||||
if (!config_file) goto free_cfg_str;
|
if (!config_file) goto free_cfg_str;
|
||||||
|
|
||||||
ssi = secure_open(config_file, 0177);
|
ssi = secure_open(config_file);
|
||||||
if (ssi) {
|
if (ssi) {
|
||||||
secure_fputs(ssi, cfg_str);
|
secure_fputs(ssi, cfg_str);
|
||||||
ret = secure_close(ssi);
|
ret = secure_close(ssi);
|
||||||
|
@ -193,7 +193,7 @@ static struct option_info config_options_info[] = {
|
|||||||
INIT_OPT_STRING("document.browse.forms", N_("External editor"),
|
INIT_OPT_STRING("document.browse.forms", N_("External editor"),
|
||||||
"editor", 0, "",
|
"editor", 0, "",
|
||||||
N_("Path to the executable that ELinks should launch when the user\n"
|
N_("Path to the executable that ELinks should launch when the user\n"
|
||||||
"requests to edit a textarea with an external editor.\n\n"
|
"requests to edit a textarea with an external editor.\n"
|
||||||
"If this is blank, ELinks will use the value of the environmental\n"
|
"If this is blank, ELinks will use the value of the environmental\n"
|
||||||
"variable $EDITOR. If $EDITOR is empty or not set, ELinks will then\n"
|
"variable $EDITOR. If $EDITOR is empty or not set, ELinks will then\n"
|
||||||
"default to \"vi\".")),
|
"default to \"vi\".")),
|
||||||
@ -730,7 +730,7 @@ static struct option_info config_options_info[] = {
|
|||||||
N_("A rule for passing URI to an external command.\n"
|
N_("A rule for passing URI to an external command.\n"
|
||||||
"The format is:\n"
|
"The format is:\n"
|
||||||
"%c in the string means the current URL\n"
|
"%c in the string means the current URL\n"
|
||||||
"%% in the string means '%'\n\n"
|
"%% in the string means '%'\n"
|
||||||
"Do _not_ put single- or double-quotes around %c.")),
|
"Do _not_ put single- or double-quotes around %c.")),
|
||||||
|
|
||||||
/* Keep options in alphabetical order. */
|
/* Keep options in alphabetical order. */
|
||||||
|
@ -775,7 +775,7 @@ save_cookies(void) {
|
|||||||
cookfile = straconcat(elinks_home, COOKIES_FILENAME, NULL);
|
cookfile = straconcat(elinks_home, COOKIES_FILENAME, NULL);
|
||||||
if (!cookfile) return;
|
if (!cookfile) return;
|
||||||
|
|
||||||
ssi = secure_open(cookfile, 0177); /* rw for user only */
|
ssi = secure_open(cookfile);
|
||||||
mem_free(cookfile);
|
mem_free(cookfile);
|
||||||
if (!ssi) return;
|
if (!ssi) return;
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ menu_copying(struct terminal *term, void *xxx, void *xxxx)
|
|||||||
"\n"
|
"\n"
|
||||||
"(C) 1999 - 2002 Mikulas Patocka\n"
|
"(C) 1999 - 2002 Mikulas Patocka\n"
|
||||||
"(C) 2001 - 2004 Petr Baudis\n"
|
"(C) 2001 - 2004 Petr Baudis\n"
|
||||||
"(C) 2002 - 2005 Jonas Fonseca\n"
|
"(C) 2002 - 2006 Jonas Fonseca\n"
|
||||||
"and others\n"
|
"and others\n"
|
||||||
"\n"
|
"\n"
|
||||||
"This program is free software; you can redistribute it "
|
"This program is free software; you can redistribute it "
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "document/renderer.h"
|
#include "document/renderer.h"
|
||||||
#include "dom/scanner.h"
|
#include "dom/scanner.h"
|
||||||
#include "dom/sgml/parser.h"
|
#include "dom/sgml/parser.h"
|
||||||
|
#include "dom/sgml/rss/rss.h"
|
||||||
#include "dom/node.h"
|
#include "dom/node.h"
|
||||||
#include "dom/stack.h"
|
#include "dom/stack.h"
|
||||||
#include "intl/charsets.h"
|
#include "intl/charsets.h"
|
||||||
@ -54,6 +55,13 @@ struct dom_renderer {
|
|||||||
unsigned int find_url:1;
|
unsigned int find_url:1;
|
||||||
#endif
|
#endif
|
||||||
struct screen_char styles[DOM_NODES];
|
struct screen_char styles[DOM_NODES];
|
||||||
|
|
||||||
|
/* RSS renderer variables */
|
||||||
|
struct dom_node *channel;
|
||||||
|
struct dom_node_list *items;
|
||||||
|
struct dom_node *item;
|
||||||
|
struct dom_node *node;
|
||||||
|
struct dom_string text;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define URL_REGEX "(file://|((f|ht|nt)tp(s)?|smb)://[[:alnum:]]+([-@:.]?[[:alnum:]])*\\.[[:alpha:]]{2,4}(:[[:digit:]]+)?)(/(%[[:xdigit:]]{2}|[-_~&=;?.a-z0-9])*)*"
|
#define URL_REGEX "(file://|((f|ht|nt)tp(s)?|smb)://[[:alnum:]]+([-@:.]?[[:alnum:]])*\\.[[:alpha:]]{2,4}(:[[:digit:]]+)?)(/(%[[:xdigit:]]{2}|[-_~&=;?.a-z0-9])*)*"
|
||||||
@ -61,11 +69,11 @@ struct dom_renderer {
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
init_template(struct screen_char *template, struct document_options *options,
|
init_template(struct screen_char *template, struct document_options *options,
|
||||||
color_T background, color_T foreground)
|
color_T background, color_T foreground, enum screen_char_attr attr)
|
||||||
{
|
{
|
||||||
struct color_pair colors = INIT_COLOR_PAIR(background, foreground);
|
struct color_pair colors = INIT_COLOR_PAIR(background, foreground);
|
||||||
|
|
||||||
template->attr = 0;
|
template->attr = attr;
|
||||||
template->data = ' ';
|
template->data = ' ';
|
||||||
set_term_color(template, &colors,
|
set_term_color(template, &colors,
|
||||||
options->color_flags, options->color_mode);
|
options->color_flags, options->color_mode);
|
||||||
@ -115,6 +123,7 @@ init_dom_renderer(struct dom_renderer *renderer, struct document *document,
|
|||||||
struct screen_char *template = &renderer->styles[type];
|
struct screen_char *template = &renderer->styles[type];
|
||||||
color_T background = document->options.default_bg;
|
color_T background = document->options.default_bg;
|
||||||
color_T foreground = document->options.default_fg;
|
color_T foreground = document->options.default_fg;
|
||||||
|
enum screen_char_attr attr = 0;
|
||||||
static int i_want_struct_module_for_dom;
|
static int i_want_struct_module_for_dom;
|
||||||
|
|
||||||
struct dom_string *name = get_dom_node_type_name(type);
|
struct dom_string *name = get_dom_node_type_name(type);
|
||||||
@ -157,9 +166,31 @@ init_dom_renderer(struct dom_renderer *renderer, struct document *document,
|
|||||||
|
|
||||||
property = get_css_property(properties, CSS_PT_COLOR);
|
property = get_css_property(properties, CSS_PT_COLOR);
|
||||||
if (property) foreground = property->value.color;
|
if (property) foreground = property->value.color;
|
||||||
|
|
||||||
|
property = get_css_property(properties, CSS_PT_FONT_WEIGHT);
|
||||||
|
if (property) {
|
||||||
|
if (property->value.font_attribute.add & AT_BOLD)
|
||||||
|
attr |= SCREEN_ATTR_BOLD;
|
||||||
|
}
|
||||||
|
|
||||||
|
property = get_css_property(properties, CSS_PT_FONT_STYLE);
|
||||||
|
if (property) {
|
||||||
|
if (property->value.font_attribute.add & AT_UNDERLINE)
|
||||||
|
attr |= SCREEN_ATTR_UNDERLINE;
|
||||||
|
|
||||||
|
if (property->value.font_attribute.add & AT_ITALIC)
|
||||||
|
attr |= SCREEN_ATTR_ITALIC;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
property = get_css_property(properties, CSS_PT_TEXT_DECORATION);
|
||||||
|
if (property) {
|
||||||
|
if (property->value.font_attribute.add & AT_UNDERLINE)
|
||||||
|
attr |= SCREEN_ATTR_UNDERLINE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init_template(template, &document->options, background, foreground);
|
init_template(template, &document->options, background, foreground, attr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,7 +342,8 @@ render_dom_text(struct dom_renderer *renderer, struct screen_char *template,
|
|||||||
ALIGN_LINK(&(doc)->links, (doc)->nlinks, size)
|
ALIGN_LINK(&(doc)->links, (doc)->nlinks, size)
|
||||||
|
|
||||||
static inline struct link *
|
static inline struct link *
|
||||||
add_dom_link(struct dom_renderer *renderer, unsigned char *string, int length)
|
add_dom_link(struct dom_renderer *renderer, unsigned char *string, int length,
|
||||||
|
unsigned char *uristring, int urilength)
|
||||||
{
|
{
|
||||||
struct document *document = renderer->document;
|
struct document *document = renderer->document;
|
||||||
int x = renderer->canvas_x;
|
int x = renderer->canvas_x;
|
||||||
@ -320,7 +352,6 @@ add_dom_link(struct dom_renderer *renderer, unsigned char *string, int length)
|
|||||||
struct link *link;
|
struct link *link;
|
||||||
struct point *point;
|
struct point *point;
|
||||||
struct screen_char template;
|
struct screen_char template;
|
||||||
unsigned char *uristring;
|
|
||||||
color_T fgcolor;
|
color_T fgcolor;
|
||||||
|
|
||||||
if (!realloc_document_links(document, document->nlinks + 1))
|
if (!realloc_document_links(document, document->nlinks + 1))
|
||||||
@ -332,7 +363,7 @@ add_dom_link(struct dom_renderer *renderer, unsigned char *string, int length)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
uristring = convert_string(renderer->convert_table,
|
uristring = convert_string(renderer->convert_table,
|
||||||
string, length, document->options.cp,
|
uristring, urilength, document->options.cp,
|
||||||
CSM_DEFAULT, NULL, NULL, NULL);
|
CSM_DEFAULT, NULL, NULL, NULL);
|
||||||
if (!uristring) return NULL;
|
if (!uristring) return NULL;
|
||||||
|
|
||||||
@ -361,7 +392,7 @@ add_dom_link(struct dom_renderer *renderer, unsigned char *string, int length)
|
|||||||
link->number = document->nlinks;
|
link->number = document->nlinks;
|
||||||
|
|
||||||
init_template(&template, &document->options,
|
init_template(&template, &document->options,
|
||||||
link->color.background, link->color.foreground);
|
link->color.background, link->color.foreground, 0);
|
||||||
|
|
||||||
render_dom_text(renderer, &template, string, length);
|
render_dom_text(renderer, &template, string, length);
|
||||||
|
|
||||||
@ -456,7 +487,7 @@ render_dom_node_enhanced_text(struct dom_renderer *renderer, struct dom_node *no
|
|||||||
string += offset;
|
string += offset;
|
||||||
length -= offset;
|
length -= offset;
|
||||||
|
|
||||||
add_dom_link(renderer, string, matchlen);
|
add_dom_link(renderer, string, matchlen, string, matchlen);
|
||||||
|
|
||||||
length -= matchlen;
|
length -= matchlen;
|
||||||
string += matchlen;
|
string += matchlen;
|
||||||
@ -578,7 +609,8 @@ render_dom_attribute_source(struct dom_stack *stack, struct dom_node *node, void
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_dom_link(renderer, value, valuelen - skips);
|
add_dom_link(renderer, value, valuelen - skips,
|
||||||
|
value, valuelen - skips);
|
||||||
|
|
||||||
if (skips > 0) {
|
if (skips > 0) {
|
||||||
value += valuelen - skips;
|
value += valuelen - skips;
|
||||||
@ -659,23 +691,298 @@ static struct dom_stack_context_info dom_source_renderer_context_info = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* DOM RSS Renderer */
|
||||||
|
|
||||||
|
static void
|
||||||
|
dom_rss_push_element(struct dom_stack *stack, struct dom_node *node, void *data)
|
||||||
|
{
|
||||||
|
struct dom_renderer *renderer = stack->current->data;
|
||||||
|
|
||||||
|
assert(node && renderer && renderer->document);
|
||||||
|
|
||||||
|
switch (node->data.element.type) {
|
||||||
|
case RSS_ELEMENT_CHANNEL:
|
||||||
|
/* The stack should have: #document * channel */
|
||||||
|
if (stack->depth != 3)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!renderer->channel) {
|
||||||
|
renderer->channel = node;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RSS_ELEMENT_ITEM:
|
||||||
|
/* The stack should have: #document * channel item */
|
||||||
|
#if 0
|
||||||
|
/* Don't be so strict ... */
|
||||||
|
if (stack->depth != 4)
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
/* ... but be exclusive. */
|
||||||
|
if (renderer->item)
|
||||||
|
break;
|
||||||
|
add_to_dom_node_list(&renderer->items, node, -1);
|
||||||
|
renderer->item = node;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RSS_ELEMENT_LINK:
|
||||||
|
case RSS_ELEMENT_DESCRIPTION:
|
||||||
|
case RSS_ELEMENT_TITLE:
|
||||||
|
case RSS_ELEMENT_AUTHOR:
|
||||||
|
case RSS_ELEMENT_PUBDATE:
|
||||||
|
if (!node->parent || renderer->node != node->parent)
|
||||||
|
break;
|
||||||
|
|
||||||
|
renderer->node = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dom_rss_pop_element(struct dom_stack *stack, struct dom_node *node, void *data)
|
||||||
|
{
|
||||||
|
struct dom_renderer *renderer = stack->current->data;
|
||||||
|
struct dom_node_list **list;
|
||||||
|
|
||||||
|
assert(node && renderer && renderer->document);
|
||||||
|
|
||||||
|
switch (node->data.element.type) {
|
||||||
|
case RSS_ELEMENT_ITEM:
|
||||||
|
if (is_dom_string_set(&renderer->text))
|
||||||
|
done_dom_string(&renderer->text);
|
||||||
|
renderer->item = NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RSS_ELEMENT_LINK:
|
||||||
|
case RSS_ELEMENT_DESCRIPTION:
|
||||||
|
case RSS_ELEMENT_TITLE:
|
||||||
|
case RSS_ELEMENT_AUTHOR:
|
||||||
|
case RSS_ELEMENT_PUBDATE:
|
||||||
|
if (!is_dom_string_set(&renderer->text)
|
||||||
|
|| !node->parent
|
||||||
|
|| renderer->item != node->parent
|
||||||
|
|| renderer->node != node)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Replace any child nodes with the normalized text node. */
|
||||||
|
list = get_dom_node_list(node->parent, node);
|
||||||
|
done_dom_node_list(*list);
|
||||||
|
if (is_dom_string_set(&renderer->text)) {
|
||||||
|
if (!add_dom_node(node, DOM_NODE_TEXT, &renderer->text))
|
||||||
|
done_dom_string(&renderer->text);
|
||||||
|
}
|
||||||
|
renderer->node = NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dom_rss_push_content(struct dom_stack *stack, struct dom_node *node, void *data)
|
||||||
|
{
|
||||||
|
struct dom_renderer *renderer = stack->current->data;
|
||||||
|
unsigned char *string = node->string.string;
|
||||||
|
int length = node->string.length;
|
||||||
|
|
||||||
|
assert(node && renderer && renderer->document);
|
||||||
|
|
||||||
|
if (!renderer->node)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (node->type == DOM_NODE_ENTITY_REFERENCE) {
|
||||||
|
string -= 1;
|
||||||
|
length += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_dom_string_set(&renderer->text)) {
|
||||||
|
init_dom_string(&renderer->text, string, length);
|
||||||
|
} else {
|
||||||
|
add_to_dom_string(&renderer->text, string, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct dom_string *
|
||||||
|
get_rss_node_text(struct dom_node *node)
|
||||||
|
{
|
||||||
|
struct dom_node *child;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
if (!node->data.element.children)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
foreach_dom_node (node->data.element.children, child, index) {
|
||||||
|
if (child->type == DOM_NODE_TEXT)
|
||||||
|
return &child->string;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct dom_node *
|
||||||
|
get_rss_child(struct dom_node *parent, enum rss_element_type type)
|
||||||
|
{
|
||||||
|
struct dom_node *node;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
if (!parent->data.element.children)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
foreach_dom_node (parent->data.element.children, node, index) {
|
||||||
|
if (node->type == DOM_NODE_ELEMENT
|
||||||
|
&& type == node->data.element.type)
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct dom_string *
|
||||||
|
get_rss_text(struct dom_node *node, enum rss_element_type type)
|
||||||
|
{
|
||||||
|
node = get_rss_child(node, type);
|
||||||
|
|
||||||
|
return node ? get_rss_node_text(node) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
render_rss_item(struct dom_renderer *renderer, struct dom_node *item)
|
||||||
|
{
|
||||||
|
struct dom_string *title = get_rss_text(item, RSS_ELEMENT_TITLE);
|
||||||
|
struct dom_string *link = get_rss_text(item, RSS_ELEMENT_LINK);
|
||||||
|
struct dom_string *author = get_rss_text(item, RSS_ELEMENT_AUTHOR);
|
||||||
|
struct dom_string *date = get_rss_text(item, RSS_ELEMENT_PUBDATE);
|
||||||
|
|
||||||
|
if (title && is_dom_string_set(title)) {
|
||||||
|
if (item == renderer->channel) {
|
||||||
|
unsigned char *str;
|
||||||
|
|
||||||
|
str = convert_string(renderer->convert_table,
|
||||||
|
title->string, title->length,
|
||||||
|
renderer->document->options.cp,
|
||||||
|
CSM_DEFAULT, NULL, NULL, NULL);
|
||||||
|
if (str)
|
||||||
|
renderer->document->title = str;
|
||||||
|
}
|
||||||
|
render_dom_text(renderer, &renderer->styles[DOM_NODE_ELEMENT],
|
||||||
|
title->string, title->length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (link && is_dom_string_set(link)) {
|
||||||
|
X(renderer)++;
|
||||||
|
add_dom_link(renderer, "[link]", 6, link->string, link->length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* New line, and indent */
|
||||||
|
Y(renderer)++;
|
||||||
|
X(renderer) = 0;
|
||||||
|
|
||||||
|
if (author && is_dom_string_set(author)) {
|
||||||
|
render_dom_text(renderer, &renderer->styles[DOM_NODE_COMMENT],
|
||||||
|
author->string, author->length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (date && is_dom_string_set(date)) {
|
||||||
|
if (author && is_dom_string_set(author)) {
|
||||||
|
render_dom_text(renderer, &renderer->styles[DOM_NODE_COMMENT],
|
||||||
|
" - ", 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
render_dom_text(renderer, &renderer->styles[DOM_NODE_COMMENT],
|
||||||
|
date->string, date->length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((author && is_dom_string_set(author))
|
||||||
|
|| (date && is_dom_string_set(date))) {
|
||||||
|
/* New line, and indent */
|
||||||
|
Y(renderer)++;
|
||||||
|
X(renderer) = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dom_rss_pop_document(struct dom_stack *stack, struct dom_node *root, void *data)
|
||||||
|
{
|
||||||
|
struct dom_renderer *renderer = stack->current->data;
|
||||||
|
|
||||||
|
if (!renderer->channel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
render_rss_item(renderer, renderer->channel);
|
||||||
|
|
||||||
|
if (renderer->items) {
|
||||||
|
struct dom_node *node;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
foreach_dom_node (renderer->items, node, index) {
|
||||||
|
Y(renderer)++;
|
||||||
|
X(renderer) = 0;
|
||||||
|
render_rss_item(renderer, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_dom_string_set(&renderer->text))
|
||||||
|
done_dom_string(&renderer->text);
|
||||||
|
mem_free_if(renderer->items);
|
||||||
|
|
||||||
|
done_dom_node(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct dom_stack_context_info dom_rss_renderer_context_info = {
|
||||||
|
/* Object size: */ 0,
|
||||||
|
/* Push: */
|
||||||
|
{
|
||||||
|
/* */ NULL,
|
||||||
|
/* DOM_NODE_ELEMENT */ dom_rss_push_element,
|
||||||
|
/* DOM_NODE_ATTRIBUTE */ NULL,
|
||||||
|
/* DOM_NODE_TEXT */ dom_rss_push_content,
|
||||||
|
/* DOM_NODE_CDATA_SECTION */ dom_rss_push_content,
|
||||||
|
/* DOM_NODE_ENTITY_REFERENCE */ dom_rss_push_content,
|
||||||
|
/* DOM_NODE_ENTITY */ NULL,
|
||||||
|
/* DOM_NODE_PROC_INSTRUCTION */ NULL,
|
||||||
|
/* DOM_NODE_COMMENT */ NULL,
|
||||||
|
/* DOM_NODE_DOCUMENT */ NULL,
|
||||||
|
/* DOM_NODE_DOCUMENT_TYPE */ NULL,
|
||||||
|
/* DOM_NODE_DOCUMENT_FRAGMENT */ NULL,
|
||||||
|
/* DOM_NODE_NOTATION */ NULL,
|
||||||
|
},
|
||||||
|
/* Pop: */
|
||||||
|
{
|
||||||
|
/* */ NULL,
|
||||||
|
/* DOM_NODE_ELEMENT */ dom_rss_pop_element,
|
||||||
|
/* DOM_NODE_ATTRIBUTE */ NULL,
|
||||||
|
/* DOM_NODE_TEXT */ NULL,
|
||||||
|
/* DOM_NODE_CDATA_SECTION */ NULL,
|
||||||
|
/* DOM_NODE_ENTITY_REFERENCE */ NULL,
|
||||||
|
/* DOM_NODE_ENTITY */ NULL,
|
||||||
|
/* DOM_NODE_PROC_INSTRUCTION */ NULL,
|
||||||
|
/* DOM_NODE_COMMENT */ NULL,
|
||||||
|
/* DOM_NODE_DOCUMENT */ dom_rss_pop_document,
|
||||||
|
/* DOM_NODE_DOCUMENT_TYPE */ NULL,
|
||||||
|
/* DOM_NODE_DOCUMENT_FRAGMENT */ NULL,
|
||||||
|
/* DOM_NODE_NOTATION */ NULL,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Shared multiplexor between renderers */
|
/* Shared multiplexor between renderers */
|
||||||
void
|
void
|
||||||
render_dom_document(struct cache_entry *cached, struct document *document,
|
render_dom_document(struct cache_entry *cached, struct document *document,
|
||||||
struct string *buffer)
|
struct string *buffer)
|
||||||
{
|
{
|
||||||
unsigned char *head = empty_string_or_(cached->head);
|
unsigned char *head = empty_string_or_(cached->head);
|
||||||
struct dom_node *root;
|
|
||||||
struct dom_renderer renderer;
|
struct dom_renderer renderer;
|
||||||
struct conv_table *convert_table;
|
struct conv_table *convert_table;
|
||||||
struct sgml_parser *parser;
|
struct sgml_parser *parser;
|
||||||
enum sgml_document_type doctype;
|
enum sgml_document_type doctype;
|
||||||
|
enum sgml_parser_type parser_type;
|
||||||
unsigned char *string = struri(cached->uri);
|
unsigned char *string = struri(cached->uri);
|
||||||
size_t length = strlen(string);
|
size_t length = strlen(string);
|
||||||
struct dom_string uri = INIT_DOM_STRING(string, length);
|
struct dom_string uri = INIT_DOM_STRING(string, length);
|
||||||
struct dom_string source = INIT_DOM_STRING(buffer->source, buffer->length);
|
struct dom_string source = INIT_DOM_STRING(buffer->source, buffer->length);
|
||||||
|
enum sgml_parser_code code;
|
||||||
assert(document->options.plain);
|
|
||||||
|
|
||||||
convert_table = get_convert_table(head, document->options.cp,
|
convert_table = get_convert_table(head, document->options.cp,
|
||||||
document->options.assume_cp,
|
document->options.assume_cp,
|
||||||
@ -687,6 +994,11 @@ render_dom_document(struct cache_entry *cached, struct document *document,
|
|||||||
|
|
||||||
document->bgcolor = document->options.default_bg;
|
document->bgcolor = document->options.default_bg;
|
||||||
|
|
||||||
|
if (document->options.plain)
|
||||||
|
parser_type = SGML_PARSER_STREAM;
|
||||||
|
else
|
||||||
|
parser_type = SGML_PARSER_TREE;
|
||||||
|
|
||||||
/* FIXME: Refactor the doctype lookup. */
|
/* FIXME: Refactor the doctype lookup. */
|
||||||
if (!strcasecmp("application/rss+xml", cached->content_type)) {
|
if (!strcasecmp("application/rss+xml", cached->content_type)) {
|
||||||
doctype = SGML_DOCTYPE_RSS;
|
doctype = SGML_DOCTYPE_RSS;
|
||||||
@ -707,14 +1019,24 @@ render_dom_document(struct cache_entry *cached, struct document *document,
|
|||||||
doctype = SGML_DOCTYPE_HTML;
|
doctype = SGML_DOCTYPE_HTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
parser = init_sgml_parser(SGML_PARSER_STREAM, doctype, &uri);
|
parser = init_sgml_parser(parser_type, doctype, &uri, 0);
|
||||||
if (!parser) return;
|
if (!parser) return;
|
||||||
|
|
||||||
|
if (document->options.plain) {
|
||||||
|
add_dom_stack_context(&parser->stack, &renderer,
|
||||||
|
&dom_source_renderer_context_info);
|
||||||
|
|
||||||
add_dom_stack_context(&parser->stack, &renderer,
|
} else if (doctype == SGML_DOCTYPE_RSS) {
|
||||||
&dom_source_renderer_context_info);
|
add_dom_stack_context(&parser->stack, &renderer,
|
||||||
|
&dom_rss_renderer_context_info);
|
||||||
|
}
|
||||||
|
|
||||||
root = parse_sgml(parser, &source);
|
/* FIXME: When rendering this way we don't really care about the code.
|
||||||
if (root) {
|
* However, it will be useful when we will be able to also
|
||||||
|
* incrementally parse new data. This will require the parser to live
|
||||||
|
* during the fetching of data. */
|
||||||
|
code = parse_sgml(parser, &source, 1);
|
||||||
|
if (parser->root) {
|
||||||
assert(parser->stack.depth == 1);
|
assert(parser->stack.depth == 1);
|
||||||
|
|
||||||
get_dom_stack_top(&parser->stack)->immutable = 0;
|
get_dom_stack_top(&parser->stack)->immutable = 0;
|
||||||
|
@ -114,9 +114,10 @@ struct html_context {
|
|||||||
void *(*special_f)(struct html_context *, enum html_special_type, ...);
|
void *(*special_f)(struct html_context *, enum html_special_type, ...);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define format (((struct html_element *) html_context->stack.next)->attr)
|
#define html_top ((struct html_element *) html_context->stack.next)
|
||||||
#define par_format (((struct html_element *) html_context->stack.next)->parattr)
|
#define html_bottom ((struct html_element *) html_context->stack.prev)
|
||||||
#define html_top (*(struct html_element *) html_context->stack.next)
|
#define format (html_top->attr)
|
||||||
|
#define par_format (html_top->parattr)
|
||||||
|
|
||||||
#define html_is_preformatted() (format.style.attr & AT_PREFORMATTED)
|
#define html_is_preformatted() (format.style.attr & AT_PREFORMATTED)
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ get_target(struct document_options *options, unsigned char *a)
|
|||||||
void
|
void
|
||||||
ln_break(struct html_context *html_context, int n)
|
ln_break(struct html_context *html_context, int n)
|
||||||
{
|
{
|
||||||
if (!n || html_top.invisible) return;
|
if (!n || html_top->invisible) return;
|
||||||
while (n > html_context->line_breax) {
|
while (n > html_context->line_breax) {
|
||||||
html_context->line_breax++;
|
html_context->line_breax++;
|
||||||
html_context->line_break_f(html_context);
|
html_context->line_break_f(html_context);
|
||||||
@ -108,7 +108,7 @@ put_chrs(struct html_context *html_context, unsigned char *start, int len)
|
|||||||
if (html_is_preformatted())
|
if (html_is_preformatted())
|
||||||
html_context->putsp = HTML_SPACE_NORMAL;
|
html_context->putsp = HTML_SPACE_NORMAL;
|
||||||
|
|
||||||
if (!len || html_top.invisible)
|
if (!len || html_top->invisible)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (html_context->putsp) {
|
switch (html_context->putsp) {
|
||||||
@ -258,8 +258,8 @@ html_focusable(struct html_context *html_context, unsigned char *a)
|
|||||||
void
|
void
|
||||||
html_skip(struct html_context *html_context, unsigned char *a)
|
html_skip(struct html_context *html_context, unsigned char *a)
|
||||||
{
|
{
|
||||||
html_top.invisible = 1;
|
html_top->invisible = 1;
|
||||||
html_top.type = ELEMENT_DONT_KILL;
|
html_top->type = ELEMENT_DONT_KILL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -663,10 +663,7 @@ init_html_parser_state(struct html_context *html_context,
|
|||||||
enum html_element_type type,
|
enum html_element_type type,
|
||||||
int align, int margin, int width)
|
int align, int margin, int width)
|
||||||
{
|
{
|
||||||
struct html_element *element;
|
|
||||||
|
|
||||||
html_stack_dup(html_context, type);
|
html_stack_dup(html_context, type);
|
||||||
element = &html_top;
|
|
||||||
|
|
||||||
par_format.align = align;
|
par_format.align = align;
|
||||||
|
|
||||||
@ -677,10 +674,10 @@ init_html_parser_state(struct html_context *html_context,
|
|||||||
par_format.list_level = 0;
|
par_format.list_level = 0;
|
||||||
par_format.list_number = 0;
|
par_format.list_number = 0;
|
||||||
par_format.dd_margin = 0;
|
par_format.dd_margin = 0;
|
||||||
html_top.namelen = 0;
|
html_top->namelen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return element;
|
return html_top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -691,20 +688,20 @@ done_html_parser_state(struct html_context *html_context,
|
|||||||
{
|
{
|
||||||
html_context->line_breax = 1;
|
html_context->line_breax = 1;
|
||||||
|
|
||||||
while (&html_top != element) {
|
while (html_top != element) {
|
||||||
kill_html_stack_item(html_context, &html_top);
|
pop_html_element(html_context);
|
||||||
#if 0
|
#if 0
|
||||||
/* I've preserved this bit to show an example of the Old Code
|
/* I've preserved this bit to show an example of the Old Code
|
||||||
* of the Mikulas days (I _HOPE_ it's by Mikulas, at least ;-).
|
* of the Mikulas days (I _HOPE_ it's by Mikulas, at least ;-).
|
||||||
* I think this assert() can never fail, for one. --pasky */
|
* I think this assert() can never fail, for one. --pasky */
|
||||||
assertm(&html_top && (void *) &html_top != (void *) &html_stack,
|
assertm(html_top && (void *) html_top != (void *) &html_stack,
|
||||||
"html stack trashed");
|
"html stack trashed");
|
||||||
if_assert_failed break;
|
if_assert_failed break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
html_top.type = ELEMENT_KILLABLE;
|
html_top->type = ELEMENT_KILLABLE;
|
||||||
kill_html_stack_item(html_context, &html_top);
|
pop_html_element(html_context);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -777,12 +774,12 @@ init_html_parser(struct uri *uri, struct document_options *options,
|
|||||||
|
|
||||||
par_format.bgcolor = options->default_bg;
|
par_format.bgcolor = options->default_bg;
|
||||||
|
|
||||||
html_top.invisible = 0;
|
html_top->invisible = 0;
|
||||||
html_top.name = NULL;
|
html_top->name = NULL;
|
||||||
html_top.namelen = 0;
|
html_top->namelen = 0;
|
||||||
html_top.options = NULL;
|
html_top->options = NULL;
|
||||||
html_top.linebreak = 1;
|
html_top->linebreak = 1;
|
||||||
html_top.type = ELEMENT_DONT_KILL;
|
html_top->type = ELEMENT_DONT_KILL;
|
||||||
|
|
||||||
html_context->has_link_lines = 0;
|
html_context->has_link_lines = 0;
|
||||||
html_context->table_level = 0;
|
html_context->table_level = 0;
|
||||||
|
@ -254,7 +254,7 @@ html_input_format(struct html_context *html_context, unsigned char *a,
|
|||||||
case FC_HIDDEN:
|
case FC_HIDDEN:
|
||||||
INTERNAL("bad control type");
|
INTERNAL("bad control type");
|
||||||
}
|
}
|
||||||
kill_html_stack_item(html_context, &html_top);
|
pop_html_element(html_context);
|
||||||
put_chrs(html_context, " ", 1);
|
put_chrs(html_context, " ", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,7 +498,7 @@ end_parse:
|
|||||||
for (i = 0; i < max_width; i++)
|
for (i = 0; i < max_width; i++)
|
||||||
put_chrs(html_context, "_", 1);
|
put_chrs(html_context, "_", 1);
|
||||||
|
|
||||||
kill_html_stack_item(html_context, &html_top);
|
pop_html_element(html_context);
|
||||||
put_chrs(html_context, "]", 1);
|
put_chrs(html_context, "]", 1);
|
||||||
html_context->special_f(html_context, SP_CONTROL, fc);
|
html_context->special_f(html_context, SP_CONTROL, fc);
|
||||||
}
|
}
|
||||||
@ -513,7 +513,7 @@ do_html_select_multiple(struct html_context *html_context, unsigned char *a,
|
|||||||
|
|
||||||
if (!al) return;
|
if (!al) return;
|
||||||
html_focusable(html_context, a);
|
html_focusable(html_context, a);
|
||||||
html_top.type = ELEMENT_DONT_KILL;
|
html_top->type = ELEMENT_DONT_KILL;
|
||||||
mem_free_set(&format.select, al);
|
mem_free_set(&format.select, al);
|
||||||
format.select_disabled = has_attr(a, "disabled", html_context->options)
|
format.select_disabled = has_attr(a, "disabled", html_context->options)
|
||||||
? FORM_MODE_DISABLED
|
? FORM_MODE_DISABLED
|
||||||
@ -574,10 +574,10 @@ sp:
|
|||||||
goto se;
|
goto se;
|
||||||
}
|
}
|
||||||
if (parse_element(r, html_context->eoff, &name, &namelen, NULL, &p)) goto sp;
|
if (parse_element(r, html_context->eoff, &name, &namelen, NULL, &p)) goto sp;
|
||||||
|
|
||||||
if (namelen < 6) goto se;
|
if (namelen < 6) goto se;
|
||||||
if (name[0] == '/') name++, namelen--;
|
if (name[0] == '/') name++, namelen--;
|
||||||
|
|
||||||
if (strlcasecmp(name, namelen, "OPTION", 6)
|
if (strlcasecmp(name, namelen, "OPTION", 6)
|
||||||
&& strlcasecmp(name, namelen, "SELECT", 6)
|
&& strlcasecmp(name, namelen, "SELECT", 6)
|
||||||
&& strlcasecmp(name, namelen, "OPTGROUP", 8))
|
&& strlcasecmp(name, namelen, "OPTGROUP", 8))
|
||||||
@ -603,7 +603,7 @@ end_parse:
|
|||||||
format.form = fc;
|
format.form = fc;
|
||||||
format.style.attr |= AT_BOLD;
|
format.style.attr |= AT_BOLD;
|
||||||
put_chrs(html_context, "[ ]", 3);
|
put_chrs(html_context, "[ ]", 3);
|
||||||
kill_html_stack_item(html_context, &html_top);
|
pop_html_element(html_context);
|
||||||
put_chrs(html_context, " ", 1);
|
put_chrs(html_context, " ", 1);
|
||||||
html_context->special_f(html_context, SP_CONTROL, fc);
|
html_context->special_f(html_context, SP_CONTROL, fc);
|
||||||
}
|
}
|
||||||
@ -709,7 +709,7 @@ pp:
|
|||||||
ln_break(html_context, 1);
|
ln_break(html_context, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
kill_html_stack_item(html_context, &html_top);
|
pop_html_element(html_context);
|
||||||
if (rows > 1)
|
if (rows > 1)
|
||||||
ln_break(html_context, 1);
|
ln_break(html_context, 1);
|
||||||
else
|
else
|
||||||
|
@ -141,14 +141,14 @@ html_apply_canvas_bgcolor(struct html_context *html_context)
|
|||||||
/* If there are any CSS twaks regarding bgcolor, make sure we will get
|
/* If there are any CSS twaks regarding bgcolor, make sure we will get
|
||||||
* it _and_ prefer it over bgcolor attribute. */
|
* it _and_ prefer it over bgcolor attribute. */
|
||||||
if (html_context->options->css_enable)
|
if (html_context->options->css_enable)
|
||||||
css_apply(html_context, &html_top, &html_context->css_styles,
|
css_apply(html_context, html_top, &html_context->css_styles,
|
||||||
&html_context->stack);
|
&html_context->stack);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (par_format.bgcolor != format.style.bg) {
|
if (par_format.bgcolor != format.style.bg) {
|
||||||
/* Modify the root HTML element - format_html_part() will take
|
/* Modify the root HTML element - format_html_part() will take
|
||||||
* this from there. */
|
* this from there. */
|
||||||
struct html_element *e = html_context->stack.prev;
|
struct html_element *e = html_bottom;
|
||||||
|
|
||||||
html_context->was_body_background = 1;
|
html_context->was_body_background = 1;
|
||||||
e->parattr.bgcolor = e->attr.style.bg = par_format.bgcolor = format.style.bg;
|
e->parattr.bgcolor = e->attr.style.bg = par_format.bgcolor = format.style.bg;
|
||||||
@ -195,7 +195,7 @@ html_script(struct html_context *html_context, unsigned char *a,
|
|||||||
mem_free(type);
|
mem_free(type);
|
||||||
not_processed:
|
not_processed:
|
||||||
/* Permit nested scripts and retreat. */
|
/* Permit nested scripts and retreat. */
|
||||||
html_top.invisible++;
|
html_top->invisible++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,7 +364,7 @@ html_html(struct html_context *html_context, unsigned char *a,
|
|||||||
|
|
||||||
/* Modify the root HTML element - format_html_part() will take
|
/* Modify the root HTML element - format_html_part() will take
|
||||||
* this from there. */
|
* this from there. */
|
||||||
struct html_element *e = html_context->stack.prev;
|
struct html_element *e = html_bottom;
|
||||||
|
|
||||||
if (par_format.bgcolor != format.style.bg)
|
if (par_format.bgcolor != format.style.bg)
|
||||||
e->parattr.bgcolor = e->attr.style.bg = par_format.bgcolor = format.style.bg;
|
e->parattr.bgcolor = e->attr.style.bg = par_format.bgcolor = format.style.bg;
|
||||||
@ -403,8 +403,8 @@ void
|
|||||||
html_title(struct html_context *html_context, unsigned char *a,
|
html_title(struct html_context *html_context, unsigned char *a,
|
||||||
unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5)
|
unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5)
|
||||||
{
|
{
|
||||||
html_top.invisible = 1;
|
html_top->invisible = 1;
|
||||||
html_top.type = ELEMENT_WEAK;
|
html_top->type = ELEMENT_WEAK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -586,7 +586,7 @@ html_hr(struct html_context *html_context, unsigned char *a,
|
|||||||
}
|
}
|
||||||
html_context->special_f(html_context, SP_NOWRAP, 0);
|
html_context->special_f(html_context, SP_NOWRAP, 0);
|
||||||
ln_break(html_context, 2);
|
ln_break(html_context, 2);
|
||||||
kill_html_stack_item(html_context, &html_top);
|
pop_html_element(html_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -690,7 +690,7 @@ html_ul(struct html_context *html_context, unsigned char *a,
|
|||||||
int_upper_bound(&par_format.leftmargin, par_format.width / 2);
|
int_upper_bound(&par_format.leftmargin, par_format.width / 2);
|
||||||
|
|
||||||
par_format.align = ALIGN_LEFT;
|
par_format.align = ALIGN_LEFT;
|
||||||
html_top.type = ELEMENT_DONT_KILL;
|
html_top->type = ELEMENT_DONT_KILL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -725,7 +725,7 @@ html_ol(struct html_context *html_context, unsigned char *a,
|
|||||||
int_upper_bound(&par_format.leftmargin, par_format.width / 2);
|
int_upper_bound(&par_format.leftmargin, par_format.width / 2);
|
||||||
|
|
||||||
par_format.align = ALIGN_LEFT;
|
par_format.align = ALIGN_LEFT;
|
||||||
html_top.type = ELEMENT_DONT_KILL;
|
html_top->type = ELEMENT_DONT_KILL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
@ -873,10 +873,10 @@ html_dl(struct html_context *html_context, unsigned char *a,
|
|||||||
par_format.list_number = 0;
|
par_format.list_number = 0;
|
||||||
par_format.align = ALIGN_LEFT;
|
par_format.align = ALIGN_LEFT;
|
||||||
par_format.dd_margin = par_format.leftmargin;
|
par_format.dd_margin = par_format.leftmargin;
|
||||||
html_top.type = ELEMENT_DONT_KILL;
|
html_top->type = ELEMENT_DONT_KILL;
|
||||||
if (!(par_format.flags & P_COMPACT)) {
|
if (!(par_format.flags & P_COMPACT)) {
|
||||||
ln_break(html_context, 2);
|
ln_break(html_context, 2);
|
||||||
html_top.linebreak = 2;
|
html_top->linebreak = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -948,14 +948,14 @@ html_frame(struct html_context *html_context, unsigned char *a,
|
|||||||
}
|
}
|
||||||
if (!name) return;
|
if (!name) return;
|
||||||
|
|
||||||
if (!html_context->options->frames || !html_top.frameset) {
|
if (!html_context->options->frames || !html_top->frameset) {
|
||||||
html_focusable(html_context, a);
|
html_focusable(html_context, a);
|
||||||
put_link_line("Frame: ", name, url, "", html_context);
|
put_link_line("Frame: ", name, url, "", html_context);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (html_context->special_f(html_context, SP_USED, NULL)) {
|
if (html_context->special_f(html_context, SP_USED, NULL)) {
|
||||||
html_context->special_f(html_context, SP_FRAME,
|
html_context->special_f(html_context, SP_FRAME,
|
||||||
html_top.frameset, name, url);
|
html_top->frameset, name, url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -997,12 +997,12 @@ html_frameset(struct html_context *html_context, unsigned char *a,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!html_top.frameset) {
|
if (!html_top->frameset) {
|
||||||
width = html_context->options->box.width;
|
width = html_context->options->box.width;
|
||||||
height = html_context->options->box.height;
|
height = html_context->options->box.height;
|
||||||
html_context->options->needs_height = 1;
|
html_context->options->needs_height = 1;
|
||||||
} else {
|
} else {
|
||||||
struct frameset_desc *frameset_desc = html_top.frameset;
|
struct frameset_desc *frameset_desc = html_top->frameset;
|
||||||
int offset;
|
int offset;
|
||||||
|
|
||||||
if (frameset_desc->box.y >= frameset_desc->box.height)
|
if (frameset_desc->box.y >= frameset_desc->box.height)
|
||||||
@ -1020,9 +1020,9 @@ html_frameset(struct html_context *html_context, unsigned char *a,
|
|||||||
parse_frame_widths(rows, height, HTML_FRAME_CHAR_HEIGHT,
|
parse_frame_widths(rows, height, HTML_FRAME_CHAR_HEIGHT,
|
||||||
&fp.height, &fp.y);
|
&fp.height, &fp.y);
|
||||||
|
|
||||||
fp.parent = html_top.frameset;
|
fp.parent = html_top->frameset;
|
||||||
if (fp.x && fp.y) {
|
if (fp.x && fp.y) {
|
||||||
html_top.frameset = html_context->special_f(html_context, SP_FRAMESET, &fp);
|
html_top->frameset = html_context->special_f(html_context, SP_FRAMESET, &fp);
|
||||||
}
|
}
|
||||||
mem_free_if(fp.width);
|
mem_free_if(fp.width);
|
||||||
mem_free_if(fp.height);
|
mem_free_if(fp.height);
|
||||||
|
@ -67,20 +67,20 @@ html_a(struct html_context *html_context, unsigned char *a,
|
|||||||
#ifdef CONFIG_GLOBHIST
|
#ifdef CONFIG_GLOBHIST
|
||||||
} else if (get_global_history_item(format.link)) {
|
} else if (get_global_history_item(format.link)) {
|
||||||
format.style.fg = format.vlink;
|
format.style.fg = format.vlink;
|
||||||
html_top.pseudo_class &= ~ELEMENT_LINK;
|
html_top->pseudo_class &= ~ELEMENT_LINK;
|
||||||
html_top.pseudo_class |= ELEMENT_VISITED;
|
html_top->pseudo_class |= ELEMENT_VISITED;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_BOOKMARKS
|
#ifdef CONFIG_BOOKMARKS
|
||||||
} else if (get_bookmark(format.link)) {
|
} else if (get_bookmark(format.link)) {
|
||||||
format.style.fg = format.bookmark_link;
|
format.style.fg = format.bookmark_link;
|
||||||
html_top.pseudo_class &= ~ELEMENT_VISITED;
|
html_top->pseudo_class &= ~ELEMENT_VISITED;
|
||||||
/* XXX: Really set ELEMENT_LINK? --pasky */
|
/* XXX: Really set ELEMENT_LINK? --pasky */
|
||||||
html_top.pseudo_class |= ELEMENT_LINK;
|
html_top->pseudo_class |= ELEMENT_LINK;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
format.style.fg = format.clink;
|
format.style.fg = format.clink;
|
||||||
html_top.pseudo_class &= ~ELEMENT_VISITED;
|
html_top->pseudo_class &= ~ELEMENT_VISITED;
|
||||||
html_top.pseudo_class |= ELEMENT_LINK;
|
html_top->pseudo_class |= ELEMENT_LINK;
|
||||||
}
|
}
|
||||||
|
|
||||||
mem_free_set(&format.title,
|
mem_free_set(&format.title,
|
||||||
@ -89,7 +89,7 @@ html_a(struct html_context *html_context, unsigned char *a,
|
|||||||
html_focusable(html_context, a);
|
html_focusable(html_context, a);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
kill_html_stack_item(html_context, &html_top);
|
pop_html_element(html_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_fragment_identifier(html_context, a, "name");
|
set_fragment_identifier(html_context, a, "name");
|
||||||
@ -269,7 +269,7 @@ html_img_do(unsigned char *a, unsigned char *object_src,
|
|||||||
* If not, just exit now. */
|
* If not, just exit now. */
|
||||||
if (!options->images && !format.link) {
|
if (!options->images && !format.link) {
|
||||||
mem_free_if(src);
|
mem_free_if(src);
|
||||||
if (usemap) kill_html_stack_item(html_context, &html_top);
|
if (usemap) pop_html_element(html_context);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,7 +332,7 @@ html_img_do(unsigned char *a, unsigned char *object_src,
|
|||||||
|
|
||||||
put_image_label(a, label, html_context);
|
put_image_label(a, label, html_context);
|
||||||
|
|
||||||
if (ismap) kill_html_stack_item(html_context, &html_top);
|
if (ismap) pop_html_element(html_context);
|
||||||
mem_free_set(&format.image, NULL);
|
mem_free_set(&format.image, NULL);
|
||||||
mem_free_set(&format.title, NULL);
|
mem_free_set(&format.title, NULL);
|
||||||
}
|
}
|
||||||
@ -341,7 +341,7 @@ html_img_do(unsigned char *a, unsigned char *object_src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
mem_free_if(src);
|
mem_free_if(src);
|
||||||
if (usemap) kill_html_stack_item(html_context, &html_top);
|
if (usemap) pop_html_element(html_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -369,7 +369,7 @@ put_link_line(unsigned char *prefix, unsigned char *linkname,
|
|||||||
format.style.fg = format.clink;
|
format.style.fg = format.clink;
|
||||||
put_chrs(html_context, linkname, strlen(linkname));
|
put_chrs(html_context, linkname, strlen(linkname));
|
||||||
ln_break(html_context, 1);
|
ln_break(html_context, 1);
|
||||||
kill_html_stack_item(html_context, &html_top);
|
pop_html_element(html_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -714,7 +714,7 @@ next_break:
|
|||||||
|
|
||||||
element:
|
element:
|
||||||
endingtag = *name == '/'; name += endingtag; namelen -= endingtag;
|
endingtag = *name == '/'; name += endingtag; namelen -= endingtag;
|
||||||
if (!endingtag && html_context->putsp == HTML_SPACE_ADD && !html_top.invisible)
|
if (!endingtag && html_context->putsp == HTML_SPACE_ADD && !html_top->invisible)
|
||||||
put_chrs(html_context, " ", 1);
|
put_chrs(html_context, " ", 1);
|
||||||
put_chrs(html_context, base_pos, html - base_pos);
|
put_chrs(html_context, base_pos, html - base_pos);
|
||||||
if (!html_is_preformatted() && !endingtag && html_context->putsp == HTML_SPACE_NORMAL) {
|
if (!html_is_preformatted() && !endingtag && html_context->putsp == HTML_SPACE_NORMAL) {
|
||||||
@ -766,14 +766,14 @@ start_element(struct element_info *ei,
|
|||||||
struct css_selector *selector = NULL;
|
struct css_selector *selector = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (html_top.type == ELEMENT_WEAK) {
|
if (html_top->type == ELEMENT_WEAK) {
|
||||||
kill_html_stack_item(html_context, &html_top);
|
pop_html_element(html_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We try to process nested <script> if we didn't process the parent
|
/* We try to process nested <script> if we didn't process the parent
|
||||||
* one. */
|
* one. */
|
||||||
if (html_top.invisible
|
if (html_top->invisible
|
||||||
&& (ei->func != html_script || html_top.invisible < 2)) {
|
&& (ei->func != html_script || html_top->invisible < 2)) {
|
||||||
ELEMENT_RENDER_PROLOGUE
|
ELEMENT_RENDER_PROLOGUE
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
@ -803,11 +803,14 @@ start_element(struct element_info *ei,
|
|||||||
if (e->type < ELEMENT_KILLABLE) break;
|
if (e->type < ELEMENT_KILLABLE) break;
|
||||||
if (is_block_element(e) || is_inline_element(ei)) break;
|
if (is_block_element(e) || is_inline_element(ei)) break;
|
||||||
}
|
}
|
||||||
} else foreach (e, html_context->stack) {
|
} else {
|
||||||
if (is_block_element(e) && is_inline_element(ei)) break;
|
foreach (e, html_context->stack) {
|
||||||
if (e->type < ELEMENT_KILLABLE) break;
|
if (is_block_element(e) && is_inline_element(ei)) break;
|
||||||
if (!strlcasecmp(e->name, e->namelen, name, namelen)) break;
|
if (e->type < ELEMENT_KILLABLE) break;
|
||||||
|
if (!strlcasecmp(e->name, e->namelen, name, namelen)) break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strlcasecmp(e->name, e->namelen, name, namelen)) {
|
if (!strlcasecmp(e->name, e->namelen, name, namelen)) {
|
||||||
while (e->prev != (void *) &html_context->stack)
|
while (e->prev != (void *) &html_context->stack)
|
||||||
kill_html_stack_item(html_context, e->prev);
|
kill_html_stack_item(html_context, e->prev);
|
||||||
@ -819,10 +822,10 @@ start_element(struct element_info *ei,
|
|||||||
|
|
||||||
if (ei->type != ELEMENT_TYPE_NON_PAIRABLE) {
|
if (ei->type != ELEMENT_TYPE_NON_PAIRABLE) {
|
||||||
html_stack_dup(html_context, ELEMENT_KILLABLE);
|
html_stack_dup(html_context, ELEMENT_KILLABLE);
|
||||||
html_top.name = name;
|
html_top->name = name;
|
||||||
html_top.namelen = namelen;
|
html_top->namelen = namelen;
|
||||||
html_top.options = attr;
|
html_top->options = attr;
|
||||||
html_top.linebreak = ei->linebreak;
|
html_top->linebreak = ei->linebreak;
|
||||||
|
|
||||||
#ifdef CONFIG_ECMASCRIPT
|
#ifdef CONFIG_ECMASCRIPT
|
||||||
if (has_attr(attr, "onClick", html_context->options)) {
|
if (has_attr(attr, "onClick", html_context->options)) {
|
||||||
@ -830,7 +833,7 @@ start_element(struct element_info *ei,
|
|||||||
mem_free_set(&format.link, stracpy("javascript:void(0);"));
|
mem_free_set(&format.link, stracpy("javascript:void(0);"));
|
||||||
mem_free_set(&format.target, stracpy(html_context->base_target));
|
mem_free_set(&format.target, stracpy(html_context->base_target));
|
||||||
format.style.fg = format.clink;
|
format.style.fg = format.clink;
|
||||||
html_top.pseudo_class = ELEMENT_LINK;
|
html_top->pseudo_class = ELEMENT_LINK;
|
||||||
mem_free_set(&format.title, stracpy("onClick placeholder"));
|
mem_free_set(&format.title, stracpy("onClick placeholder"));
|
||||||
/* Er. I know. Well, double html_focusable()s shouldn't
|
/* Er. I know. Well, double html_focusable()s shouldn't
|
||||||
* really hurt. */
|
* really hurt. */
|
||||||
@ -840,7 +843,7 @@ start_element(struct element_info *ei,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_CSS
|
#ifdef CONFIG_CSS
|
||||||
if (html_top.options && html_context->options->css_enable) {
|
if (html_top->options && html_context->options->css_enable) {
|
||||||
/* XXX: We should apply CSS otherwise as well, but that'll need
|
/* XXX: We should apply CSS otherwise as well, but that'll need
|
||||||
* some deeper changes in order to have options filled etc.
|
* some deeper changes in order to have options filled etc.
|
||||||
* Probably just applying CSS from more places, since we
|
* Probably just applying CSS from more places, since we
|
||||||
@ -852,12 +855,12 @@ start_element(struct element_info *ei,
|
|||||||
/* FIXME: The caching of the CSS selector is broken, since t can
|
/* FIXME: The caching of the CSS selector is broken, since t can
|
||||||
* lead to wrong styles being applied to following elements, so
|
* lead to wrong styles being applied to following elements, so
|
||||||
* disabled for now. */
|
* disabled for now. */
|
||||||
selector = get_css_selector_for_element(html_context, &html_top,
|
selector = get_css_selector_for_element(html_context, html_top,
|
||||||
&html_context->css_styles,
|
&html_context->css_styles,
|
||||||
&html_context->stack);
|
&html_context->stack);
|
||||||
|
|
||||||
if (selector) {
|
if (selector) {
|
||||||
apply_css_selector_style(html_context, &html_top, selector);
|
apply_css_selector_style(html_context, html_top, selector);
|
||||||
done_css_selector(selector);
|
done_css_selector(selector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -868,14 +871,14 @@ start_element(struct element_info *ei,
|
|||||||
ELEMENT_RENDER_PROLOGUE
|
ELEMENT_RENDER_PROLOGUE
|
||||||
if (ei->func) ei->func(html_context, attr, html, eof, &html);
|
if (ei->func) ei->func(html_context, attr, html, eof, &html);
|
||||||
#ifdef CONFIG_CSS
|
#ifdef CONFIG_CSS
|
||||||
if (selector && html_top.options) {
|
if (selector && html_top->options) {
|
||||||
/* Call it now to override default colors of the elements. */
|
/* Call it now to override default colors of the elements. */
|
||||||
selector = get_css_selector_for_element(html_context, &html_top,
|
selector = get_css_selector_for_element(html_context, html_top,
|
||||||
&html_context->css_styles,
|
&html_context->css_styles,
|
||||||
&html_context->stack);
|
&html_context->stack);
|
||||||
|
|
||||||
if (selector) {
|
if (selector) {
|
||||||
apply_css_selector_style(html_context, &html_top, selector);
|
apply_css_selector_style(html_context, html_top, selector);
|
||||||
done_css_selector(selector);
|
done_css_selector(selector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -909,7 +912,7 @@ end_element(struct element_info *ei,
|
|||||||
|
|
||||||
/* Apply background color from the <HTML> element. (bug 696) */
|
/* Apply background color from the <HTML> element. (bug 696) */
|
||||||
if (ei->func == html_html
|
if (ei->func == html_html
|
||||||
&& html_top.type >= ELEMENT_KILLABLE
|
&& html_top->type >= ELEMENT_KILLABLE
|
||||||
&& !html_context->was_body_background)
|
&& !html_context->was_body_background)
|
||||||
html_apply_canvas_bgcolor(html_context);
|
html_apply_canvas_bgcolor(html_context);
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ search_html_stack(struct html_context *html_context, unsigned char *name)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
foreach (element, html_context->stack) {
|
foreach (element, html_context->stack) {
|
||||||
if (element == &html_top)
|
if (element == html_top)
|
||||||
continue; /* skip the top element */
|
continue; /* skip the top element */
|
||||||
if (strlcasecmp(element->name, element->namelen, name, namelen))
|
if (strlcasecmp(element->name, element->namelen, name, namelen))
|
||||||
continue;
|
continue;
|
||||||
@ -189,7 +189,7 @@ kill_element(struct html_context *html_context, int ls, struct html_element *e)
|
|||||||
void
|
void
|
||||||
kill_html_stack_until(struct html_context *html_context, int ls, ...)
|
kill_html_stack_until(struct html_context *html_context, int ls, ...)
|
||||||
{
|
{
|
||||||
struct html_element *e = &html_top;
|
struct html_element *e = html_top;
|
||||||
|
|
||||||
if (ls) e = e->next;
|
if (ls) e = e->next;
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@ void html_stack_dup(struct html_context *html_context,
|
|||||||
|
|
||||||
void kill_html_stack_item(struct html_context *html_context,
|
void kill_html_stack_item(struct html_context *html_context,
|
||||||
struct html_element *e);
|
struct html_element *e);
|
||||||
|
#define pop_html_element(html_context) \
|
||||||
|
kill_html_stack_item(html_context, html_top)
|
||||||
void kill_html_stack_until(struct html_context *html_context, int ls, ...);
|
void kill_html_stack_until(struct html_context *html_context, int ls, ...);
|
||||||
|
|
||||||
/* void dump_html_stack(struct html_context *html_context); */
|
/* void dump_html_stack(struct html_context *html_context); */
|
||||||
|
@ -254,7 +254,13 @@ render_encoded_document(struct cache_entry *cached, struct document *document)
|
|||||||
render_plain_document(cached, document, &buffer);
|
render_plain_document(cached, document, &buffer);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
render_html_document(cached, document, &buffer);
|
#ifdef CONFIG_DOM
|
||||||
|
if (cached->content_type
|
||||||
|
&& (!strlcasecmp("application/rss+xml", 19, cached->content_type, -1)))
|
||||||
|
render_dom_document(cached, document, &buffer);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
render_html_document(cached, document, &buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (encoding != ENCODING_NONE) {
|
if (encoding != ENCODING_NONE) {
|
||||||
|
@ -6,7 +6,4 @@ OBJS = node.o select.o stack.o scanner.o
|
|||||||
|
|
||||||
SUBDIRS-$(CONFIG_DEBUG) += test
|
SUBDIRS-$(CONFIG_DEBUG) += test
|
||||||
|
|
||||||
test: all
|
|
||||||
make test -C test
|
|
||||||
|
|
||||||
include $(top_srcdir)/Makefile.lib
|
include $(top_srcdir)/Makefile.lib
|
||||||
|
@ -360,7 +360,7 @@ done_dom_node(struct dom_node *node)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done_dom_node_data(node);
|
done_dom_node_data(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +154,8 @@ init_dom_scanner_info(struct dom_scanner_info *scanner_info)
|
|||||||
|
|
||||||
void
|
void
|
||||||
init_dom_scanner(struct dom_scanner *scanner, struct dom_scanner_info *scanner_info,
|
init_dom_scanner(struct dom_scanner *scanner, struct dom_scanner_info *scanner_info,
|
||||||
struct dom_string *string, int state, int count_lines)
|
struct dom_string *string, int state, int count_lines, int complete,
|
||||||
|
int check_complete, int detect_errors)
|
||||||
{
|
{
|
||||||
if (!scanner_info->initialized) {
|
if (!scanner_info->initialized) {
|
||||||
init_dom_scanner_info(scanner_info);
|
init_dom_scanner_info(scanner_info);
|
||||||
@ -170,6 +171,9 @@ init_dom_scanner(struct dom_scanner *scanner, struct dom_scanner_info *scanner_i
|
|||||||
scanner->info = scanner_info;
|
scanner->info = scanner_info;
|
||||||
scanner->state = state;
|
scanner->state = state;
|
||||||
scanner->count_lines = !!count_lines;
|
scanner->count_lines = !!count_lines;
|
||||||
|
scanner->incomplete = !complete;
|
||||||
|
scanner->check_complete = !!check_complete;
|
||||||
|
scanner->detect_errors = !!detect_errors;
|
||||||
scanner->lineno = scanner->count_lines;
|
scanner->lineno = scanner->count_lines;
|
||||||
scanner->info->scan(scanner);
|
scanner->info->scan(scanner);
|
||||||
}
|
}
|
||||||
|
@ -7,27 +7,32 @@
|
|||||||
/* Define if you want a talking scanner */
|
/* Define if you want a talking scanner */
|
||||||
/* #define DEBUG_DOM_SCANNER */
|
/* #define DEBUG_DOM_SCANNER */
|
||||||
|
|
||||||
/* The {struct dom_scanner_token} describes one scanner state. There are two
|
/** DOM scanner token
|
||||||
* kinds of tokens: char and non-char tokens. Char tokens contains only one
|
*
|
||||||
* char and simply have their char value as type. They are tokens having
|
* This struct describes one scanner state. There are two kinds of tokens: char
|
||||||
* special control meaning in the code, like ':', ';', '{', '}' and '*'. Non
|
* and non-char tokens. Char tokens contains only one char and simply have
|
||||||
* char tokens has one or more chars and contain stuff like number or
|
* their char value as type. They are tokens having special control meaning in
|
||||||
* indentifier strings. */
|
* the code, like ':', ';', '{', '}' and '*'. Non-char tokens have one or more
|
||||||
|
* chars and contain stuff like number or indentifier strings. */
|
||||||
struct dom_scanner_token {
|
struct dom_scanner_token {
|
||||||
/* The type the token */
|
/** The type the token. */
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
/* Some precedence value */
|
/** Some precedence value. */
|
||||||
int precedence;
|
int precedence;
|
||||||
|
|
||||||
/* The start of the token string and the token length */
|
/** The line number; used for error tokens. */
|
||||||
|
unsigned int lineno;
|
||||||
|
|
||||||
|
/** The start of the token string and the token length. */
|
||||||
struct dom_string string;
|
struct dom_string string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Skip the first charector of a token */
|
||||||
#define skip_dom_scanner_token_char(token) \
|
#define skip_dom_scanner_token_char(token) \
|
||||||
do { (token)->string.string++; (token)->string.length--; } while (0)
|
do { (token)->string.string++; (token)->string.length--; } while (0)
|
||||||
|
|
||||||
/* Compare the string of @token with the "static" string in @str. */
|
/** Compare the token string to a "static" string */
|
||||||
#define dom_scanner_token_contains(token, str) \
|
#define dom_scanner_token_contains(token, str) \
|
||||||
((token)->string.length == (sizeof(str) - 1) \
|
((token)->string.length == (sizeof(str) - 1) \
|
||||||
&& !strncasecmp((token)->string.string, str, sizeof(str) - 1))
|
&& !strncasecmp((token)->string.string, str, sizeof(str) - 1))
|
||||||
@ -67,54 +72,72 @@ struct dom_scanner_string_mapping {
|
|||||||
|
|
||||||
struct dom_scanner;
|
struct dom_scanner;
|
||||||
|
|
||||||
|
/** DOM scanner info
|
||||||
|
*
|
||||||
|
* Backend-specific information used during the actual scanning and
|
||||||
|
* by the front end to fill the token table on-demand, etc.
|
||||||
|
*/
|
||||||
struct dom_scanner_info {
|
struct dom_scanner_info {
|
||||||
/* Table containing how to map strings to token types */
|
/** Table containing how to map strings to token types */
|
||||||
const struct dom_scanner_string_mapping *mappings;
|
const struct dom_scanner_string_mapping *mappings;
|
||||||
|
|
||||||
/* Information for how to initialize the scanner table */
|
/** Information for how to initialize the scanner table */
|
||||||
const struct dom_scan_table_info *scan_table_info;
|
const struct dom_scan_table_info *scan_table_info;
|
||||||
|
|
||||||
/* Fills the scanner with tokens. Already scanned tokens which have not
|
/**
|
||||||
|
* Fills the scanner with tokens. Already scanned tokens which have not
|
||||||
* been requested remain and are moved to the start of the scanners
|
* been requested remain and are moved to the start of the scanners
|
||||||
* token table. */
|
* token table. Returns the current token or NULL if there are none. */
|
||||||
/* Returns the current token or NULL if there are none. */
|
|
||||||
struct dom_scanner_token *(*scan)(struct dom_scanner *scanner);
|
struct dom_scanner_token *(*scan)(struct dom_scanner *scanner);
|
||||||
|
|
||||||
/* The scanner table */
|
/**
|
||||||
/* Contains bitmaps for the various characters groups.
|
* The scanner table. Contains bitmaps for the various characters
|
||||||
* Idea sync'ed from mozilla browser. */
|
* groups. Idea sync'ed from mozilla browser. */
|
||||||
int scan_table[DOM_SCAN_TABLE_SIZE];
|
int scan_table[DOM_SCAN_TABLE_SIZE];
|
||||||
|
|
||||||
/* Has the scanner info been initialized? */
|
/** Has the scanner info been initialized? */
|
||||||
unsigned int initialized:1;
|
unsigned int initialized:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Initializes the scanner. */
|
/** Initializes a DOM scanner
|
||||||
|
*
|
||||||
|
* See struct ref:[dom_scanner] for a description of the `int` flags. */
|
||||||
void init_dom_scanner(struct dom_scanner *scanner, struct dom_scanner_info *scanner_info,
|
void init_dom_scanner(struct dom_scanner *scanner, struct dom_scanner_info *scanner_info,
|
||||||
struct dom_string *string, int state, int count_lines);
|
struct dom_string *string, int state, int count_lines, int complete,
|
||||||
|
int check_complete, int detect_error);
|
||||||
|
|
||||||
/* The number of tokens in the scanners token table:
|
/** The number of tokens in the scanners token table
|
||||||
|
*
|
||||||
* At best it should be big enough to contain properties with space separated
|
* At best it should be big enough to contain properties with space separated
|
||||||
* values and function calls with up to 3 variables like rgb(). At worst it
|
* values and function calls with up to 3 variables like rgb(). At worst it
|
||||||
* should be no less than 2 in order to be able to peek at the next token in
|
* should be no less than 2 in order to be able to peek at the next token in
|
||||||
* the scanner. */
|
* the scanner. */
|
||||||
#define DOM_SCANNER_TOKENS 10
|
#define DOM_SCANNER_TOKENS 10
|
||||||
|
|
||||||
/* The {struct dom_scanner} describes the current state of the scanner. */
|
/** DOM scanner
|
||||||
|
*
|
||||||
|
* Holds the current state of the scanner. */
|
||||||
struct dom_scanner {
|
struct dom_scanner {
|
||||||
/* The very start of the scanned string, the position in the string
|
/** The start of the scanned string. */
|
||||||
* where to scan next and the end of the string. If position is NULL it
|
unsigned char *string;
|
||||||
* means that no more tokens can be retrieved from the string. */
|
/** The end of the scanned string. */
|
||||||
unsigned char *string, *position, *end;
|
unsigned char *end;
|
||||||
|
/**
|
||||||
|
* The position in the string where to scan next and the end of the
|
||||||
|
* string. If position is NULL it means that no more tokens can be
|
||||||
|
* retrieved from the string. */
|
||||||
|
unsigned char *position;
|
||||||
|
|
||||||
/* The current token and number of scanned tokens in the table.
|
/**
|
||||||
* If the number of scanned tokens is less than DOM_SCANNER_TOKENS it
|
* The current token. If the number of scanned tokens is less than
|
||||||
* is because there are no more tokens in the string. */
|
* ref:[DOM_SCANNER_TOKENS] it is because there are no more tokens in
|
||||||
|
* the string. */
|
||||||
struct dom_scanner_token *current;
|
struct dom_scanner_token *current;
|
||||||
|
/** The number of scanned tokens left in the table. */
|
||||||
int tokens;
|
int tokens;
|
||||||
|
|
||||||
/* The 'meta' scanner information */
|
/** The 'meta' scanner information */
|
||||||
struct dom_scanner_info *info;
|
struct dom_scanner_info *info;
|
||||||
|
|
||||||
#ifdef DEBUG_SCANNER
|
#ifdef DEBUG_SCANNER
|
||||||
@ -123,19 +146,30 @@ struct dom_scanner {
|
|||||||
int line;
|
int line;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned int count_lines:1;
|
/* The following two flags are used when parsing is incremental and
|
||||||
unsigned int lineno;
|
* the scanner must ensure that only tokens that are complete are
|
||||||
|
* generated. */
|
||||||
|
unsigned int check_complete:1; /*: Only generate complete tokens */
|
||||||
|
unsigned int incomplete:1; /*: The scanned string is incomplete */
|
||||||
|
|
||||||
/* Some state indicator only meaningful to the scanner internals */
|
unsigned int detect_errors:1; /*: Check for markup errors */
|
||||||
|
unsigned int found_error; /*: Did we already report this error? */
|
||||||
|
|
||||||
|
unsigned int count_lines:1; /*: Is line counting enbaled? */
|
||||||
|
unsigned int lineno; /*: Line # of the last scanned token */
|
||||||
|
|
||||||
|
/** Some state indicator only meaningful to the scanner internals */
|
||||||
int state;
|
int state;
|
||||||
|
|
||||||
/* The table contain already scanned tokens. It is maintained in
|
/**
|
||||||
|
* The table contain already scanned tokens. It is maintained in
|
||||||
* order to optimize the scanning a bit and make it possible to look
|
* order to optimize the scanning a bit and make it possible to look
|
||||||
* ahead at the next token. You should always use the accessors
|
* ahead at the next token. You should always use the accessors
|
||||||
* (defined below) for getting tokens from the scanner. */
|
* (defined below) for getting tokens from the scanner. */
|
||||||
struct dom_scanner_token table[DOM_SCANNER_TOKENS];
|
struct dom_scanner_token table[DOM_SCANNER_TOKENS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Check if there are more tokens */
|
||||||
#define dom_scanner_has_tokens(scanner) \
|
#define dom_scanner_has_tokens(scanner) \
|
||||||
((scanner)->tokens > 0 && (scanner)->current < (scanner)->table + (scanner)->tokens)
|
((scanner)->tokens > 0 && (scanner)->current < (scanner)->table + (scanner)->tokens)
|
||||||
|
|
||||||
@ -149,22 +183,24 @@ struct dom_scanner {
|
|||||||
|
|
||||||
/* Scanner table accessors and mutators */
|
/* Scanner table accessors and mutators */
|
||||||
|
|
||||||
/* Checks the type of the next token */
|
/** Check the type of the next token */
|
||||||
#define check_next_dom_scanner_token(scanner, token_type) \
|
#define check_next_dom_scanner_token(scanner, token_type) \
|
||||||
(scanner_has_tokens(scanner) \
|
(scanner_has_tokens(scanner) \
|
||||||
&& ((scanner)->current + 1 < (scanner)->table + (scanner)->tokens) \
|
&& ((scanner)->current + 1 < (scanner)->table + (scanner)->tokens) \
|
||||||
&& (scanner)->current[1].type == (token_type))
|
&& (scanner)->current[1].type == (token_type))
|
||||||
|
|
||||||
/* Access current and next token. Getting the next token might cause
|
/** Get the current token */
|
||||||
* a rescan so any token pointers that has been stored in a local variable
|
|
||||||
* might not be valid after the call. */
|
|
||||||
static inline struct dom_scanner_token *
|
static inline struct dom_scanner_token *
|
||||||
get_dom_scanner_token(struct dom_scanner *scanner)
|
get_dom_scanner_token(struct dom_scanner *scanner)
|
||||||
{
|
{
|
||||||
return dom_scanner_has_tokens(scanner) ? scanner->current : NULL;
|
return dom_scanner_has_tokens(scanner) ? scanner->current : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do a scanning if we do not have also have access to next token. */
|
/** Get the next token
|
||||||
|
*
|
||||||
|
* Getting the next token might cause a rescan so any token pointers that has
|
||||||
|
* been stored in a local variable might not be valid after the call. */
|
||||||
|
/* Do a scanning if we do not also have access to next token. */
|
||||||
static inline struct dom_scanner_token *
|
static inline struct dom_scanner_token *
|
||||||
get_next_dom_scanner_token(struct dom_scanner *scanner)
|
get_next_dom_scanner_token(struct dom_scanner *scanner)
|
||||||
{
|
{
|
||||||
@ -173,16 +209,20 @@ get_next_dom_scanner_token(struct dom_scanner *scanner)
|
|||||||
? scanner->info->scan(scanner) : get_dom_scanner_token(scanner));
|
? scanner->info->scan(scanner) : get_dom_scanner_token(scanner));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This should just make the code more understandable .. hopefully */
|
/** Skip the current token */
|
||||||
#define skip_dom_scanner_token(scanner) get_next_dom_scanner_token(scanner)
|
#define skip_dom_scanner_token(scanner) get_next_dom_scanner_token(scanner)
|
||||||
|
|
||||||
/* Removes tokens from the scanner until it meets a token of the given type.
|
/** Conditionally skip tokens
|
||||||
|
*
|
||||||
|
* Removes tokens from the scanner until it meets a token of the given type.
|
||||||
* This token will then also be skipped. */
|
* This token will then also be skipped. */
|
||||||
struct dom_scanner_token *
|
struct dom_scanner_token *
|
||||||
skip_dom_scanner_tokens(struct dom_scanner *scanner, int skipto, int precedence);
|
skip_dom_scanner_tokens(struct dom_scanner *scanner, int skipto, int precedence);
|
||||||
|
|
||||||
/* Looks up the string from @ident to @end to in the scanners string mapping
|
/** Map a string to internal ID
|
||||||
* table */
|
*
|
||||||
|
* Looks up the string from @ident to @end to in the scanners string mapping
|
||||||
|
* table. */
|
||||||
int
|
int
|
||||||
map_dom_scanner_string(struct dom_scanner *scanner,
|
map_dom_scanner_string(struct dom_scanner *scanner,
|
||||||
unsigned char *ident, unsigned char *end, int base_type);
|
unsigned char *ident, unsigned char *end, int base_type);
|
||||||
|
@ -158,13 +158,13 @@ parse_dom_select_attribute(struct dom_select_node *sel, struct dom_scanner *scan
|
|||||||
|
|
||||||
/* Parse:
|
/* Parse:
|
||||||
*
|
*
|
||||||
* 0n+1 / 1
|
* 0n+1 / 1
|
||||||
* 2n+0 / 2n
|
* 2n+0 / 2n
|
||||||
* 2n+1
|
* 2n+1
|
||||||
* -0n+2
|
* -0n+2
|
||||||
* -0n+1 / -1
|
* -0n+1 / -1
|
||||||
* 1n+0 / n+0 / n
|
* 1n+0 / n+0 / n
|
||||||
* 0n+0
|
* 0n+0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* FIXME: Move somewhere else? dom/scanner.h? */
|
/* FIXME: Move somewhere else? dom/scanner.h? */
|
||||||
@ -391,7 +391,7 @@ parse_dom_select(struct dom_select *select, struct dom_stack *stack,
|
|||||||
struct dom_scanner scanner;
|
struct dom_scanner scanner;
|
||||||
struct dom_select_node sel;
|
struct dom_select_node sel;
|
||||||
|
|
||||||
init_dom_scanner(&scanner, &dom_css_scanner_info, string, 0, 0);
|
init_dom_scanner(&scanner, &dom_css_scanner_info, string, 0, 0, 1, 0, 0);
|
||||||
|
|
||||||
memset(&sel, 0, sizeof(sel));
|
memset(&sel, 0, sizeof(sel));
|
||||||
|
|
||||||
@ -441,8 +441,8 @@ parse_dom_select(struct dom_select *select, struct dom_stack *stack,
|
|||||||
|
|
||||||
sel.node.type = DOM_NODE_ATTRIBUTE;
|
sel.node.type = DOM_NODE_ATTRIBUTE;
|
||||||
sel.match.attribute |= DOM_SELECT_ATTRIBUTE_SPACE_LIST;
|
sel.match.attribute |= DOM_SELECT_ATTRIBUTE_SPACE_LIST;
|
||||||
set_dom_string(&sel.node.string, "class", -1);
|
set_dom_string(&sel.node.string, "class", -1);
|
||||||
copy_dom_string(&sel.node.data.attribute.value, &token->string);
|
copy_dom_string(&sel.node.data.attribute.value, &token->string);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ':':
|
case ':':
|
||||||
@ -530,7 +530,7 @@ init_dom_select(enum dom_select_syntax syntax, struct dom_string *string)
|
|||||||
struct dom_stack stack;
|
struct dom_stack stack;
|
||||||
enum dom_exception_code code;
|
enum dom_exception_code code;
|
||||||
|
|
||||||
init_dom_stack(&stack, DOM_STACK_KEEP_NODES);
|
init_dom_stack(&stack, DOM_STACK_FLAG_NONE);
|
||||||
add_dom_stack_tracer(&stack, "init-select: ");
|
add_dom_stack_tracer(&stack, "init-select: ");
|
||||||
|
|
||||||
code = parse_dom_select(select, &stack, string);
|
code = parse_dom_select(select, &stack, string);
|
||||||
@ -1060,12 +1060,12 @@ select_dom_nodes(struct dom_select *select, struct dom_node *root)
|
|||||||
|
|
||||||
select_data.select = select;;
|
select_data.select = select;;
|
||||||
|
|
||||||
init_dom_stack(&stack, DOM_STACK_KEEP_NODES);
|
init_dom_stack(&stack, DOM_STACK_FLAG_NONE);
|
||||||
add_dom_stack_context(&stack, &select_data,
|
add_dom_stack_context(&stack, &select_data,
|
||||||
&dom_select_context_info);
|
&dom_select_context_info);
|
||||||
add_dom_stack_tracer(&stack, "select-tree: ");
|
add_dom_stack_tracer(&stack, "select-tree: ");
|
||||||
|
|
||||||
init_dom_stack(&select_data.stack, DOM_STACK_KEEP_NODES);
|
init_dom_stack(&select_data.stack, DOM_STACK_FLAG_NONE);
|
||||||
add_dom_stack_context(&select_data.stack, &select_data,
|
add_dom_stack_context(&select_data.stack, &select_data,
|
||||||
&dom_select_data_context_info);
|
&dom_select_data_context_info);
|
||||||
add_dom_stack_tracer(&select_data.stack, "select-match: ");
|
add_dom_stack_tracer(&select_data.stack, "select-match: ");
|
||||||
|
@ -154,7 +154,18 @@ add_sgml_node(struct dom_stack *stack, enum dom_node_type type, struct dom_scann
|
|||||||
|
|
||||||
/* SGML parser main handling: */
|
/* SGML parser main handling: */
|
||||||
|
|
||||||
static inline void
|
static enum sgml_parser_code
|
||||||
|
call_sgml_error_function(struct dom_stack *stack, struct dom_scanner_token *token)
|
||||||
|
{
|
||||||
|
struct sgml_parser *parser = get_sgml_parser(stack);
|
||||||
|
unsigned int line = get_sgml_parser_line_number(parser);
|
||||||
|
|
||||||
|
assert(parser->error_func);
|
||||||
|
|
||||||
|
return parser->error_func(parser, &token->string, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline enum sgml_parser_code
|
||||||
parse_sgml_attributes(struct dom_stack *stack, struct dom_scanner *scanner)
|
parse_sgml_attributes(struct dom_stack *stack, struct dom_scanner *scanner)
|
||||||
{
|
{
|
||||||
struct dom_scanner_token name;
|
struct dom_scanner_token name;
|
||||||
@ -179,22 +190,30 @@ parse_sgml_attributes(struct dom_stack *stack, struct dom_scanner *scanner)
|
|||||||
case SGML_TOKEN_ELEMENT_BEGIN:
|
case SGML_TOKEN_ELEMENT_BEGIN:
|
||||||
case SGML_TOKEN_ELEMENT_END:
|
case SGML_TOKEN_ELEMENT_END:
|
||||||
case SGML_TOKEN_ELEMENT_EMPTY_END:
|
case SGML_TOKEN_ELEMENT_EMPTY_END:
|
||||||
return;
|
return SGML_PARSER_CODE_OK;
|
||||||
|
|
||||||
case SGML_TOKEN_IDENT:
|
case SGML_TOKEN_IDENT:
|
||||||
copy_struct(&name, token);
|
copy_struct(&name, token);
|
||||||
|
|
||||||
/* Skip the attribute name token */
|
/* Skip the attribute name token */
|
||||||
token = get_next_dom_scanner_token(scanner);
|
token = get_next_dom_scanner_token(scanner);
|
||||||
|
|
||||||
if (token && token->type == '=') {
|
if (token && token->type == '=') {
|
||||||
/* If the token is not a valid value token
|
/* If the token is not a valid value token
|
||||||
* ignore it. */
|
* ignore it. */
|
||||||
token = get_next_dom_scanner_token(scanner);
|
token = get_next_dom_scanner_token(scanner);
|
||||||
|
if (token && token->type == SGML_TOKEN_INCOMPLETE)
|
||||||
|
return SGML_PARSER_CODE_INCOMPLETE;
|
||||||
|
|
||||||
if (token
|
if (token
|
||||||
&& token->type != SGML_TOKEN_IDENT
|
&& token->type != SGML_TOKEN_IDENT
|
||||||
&& token->type != SGML_TOKEN_ATTRIBUTE
|
&& token->type != SGML_TOKEN_ATTRIBUTE
|
||||||
&& token->type != SGML_TOKEN_STRING)
|
&& token->type != SGML_TOKEN_STRING)
|
||||||
token = NULL;
|
token = NULL;
|
||||||
|
|
||||||
|
} else if (token && token->type == SGML_TOKEN_INCOMPLETE) {
|
||||||
|
return SGML_PARSER_CODE_INCOMPLETE;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
token = NULL;
|
token = NULL;
|
||||||
}
|
}
|
||||||
@ -206,14 +225,29 @@ parse_sgml_attributes(struct dom_stack *stack, struct dom_scanner *scanner)
|
|||||||
skip_dom_scanner_token(scanner);
|
skip_dom_scanner_token(scanner);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SGML_TOKEN_INCOMPLETE:
|
||||||
|
return SGML_PARSER_CODE_INCOMPLETE;
|
||||||
|
|
||||||
|
case SGML_TOKEN_ERROR:
|
||||||
|
{
|
||||||
|
enum sgml_parser_code code;
|
||||||
|
|
||||||
|
code = call_sgml_error_function(stack, token);
|
||||||
|
if (code != SGML_PARSER_CODE_OK)
|
||||||
|
return code;
|
||||||
|
|
||||||
|
skip_dom_scanner_token(scanner);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
skip_dom_scanner_token(scanner);
|
skip_dom_scanner_token(scanner);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return SGML_PARSER_CODE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static enum sgml_parser_code
|
||||||
parse_sgml_plain(struct dom_stack *stack, struct dom_scanner *scanner)
|
parse_sgml_plain(struct dom_stack *stack, struct dom_scanner *scanner)
|
||||||
{
|
{
|
||||||
struct dom_scanner_token target;
|
struct dom_scanner_token target;
|
||||||
@ -235,7 +269,12 @@ parse_sgml_plain(struct dom_stack *stack, struct dom_scanner *scanner)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (token->type == SGML_TOKEN_ELEMENT_BEGIN) {
|
if (token->type == SGML_TOKEN_ELEMENT_BEGIN) {
|
||||||
parse_sgml_attributes(stack, scanner);
|
enum sgml_parser_code code;
|
||||||
|
|
||||||
|
code = parse_sgml_attributes(stack, scanner);
|
||||||
|
if (code != SGML_PARSER_CODE_OK)
|
||||||
|
return code;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
skip_dom_scanner_token(scanner);
|
skip_dom_scanner_token(scanner);
|
||||||
}
|
}
|
||||||
@ -294,10 +333,16 @@ parse_sgml_plain(struct dom_stack *stack, struct dom_scanner *scanner)
|
|||||||
|
|
||||||
/* Skip the target token */
|
/* Skip the target token */
|
||||||
token = get_next_dom_scanner_token(scanner);
|
token = get_next_dom_scanner_token(scanner);
|
||||||
if (!token) break;
|
if (!token || token->type == SGML_TOKEN_INCOMPLETE)
|
||||||
|
return SGML_PARSER_CODE_INCOMPLETE;
|
||||||
|
|
||||||
|
if (token->type == SGML_TOKEN_ERROR)
|
||||||
|
break;
|
||||||
|
|
||||||
assert(token->type == SGML_TOKEN_PROCESS_DATA);
|
assert(token->type == SGML_TOKEN_PROCESS_DATA);
|
||||||
|
/* Fall-through */
|
||||||
|
|
||||||
|
case SGML_TOKEN_PROCESS_DATA:
|
||||||
if (add_sgml_proc_instruction(stack, &target, token)
|
if (add_sgml_proc_instruction(stack, &target, token)
|
||||||
&& (target.type == SGML_TOKEN_PROCESS_XML
|
&& (target.type == SGML_TOKEN_PROCESS_XML
|
||||||
|| target.type == SGML_TOKEN_PROCESS_XML_STYLESHEET)
|
|| target.type == SGML_TOKEN_PROCESS_XML_STYLESHEET)
|
||||||
@ -305,12 +350,19 @@ parse_sgml_plain(struct dom_stack *stack, struct dom_scanner *scanner)
|
|||||||
/* Parse the <?xml data="attributes"?>. */
|
/* Parse the <?xml data="attributes"?>. */
|
||||||
struct dom_scanner attr_scanner;
|
struct dom_scanner attr_scanner;
|
||||||
|
|
||||||
|
/* The attribute souce is complete. */
|
||||||
init_dom_scanner(&attr_scanner, &sgml_scanner_info,
|
init_dom_scanner(&attr_scanner, &sgml_scanner_info,
|
||||||
&token->string, SGML_STATE_ELEMENT,
|
&token->string, SGML_STATE_ELEMENT,
|
||||||
scanner->count_lines);
|
scanner->count_lines, 1, 0, 0);
|
||||||
|
|
||||||
if (dom_scanner_has_tokens(&attr_scanner))
|
if (dom_scanner_has_tokens(&attr_scanner)) {
|
||||||
|
/* Ignore parser codes from this
|
||||||
|
* enhanced parsing of attributes. It
|
||||||
|
* is really just a simple way to try
|
||||||
|
* and support xml and xml-stylesheet
|
||||||
|
* instructions. */
|
||||||
parse_sgml_attributes(stack, &attr_scanner);
|
parse_sgml_attributes(stack, &attr_scanner);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pop_dom_node(stack);
|
pop_dom_node(stack);
|
||||||
@ -322,6 +374,20 @@ parse_sgml_plain(struct dom_stack *stack, struct dom_scanner *scanner)
|
|||||||
skip_dom_scanner_token(scanner);
|
skip_dom_scanner_token(scanner);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SGML_TOKEN_INCOMPLETE:
|
||||||
|
return SGML_PARSER_CODE_INCOMPLETE;
|
||||||
|
|
||||||
|
case SGML_TOKEN_ERROR:
|
||||||
|
{
|
||||||
|
enum sgml_parser_code code;
|
||||||
|
|
||||||
|
code = call_sgml_error_function(stack, token);
|
||||||
|
if (code != SGML_PARSER_CODE_OK)
|
||||||
|
return code;
|
||||||
|
|
||||||
|
skip_dom_scanner_token(scanner);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case SGML_TOKEN_SPACE:
|
case SGML_TOKEN_SPACE:
|
||||||
case SGML_TOKEN_TEXT:
|
case SGML_TOKEN_TEXT:
|
||||||
default:
|
default:
|
||||||
@ -329,30 +395,34 @@ parse_sgml_plain(struct dom_stack *stack, struct dom_scanner *scanner)
|
|||||||
skip_dom_scanner_token(scanner);
|
skip_dom_scanner_token(scanner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return SGML_PARSER_CODE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dom_node *
|
enum sgml_parser_code
|
||||||
parse_sgml(struct sgml_parser *parser, struct dom_string *buffer)
|
parse_sgml(struct sgml_parser *parser, struct dom_string *buffer, int complete)
|
||||||
{
|
{
|
||||||
struct sgml_parsing_state *parsing;
|
struct sgml_parsing_state *parsing;
|
||||||
|
enum sgml_parser_code code;
|
||||||
|
|
||||||
|
if (complete)
|
||||||
|
parser->flags |= SGML_PARSER_COMPLETE;
|
||||||
|
|
||||||
if (!parser->root) {
|
if (!parser->root) {
|
||||||
parser->root = add_sgml_document(&parser->stack, &parser->uri);
|
parser->root = add_sgml_document(&parser->stack, &parser->uri);
|
||||||
if (!parser->root)
|
if (!parser->root)
|
||||||
return NULL;
|
return SGML_PARSER_CODE_MEM_ALLOC;
|
||||||
get_dom_stack_top(&parser->stack)->immutable = 1;
|
get_dom_stack_top(&parser->stack)->immutable = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
parsing = init_sgml_parsing_state(parser, buffer);
|
parsing = init_sgml_parsing_state(parser, buffer);
|
||||||
if (!parsing) return NULL;
|
if (!parsing) return SGML_PARSER_CODE_MEM_ALLOC;
|
||||||
|
|
||||||
/* FIXME: Make parse_sgml_plain() return something (error code or if
|
code = parse_sgml_plain(&parser->stack, &parsing->scanner);
|
||||||
* can be guarenteed a root node). */
|
|
||||||
parse_sgml_plain(&parser->stack, &parsing->scanner);
|
|
||||||
|
|
||||||
pop_dom_node(&parser->parsing);
|
pop_dom_node(&parser->parsing);
|
||||||
|
|
||||||
return parser->root;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -368,11 +438,16 @@ sgml_parsing_push(struct dom_stack *stack, struct dom_node *node, void *data)
|
|||||||
{
|
{
|
||||||
struct sgml_parser *parser = get_sgml_parser(stack);
|
struct sgml_parser *parser = get_sgml_parser(stack);
|
||||||
struct sgml_parsing_state *parsing = data;
|
struct sgml_parsing_state *parsing = data;
|
||||||
|
int count_lines = !!(parser->flags & SGML_PARSER_COUNT_LINES);
|
||||||
|
int complete = !!(parser->flags & SGML_PARSER_COMPLETE);
|
||||||
|
int incremental = !!(parser->flags & SGML_PARSER_INCREMENTAL);
|
||||||
|
int detect_errors = !!(parser->flags & SGML_PARSER_DETECT_ERRORS);
|
||||||
|
|
||||||
parsing->depth = parser->stack.depth;
|
parsing->depth = parser->stack.depth;
|
||||||
get_dom_stack_top(&parser->stack)->immutable = 1;
|
get_dom_stack_top(&parser->stack)->immutable = 1;
|
||||||
init_dom_scanner(&parsing->scanner, &sgml_scanner_info, &node->string,
|
init_dom_scanner(&parsing->scanner, &sgml_scanner_info, &node->string,
|
||||||
SGML_STATE_TEXT, 0);
|
SGML_STATE_TEXT, count_lines, complete, incremental,
|
||||||
|
detect_errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -443,6 +518,30 @@ init_sgml_parsing_state(struct sgml_parser *parser, struct dom_string *buffer)
|
|||||||
return get_dom_stack_state_data(parser->parsing.contexts[0], state);
|
return get_dom_stack_state_data(parser->parsing.contexts[0], state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
get_sgml_parser_line_number(struct sgml_parser *parser)
|
||||||
|
{
|
||||||
|
struct dom_stack_state *state;
|
||||||
|
struct sgml_parsing_state *pstate;
|
||||||
|
|
||||||
|
assert(parser->flags & SGML_PARSER_COUNT_LINES);
|
||||||
|
|
||||||
|
if (dom_stack_is_empty(&parser->parsing))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
state = get_dom_stack_top(&parser->parsing);
|
||||||
|
pstate = get_dom_stack_state_data(parser->parsing.contexts[0], state);
|
||||||
|
|
||||||
|
assert(pstate->scanner.count_lines && pstate->scanner.lineno);
|
||||||
|
|
||||||
|
if (pstate->scanner.current
|
||||||
|
&& pstate->scanner.current < pstate->scanner.table + DOM_SCANNER_TOKENS
|
||||||
|
&& pstate->scanner.current->type == SGML_TOKEN_ERROR)
|
||||||
|
return pstate->scanner.current->lineno;
|
||||||
|
|
||||||
|
return pstate->scanner.lineno;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Parser creation and destruction: */
|
/* Parser creation and destruction: */
|
||||||
|
|
||||||
@ -486,10 +585,10 @@ static struct dom_stack_context_info sgml_parser_context_info = {
|
|||||||
|
|
||||||
struct sgml_parser *
|
struct sgml_parser *
|
||||||
init_sgml_parser(enum sgml_parser_type type, enum sgml_document_type doctype,
|
init_sgml_parser(enum sgml_parser_type type, enum sgml_document_type doctype,
|
||||||
struct dom_string *uri)
|
struct dom_string *uri, enum sgml_parser_flag flags)
|
||||||
{
|
{
|
||||||
struct sgml_parser *parser;
|
struct sgml_parser *parser;
|
||||||
enum dom_stack_flag flags = 0;
|
enum dom_stack_flag stack_flags = 0;
|
||||||
|
|
||||||
parser = mem_calloc(1, sizeof(*parser));
|
parser = mem_calloc(1, sizeof(*parser));
|
||||||
if (!parser) return NULL;
|
if (!parser) return NULL;
|
||||||
@ -499,19 +598,23 @@ init_sgml_parser(enum sgml_parser_type type, enum sgml_document_type doctype,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
parser->type = type;
|
if (flags & SGML_PARSER_DETECT_ERRORS)
|
||||||
parser->info = get_sgml_info(doctype);
|
flags |= SGML_PARSER_COUNT_LINES;
|
||||||
|
|
||||||
if (type == SGML_PARSER_TREE)
|
parser->type = type;
|
||||||
flags |= DOM_STACK_KEEP_NODES;
|
parser->flags = flags;
|
||||||
|
parser->info = get_sgml_info(doctype);
|
||||||
|
|
||||||
init_dom_stack(&parser->stack, flags);
|
if (type == SGML_PARSER_STREAM)
|
||||||
|
stack_flags |= DOM_STACK_FLAG_FREE_NODES;
|
||||||
|
|
||||||
|
init_dom_stack(&parser->stack, stack_flags);
|
||||||
/* FIXME: Some sgml backend specific callbacks? Handle HTML script tags,
|
/* FIXME: Some sgml backend specific callbacks? Handle HTML script tags,
|
||||||
* and feed document.write() data back to the parser. */
|
* and feed document.write() data back to the parser. */
|
||||||
add_dom_stack_context(&parser->stack, parser, &sgml_parser_context_info);
|
add_dom_stack_context(&parser->stack, parser, &sgml_parser_context_info);
|
||||||
|
|
||||||
/* Don't keep the 'fake' text nodes that holds the parsing data. */
|
/* Don't keep the 'fake' text nodes that holds the parsing data. */
|
||||||
init_dom_stack(&parser->parsing, 0);
|
init_dom_stack(&parser->parsing, DOM_STACK_FLAG_FREE_NODES);
|
||||||
add_dom_stack_context(&parser->parsing, parser, &sgml_parsing_context_info);
|
add_dom_stack_context(&parser->parsing, parser, &sgml_parsing_context_info);
|
||||||
|
|
||||||
return parser;
|
return parser;
|
||||||
|
@ -7,49 +7,150 @@
|
|||||||
#include "dom/sgml/sgml.h"
|
#include "dom/sgml/sgml.h"
|
||||||
#include "dom/scanner.h"
|
#include "dom/scanner.h"
|
||||||
|
|
||||||
|
struct sgml_parser;
|
||||||
struct string;
|
struct string;
|
||||||
struct uri;
|
struct uri;
|
||||||
|
|
||||||
|
/** SGML parser type
|
||||||
|
*
|
||||||
|
* There are two kinds of parser types: One that optimises one-time access to
|
||||||
|
* the DOM tree and one that creates a persistent DOM tree. */
|
||||||
enum sgml_parser_type {
|
enum sgml_parser_type {
|
||||||
/* The first one is a DOM tree builder. */
|
/**
|
||||||
SGML_PARSER_TREE,
|
* The first one will simply push nodes on the stack, not building a
|
||||||
/* The second one will simply push nodes on the stack, not building a
|
|
||||||
* DOM tree. This interface is similar to that of SAX (Simple API for
|
* DOM tree. This interface is similar to that of SAX (Simple API for
|
||||||
* XML) where events are fired when nodes are entered and exited. It is
|
* XML) where events are fired when nodes are entered and exited. It is
|
||||||
* useful when you are not actually interested in the DOM tree, but can
|
* useful when you are not actually interested in the DOM tree, but can
|
||||||
* do all processing in a stream-like manner, such as when highlighting
|
* do all processing in a stream-like manner, such as when highlighting
|
||||||
* HTML code. */
|
* HTML code. */
|
||||||
SGML_PARSER_STREAM,
|
SGML_PARSER_STREAM,
|
||||||
|
/**
|
||||||
|
* The second one is a DOM tree builder, that builds a persistent DOM
|
||||||
|
* tree. When using this type, it is possible to do even more
|
||||||
|
* (pre)processing than for parser streams. For example you can sort
|
||||||
|
* element child nodes, or purge various node such as text nodes that
|
||||||
|
* only contain space characters. */
|
||||||
|
SGML_PARSER_TREE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** SGML parser flags
|
||||||
|
*
|
||||||
|
* These flags control how the parser behaves.
|
||||||
|
*/
|
||||||
|
enum sgml_parser_flag {
|
||||||
|
SGML_PARSER_COUNT_LINES = 1, /*: Make line numbers available. */
|
||||||
|
SGML_PARSER_COMPLETE = 2, /*: Used internally when incremental. */
|
||||||
|
SGML_PARSER_INCREMENTAL = 4, /*: Parse chunks of input. */
|
||||||
|
SGML_PARSER_DETECT_ERRORS = 8, /*: Report errors. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/** SGML parser state
|
||||||
|
*
|
||||||
|
* The SGML parser has only little state.
|
||||||
|
*/
|
||||||
struct sgml_parser_state {
|
struct sgml_parser_state {
|
||||||
/* Info about the properties of the node contained by state.
|
/**
|
||||||
|
* Info about the properties of the node contained by state.
|
||||||
* This is only meaningful to element and attribute nodes. For
|
* This is only meaningful to element and attribute nodes. For
|
||||||
* unknown nodes it points to the common 'unknown node' info. */
|
* unknown nodes it points to the common 'unknown node' info. */
|
||||||
struct sgml_node_info *info;
|
struct sgml_node_info *info;
|
||||||
/* This is used by the DOM source renderer for highlighting the
|
/**
|
||||||
|
* This is used by the DOM source renderer for highlighting the
|
||||||
* end-tag of an element. */
|
* end-tag of an element. */
|
||||||
struct dom_scanner_token end_token;
|
struct dom_scanner_token end_token;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sgml_parser {
|
/** (Error) codes for the SGML parser
|
||||||
enum sgml_parser_type type; /* Stream or tree */
|
*
|
||||||
|
* These enum values are used for return codes.
|
||||||
struct sgml_info *info; /* Backend dependent info */
|
*/
|
||||||
|
enum sgml_parser_code {
|
||||||
struct dom_string uri; /* The URI of the DOM document */
|
SGML_PARSER_CODE_OK, /*: The parsing was successful */
|
||||||
struct dom_node *root; /* The document root node */
|
SGML_PARSER_CODE_INCOMPLETE, /*: The parsing could not be completed */
|
||||||
|
SGML_PARSER_CODE_MEM_ALLOC, /*: Failed to allocate memory */
|
||||||
struct dom_stack stack; /* A stack for tracking parsed nodes */
|
/**
|
||||||
struct dom_stack parsing; /* Used for tracking parsing states */
|
* FIXME: For when we will add support for requiring stricter parsing
|
||||||
|
* or even a validator. */
|
||||||
|
SGML_PARSER_CODE_ERROR,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** SGML error callback
|
||||||
|
*
|
||||||
|
* Called by the SGML parser when a parsing error has occurred.
|
||||||
|
*
|
||||||
|
* If the return code is not ref:[SGML_PARSER_CODE_OK] the parsing will be
|
||||||
|
* ended and that code will be returned. */
|
||||||
|
typedef enum sgml_parser_code
|
||||||
|
(*sgml_error_T)(struct sgml_parser *, struct dom_string *, unsigned int);
|
||||||
|
|
||||||
|
|
||||||
|
/** The SGML parser
|
||||||
|
*
|
||||||
|
* This struct hold info used while parsing SGML data.
|
||||||
|
*
|
||||||
|
* NOTE: The only variable the user should set is ref:[sgml_parser.error_func].
|
||||||
|
*/
|
||||||
|
struct sgml_parser {
|
||||||
|
enum sgml_parser_type type; /*: Stream or tree */
|
||||||
|
enum sgml_parser_flag flags; /*: Flags that control the behaviour */
|
||||||
|
|
||||||
|
struct sgml_info *info; /*: Backend dependent info */
|
||||||
|
|
||||||
|
struct dom_string uri; /*: The URI of the DOM document */
|
||||||
|
struct dom_node *root; /*: The document root node */
|
||||||
|
|
||||||
|
sgml_error_T error_func; /*: Called for detected errors */
|
||||||
|
|
||||||
|
struct dom_stack stack; /*: A stack for tracking parsed nodes */
|
||||||
|
struct dom_stack parsing; /*: Used for tracking parsing states */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** Initialise an SGML parser
|
||||||
|
*
|
||||||
|
* Initialise an SGML parser with the given properties.
|
||||||
|
*
|
||||||
|
* type:: Stream or tree; one-time or persistant.
|
||||||
|
* doctype:: The document type, this affects what sub type nodes are given.
|
||||||
|
* uri:: The URI of the document root.
|
||||||
|
* flags:: Flags controlling the behaviour of the parser.
|
||||||
|
*
|
||||||
|
* Returns the created parser or NULL.
|
||||||
|
*/
|
||||||
struct sgml_parser *
|
struct sgml_parser *
|
||||||
init_sgml_parser(enum sgml_parser_type type, enum sgml_document_type doctype,
|
init_sgml_parser(enum sgml_parser_type type, enum sgml_document_type doctype,
|
||||||
struct dom_string *uri);
|
struct dom_string *uri, enum sgml_parser_flag flags);
|
||||||
|
|
||||||
|
/** Release an SGML parser
|
||||||
|
*
|
||||||
|
* Deallocates all resources, _expect_ the root node.
|
||||||
|
*
|
||||||
|
* parser:: The parser being released.
|
||||||
|
*/
|
||||||
void done_sgml_parser(struct sgml_parser *parser);
|
void done_sgml_parser(struct sgml_parser *parser);
|
||||||
|
|
||||||
struct dom_node *parse_sgml(struct sgml_parser *parser, struct dom_string *buffer);
|
/** Parse a chunk of SGML source
|
||||||
|
*
|
||||||
|
* Parses the given `buffer`. For incremental rendering the last buffer can be
|
||||||
|
* signals through the `complete` parameter.
|
||||||
|
*
|
||||||
|
* parser:: A parser created with ref:[init_sgml_parser].
|
||||||
|
* buffer:: A string containing the chunk to parse.
|
||||||
|
* complete:: Whether this is the last chunk to parse.
|
||||||
|
*
|
||||||
|
* The returned code is ref:[SGML_PARSER_CODE_OK] if the buffer was
|
||||||
|
* successfully parserd, else a code hinting at the error.
|
||||||
|
*/
|
||||||
|
enum sgml_parser_code
|
||||||
|
parse_sgml(struct sgml_parser *parser, struct dom_string *buffer, int complete);
|
||||||
|
|
||||||
|
/** Get the line position in the source
|
||||||
|
*
|
||||||
|
* Returns what line number the parser is currently at or zero if there has
|
||||||
|
* been no parsing yet.
|
||||||
|
*
|
||||||
|
* NOTE: Line numbers are recorded in the scanner tokens.
|
||||||
|
*/
|
||||||
|
unsigned int get_sgml_parser_line_number(struct sgml_parser *parser);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -98,6 +98,104 @@ skip_sgml_space(struct dom_scanner *scanner, unsigned char **string)
|
|||||||
*string = pos;
|
*string = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define check_sgml_incomplete(scanner, string) \
|
||||||
|
((scanner)->check_complete \
|
||||||
|
&& (scanner)->incomplete \
|
||||||
|
&& (string) == (scanner)->end)
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_sgml_incomplete(struct dom_scanner *scanner, struct dom_scanner_token *token)
|
||||||
|
{
|
||||||
|
size_t left = scanner->end - scanner->position;
|
||||||
|
|
||||||
|
assert(left > 0);
|
||||||
|
|
||||||
|
token->type = SGML_TOKEN_INCOMPLETE;
|
||||||
|
set_dom_string(&token->string, scanner->position, left);
|
||||||
|
|
||||||
|
/* Stop the scanning. */
|
||||||
|
scanner->position = scanner->end;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
check_sgml_error(struct dom_scanner *scanner)
|
||||||
|
{
|
||||||
|
unsigned int found_error = scanner->found_error;
|
||||||
|
|
||||||
|
/* Toggle if we found an error previously. */
|
||||||
|
scanner->found_error = 0;
|
||||||
|
|
||||||
|
return scanner->detect_errors && !found_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned char *
|
||||||
|
get_sgml_error_end(struct dom_scanner *scanner, enum sgml_token_type type,
|
||||||
|
unsigned char *end)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case SGML_TOKEN_CDATA_SECTION:
|
||||||
|
case SGML_TOKEN_NOTATION_ATTLIST:
|
||||||
|
case SGML_TOKEN_NOTATION_DOCTYPE:
|
||||||
|
case SGML_TOKEN_NOTATION_ELEMENT:
|
||||||
|
if (scanner->position + 9 < end)
|
||||||
|
end = scanner->position + 9;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SGML_TOKEN_NOTATION_COMMENT:
|
||||||
|
/* Just include the '<!--' part. */
|
||||||
|
if (scanner->position + 4 < end)
|
||||||
|
end = scanner->position + 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SGML_TOKEN_NOTATION_ENTITY:
|
||||||
|
if (scanner->position + 6 < end)
|
||||||
|
end = scanner->position + 6;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SGML_TOKEN_PROCESS_XML:
|
||||||
|
if (scanner->position + 5 < end)
|
||||||
|
end = scanner->position + 5;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SGML_TOKEN_PROCESS_XML_STYLESHEET:
|
||||||
|
if (scanner->position + 16 < end)
|
||||||
|
end = scanner->position + 16;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct dom_scanner_token *
|
||||||
|
set_sgml_error(struct dom_scanner *scanner, unsigned char *end)
|
||||||
|
{
|
||||||
|
struct dom_scanner_token *token = scanner->current;
|
||||||
|
struct dom_scanner_token *next;
|
||||||
|
|
||||||
|
assert(!scanner->found_error);
|
||||||
|
|
||||||
|
if (scanner->current >= scanner->table + DOM_SCANNER_TOKENS) {
|
||||||
|
scanner->found_error = 1;
|
||||||
|
next = NULL;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
scanner->current++;
|
||||||
|
next = scanner->current;
|
||||||
|
copy_struct(next, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
token->type = SGML_TOKEN_ERROR;
|
||||||
|
token->lineno = scanner->lineno;
|
||||||
|
set_dom_string(&token->string, scanner->position, end - scanner->position);
|
||||||
|
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Text token scanning */
|
/* Text token scanning */
|
||||||
|
|
||||||
@ -119,6 +217,8 @@ scan_sgml_text_token(struct dom_scanner *scanner, struct dom_scanner_token *toke
|
|||||||
token->string.string = string++;
|
token->string.string = string++;
|
||||||
|
|
||||||
if (first_char == '&') {
|
if (first_char == '&') {
|
||||||
|
int complete = 0;
|
||||||
|
|
||||||
if (is_sgml_entity(*string)) {
|
if (is_sgml_entity(*string)) {
|
||||||
scan_sgml(scanner, string, SGML_CHAR_ENTITY);
|
scan_sgml(scanner, string, SGML_CHAR_ENTITY);
|
||||||
type = SGML_TOKEN_ENTITY;
|
type = SGML_TOKEN_ENTITY;
|
||||||
@ -128,13 +228,32 @@ scan_sgml_text_token(struct dom_scanner *scanner, struct dom_scanner_token *toke
|
|||||||
|
|
||||||
foreach_sgml_cdata (scanner, string) {
|
foreach_sgml_cdata (scanner, string) {
|
||||||
if (*string == ';') {
|
if (*string == ';') {
|
||||||
|
complete = 1;
|
||||||
string++;
|
string++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We want the biggest possible text token. */
|
||||||
|
if (!complete) {
|
||||||
|
if (check_sgml_incomplete(scanner, string)) {
|
||||||
|
set_sgml_incomplete(scanner, token);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_sgml_error(scanner)) {
|
||||||
|
token = set_sgml_error(scanner, string);
|
||||||
|
if (!token)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (is_sgml_space(first_char)) {
|
if (is_sgml_space(first_char)) {
|
||||||
|
if (scanner->count_lines
|
||||||
|
&& is_sgml_newline(first_char))
|
||||||
|
scanner->lineno++;
|
||||||
|
|
||||||
skip_sgml_space(scanner, &string);
|
skip_sgml_space(scanner, &string);
|
||||||
type = string < scanner->end && is_sgml_text(*string)
|
type = string < scanner->end && is_sgml_text(*string)
|
||||||
? SGML_TOKEN_TEXT : SGML_TOKEN_SPACE;
|
? SGML_TOKEN_TEXT : SGML_TOKEN_SPACE;
|
||||||
@ -142,8 +261,21 @@ scan_sgml_text_token(struct dom_scanner *scanner, struct dom_scanner_token *toke
|
|||||||
type = SGML_TOKEN_TEXT;
|
type = SGML_TOKEN_TEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach_sgml_cdata (scanner, string) {
|
if (scanner->count_lines) {
|
||||||
/* m33p */;
|
foreach_sgml_cdata (scanner, string) {
|
||||||
|
if (is_sgml_newline(*string))
|
||||||
|
scanner->lineno++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foreach_sgml_cdata (scanner, string) {
|
||||||
|
/* m33p */;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We want the biggest possible text token. */
|
||||||
|
if (check_sgml_incomplete(scanner, string)) {
|
||||||
|
set_sgml_incomplete(scanner, token);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +358,8 @@ skip_sgml(struct dom_scanner *scanner, unsigned char **string, unsigned char ski
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
skip_sgml_comment(struct dom_scanner *scanner, unsigned char **string)
|
skip_sgml_comment(struct dom_scanner *scanner, unsigned char **string,
|
||||||
|
int *possibly_incomplete)
|
||||||
{
|
{
|
||||||
unsigned char *pos = *string;
|
unsigned char *pos = *string;
|
||||||
int length = 0;
|
int length = 0;
|
||||||
@ -238,6 +371,7 @@ skip_sgml_comment(struct dom_scanner *scanner, unsigned char **string)
|
|||||||
* preceeding '-'. */
|
* preceeding '-'. */
|
||||||
if (pos[-2] == '-' && pos[-1] == '-' && &pos[-2] >= *string) {
|
if (pos[-2] == '-' && pos[-1] == '-' && &pos[-2] >= *string) {
|
||||||
length = pos - *string - 2;
|
length = pos - *string - 2;
|
||||||
|
*possibly_incomplete = 0;
|
||||||
pos++;
|
pos++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -245,6 +379,9 @@ skip_sgml_comment(struct dom_scanner *scanner, unsigned char **string)
|
|||||||
|
|
||||||
if (!pos) {
|
if (!pos) {
|
||||||
pos = scanner->end;
|
pos = scanner->end;
|
||||||
|
/* The token is incomplete but set the length to handle tag
|
||||||
|
* tag soup graciously. */
|
||||||
|
*possibly_incomplete = 1;
|
||||||
length = pos - *string;
|
length = pos - *string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,7 +390,8 @@ skip_sgml_comment(struct dom_scanner *scanner, unsigned char **string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
skip_sgml_cdata_section(struct dom_scanner *scanner, unsigned char **string)
|
skip_sgml_cdata_section(struct dom_scanner *scanner, unsigned char **string,
|
||||||
|
int *possibly_incomplete)
|
||||||
{
|
{
|
||||||
unsigned char *pos = *string;
|
unsigned char *pos = *string;
|
||||||
int length = 0;
|
int length = 0;
|
||||||
@ -263,6 +401,7 @@ skip_sgml_cdata_section(struct dom_scanner *scanner, unsigned char **string)
|
|||||||
* are supposed to have '<![CDATA[' before this is called. */
|
* are supposed to have '<![CDATA[' before this is called. */
|
||||||
if (pos[-2] == ']' && pos[-1] == ']') {
|
if (pos[-2] == ']' && pos[-1] == ']') {
|
||||||
length = pos - *string - 2;
|
length = pos - *string - 2;
|
||||||
|
*possibly_incomplete = 0;
|
||||||
pos++;
|
pos++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -270,6 +409,9 @@ skip_sgml_cdata_section(struct dom_scanner *scanner, unsigned char **string)
|
|||||||
|
|
||||||
if (!pos) {
|
if (!pos) {
|
||||||
pos = scanner->end;
|
pos = scanner->end;
|
||||||
|
/* The token is incomplete but set the length to handle tag
|
||||||
|
* soup graciously. */
|
||||||
|
*possibly_incomplete = 1;
|
||||||
length = pos - *string;
|
length = pos - *string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,6 +430,7 @@ scan_sgml_element_token(struct dom_scanner *scanner, struct dom_scanner_token *t
|
|||||||
unsigned char first_char = *string;
|
unsigned char first_char = *string;
|
||||||
enum sgml_token_type type = SGML_TOKEN_GARBAGE;
|
enum sgml_token_type type = SGML_TOKEN_GARBAGE;
|
||||||
int real_length = -1;
|
int real_length = -1;
|
||||||
|
int possibly_incomplete = 1;
|
||||||
|
|
||||||
token->string.string = string++;
|
token->string.string = string++;
|
||||||
|
|
||||||
@ -302,6 +445,9 @@ scan_sgml_element_token(struct dom_scanner *scanner, struct dom_scanner_token *t
|
|||||||
type = SGML_TOKEN_TAG_END;
|
type = SGML_TOKEN_TAG_END;
|
||||||
scanner->state = SGML_STATE_TEXT;
|
scanner->state = SGML_STATE_TEXT;
|
||||||
|
|
||||||
|
/* We are creating a 'virtual' that has no source. */
|
||||||
|
possibly_incomplete = 0;
|
||||||
|
|
||||||
} else if (is_sgml_ident(*string)) {
|
} else if (is_sgml_ident(*string)) {
|
||||||
token->string.string = string;
|
token->string.string = string;
|
||||||
scan_sgml(scanner, string, SGML_CHAR_IDENT);
|
scan_sgml(scanner, string, SGML_CHAR_IDENT);
|
||||||
@ -312,7 +458,16 @@ scan_sgml_element_token(struct dom_scanner *scanner, struct dom_scanner_token *t
|
|||||||
if (*string == '>') {
|
if (*string == '>') {
|
||||||
type = SGML_TOKEN_ELEMENT;
|
type = SGML_TOKEN_ELEMENT;
|
||||||
string++;
|
string++;
|
||||||
|
|
||||||
|
/* We found the end. */
|
||||||
|
possibly_incomplete = 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
/* Was any space skipped? */
|
||||||
|
if (is_sgml_space(string[-1])) {
|
||||||
|
/* We found the end. */
|
||||||
|
possibly_incomplete = 0;
|
||||||
|
}
|
||||||
scanner->state = SGML_STATE_ELEMENT;
|
scanner->state = SGML_STATE_ELEMENT;
|
||||||
type = SGML_TOKEN_ELEMENT_BEGIN;
|
type = SGML_TOKEN_ELEMENT_BEGIN;
|
||||||
}
|
}
|
||||||
@ -330,7 +485,8 @@ scan_sgml_element_token(struct dom_scanner *scanner, struct dom_scanner_token *t
|
|||||||
string += 2;
|
string += 2;
|
||||||
type = SGML_TOKEN_NOTATION_COMMENT;
|
type = SGML_TOKEN_NOTATION_COMMENT;
|
||||||
token->string.string = string;
|
token->string.string = string;
|
||||||
real_length = skip_sgml_comment(scanner, &string);
|
real_length = skip_sgml_comment(scanner, &string,
|
||||||
|
&possibly_incomplete);
|
||||||
assert(real_length >= 0);
|
assert(real_length >= 0);
|
||||||
|
|
||||||
} else if (string + 6 < scanner->end
|
} else if (string + 6 < scanner->end
|
||||||
@ -339,13 +495,17 @@ scan_sgml_element_token(struct dom_scanner *scanner, struct dom_scanner_token *t
|
|||||||
string += 7;
|
string += 7;
|
||||||
type = SGML_TOKEN_CDATA_SECTION;
|
type = SGML_TOKEN_CDATA_SECTION;
|
||||||
token->string.string = string;
|
token->string.string = string;
|
||||||
real_length = skip_sgml_cdata_section(scanner, &string);
|
real_length = skip_sgml_cdata_section(scanner, &string,
|
||||||
|
&possibly_incomplete);
|
||||||
assert(real_length >= 0);
|
assert(real_length >= 0);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
skip_sgml_space(scanner, &string);
|
scan_sgml(scanner, string, SGML_CHAR_IDENT);
|
||||||
type = map_dom_scanner_string(scanner, ident, string, base);
|
type = map_dom_scanner_string(scanner, ident, string, base);
|
||||||
skip_sgml(scanner, &string, '>', 0);
|
if (skip_sgml(scanner, &string, '>', 0)) {
|
||||||
|
/* We found the end. */
|
||||||
|
possibly_incomplete = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (*string == '?') {
|
} else if (*string == '?') {
|
||||||
@ -361,6 +521,16 @@ scan_sgml_element_token(struct dom_scanner *scanner, struct dom_scanner_token *t
|
|||||||
|
|
||||||
scanner->state = SGML_STATE_PROC_INST;
|
scanner->state = SGML_STATE_PROC_INST;
|
||||||
|
|
||||||
|
real_length = string - token->string.string;
|
||||||
|
skip_sgml_space(scanner, &string);
|
||||||
|
|
||||||
|
/* Make '<?xml ' cause the right kind of error. */
|
||||||
|
if (is_sgml_space(string[-1])
|
||||||
|
&& string < scanner->end) {
|
||||||
|
/* We found the end. */
|
||||||
|
possibly_incomplete = 0;
|
||||||
|
}
|
||||||
|
|
||||||
} else if (*string == '/') {
|
} else if (*string == '/') {
|
||||||
string++;
|
string++;
|
||||||
skip_sgml_space(scanner, &string);
|
skip_sgml_space(scanner, &string);
|
||||||
@ -371,12 +541,18 @@ scan_sgml_element_token(struct dom_scanner *scanner, struct dom_scanner_token *t
|
|||||||
real_length = string - token->string.string;
|
real_length = string - token->string.string;
|
||||||
|
|
||||||
type = SGML_TOKEN_ELEMENT_END;
|
type = SGML_TOKEN_ELEMENT_END;
|
||||||
skip_sgml(scanner, &string, '>', 1);
|
if (skip_sgml(scanner, &string, '>', 1)) {
|
||||||
|
/* We found the end. */
|
||||||
|
possibly_incomplete = 0;
|
||||||
|
}
|
||||||
|
|
||||||
} else if (*string == '>') {
|
} else if (*string == '>') {
|
||||||
string++;
|
string++;
|
||||||
real_length = 0;
|
real_length = 0;
|
||||||
type = SGML_TOKEN_ELEMENT_END;
|
type = SGML_TOKEN_ELEMENT_END;
|
||||||
|
|
||||||
|
/* We found the end. */
|
||||||
|
possibly_incomplete = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type != SGML_TOKEN_GARBAGE)
|
if (type != SGML_TOKEN_GARBAGE)
|
||||||
@ -384,15 +560,28 @@ scan_sgml_element_token(struct dom_scanner *scanner, struct dom_scanner_token *t
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* Alien < > stuff so ignore it */
|
/* Alien < > stuff so ignore it */
|
||||||
skip_sgml(scanner, &string, '>', 0);
|
if (skip_sgml(scanner, &string, '>', 0)) {
|
||||||
|
/* We found the end. */
|
||||||
|
possibly_incomplete = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (first_char == '=') {
|
} else if (first_char == '=') {
|
||||||
type = '=';
|
type = '=';
|
||||||
|
/* We found the end. */
|
||||||
|
possibly_incomplete = 0;
|
||||||
|
|
||||||
} else if (first_char == '?' || first_char == '>') {
|
} else if (first_char == '?' || first_char == '>') {
|
||||||
if (first_char == '?') {
|
if (first_char == '?') {
|
||||||
skip_sgml(scanner, &string, '>', 0);
|
if (skip_sgml(scanner, &string, '>', 0)) {
|
||||||
|
/* We found the end. */
|
||||||
|
possibly_incomplete = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert(first_char == '>');
|
||||||
|
|
||||||
|
/* We found the end. */
|
||||||
|
possibly_incomplete = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
type = SGML_TOKEN_TAG_END;
|
type = SGML_TOKEN_TAG_END;
|
||||||
@ -400,17 +589,33 @@ scan_sgml_element_token(struct dom_scanner *scanner, struct dom_scanner_token *t
|
|||||||
scanner->state = SGML_STATE_TEXT;
|
scanner->state = SGML_STATE_TEXT;
|
||||||
|
|
||||||
} else if (first_char == '/') {
|
} else if (first_char == '/') {
|
||||||
|
/* We allow '/' inside elements and only consider it as an end
|
||||||
|
* tag if immediately preceeds the '>' char. This is to allow
|
||||||
|
*
|
||||||
|
* '<form action=/ >' where '/' is part of a path and
|
||||||
|
* '<form action=a />' where '/>' is truely a tag end
|
||||||
|
*
|
||||||
|
* For stricter parsing we should always require attribute
|
||||||
|
* values to be quoted.
|
||||||
|
*/
|
||||||
if (*string == '>') {
|
if (*string == '>') {
|
||||||
string++;
|
string++;
|
||||||
real_length = 0;
|
real_length = 0;
|
||||||
type = SGML_TOKEN_ELEMENT_EMPTY_END;
|
type = SGML_TOKEN_ELEMENT_EMPTY_END;
|
||||||
assert(scanner->state == SGML_STATE_ELEMENT);
|
assert(scanner->state == SGML_STATE_ELEMENT);
|
||||||
scanner->state = SGML_STATE_TEXT;
|
scanner->state = SGML_STATE_TEXT;
|
||||||
|
|
||||||
|
/* We found the end. */
|
||||||
|
possibly_incomplete = 0;
|
||||||
|
|
||||||
} else if (is_sgml_attribute(*string)) {
|
} else if (is_sgml_attribute(*string)) {
|
||||||
scan_sgml_attribute(scanner, string);
|
scan_sgml_attribute(scanner, string);
|
||||||
type = SGML_TOKEN_ATTRIBUTE;
|
type = SGML_TOKEN_ATTRIBUTE;
|
||||||
if (string[-1] == '/' && string[0] == '>')
|
if (string[-1] == '/' && string[0] == '>') {
|
||||||
string--;
|
string--;
|
||||||
|
/* We found the end. */
|
||||||
|
possibly_incomplete = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (isquote(first_char)) {
|
} else if (isquote(first_char)) {
|
||||||
@ -422,6 +627,10 @@ scan_sgml_element_token(struct dom_scanner *scanner, struct dom_scanner_token *t
|
|||||||
real_length = string_end - token->string.string;
|
real_length = string_end - token->string.string;
|
||||||
string = string_end + 1;
|
string = string_end + 1;
|
||||||
type = SGML_TOKEN_STRING;
|
type = SGML_TOKEN_STRING;
|
||||||
|
|
||||||
|
/* We found the end. */
|
||||||
|
possibly_incomplete = 0;
|
||||||
|
|
||||||
} else if (is_sgml_attribute(*string)) {
|
} else if (is_sgml_attribute(*string)) {
|
||||||
token->string.string++;
|
token->string.string++;
|
||||||
scan_sgml_attribute(scanner, string);
|
scan_sgml_attribute(scanner, string);
|
||||||
@ -437,8 +646,27 @@ scan_sgml_element_token(struct dom_scanner *scanner, struct dom_scanner_token *t
|
|||||||
if (is_sgml_attribute(*string)) {
|
if (is_sgml_attribute(*string)) {
|
||||||
scan_sgml_attribute(scanner, string);
|
scan_sgml_attribute(scanner, string);
|
||||||
type = SGML_TOKEN_ATTRIBUTE;
|
type = SGML_TOKEN_ATTRIBUTE;
|
||||||
if (string[-1] == '/' && string[0] == '>')
|
if (string[-1] == '/' && string[0] == '>') {
|
||||||
|
/* We found the end. */
|
||||||
|
possibly_incomplete = 0;
|
||||||
string--;
|
string--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (possibly_incomplete) {
|
||||||
|
if (check_sgml_incomplete(scanner, string)) {
|
||||||
|
set_sgml_incomplete(scanner, token);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_sgml_error(scanner) && string == scanner->end) {
|
||||||
|
unsigned char *end;
|
||||||
|
|
||||||
|
end = get_sgml_error_end(scanner, type, string);
|
||||||
|
token = set_sgml_error(scanner, end);
|
||||||
|
if (!token)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -455,6 +683,8 @@ static inline void
|
|||||||
scan_sgml_proc_inst_token(struct dom_scanner *scanner, struct dom_scanner_token *token)
|
scan_sgml_proc_inst_token(struct dom_scanner *scanner, struct dom_scanner_token *token)
|
||||||
{
|
{
|
||||||
unsigned char *string = scanner->position;
|
unsigned char *string = scanner->position;
|
||||||
|
/* The length can be empty for '<??>'. */
|
||||||
|
size_t length = -1;
|
||||||
|
|
||||||
token->string.string = string;
|
token->string.string = string;
|
||||||
|
|
||||||
@ -464,14 +694,30 @@ scan_sgml_proc_inst_token(struct dom_scanner *scanner, struct dom_scanner_token
|
|||||||
for ( ; (string = skip_sgml_chars(scanner, string, '>')); string++) {
|
for ( ; (string = skip_sgml_chars(scanner, string, '>')); string++) {
|
||||||
if (string[-1] == '?') {
|
if (string[-1] == '?') {
|
||||||
string++;
|
string++;
|
||||||
|
length = string - token->string.string - 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string) string = scanner->end;
|
if (!string) {
|
||||||
|
/* Makes the next succeed when checking for incompletion, and
|
||||||
|
* puts the rest of the text within the token. */
|
||||||
|
string = scanner->end;
|
||||||
|
|
||||||
|
if (check_sgml_incomplete(scanner, string)) {
|
||||||
|
set_sgml_incomplete(scanner, token);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_sgml_error(scanner)) {
|
||||||
|
token = set_sgml_error(scanner, string);
|
||||||
|
if (!token)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
token->type = SGML_TOKEN_PROCESS_DATA;
|
token->type = SGML_TOKEN_PROCESS_DATA;
|
||||||
token->string.length = string - token->string.string - 2;
|
token->string.length = length >= 0 ? length : string - token->string.string;
|
||||||
token->precedence = get_sgml_precedence(token->type);
|
token->precedence = get_sgml_precedence(token->type);
|
||||||
scanner->position = string;
|
scanner->position = string;
|
||||||
scanner->state = SGML_STATE_TEXT;
|
scanner->state = SGML_STATE_TEXT;
|
||||||
@ -484,36 +730,34 @@ static struct dom_scanner_token *
|
|||||||
scan_sgml_tokens(struct dom_scanner *scanner)
|
scan_sgml_tokens(struct dom_scanner *scanner)
|
||||||
{
|
{
|
||||||
struct dom_scanner_token *table_end = scanner->table + DOM_SCANNER_TOKENS;
|
struct dom_scanner_token *table_end = scanner->table + DOM_SCANNER_TOKENS;
|
||||||
struct dom_scanner_token *current;
|
|
||||||
|
|
||||||
if (!begin_dom_token_scanning(scanner))
|
if (!begin_dom_token_scanning(scanner))
|
||||||
return get_dom_scanner_token(scanner);
|
return get_dom_scanner_token(scanner);
|
||||||
|
|
||||||
/* Scan tokens until we fill the table */
|
/* Scan tokens until we fill the table */
|
||||||
for (current = scanner->table + scanner->tokens;
|
for (scanner->current = scanner->table + scanner->tokens;
|
||||||
current < table_end && scanner->position < scanner->end;
|
scanner->current < table_end && scanner->position < scanner->end;
|
||||||
current++) {
|
scanner->current++) {
|
||||||
if (scanner->state == SGML_STATE_ELEMENT
|
if (scanner->state == SGML_STATE_ELEMENT
|
||||||
|| (*scanner->position == '<'
|
|| (*scanner->position == '<'
|
||||||
&& scanner->state != SGML_STATE_PROC_INST)) {
|
&& scanner->state != SGML_STATE_PROC_INST)) {
|
||||||
skip_sgml_space(scanner, &scanner->position);
|
skip_sgml_space(scanner, &scanner->position);
|
||||||
if (scanner->position >= scanner->end) break;
|
if (scanner->position >= scanner->end) break;
|
||||||
|
|
||||||
scan_sgml_element_token(scanner, current);
|
scan_sgml_element_token(scanner, scanner->current);
|
||||||
|
|
||||||
/* Shall we scratch this token? */
|
/* Shall we scratch this token? */
|
||||||
if (current->type == SGML_TOKEN_SKIP) {
|
if (scanner->current->type == SGML_TOKEN_SKIP) {
|
||||||
current--;
|
scanner->current--;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (scanner->state == SGML_STATE_TEXT) {
|
} else if (scanner->state == SGML_STATE_TEXT) {
|
||||||
scan_sgml_text_token(scanner, current);
|
scan_sgml_text_token(scanner, scanner->current);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
skip_sgml_space(scanner, &scanner->position);
|
scan_sgml_proc_inst_token(scanner, scanner->current);
|
||||||
scan_sgml_proc_inst_token(scanner, current);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return end_dom_token_scanning(scanner, current);
|
return end_dom_token_scanning(scanner, scanner->current);
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,14 @@ enum sgml_token_type {
|
|||||||
/* A special token for unrecognized strings */
|
/* A special token for unrecognized strings */
|
||||||
SGML_TOKEN_GARBAGE,
|
SGML_TOKEN_GARBAGE,
|
||||||
|
|
||||||
|
/* A special token for marking that it is assummed that the token is
|
||||||
|
* not complete. Only meaningful if scanner->complete is incomplete. */
|
||||||
|
SGML_TOKEN_INCOMPLETE,
|
||||||
|
|
||||||
|
/* A special token for reporting that an error in the markup was found.
|
||||||
|
* Only in effect when error checking has been requested. */
|
||||||
|
SGML_TOKEN_ERROR,
|
||||||
|
|
||||||
/* Token type used internally when scanning to signal that the token
|
/* Token type used internally when scanning to signal that the token
|
||||||
* should not be recorded in the scanners token table. */
|
* should not be recorded in the scanners token table. */
|
||||||
SGML_TOKEN_SKIP,
|
SGML_TOKEN_SKIP,
|
||||||
|
@ -213,7 +213,7 @@ pop_dom_node(struct dom_stack *stack)
|
|||||||
|
|
||||||
call_dom_stack_callbacks(stack, state, DOM_STACK_POP);
|
call_dom_stack_callbacks(stack, state, DOM_STACK_POP);
|
||||||
|
|
||||||
if (!(stack->flags & DOM_STACK_KEEP_NODES))
|
if (stack->flags & DOM_STACK_FLAG_FREE_NODES)
|
||||||
done_dom_node(state->node);
|
done_dom_node(state->node);
|
||||||
|
|
||||||
stack->depth--;
|
stack->depth--;
|
||||||
|
197
src/dom/stack.h
197
src/dom/stack.h
@ -7,73 +7,110 @@
|
|||||||
|
|
||||||
struct dom_stack;
|
struct dom_stack;
|
||||||
|
|
||||||
|
/** DOM stack callback
|
||||||
|
*
|
||||||
|
* Used by contexts, for 'hooking' into the node traversing. */
|
||||||
typedef void (*dom_stack_callback_T)(struct dom_stack *, struct dom_node *, void *);
|
typedef void (*dom_stack_callback_T)(struct dom_stack *, struct dom_node *, void *);
|
||||||
|
|
||||||
#define DOM_STACK_MAX_DEPTH 4096
|
#define DOM_STACK_MAX_DEPTH 4096
|
||||||
|
|
||||||
|
/** DOM stack state
|
||||||
|
*
|
||||||
|
* This state records what node and where it is placed. */
|
||||||
struct dom_stack_state {
|
struct dom_stack_state {
|
||||||
|
/** The node assiciated with the state */
|
||||||
struct dom_node *node;
|
struct dom_node *node;
|
||||||
|
/**
|
||||||
/* The depth of the state in the stack. This is amongst other things
|
* The depth of the state in the stack. This is amongst other things
|
||||||
* used to get the state object data. */
|
* used to get the state object data. */
|
||||||
unsigned int depth;
|
unsigned int depth;
|
||||||
|
/** Whether this stack state can be popped with pop_dom_*() family. */
|
||||||
/* Wether this stack state can be popped with pop_dom_*() family. */
|
|
||||||
unsigned int immutable:1;
|
unsigned int immutable:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** DOM stack context info
|
||||||
|
*
|
||||||
|
* To add a DOM stack context define this struct either statically or on the
|
||||||
|
* stack. */
|
||||||
struct dom_stack_context_info {
|
struct dom_stack_context_info {
|
||||||
/* The @object_size member tells whether the stack should allocate
|
/**
|
||||||
* objects for each state to be assigned to the state's @data member.
|
* This member tells whether the stack should allocate objects for each
|
||||||
* Zero means no state data should be allocated. */
|
* state to be assigned to the state's @data member. Zero means no
|
||||||
|
* state data should be allocated. */
|
||||||
size_t object_size;
|
size_t object_size;
|
||||||
|
|
||||||
/* Callbacks to be called when pushing and popping nodes. */
|
/** Callbacks to be called when pushing nodes. */
|
||||||
dom_stack_callback_T push[DOM_NODES];
|
dom_stack_callback_T push[DOM_NODES];
|
||||||
|
/** Callbacks to be called when popping nodes. */
|
||||||
dom_stack_callback_T pop[DOM_NODES];
|
dom_stack_callback_T pop[DOM_NODES];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** DOM stack context
|
||||||
|
*
|
||||||
|
* This holds 'runtime' data for the stack context. */
|
||||||
struct dom_stack_context {
|
struct dom_stack_context {
|
||||||
/* Data specific to the context. */
|
/** Data specific to the context. */
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
/* This is one big array of context specific objects. */
|
/**
|
||||||
/* For the SGML parser this holds DTD-oriented info about the node
|
* This is one big array of context specific objects. For the SGML
|
||||||
* (recorded in struct sgml_node_info). E.g. whether an element node
|
* parser this holds DTD-oriented info about the node (recorded in
|
||||||
* is optional. */
|
* struct sgml_node_info). E.g. whether an element node is optional.
|
||||||
|
*/
|
||||||
unsigned char *state_objects;
|
unsigned char *state_objects;
|
||||||
|
|
||||||
/* Info about node callbacks and such. */
|
/** Info about node callbacks and such. */
|
||||||
struct dom_stack_context_info *info;
|
struct dom_stack_context_info *info;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Flags for controlling the DOM stack */
|
||||||
enum dom_stack_flag {
|
enum dom_stack_flag {
|
||||||
/* Keep nodes when popping them or call done_dom_node() on them. */
|
/** No flag needed. */
|
||||||
DOM_STACK_KEEP_NODES = 1,
|
DOM_STACK_FLAG_NONE = 0,
|
||||||
|
|
||||||
|
/** Free nodes when popping by calling ref:[done_dom_node]. */
|
||||||
|
DOM_STACK_FLAG_FREE_NODES = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The DOM stack is a convenient way to traverse DOM trees. Also it
|
/** The DOM stack
|
||||||
|
*
|
||||||
|
* The DOM stack is a convenient way to traverse DOM trees. Also it
|
||||||
* maintains needed state info and is therefore also a holder of the current
|
* maintains needed state info and is therefore also a holder of the current
|
||||||
* context since the stack is used to when the DOM tree is manipulated. */
|
* context since the stack is used to when the DOM tree is manipulated. */
|
||||||
struct dom_stack {
|
struct dom_stack {
|
||||||
/* The stack of nodes */
|
/** The states currently on the stack. */
|
||||||
struct dom_stack_state *states;
|
struct dom_stack_state *states;
|
||||||
|
/** The depth of the stack. */
|
||||||
size_t depth;
|
size_t depth;
|
||||||
|
|
||||||
|
/** Flags given to ref:[init_dom_stack]. */
|
||||||
enum dom_stack_flag flags;
|
enum dom_stack_flag flags;
|
||||||
|
|
||||||
/* Contexts for the pushed and popped nodes. */
|
/** Contexts for the pushed and popped nodes. */
|
||||||
struct dom_stack_context **contexts;
|
struct dom_stack_context **contexts;
|
||||||
|
/** The number of active contexts. */
|
||||||
size_t contexts_size;
|
size_t contexts_size;
|
||||||
|
|
||||||
/* The current context. */
|
/**
|
||||||
/* XXX: Only meaningful within dom_stack_callback_T functions. */
|
* The current context. Only meaningful within
|
||||||
|
* ref:[dom_stack_callback_T] functions. */
|
||||||
struct dom_stack_context *current;
|
struct dom_stack_context *current;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Check whether stack is empty or not
|
||||||
|
*
|
||||||
|
* stack:: The stack to check.
|
||||||
|
*
|
||||||
|
* Returns non-zero if stack is empty. */
|
||||||
#define dom_stack_is_empty(stack) \
|
#define dom_stack_is_empty(stack) \
|
||||||
(!(stack)->states || (stack)->depth == 0)
|
(!(stack)->states || (stack)->depth == 0)
|
||||||
|
|
||||||
|
/** Access state by offset from top
|
||||||
|
*
|
||||||
|
* stack:: The stack to fetch the state from.
|
||||||
|
* top_offset:: The offset from the stack top, zero is the top.
|
||||||
|
*
|
||||||
|
* Returns the requested state. */
|
||||||
static inline struct dom_stack_state *
|
static inline struct dom_stack_state *
|
||||||
get_dom_stack_state(struct dom_stack *stack, int top_offset)
|
get_dom_stack_state(struct dom_stack *stack, int top_offset)
|
||||||
{
|
{
|
||||||
@ -82,8 +119,24 @@ get_dom_stack_state(struct dom_stack *stack, int top_offset)
|
|||||||
return &stack->states[stack->depth - 1 - top_offset];
|
return &stack->states[stack->depth - 1 - top_offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
#define get_dom_stack_top(stack) get_dom_stack_state(stack, 0)
|
/** Access the stack top
|
||||||
|
*
|
||||||
|
* stack:: The stack to get the top state from.
|
||||||
|
*
|
||||||
|
* Returns the top state. */
|
||||||
|
#define get_dom_stack_top(stack) \
|
||||||
|
get_dom_stack_state(stack, 0)
|
||||||
|
|
||||||
|
/** Access context specific state data
|
||||||
|
*
|
||||||
|
* Similar to ref:[get_dom_stack_state], this will fetch the data
|
||||||
|
* associated with the state for the given context.
|
||||||
|
*
|
||||||
|
* context:: The context to get data from.
|
||||||
|
* state:: The stack state to get data from.
|
||||||
|
*
|
||||||
|
* Returns the state data or NULL if ref:[dom_stack_context_info.object_size]
|
||||||
|
* was zero. */
|
||||||
static inline void *
|
static inline void *
|
||||||
get_dom_stack_state_data(struct dom_stack_context *context,
|
get_dom_stack_state_data(struct dom_stack_context *context,
|
||||||
struct dom_stack_state *state)
|
struct dom_stack_state *state)
|
||||||
@ -97,25 +150,36 @@ get_dom_stack_state_data(struct dom_stack_context *context,
|
|||||||
return (void *) &context->state_objects[state->depth * object_size];
|
return (void *) &context->state_objects[state->depth * object_size];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Define to have debug info about the nodes added printed to the log.
|
|
||||||
* Run as: ELINKS_LOG=/tmp/dom-dump.txt ./elinks -no-connect <url>
|
|
||||||
* to have the debug dumped into a file. */
|
|
||||||
/*#define DOM_STACK_TRACE*/
|
/*#define DOM_STACK_TRACE*/
|
||||||
|
|
||||||
#ifdef DOM_STACK_TRACE
|
#ifdef DOM_STACK_TRACE
|
||||||
extern struct dom_stack_context_info dom_stack_trace_context_info;
|
extern struct dom_stack_context_info dom_stack_trace_context_info;
|
||||||
|
/** Get debug info from the DOM stack
|
||||||
|
*
|
||||||
|
* Define `DOM_STACK_TRACE` to have debug info about the nodes added printed to
|
||||||
|
* the log. It will define add_dom_stack_tracer() to not be a no-op.
|
||||||
|
*
|
||||||
|
* Run as:
|
||||||
|
*
|
||||||
|
* ELINKS_LOG=/tmp/dom-dump.txt ./elinks -no-connect <url>
|
||||||
|
*
|
||||||
|
* to have the debug dumped into a file. */
|
||||||
#define add_dom_stack_tracer(stack, name) \
|
#define add_dom_stack_tracer(stack, name) \
|
||||||
add_dom_stack_context(stack, name, &dom_stack_trace_context_info)
|
add_dom_stack_context(stack, name, &dom_stack_trace_context_info)
|
||||||
#else
|
#else
|
||||||
#define add_dom_stack_tracer(stack, name) /* Nada */
|
#define add_dom_stack_tracer(stack, name) /* Nada */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The state iterators do not include the bottom state */
|
/** The state iterators
|
||||||
|
*
|
||||||
|
* To safely iterate through the stack state iterators. */
|
||||||
|
|
||||||
|
/** Iterate the stack from bottom to top. */
|
||||||
#define foreach_dom_stack_state(stack, state, pos) \
|
#define foreach_dom_stack_state(stack, state, pos) \
|
||||||
for ((pos) = 0; (pos) < (stack)->depth; (pos)++) \
|
for ((pos) = 0; (pos) < (stack)->depth; (pos)++) \
|
||||||
if (((state) = &(stack)->states[(pos)]))
|
if (((state) = &(stack)->states[(pos)]))
|
||||||
|
|
||||||
|
/** Iterate the stack from top to bottom. */
|
||||||
#define foreachback_dom_stack_state(stack, state, pos) \
|
#define foreachback_dom_stack_state(stack, state, pos) \
|
||||||
for ((pos) = (stack)->depth - 1; (pos) >= 0; (pos)--) \
|
for ((pos) = (stack)->depth - 1; (pos) >= 0; (pos)--) \
|
||||||
if (((state) = &(stack)->states[(pos)]))
|
if (((state) = &(stack)->states[(pos)]))
|
||||||
@ -123,41 +187,96 @@ extern struct dom_stack_context_info dom_stack_trace_context_info;
|
|||||||
|
|
||||||
/* Life cycle functions. */
|
/* Life cycle functions. */
|
||||||
|
|
||||||
|
/** Initialise a DOM stack
|
||||||
|
* stack:: Pointer to a (preallocated) stack.
|
||||||
|
* flags:: Any flags needed for controlling the behaviour of the stack.
|
||||||
|
*/
|
||||||
void init_dom_stack(struct dom_stack *stack, enum dom_stack_flag flags);
|
void init_dom_stack(struct dom_stack *stack, enum dom_stack_flag flags);
|
||||||
|
/** Release a DOM stack
|
||||||
|
*
|
||||||
|
* Free all resources collected by the stack.
|
||||||
|
*
|
||||||
|
* stack:: The stack to release. */
|
||||||
void done_dom_stack(struct dom_stack *stack);
|
void done_dom_stack(struct dom_stack *stack);
|
||||||
|
|
||||||
/* Add a context to the stack. This is needed if either you want to have the
|
/** Add a context to the stack
|
||||||
* stack allocated objects for created states and/or if you want to install
|
*
|
||||||
* callbacks for pushing or popping. . */
|
* This is needed if either you want to have the stack allocated objects for
|
||||||
|
* created states and/or if you want to install callbacks for pushing or
|
||||||
|
* popping.
|
||||||
|
*
|
||||||
|
* stack:: The stack where the context should be created.
|
||||||
|
* data:: Private data to be stored in ref:[dom_stack_context.data].
|
||||||
|
* context_info:: Information about state objects and node callbacks.
|
||||||
|
*
|
||||||
|
* Returns a pointer to the newly created context or NULL. */
|
||||||
struct dom_stack_context *
|
struct dom_stack_context *
|
||||||
add_dom_stack_context(struct dom_stack *stack, void *data,
|
add_dom_stack_context(struct dom_stack *stack, void *data,
|
||||||
struct dom_stack_context_info *context_info);
|
struct dom_stack_context_info *context_info);
|
||||||
|
|
||||||
/* Unregister a stack @context. This should be done especially for temporary
|
/** Unregister a stack context
|
||||||
* stack contexts (without any callbacks) so that they do not increasing the
|
* This should be done especially for temporary stack contexts (without any
|
||||||
* memory usage. */
|
* callbacks) so that they do not increasing the memory usage. */
|
||||||
void done_dom_stack_context(struct dom_stack *stack, struct dom_stack_context *context);
|
void done_dom_stack_context(struct dom_stack *stack, struct dom_stack_context *context);
|
||||||
|
|
||||||
/* Decends down to the given node making it the current parent */
|
/** Push a node onto the stack
|
||||||
/* If an error occurs the node is free()d and NULL is returned */
|
*
|
||||||
|
* Makes the pushed node the new top of the stack.
|
||||||
|
*
|
||||||
|
* stack:: The stack to push onto.
|
||||||
|
* node:: The node to push onto the stack.
|
||||||
|
*
|
||||||
|
* If an error occurs the node is released with ref:[done_dom_node] and NULL is
|
||||||
|
* returned. Else the pushed node is returned. */
|
||||||
struct dom_node *push_dom_node(struct dom_stack *stack, struct dom_node *node);
|
struct dom_node *push_dom_node(struct dom_stack *stack, struct dom_node *node);
|
||||||
|
|
||||||
/* Ascends the stack to the current parent */
|
/** Pop the top stack state
|
||||||
|
*
|
||||||
|
* stack:: The stack to pop from. */
|
||||||
void pop_dom_node(struct dom_stack *stack);
|
void pop_dom_node(struct dom_stack *stack);
|
||||||
|
|
||||||
/* Ascends the stack looking for specific parent */
|
/** Conditionally pop the stack states
|
||||||
|
*
|
||||||
|
* Searches the stack (using ref:[search_dom_stack]) for a specific node and
|
||||||
|
* pops all states until that particular state is met.
|
||||||
|
*
|
||||||
|
* NOTE: The popping is stopped if an immutable state is encountered. */
|
||||||
void pop_dom_nodes(struct dom_stack *stack, enum dom_node_type type,
|
void pop_dom_nodes(struct dom_stack *stack, enum dom_node_type type,
|
||||||
struct dom_string *string);
|
struct dom_string *string);
|
||||||
|
|
||||||
/* Pop all stack states until a specific state is reached. */
|
/** Pop all states until target state
|
||||||
|
*
|
||||||
|
* Pop all stack states until a specific state is reached. The target state
|
||||||
|
* is also popped.
|
||||||
|
*
|
||||||
|
* stack:: The stack to pop from.
|
||||||
|
* target:: The state to pop until and including. */
|
||||||
void pop_dom_state(struct dom_stack *stack, struct dom_stack_state *target);
|
void pop_dom_state(struct dom_stack *stack, struct dom_stack_state *target);
|
||||||
|
|
||||||
/* Dive through the stack states in search for the specified match. */
|
/** Search the stack states
|
||||||
|
*
|
||||||
|
* The string comparison is done against the ref:[dom_node.string] member of
|
||||||
|
* the of the state nodes.
|
||||||
|
*
|
||||||
|
* stack:: The stack to search in.
|
||||||
|
* type:: The type of node to match against.
|
||||||
|
* string:: The string to match against.
|
||||||
|
*
|
||||||
|
* Returns a state that matched the type and string or NULL. */
|
||||||
struct dom_stack_state *
|
struct dom_stack_state *
|
||||||
search_dom_stack(struct dom_stack *stack, enum dom_node_type type,
|
search_dom_stack(struct dom_stack *stack, enum dom_node_type type,
|
||||||
struct dom_string *string);
|
struct dom_string *string);
|
||||||
|
|
||||||
/* Visit each node in the tree rooted at @root pre-order */
|
/** Walk all nodes reachable from a given node
|
||||||
|
*
|
||||||
|
* Visits each node in the DOM tree rooted at a given node, pre-order style.
|
||||||
|
*
|
||||||
|
* stack:: The stack to use for walking the nodes.
|
||||||
|
* root:: The root node to start from.
|
||||||
|
*
|
||||||
|
* It is assummed that the given stack has been initialised with
|
||||||
|
* ref:[init_dom_stack] and that the caller already added one or more
|
||||||
|
* context to the stack. */
|
||||||
void walk_dom_nodes(struct dom_stack *stack, struct dom_node *root);
|
void walk_dom_nodes(struct dom_stack *stack, struct dom_node *root);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -39,21 +39,28 @@ dom_string_ncasecmp(struct dom_string *string1, struct dom_string *string2, size
|
|||||||
set_dom_string(string1, (string2)->string, (string2)->length)
|
set_dom_string(string1, (string2)->string, (string2)->length)
|
||||||
|
|
||||||
static inline struct dom_string *
|
static inline struct dom_string *
|
||||||
init_dom_string(struct dom_string *string, unsigned char *str, size_t len)
|
add_to_dom_string(struct dom_string *string, unsigned char *str, size_t len)
|
||||||
{
|
{
|
||||||
string->string = mem_alloc(len + 1);
|
unsigned char *newstring;
|
||||||
if (!string->string)
|
|
||||||
|
newstring = mem_realloc(string->string, string->length + len + 1);
|
||||||
|
if (!newstring)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
memcpy(string->string, str, len);
|
string->string = newstring;
|
||||||
string->string[len] = 0;
|
memcpy(string->string + string->length, str, len);
|
||||||
string->length = len;
|
string->length += len;
|
||||||
|
string->string[string->length] = 0;
|
||||||
|
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define init_dom_string(string, str, len) add_to_dom_string(string, str, len)
|
||||||
|
|
||||||
#define is_dom_string_set(str) ((str)->string && (str)->length)
|
#define is_dom_string_set(str) ((str)->string && (str)->length)
|
||||||
|
|
||||||
#define done_dom_string(str) mem_free((str)->string);
|
#define done_dom_string(str) \
|
||||||
|
do { mem_free_set(&(str)->string, NULL); (str)->length = 0; } while (0)
|
||||||
|
|
||||||
#define isquote(c) ((c) == '"' || (c) == '\'')
|
#define isquote(c) ((c) == '"' || (c) == '\'')
|
||||||
|
|
||||||
|
@ -11,33 +11,7 @@ TESTDEPS = \
|
|||||||
$(top_builddir)/src/util/error.o \
|
$(top_builddir)/src/util/error.o \
|
||||||
$(top_builddir)/src/osdep/stub.o \
|
$(top_builddir)/src/osdep/stub.o \
|
||||||
$(top_builddir)/src/util/hash.o \
|
$(top_builddir)/src/util/hash.o \
|
||||||
$(top_builddir)/src/util/memdebug.o \
|
|
||||||
$(top_builddir)/src/util/string.o \
|
$(top_builddir)/src/util/string.o \
|
||||||
$(top_builddir)/src/util/memory.o
|
$(top_builddir)/src/util/memory.o
|
||||||
|
|
||||||
$(TEST_PROGS): $(TESTDEPS) $$@.o
|
|
||||||
$(call cmd,link)
|
|
||||||
|
|
||||||
TESTS = $(wildcard test-*)
|
|
||||||
|
|
||||||
$(TESTS): $(TEST_PROGS)
|
|
||||||
@echo "*** $@ ***"; $(call shellquote,$(SHELL)) $@ $(TEST_OPTS)
|
|
||||||
|
|
||||||
test: $(TESTS)
|
|
||||||
|
|
||||||
clean-local:
|
|
||||||
@rm -fr trash
|
|
||||||
|
|
||||||
CLEAN += $(TEST_PROGS) $(patsubst %,%.o,$(TEST_PROGS))
|
|
||||||
|
|
||||||
.PHONY: $(TESTS)
|
|
||||||
.NOPARALLEL:
|
|
||||||
|
|
||||||
include $(top_srcdir)/Makefile.lib
|
include $(top_srcdir)/Makefile.lib
|
||||||
|
|
||||||
# Shell quote;
|
|
||||||
# Result of this needs to be placed inside ''
|
|
||||||
# XXX: Placed here because Vim cannot highlight things right afterwards
|
|
||||||
shq = $(subst ','\'',$(1))
|
|
||||||
# This has surrounding ''
|
|
||||||
shellquote = '$(call shq,$(1))'
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
Core GIT Tests
|
ELinks testing infrastructure
|
||||||
==============
|
=============================
|
||||||
|
|
||||||
This directory holdstest scripts for the DOM implementation. The first part of
|
This directory holds test scripts for the DOM implementation. The first part of
|
||||||
this short document describes how to run the tests and read their output.
|
this short document describes how to run the tests and read their output.
|
||||||
|
|
||||||
When fixing the tools or adding enhancements, you are strongly encouraged to
|
When fixing the tools or adding enhancements, you are strongly encouraged to
|
||||||
@ -27,7 +27,7 @@ The easiest way to run tests is to say "make test". This runs all the tests.
|
|||||||
|
|
||||||
Or you can run each test individually from command line, like this:
|
Or you can run each test individually from command line, like this:
|
||||||
|
|
||||||
$ sh ./test-sgml-parser-basic
|
$ TEST_LIB=${path_to_top_srcdir}/test/libtest.sh sh ./test-sgml-parser-basic
|
||||||
* ok 1: parse a small document.
|
* ok 1: parse a small document.
|
||||||
...
|
...
|
||||||
* ok 23: parse a CDATA section.
|
* ok 23: parse a CDATA section.
|
||||||
@ -49,6 +49,10 @@ command line argument to the test.
|
|||||||
This causes the test to immediately exit upon the first
|
This causes the test to immediately exit upon the first
|
||||||
failed test.
|
failed test.
|
||||||
|
|
||||||
|
Note, these options can be passed indirectly to all tests when running test using
|
||||||
|
make by setting TEST_OPTS, like this:
|
||||||
|
|
||||||
|
make test TEST_OPTS=--immediate
|
||||||
|
|
||||||
Naming Tests
|
Naming Tests
|
||||||
------------
|
------------
|
||||||
@ -91,20 +95,23 @@ The test script is written as a shell script. It should start with the standard
|
|||||||
|
|
||||||
|
|
||||||
Source 'libtest'
|
Source 'libtest'
|
||||||
--------------------
|
----------------
|
||||||
|
|
||||||
After assigning test_description, the test script should source test-lib.sh
|
After assigning test_description, the test script should source the shell test
|
||||||
like this:
|
library like this:
|
||||||
|
|
||||||
. ./libtest
|
. "$TEST_LIB"
|
||||||
|
|
||||||
|
This assumes that the TEST_LIB environment variable has been set and is needed
|
||||||
|
for test to run from out of tree builds.
|
||||||
|
|
||||||
This test harness library does the following things:
|
This test harness library does the following things:
|
||||||
|
|
||||||
- If the script is invoked with command line argument --help (or -h), it shows
|
- If the script is invoked with command line argument --help (or -h), it shows
|
||||||
the test_description and exits.
|
the test_description and exits.
|
||||||
|
|
||||||
- Creates an empty test directory. This directory is 'test/trash' if you must
|
- Creates an empty test directory. This directory is 'trash' if you must know,
|
||||||
know, but I do not think you care.
|
but I do not think you care.
|
||||||
|
|
||||||
- Defines standard test helper functions for your scripts to use. These
|
- Defines standard test helper functions for your scripts to use. These
|
||||||
functions are designed to make all scripts behave consistently when command
|
functions are designed to make all scripts behave consistently when command
|
||||||
|
@ -16,6 +16,24 @@
|
|||||||
#include "dom/stack.h"
|
#include "dom/stack.h"
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int number_of_lines = 0;
|
||||||
|
|
||||||
|
static int
|
||||||
|
update_number_of_lines(struct dom_stack *stack)
|
||||||
|
{
|
||||||
|
struct sgml_parser *parser = stack->contexts[0]->data;
|
||||||
|
int lines;
|
||||||
|
|
||||||
|
if (!(parser->flags & SGML_PARSER_COUNT_LINES))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
lines = get_sgml_parser_line_number(parser);
|
||||||
|
if (number_of_lines < lines)
|
||||||
|
number_of_lines = lines;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Print the string in a compressed form: a single line with newlines etc.
|
/* Print the string in a compressed form: a single line with newlines etc.
|
||||||
* replaced with "\\n" sequence. */
|
* replaced with "\\n" sequence. */
|
||||||
static void
|
static void
|
||||||
@ -72,14 +90,25 @@ static unsigned char indent_string[] =
|
|||||||
#define get_indent_offset(stack) \
|
#define get_indent_offset(stack) \
|
||||||
(((stack)->depth < sizeof(indent_string)/2 ? (stack)->depth * 2 : sizeof(indent_string)) - 2)
|
(((stack)->depth < sizeof(indent_string)/2 ? (stack)->depth * 2 : sizeof(indent_string)) - 2)
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_indent(struct dom_stack *stack)
|
||||||
|
{
|
||||||
|
printf("%.*s", get_indent_offset(stack), indent_string);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sgml_parser_test_tree(struct dom_stack *stack, struct dom_node *node, void *data)
|
sgml_parser_test_tree(struct dom_stack *stack, struct dom_node *node, void *data)
|
||||||
{
|
{
|
||||||
struct dom_string *value = &node->string;
|
struct dom_string *value = &node->string;
|
||||||
struct dom_string *name = get_dom_node_name(node);
|
struct dom_string *name = get_dom_node_name(node);
|
||||||
|
|
||||||
printf("%.*s%.*s: %.*s\n",
|
/* Always print the URI for identification. */
|
||||||
get_indent_offset(stack), indent_string,
|
if (update_number_of_lines(stack))
|
||||||
|
return;
|
||||||
|
|
||||||
|
print_indent(stack);
|
||||||
|
printf("%.*s: %.*s\n",
|
||||||
name->length, name->string,
|
name->length, name->string,
|
||||||
value->length, value->string);
|
value->length, value->string);
|
||||||
}
|
}
|
||||||
@ -92,12 +121,16 @@ sgml_parser_test_id_leaf(struct dom_stack *stack, struct dom_node *node, void *d
|
|||||||
|
|
||||||
assert(node);
|
assert(node);
|
||||||
|
|
||||||
|
if (update_number_of_lines(stack))
|
||||||
|
return;
|
||||||
|
|
||||||
name = get_dom_node_name(node);
|
name = get_dom_node_name(node);
|
||||||
id = get_dom_node_type_name(node->type);
|
id = get_dom_node_type_name(node->type);
|
||||||
|
|
||||||
printf("%.*s%.*s: %.*s -> ",
|
print_indent(stack);
|
||||||
get_indent_offset(stack), indent_string,
|
printf("%.*s: %.*s -> ",
|
||||||
id->length, id->string, name->length, name->string);
|
id->length, id->string,
|
||||||
|
name->length, name->string);
|
||||||
print_dom_node_value(node);
|
print_dom_node_value(node);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
@ -109,10 +142,13 @@ sgml_parser_test_leaf(struct dom_stack *stack, struct dom_node *node, void *data
|
|||||||
|
|
||||||
assert(node);
|
assert(node);
|
||||||
|
|
||||||
|
if (update_number_of_lines(stack))
|
||||||
|
return;
|
||||||
|
|
||||||
name = get_dom_node_name(node);
|
name = get_dom_node_name(node);
|
||||||
|
|
||||||
printf("%.*s%.*s: ",
|
print_indent(stack);
|
||||||
get_indent_offset(stack), indent_string,
|
printf("%.*s: ",
|
||||||
name->length, name->string);
|
name->length, name->string);
|
||||||
print_dom_node_value(node);
|
print_dom_node_value(node);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@ -126,14 +162,28 @@ sgml_parser_test_branch(struct dom_stack *stack, struct dom_node *node, void *da
|
|||||||
|
|
||||||
assert(node);
|
assert(node);
|
||||||
|
|
||||||
|
if (update_number_of_lines(stack))
|
||||||
|
return;
|
||||||
|
|
||||||
name = get_dom_node_name(node);
|
name = get_dom_node_name(node);
|
||||||
id = get_dom_node_type_name(node->type);
|
id = get_dom_node_type_name(node->type);
|
||||||
|
|
||||||
printf("%.*s%.*s: %.*s\n",
|
print_indent(stack);
|
||||||
get_indent_offset(stack), indent_string,
|
printf("%.*s: %.*s\n",
|
||||||
id->length, id->string, name->length, name->string);
|
id->length, id->string, name->length, name->string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sgml_parser_test_end(struct dom_stack *stack, struct dom_node *node, void *data)
|
||||||
|
{
|
||||||
|
struct sgml_parser *parser = stack->contexts[0]->data;
|
||||||
|
|
||||||
|
if ((parser->flags & SGML_PARSER_COUNT_LINES)
|
||||||
|
&& !(parser->flags & SGML_PARSER_DETECT_ERRORS)) {
|
||||||
|
printf("%d\n", number_of_lines);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct dom_stack_context_info sgml_parser_test_context_info = {
|
struct dom_stack_context_info sgml_parser_test_context_info = {
|
||||||
/* Object size: */ 0,
|
/* Object size: */ 0,
|
||||||
/* Push: */
|
/* Push: */
|
||||||
@ -163,13 +213,22 @@ struct dom_stack_context_info sgml_parser_test_context_info = {
|
|||||||
/* DOM_NODE_ENTITY */ NULL,
|
/* DOM_NODE_ENTITY */ NULL,
|
||||||
/* DOM_NODE_PROC_INSTRUCTION */ NULL,
|
/* DOM_NODE_PROC_INSTRUCTION */ NULL,
|
||||||
/* DOM_NODE_COMMENT */ NULL,
|
/* DOM_NODE_COMMENT */ NULL,
|
||||||
/* DOM_NODE_DOCUMENT */ NULL,
|
/* DOM_NODE_DOCUMENT */ sgml_parser_test_end,
|
||||||
/* DOM_NODE_DOCUMENT_TYPE */ NULL,
|
/* DOM_NODE_DOCUMENT_TYPE */ NULL,
|
||||||
/* DOM_NODE_DOCUMENT_FRAGMENT */ NULL,
|
/* DOM_NODE_DOCUMENT_FRAGMENT */ NULL,
|
||||||
/* DOM_NODE_NOTATION */ NULL,
|
/* DOM_NODE_NOTATION */ NULL,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static enum sgml_parser_code
|
||||||
|
sgml_error_function(struct sgml_parser *parser, struct dom_string *string,
|
||||||
|
unsigned int line_number)
|
||||||
|
{
|
||||||
|
printf("error on line %d: %.*s\n",
|
||||||
|
line_number, string->length, string->string);
|
||||||
|
|
||||||
|
return SGML_PARSER_CODE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
void die(const char *msg, ...)
|
void die(const char *msg, ...)
|
||||||
{
|
{
|
||||||
@ -188,9 +247,11 @@ void die(const char *msg, ...)
|
|||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct dom_node *root;
|
|
||||||
struct sgml_parser *parser;
|
struct sgml_parser *parser;
|
||||||
enum sgml_document_type doctype = SGML_DOCTYPE_HTML;
|
enum sgml_document_type doctype = SGML_DOCTYPE_HTML;
|
||||||
|
enum sgml_parser_flag flags = 0;
|
||||||
|
enum sgml_parser_code code = 0;
|
||||||
|
int complete = 1;
|
||||||
struct dom_string uri = INIT_DOM_STRING("dom://test", -1);
|
struct dom_string uri = INIT_DOM_STRING("dom://test", -1);
|
||||||
struct dom_string source = INIT_DOM_STRING("(no source)", -1);
|
struct dom_string source = INIT_DOM_STRING("(no source)", -1);
|
||||||
int i;
|
int i;
|
||||||
@ -227,6 +288,16 @@ main(int argc, char *argv[])
|
|||||||
set_dom_string(&source, argv[i], strlen(argv[i]));
|
set_dom_string(&source, argv[i], strlen(argv[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (!strcmp(arg, "print-lines")) {
|
||||||
|
flags |= SGML_PARSER_COUNT_LINES;
|
||||||
|
|
||||||
|
} else if (!strcmp(arg, "incomplete")) {
|
||||||
|
flags |= SGML_PARSER_INCREMENTAL;
|
||||||
|
complete = 0;
|
||||||
|
|
||||||
|
} else if (!strcmp(arg, "error")) {
|
||||||
|
flags |= SGML_PARSER_DETECT_ERRORS;
|
||||||
|
|
||||||
} else if (!strcmp(arg, "help")) {
|
} else if (!strcmp(arg, "help")) {
|
||||||
die(NULL);
|
die(NULL);
|
||||||
|
|
||||||
@ -235,22 +306,27 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parser = init_sgml_parser(SGML_PARSER_STREAM, doctype, &uri);
|
parser = init_sgml_parser(SGML_PARSER_STREAM, doctype, &uri, flags);
|
||||||
if (!parser) return 1;
|
if (!parser) return 1;
|
||||||
|
|
||||||
|
parser->error_func = sgml_error_function;
|
||||||
add_dom_stack_context(&parser->stack, NULL, &sgml_parser_test_context_info);
|
add_dom_stack_context(&parser->stack, NULL, &sgml_parser_test_context_info);
|
||||||
|
|
||||||
root = parse_sgml(parser, &source);
|
code = parse_sgml(parser, &source, complete);
|
||||||
if (root) {
|
if (parser->root) {
|
||||||
assert(parser->stack.depth == 1);
|
size_t root_offset = parser->stack.depth - 1;
|
||||||
|
|
||||||
|
assert(!complete || root_offset == 0);
|
||||||
|
|
||||||
|
get_dom_stack_state(&parser->stack, root_offset)->immutable = 0;
|
||||||
|
|
||||||
get_dom_stack_top(&parser->stack)->immutable = 0;
|
|
||||||
/* For SGML_PARSER_STREAM this will free the DOM
|
/* For SGML_PARSER_STREAM this will free the DOM
|
||||||
* root node. */
|
* root node. */
|
||||||
pop_dom_node(&parser->stack);
|
while (!dom_stack_is_empty(&parser->stack))
|
||||||
|
pop_dom_node(&parser->stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
done_sgml_parser(parser);
|
done_sgml_parser(parser);
|
||||||
|
|
||||||
return 0;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -9,12 +9,12 @@ This test runs very basic features, like checking that nodes are placed
|
|||||||
correctly in the DOM tree.
|
correctly in the DOM tree.
|
||||||
'
|
'
|
||||||
|
|
||||||
. ./libtest
|
. "$TEST_LIB"
|
||||||
|
|
||||||
test_output_equals () {
|
test_output_equals () {
|
||||||
desc="$1"
|
desc="$1"; shift
|
||||||
src="$2"
|
src="$1"; shift
|
||||||
out="$3"
|
out="$1"; shift
|
||||||
|
|
||||||
URI="test:$(echo "$desc" | sed '
|
URI="test:$(echo "$desc" | sed '
|
||||||
s/^[ \t]*\[[^]]*\][ \t]*//;
|
s/^[ \t]*\[[^]]*\][ \t]*//;
|
||||||
@ -28,7 +28,7 @@ test_output_equals () {
|
|||||||
echo "#document: $URI" > expected
|
echo "#document: $URI" > expected
|
||||||
echo "$out" | sed -n '2,$p' >> expected
|
echo "$out" | sed -n '2,$p' >> expected
|
||||||
|
|
||||||
test_expect_success "$desc" 'cmp -b output expected'
|
test_expect_success "$desc" 'cmp output expected'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -55,6 +55,16 @@ element: root
|
|||||||
element: child3
|
element: child3
|
||||||
#text: a'
|
#text: a'
|
||||||
|
|
||||||
|
test_output_equals \
|
||||||
|
'Parse tag soup elements.' \
|
||||||
|
'<parent attr="value" <child:1></><child:2</>a</parent>' \
|
||||||
|
'
|
||||||
|
element: parent
|
||||||
|
attribute: attr -> value
|
||||||
|
element: child:1
|
||||||
|
element: child:2
|
||||||
|
#text: a'
|
||||||
|
|
||||||
test_output_equals \
|
test_output_equals \
|
||||||
'Parse an enclosed comment.' \
|
'Parse an enclosed comment.' \
|
||||||
'<root><!-- Hello World! --></root>' \
|
'<root><!-- Hello World! --></root>' \
|
||||||
@ -63,7 +73,7 @@ element: root
|
|||||||
#comment: Hello World! '
|
#comment: Hello World! '
|
||||||
|
|
||||||
test_output_equals \
|
test_output_equals \
|
||||||
'Parse comment combinations.' \
|
'Parse comment combinations. (I)' \
|
||||||
'<root><!-- <!-- -- > --><!--foo--><!----></root>' \
|
'<root><!-- <!-- -- > --><!--foo--><!----></root>' \
|
||||||
'
|
'
|
||||||
element: root
|
element: root
|
||||||
@ -71,12 +81,29 @@ element: root
|
|||||||
#comment: foo
|
#comment: foo
|
||||||
#comment: '
|
#comment: '
|
||||||
|
|
||||||
|
test_output_equals \
|
||||||
|
'Parse comment combinations. (II).' \
|
||||||
|
'<! -- comment -->s<!-->-->t<!----->u' \
|
||||||
|
'
|
||||||
|
#comment: comment
|
||||||
|
#text: s
|
||||||
|
#comment: >
|
||||||
|
#text: t
|
||||||
|
#comment: -
|
||||||
|
#text: u'
|
||||||
|
|
||||||
test_output_equals \
|
test_output_equals \
|
||||||
'Parse bad comment.' \
|
'Parse bad comment.' \
|
||||||
'<!--->s' \
|
'<!--->s' \
|
||||||
'
|
'
|
||||||
#comment: ->s'
|
#comment: ->s'
|
||||||
|
|
||||||
|
test_output_equals \
|
||||||
|
'Parse empty notation.' \
|
||||||
|
'<!>s' \
|
||||||
|
'
|
||||||
|
#text: s'
|
||||||
|
|
||||||
test_output_equals \
|
test_output_equals \
|
||||||
'Parse an enclosed CDATA section.' \
|
'Parse an enclosed CDATA section.' \
|
||||||
'<root><![CDATA[...] ]>...]]></root>' \
|
'<root><![CDATA[...] ]>...]]></root>' \
|
||||||
@ -167,7 +194,7 @@ test_output_equals \
|
|||||||
'
|
'
|
||||||
proc-instruction: xml -> version="1.0" />
|
proc-instruction: xml -> version="1.0" />
|
||||||
attribute: version -> 1.0
|
attribute: version -> 1.0
|
||||||
proc-instruction: xml -> /'
|
proc-instruction: xml -> />-'
|
||||||
|
|
||||||
test_output_equals \
|
test_output_equals \
|
||||||
'Parse XML stylesheet processing instructions.' \
|
'Parse XML stylesheet processing instructions.' \
|
||||||
|
164
src/dom/test/test-sgml-parser-error
Executable file
164
src/dom/test/test-sgml-parser-error
Executable file
@ -0,0 +1,164 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright (c) 2005 Jonas Fonseca
|
||||||
|
#
|
||||||
|
|
||||||
|
test_description='Test SGML parser error reporting
|
||||||
|
|
||||||
|
This test checks that the SGML parser will report errors in the source
|
||||||
|
given to it.
|
||||||
|
'
|
||||||
|
|
||||||
|
. "$TEST_LIB"
|
||||||
|
|
||||||
|
test_output_error () {
|
||||||
|
desc="$1"; shift
|
||||||
|
src="$1"; shift
|
||||||
|
out="$1"; shift
|
||||||
|
|
||||||
|
sgml-parser --src "$src" --error > output
|
||||||
|
echo "$out" | sed -n '2,$p' > expected
|
||||||
|
|
||||||
|
test_expect_success "$desc" 'cmp output expected'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# Check parsing errors
|
||||||
|
|
||||||
|
test_output_error \
|
||||||
|
'Check an element error.' \
|
||||||
|
'<html' \
|
||||||
|
'
|
||||||
|
error on line 1: <html'
|
||||||
|
|
||||||
|
test_output_error \
|
||||||
|
'Check an entity reference error.' \
|
||||||
|
'a
|
||||||
|
b
|
||||||
|
&c' \
|
||||||
|
'
|
||||||
|
error on line 3: &c'
|
||||||
|
|
||||||
|
test_output_error \
|
||||||
|
'Check multiple entity reference errors.' \
|
||||||
|
'a
|
||||||
|
&b&
|
||||||
|
c
|
||||||
|
&d' \
|
||||||
|
'
|
||||||
|
error on line 2: &b
|
||||||
|
error on line 4: &d'
|
||||||
|
|
||||||
|
test_output_error \
|
||||||
|
'Check incomplete comment. (I)' \
|
||||||
|
'<!-' \
|
||||||
|
'
|
||||||
|
error on line 1: <!-'
|
||||||
|
|
||||||
|
test_output_error \
|
||||||
|
'Check incomplete comment. (II)' \
|
||||||
|
'<!-- ... ' \
|
||||||
|
"
|
||||||
|
error on line 1: <!--"
|
||||||
|
|
||||||
|
test_output_error \
|
||||||
|
'Check incomplete notation. (I)' \
|
||||||
|
'<!' \
|
||||||
|
'
|
||||||
|
error on line 1: <!'
|
||||||
|
|
||||||
|
test_output_error \
|
||||||
|
'Check incomplete notation. (II)' \
|
||||||
|
'<!DOCTYPE ...' \
|
||||||
|
'
|
||||||
|
error on line 1: <!DOCTYPE'
|
||||||
|
|
||||||
|
|
||||||
|
test_output_error \
|
||||||
|
'Check incomplete cdata section. (I)' \
|
||||||
|
'<![CDATA[ ... ' \
|
||||||
|
'
|
||||||
|
error on line 1: <![CDATA['
|
||||||
|
|
||||||
|
|
||||||
|
test_output_error \
|
||||||
|
'Check incomplete cdata section. (II)' \
|
||||||
|
'<![CDAT' \
|
||||||
|
'
|
||||||
|
error on line 1: <![CDAT'
|
||||||
|
|
||||||
|
test_output_error \
|
||||||
|
'Check incomplete processing instruction. (I)' \
|
||||||
|
'<?xml ' \
|
||||||
|
'
|
||||||
|
error on line 1: <?xml'
|
||||||
|
|
||||||
|
test_output_error \
|
||||||
|
'Check incomplete processing instruction. (II)' \
|
||||||
|
'<?xml-stylesheet attr...' \
|
||||||
|
'
|
||||||
|
error on line 1: attr...'
|
||||||
|
|
||||||
|
test_output_error \
|
||||||
|
'Check incomplete reference. (I)' \
|
||||||
|
'�' \
|
||||||
|
'
|
||||||
|
error on line 1: �'
|
||||||
|
|
||||||
|
test_output_error \
|
||||||
|
'Check incomplete reference. (II)' \
|
||||||
|
'&' \
|
||||||
|
'
|
||||||
|
error on line 1: &'
|
||||||
|
|
||||||
|
test_output_error \
|
||||||
|
'Check incomplete element. (I)' \
|
||||||
|
'<elem...' \
|
||||||
|
'
|
||||||
|
error on line 1: <elem...'
|
||||||
|
|
||||||
|
|
||||||
|
test_output_error \
|
||||||
|
'Check incomplete element. (II)' \
|
||||||
|
'<' \
|
||||||
|
'
|
||||||
|
error on line 1: <'
|
||||||
|
|
||||||
|
test_output_error \
|
||||||
|
'Check incomplete element end. (I)' \
|
||||||
|
'<a></a' \
|
||||||
|
'
|
||||||
|
error on line 1: </a'
|
||||||
|
|
||||||
|
test_output_error \
|
||||||
|
'Check incomplete element end. (II)' \
|
||||||
|
'<a></' \
|
||||||
|
'
|
||||||
|
error on line 1: </'
|
||||||
|
|
||||||
|
test_output_error \
|
||||||
|
'Check incomplete attribute.' \
|
||||||
|
'<element attr...' \
|
||||||
|
'
|
||||||
|
error on line 1: attr...'
|
||||||
|
|
||||||
|
test_output_error \
|
||||||
|
'Check incomplete attribute value.' \
|
||||||
|
'<element attr=...' \
|
||||||
|
'
|
||||||
|
error on line 1: ...'
|
||||||
|
|
||||||
|
test_output_error \
|
||||||
|
'Check incomplete attribute quoted value. (I)' \
|
||||||
|
'<element attr="...' \
|
||||||
|
'
|
||||||
|
error on line 1: "...'
|
||||||
|
|
||||||
|
test_output_error \
|
||||||
|
'Check incomplete attribute quoted value. (II)' \
|
||||||
|
"<element attr='..." \
|
||||||
|
"
|
||||||
|
error on line 1: '..."
|
||||||
|
|
||||||
|
test_done
|
107
src/dom/test/test-sgml-parser-incomplete
Executable file
107
src/dom/test/test-sgml-parser-incomplete
Executable file
@ -0,0 +1,107 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright (c) 2005 Jonas Fonseca
|
||||||
|
#
|
||||||
|
|
||||||
|
test_description='Test that incompleteness is correctly detected
|
||||||
|
|
||||||
|
This test checks that the SGML parser correctly finds and reports
|
||||||
|
when a part of the source is incomplete.
|
||||||
|
'
|
||||||
|
|
||||||
|
. "$TEST_LIB"
|
||||||
|
|
||||||
|
test_expect_incomplete () {
|
||||||
|
desc="$1"; shift
|
||||||
|
src="$1"; shift
|
||||||
|
|
||||||
|
sgml-parser --src "$src" --incomplete >/dev/null
|
||||||
|
test_expect_success "$desc" \
|
||||||
|
"test $? = 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# Check for incompleteness
|
||||||
|
|
||||||
|
test_expect_incomplete \
|
||||||
|
'Check incomplete comment. (I)' \
|
||||||
|
'<!-'
|
||||||
|
|
||||||
|
test_expect_incomplete \
|
||||||
|
'Check incomplete comment. (II)' \
|
||||||
|
'<!-- ... '
|
||||||
|
|
||||||
|
test_expect_incomplete \
|
||||||
|
'Check incomplete notation. (I)' \
|
||||||
|
'<!'
|
||||||
|
|
||||||
|
test_expect_incomplete \
|
||||||
|
'Check incomplete notation. (II)' \
|
||||||
|
'<!D'
|
||||||
|
|
||||||
|
test_expect_incomplete \
|
||||||
|
'Check incomplete cdata section. (I)' \
|
||||||
|
'<![CDATA[ ... '
|
||||||
|
|
||||||
|
test_expect_incomplete \
|
||||||
|
'Check incomplete cdata section. (II)' \
|
||||||
|
'<![CDAT'
|
||||||
|
|
||||||
|
test_expect_incomplete \
|
||||||
|
'Check incomplete element. (I)' \
|
||||||
|
'<elem...'
|
||||||
|
|
||||||
|
test_expect_incomplete \
|
||||||
|
'Check incomplete element. (II)' \
|
||||||
|
'<'
|
||||||
|
|
||||||
|
test_expect_incomplete \
|
||||||
|
'Check incomplete element end. (I)' \
|
||||||
|
'<a></a'
|
||||||
|
|
||||||
|
test_expect_incomplete \
|
||||||
|
'Check incomplete element end. (II)' \
|
||||||
|
'<a></'
|
||||||
|
|
||||||
|
test_expect_incomplete \
|
||||||
|
'Check incomplete attribute.' \
|
||||||
|
'<element attr...'
|
||||||
|
|
||||||
|
test_expect_incomplete \
|
||||||
|
'Check incomplete attribute value.' \
|
||||||
|
'<element attr=...'
|
||||||
|
|
||||||
|
test_expect_incomplete \
|
||||||
|
'Check incomplete attribute quoted value. (I)' \
|
||||||
|
'<element attr="...'
|
||||||
|
|
||||||
|
test_expect_incomplete \
|
||||||
|
'Check incomplete attribute quoted value. (II)' \
|
||||||
|
"<element attr='..."
|
||||||
|
|
||||||
|
test_expect_incomplete \
|
||||||
|
'Check incomplete processing instruction. (I)' \
|
||||||
|
'<?xml'
|
||||||
|
|
||||||
|
test_expect_incomplete \
|
||||||
|
'Check incomplete processing instruction. (II)' \
|
||||||
|
'<?xml attr...'
|
||||||
|
|
||||||
|
test_expect_incomplete \
|
||||||
|
'Check incomplete notation.' \
|
||||||
|
'<!DOCTYPE html PUBLIC ...'
|
||||||
|
|
||||||
|
test_expect_incomplete \
|
||||||
|
'Check incomplete reference. (I)' \
|
||||||
|
'�'
|
||||||
|
|
||||||
|
test_expect_incomplete \
|
||||||
|
'Check incomplete reference. (II)' \
|
||||||
|
'&'
|
||||||
|
|
||||||
|
test_expect_incomplete \
|
||||||
|
'Check incomplete text.' \
|
||||||
|
'plain text is always incomplete (if incomplete)'
|
||||||
|
|
||||||
|
test_done
|
59
src/dom/test/test-sgml-parser-lines
Executable file
59
src/dom/test/test-sgml-parser-lines
Executable file
@ -0,0 +1,59 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright (c) 2005 Jonas Fonseca
|
||||||
|
#
|
||||||
|
|
||||||
|
test_description='Test the SGML parsers counting of lines
|
||||||
|
|
||||||
|
Checks that the SGML parser correctly reports how many lines the
|
||||||
|
source has.
|
||||||
|
'
|
||||||
|
|
||||||
|
. "$TEST_LIB"
|
||||||
|
|
||||||
|
test_output_line_numbers () {
|
||||||
|
desc="$1"; shift
|
||||||
|
src="$1"; shift
|
||||||
|
expected_lines="$1"; shift
|
||||||
|
|
||||||
|
lines=$(sgml-parser --src "$src" --print-lines)
|
||||||
|
|
||||||
|
test_expect_success "$desc" "test $lines = $expected_lines"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# Check line numbers
|
||||||
|
|
||||||
|
test_output_line_numbers \
|
||||||
|
'Check line numbers. (I)' \
|
||||||
|
'<!-- line --> number <one />' \
|
||||||
|
1
|
||||||
|
|
||||||
|
test_output_line_numbers \
|
||||||
|
'Check line numbers. (II)' \
|
||||||
|
'<
|
||||||
|
line:2
|
||||||
|
line:3
|
||||||
|
=
|
||||||
|
"line:5"
|
||||||
|
><?xml
|
||||||
|
line:7="..."
|
||||||
|
line:8
|
||||||
|
=
|
||||||
|
'\''...'\''></line:10>' \
|
||||||
|
10
|
||||||
|
|
||||||
|
test_output_line_numbers \
|
||||||
|
'Check line numbers. (III)' \
|
||||||
|
'1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
5
|
||||||
|
6
|
||||||
|
7
|
||||||
|
8' \
|
||||||
|
8
|
||||||
|
|
||||||
|
test_done
|
@ -2,7 +2,10 @@ top_builddir=../..
|
|||||||
include $(top_builddir)/Makefile.config
|
include $(top_builddir)/Makefile.config
|
||||||
INCLUDES += $(SPIDERMONKEY_CFLAGS)
|
INCLUDES += $(SPIDERMONKEY_CFLAGS)
|
||||||
|
|
||||||
SUBDIRS = spidermonkey
|
SUBDIRS-$(CONFIG_SPIDERMONKEY) += spidermonkey
|
||||||
OBJS = ecmascript.o spidermonkey.o
|
SUBDIRS-$(CONFIG_SEE) += see
|
||||||
|
OBJS-$(CONFIG_SPIDERMONKEY) += spidermonkey.o
|
||||||
|
OBJS-$(CONFIG_SEE) += see.o
|
||||||
|
OBJS = ecmascript.o
|
||||||
|
|
||||||
include $(top_srcdir)/Makefile.lib
|
include $(top_srcdir)/Makefile.lib
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
#include "document/document.h"
|
#include "document/document.h"
|
||||||
#include "document/view.h"
|
#include "document/view.h"
|
||||||
#include "ecmascript/ecmascript.h"
|
#include "ecmascript/ecmascript.h"
|
||||||
#include "ecmascript/spidermonkey.h"
|
|
||||||
#include "intl/gettext/libintl.h"
|
#include "intl/gettext/libintl.h"
|
||||||
#include "main/module.h"
|
#include "main/module.h"
|
||||||
#include "protocol/uri.h"
|
#include "protocol/uri.h"
|
||||||
@ -61,49 +60,6 @@ static struct option_info ecmascript_options[] = {
|
|||||||
NULL_OPTION_INFO,
|
NULL_OPTION_INFO,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define get_ecmascript_enable() get_opt_bool("ecmascript.enable")
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
ecmascript_init(struct module *module)
|
|
||||||
{
|
|
||||||
spidermonkey_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
ecmascript_done(struct module *module)
|
|
||||||
{
|
|
||||||
spidermonkey_done();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct ecmascript_interpreter *
|
|
||||||
ecmascript_get_interpreter(struct view_state *vs)
|
|
||||||
{
|
|
||||||
struct ecmascript_interpreter *interpreter;
|
|
||||||
|
|
||||||
assert(vs);
|
|
||||||
|
|
||||||
interpreter = mem_calloc(1, sizeof(*interpreter));
|
|
||||||
if (!interpreter)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
interpreter->vs = vs;
|
|
||||||
init_list(interpreter->onload_snippets);
|
|
||||||
spidermonkey_get_interpreter(interpreter);
|
|
||||||
|
|
||||||
return interpreter;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ecmascript_put_interpreter(struct ecmascript_interpreter *interpreter)
|
|
||||||
{
|
|
||||||
assert(interpreter);
|
|
||||||
spidermonkey_put_interpreter(interpreter);
|
|
||||||
free_string_list(&interpreter->onload_snippets);
|
|
||||||
mem_free(interpreter);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ecmascript_reset_state(struct view_state *vs)
|
ecmascript_reset_state(struct view_state *vs)
|
||||||
{
|
{
|
||||||
@ -124,40 +80,6 @@ ecmascript_reset_state(struct view_state *vs)
|
|||||||
vs->ecmascript_fragile = 1;
|
vs->ecmascript_fragile = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
ecmascript_eval(struct ecmascript_interpreter *interpreter,
|
|
||||||
struct string *code)
|
|
||||||
{
|
|
||||||
if (!get_ecmascript_enable())
|
|
||||||
return;
|
|
||||||
assert(interpreter);
|
|
||||||
spidermonkey_eval(interpreter, code);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned char *
|
|
||||||
ecmascript_eval_stringback(struct ecmascript_interpreter *interpreter,
|
|
||||||
struct string *code)
|
|
||||||
{
|
|
||||||
if (!get_ecmascript_enable())
|
|
||||||
return NULL;
|
|
||||||
assert(interpreter);
|
|
||||||
return spidermonkey_eval_stringback(interpreter, code);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
ecmascript_eval_boolback(struct ecmascript_interpreter *interpreter,
|
|
||||||
struct string *code)
|
|
||||||
{
|
|
||||||
if (!get_ecmascript_enable())
|
|
||||||
return -1;
|
|
||||||
assert(interpreter);
|
|
||||||
return spidermonkey_eval_boolback(interpreter, code);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ecmascript_protocol_handler(struct session *ses, struct uri *uri)
|
ecmascript_protocol_handler(struct session *ses, struct uri *uri)
|
||||||
{
|
{
|
||||||
@ -197,6 +119,20 @@ ecmascript_protocol_handler(struct session *ses, struct uri *uri)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ecmascript_timeout_dialog(struct terminal *term, int max_exec_time)
|
||||||
|
{
|
||||||
|
info_box(term, MSGBOX_FREE_TEXT,
|
||||||
|
N_("JavaScript Emergency"), ALIGN_LEFT,
|
||||||
|
msg_text(term,
|
||||||
|
N_("A script embedded in the current document was running\n"
|
||||||
|
"for more than %d seconds. This probably means there is\n"
|
||||||
|
"a bug in the script and it could have halted the whole\n"
|
||||||
|
"ELinks, so the script execution was interrupted."),
|
||||||
|
max_exec_time));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
struct module ecmascript_module = struct_module(
|
struct module ecmascript_module = struct_module(
|
||||||
/* name: */ N_("ECMAScript"),
|
/* name: */ N_("ECMAScript"),
|
||||||
/* options: */ ecmascript_options,
|
/* options: */ ecmascript_options,
|
||||||
|
@ -9,9 +9,12 @@
|
|||||||
#include "util/time.h"
|
#include "util/time.h"
|
||||||
|
|
||||||
struct string;
|
struct string;
|
||||||
|
struct terminal;
|
||||||
struct uri;
|
struct uri;
|
||||||
struct view_state;
|
struct view_state;
|
||||||
|
|
||||||
|
#define get_ecmascript_enable() get_opt_bool("ecmascript.enable")
|
||||||
|
|
||||||
struct ecmascript_interpreter {
|
struct ecmascript_interpreter {
|
||||||
struct view_state *vs;
|
struct view_state *vs;
|
||||||
void *backend_data;
|
void *backend_data;
|
||||||
@ -63,6 +66,11 @@ int ecmascript_eval_boolback(struct ecmascript_interpreter *interpreter, struct
|
|||||||
* follows a link with this synstax. */
|
* follows a link with this synstax. */
|
||||||
void ecmascript_protocol_handler(struct session *ses, struct uri *uri);
|
void ecmascript_protocol_handler(struct session *ses, struct uri *uri);
|
||||||
|
|
||||||
|
void ecmascript_init(struct module *);
|
||||||
|
void ecmascript_done(struct module *);
|
||||||
|
void ecmascript_timeout_dialog(struct terminal *term, int max_exec_time);
|
||||||
|
|
||||||
|
|
||||||
extern struct module ecmascript_module;
|
extern struct module ecmascript_module;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
243
src/ecmascript/see.c
Normal file
243
src/ecmascript/see.c
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
/* The SEE ECMAScript backend. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "elinks.h"
|
||||||
|
|
||||||
|
#include <see/see.h>
|
||||||
|
|
||||||
|
#include "bfu/dialog.h"
|
||||||
|
#include "cache/cache.h"
|
||||||
|
#include "cookies/cookies.h"
|
||||||
|
#include "dialogs/menu.h"
|
||||||
|
#include "dialogs/status.h"
|
||||||
|
#include "document/html/frames.h"
|
||||||
|
#include "document/document.h"
|
||||||
|
#include "document/forms.h"
|
||||||
|
#include "document/view.h"
|
||||||
|
#include "ecmascript/ecmascript.h"
|
||||||
|
#include "ecmascript/see.h"
|
||||||
|
#include "ecmascript/see/document.h"
|
||||||
|
#include "ecmascript/see/form.h"
|
||||||
|
#include "ecmascript/see/input.h"
|
||||||
|
#include "ecmascript/see/location.h"
|
||||||
|
#include "ecmascript/see/navigator.h"
|
||||||
|
#include "ecmascript/see/strings.h"
|
||||||
|
#include "ecmascript/see/unibar.h"
|
||||||
|
#include "ecmascript/see/window.h"
|
||||||
|
#include "intl/gettext/libintl.h"
|
||||||
|
#include "main/select.h"
|
||||||
|
#include "osdep/newwin.h"
|
||||||
|
#include "osdep/sysname.h"
|
||||||
|
#include "protocol/http/http.h"
|
||||||
|
#include "protocol/uri.h"
|
||||||
|
#include "session/history.h"
|
||||||
|
#include "session/location.h"
|
||||||
|
#include "session/session.h"
|
||||||
|
#include "session/task.h"
|
||||||
|
#include "terminal/tab.h"
|
||||||
|
#include "terminal/terminal.h"
|
||||||
|
#include "util/conv.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
#include "viewer/text/draw.h"
|
||||||
|
#include "viewer/text/form.h"
|
||||||
|
#include "viewer/text/link.h"
|
||||||
|
#include "viewer/text/vs.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*** Global methods */
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO? Are there any which need to be implemented? */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*** The ELinks interface */
|
||||||
|
|
||||||
|
void
|
||||||
|
ecmascript_init(struct module *module)
|
||||||
|
{
|
||||||
|
see_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ecmascript_done(struct module *module)
|
||||||
|
{
|
||||||
|
see_done();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ecmascript_interpreter *
|
||||||
|
ecmascript_get_interpreter(struct view_state *vs)
|
||||||
|
{
|
||||||
|
struct ecmascript_interpreter *interpreter;
|
||||||
|
|
||||||
|
assert(vs);
|
||||||
|
|
||||||
|
interpreter = mem_calloc(1, sizeof(*interpreter));
|
||||||
|
if (!interpreter)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
interpreter->vs = vs;
|
||||||
|
init_list(interpreter->onload_snippets);
|
||||||
|
see_get_interpreter(interpreter);
|
||||||
|
|
||||||
|
return interpreter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ecmascript_put_interpreter(struct ecmascript_interpreter *interpreter)
|
||||||
|
{
|
||||||
|
assert(interpreter);
|
||||||
|
see_put_interpreter(interpreter);
|
||||||
|
free_string_list(&interpreter->onload_snippets);
|
||||||
|
mem_free(interpreter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ecmascript_eval(struct ecmascript_interpreter *interpreter,
|
||||||
|
struct string *code)
|
||||||
|
{
|
||||||
|
if (!get_ecmascript_enable())
|
||||||
|
return;
|
||||||
|
assert(interpreter);
|
||||||
|
see_eval(interpreter, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *
|
||||||
|
ecmascript_eval_stringback(struct ecmascript_interpreter *interpreter,
|
||||||
|
struct string *code)
|
||||||
|
{
|
||||||
|
if (!get_ecmascript_enable())
|
||||||
|
return NULL;
|
||||||
|
assert(interpreter);
|
||||||
|
return see_eval_stringback(interpreter, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ecmascript_eval_boolback(struct ecmascript_interpreter *interpreter,
|
||||||
|
struct string *code)
|
||||||
|
{
|
||||||
|
if (!get_ecmascript_enable())
|
||||||
|
return -1;
|
||||||
|
assert(interpreter);
|
||||||
|
return see_eval_boolback(interpreter, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
see_init(void)
|
||||||
|
{
|
||||||
|
init_intern_strings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
see_done(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
see_get_interpreter(struct ecmascript_interpreter *interpreter)
|
||||||
|
{
|
||||||
|
struct global_object *g = SEE_NEW(NULL, struct global_object);
|
||||||
|
struct SEE_interpreter *interp = &g->interp;
|
||||||
|
|
||||||
|
interpreter->backend_data = g;
|
||||||
|
g->max_exec_time = get_opt_int("ecmascript.max_exec_time");
|
||||||
|
g->exec_start = time(NULL);
|
||||||
|
SEE_interpreter_init(interp);
|
||||||
|
init_js_window_object(interpreter);
|
||||||
|
init_js_menubar_object(interpreter);
|
||||||
|
init_js_statusbar_object(interpreter);
|
||||||
|
init_js_navigator_object(interpreter);
|
||||||
|
init_js_history_object(interpreter);
|
||||||
|
init_js_location_object(interpreter);
|
||||||
|
init_js_document_object(interpreter);
|
||||||
|
init_js_forms_object(interpreter);
|
||||||
|
return interp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
see_put_interpreter(struct ecmascript_interpreter *interpreter)
|
||||||
|
{
|
||||||
|
interpreter->backend_data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
see_eval(struct ecmascript_interpreter *interpreter,
|
||||||
|
struct string *code)
|
||||||
|
{
|
||||||
|
|
||||||
|
struct SEE_interpreter *interp = interpreter->backend_data;
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct SEE_input *input = SEE_input_elinks(interp, code->source);
|
||||||
|
SEE_try_context_t try_ctxt;
|
||||||
|
struct SEE_value result;
|
||||||
|
struct SEE_value v;
|
||||||
|
|
||||||
|
g->exec_start = time(NULL);
|
||||||
|
SEE_TRY(interp, try_ctxt) {
|
||||||
|
SEE_Global_eval(interp, input, &result);
|
||||||
|
}
|
||||||
|
|
||||||
|
SEE_INPUT_CLOSE(input);
|
||||||
|
SEE_CAUGHT(try_ctxt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned char *
|
||||||
|
see_eval_stringback(struct ecmascript_interpreter *interpreter,
|
||||||
|
struct string *code)
|
||||||
|
{
|
||||||
|
struct SEE_interpreter *interp = interpreter->backend_data;
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct SEE_input *input = SEE_input_elinks(interp, code->source);
|
||||||
|
SEE_try_context_t try_ctxt;
|
||||||
|
struct SEE_value result;
|
||||||
|
unsigned char *string = NULL;
|
||||||
|
|
||||||
|
g->exec_start = time(NULL);
|
||||||
|
SEE_TRY(interp, try_ctxt) {
|
||||||
|
SEE_Global_eval(interp, input, &result);
|
||||||
|
if (SEE_VALUE_GET_TYPE(&result) != SEE_NULL)
|
||||||
|
string = SEE_value_to_unsigned_char(interp, &result);
|
||||||
|
|
||||||
|
}
|
||||||
|
SEE_INPUT_CLOSE(input);
|
||||||
|
if (SEE_CAUGHT(try_ctxt)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
see_eval_boolback(struct ecmascript_interpreter *interpreter,
|
||||||
|
struct string *code)
|
||||||
|
{
|
||||||
|
struct SEE_interpreter *interp = interpreter->backend_data;
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct SEE_input *input = SEE_input_elinks(interp, code->source);
|
||||||
|
SEE_try_context_t try_ctxt;
|
||||||
|
struct SEE_value result;
|
||||||
|
SEE_int32_t res = 0;
|
||||||
|
|
||||||
|
g->exec_start = time(NULL);
|
||||||
|
SEE_TRY(interp, try_ctxt) {
|
||||||
|
SEE_Global_eval(interp, input, &result);
|
||||||
|
/* history.back() returns SEE_NULL */
|
||||||
|
if (SEE_VALUE_GET_TYPE(&result) == SEE_NULL)
|
||||||
|
res = 0;
|
||||||
|
else
|
||||||
|
res = SEE_ToInt32(interp, &result);
|
||||||
|
}
|
||||||
|
|
||||||
|
SEE_INPUT_CLOSE(input);
|
||||||
|
if (SEE_CAUGHT(try_ctxt)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
17
src/ecmascript/see.h
Normal file
17
src/ecmascript/see.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef EL__ECMASCRIPT_SEE_H
|
||||||
|
#define EL__ECMASCRIPT_SEE_H
|
||||||
|
|
||||||
|
struct ecmascript_interpreter;
|
||||||
|
struct string;
|
||||||
|
|
||||||
|
void see_init();
|
||||||
|
void see_done();
|
||||||
|
|
||||||
|
void *see_get_interpreter(struct ecmascript_interpreter *interpreter);
|
||||||
|
void see_put_interpreter(struct ecmascript_interpreter *interpreter);
|
||||||
|
|
||||||
|
void see_eval(struct ecmascript_interpreter *interpreter, struct string *code);
|
||||||
|
unsigned char *see_eval_stringback(struct ecmascript_interpreter *interpreter, struct string *code);
|
||||||
|
int see_eval_boolback(struct ecmascript_interpreter *interpreter, struct string *code);
|
||||||
|
|
||||||
|
#endif
|
6
src/ecmascript/see/Makefile
Normal file
6
src/ecmascript/see/Makefile
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
top_builddir=../../..
|
||||||
|
include $(top_builddir)/Makefile.config
|
||||||
|
|
||||||
|
OBJS = document.o form.o input.o location.o navigator.o strings.o unibar.o window.o
|
||||||
|
|
||||||
|
include $(top_srcdir)/Makefile.lib
|
257
src/ecmascript/see/document.c
Normal file
257
src/ecmascript/see/document.c
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
/* The SEE document object implementation. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "elinks.h"
|
||||||
|
|
||||||
|
#include <see/see.h>
|
||||||
|
|
||||||
|
#include "bfu/dialog.h"
|
||||||
|
#include "cache/cache.h"
|
||||||
|
#include "cookies/cookies.h"
|
||||||
|
#include "dialogs/menu.h"
|
||||||
|
#include "dialogs/status.h"
|
||||||
|
#include "document/html/frames.h"
|
||||||
|
#include "document/document.h"
|
||||||
|
#include "document/forms.h"
|
||||||
|
#include "document/view.h"
|
||||||
|
#include "ecmascript/ecmascript.h"
|
||||||
|
#include "ecmascript/see/document.h"
|
||||||
|
#include "ecmascript/see/form.h"
|
||||||
|
#include "ecmascript/see/input.h"
|
||||||
|
#include "ecmascript/see/strings.h"
|
||||||
|
#include "ecmascript/see/window.h"
|
||||||
|
#include "intl/gettext/libintl.h"
|
||||||
|
#include "main/select.h"
|
||||||
|
#include "osdep/newwin.h"
|
||||||
|
#include "osdep/sysname.h"
|
||||||
|
#include "protocol/http/http.h"
|
||||||
|
#include "protocol/uri.h"
|
||||||
|
#include "session/history.h"
|
||||||
|
#include "session/location.h"
|
||||||
|
#include "session/session.h"
|
||||||
|
#include "session/task.h"
|
||||||
|
#include "terminal/tab.h"
|
||||||
|
#include "terminal/terminal.h"
|
||||||
|
#include "util/conv.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
#include "viewer/text/draw.h"
|
||||||
|
#include "viewer/text/form.h"
|
||||||
|
#include "viewer/text/link.h"
|
||||||
|
#include "viewer/text/vs.h"
|
||||||
|
|
||||||
|
static void document_get(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *);
|
||||||
|
static void document_put(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *, int);
|
||||||
|
static int document_canput(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
|
||||||
|
static int document_hasproperty(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
|
||||||
|
static void js_document_write(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
|
||||||
|
|
||||||
|
void location_goto(struct document_view *, unsigned char *);
|
||||||
|
|
||||||
|
struct SEE_objectclass js_document_object_class = {
|
||||||
|
NULL,
|
||||||
|
document_get,
|
||||||
|
document_put,
|
||||||
|
document_canput,
|
||||||
|
document_hasproperty,
|
||||||
|
SEE_no_delete,
|
||||||
|
SEE_no_defaultvalue,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
document_get(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p, struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct js_window_object *win = g->win;
|
||||||
|
struct view_state *vs = win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct document *document = doc_view->document;
|
||||||
|
struct js_document_object *doc = (struct js_document_object *)o;
|
||||||
|
struct session *ses = doc_view->session;
|
||||||
|
struct SEE_string *str;
|
||||||
|
unsigned char *string;
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
SEE_SET_UNDEFINED(res);
|
||||||
|
|
||||||
|
if (p == s_cookie) {
|
||||||
|
#ifdef CONFIG_COOKIES
|
||||||
|
struct string *cookies = send_cookies(vs->uri);
|
||||||
|
|
||||||
|
if (cookies) {
|
||||||
|
static unsigned char cookiestr[1024];
|
||||||
|
strncpy(cookiestr, cookies->source, 1024);
|
||||||
|
done_string(cookies);
|
||||||
|
|
||||||
|
str = string_to_SEE_string(interp, cookiestr);
|
||||||
|
} else {
|
||||||
|
str = string_to_SEE_string(interp, "");
|
||||||
|
}
|
||||||
|
SEE_SET_STRING(res, str);
|
||||||
|
#endif
|
||||||
|
} else if (p == s_title) {
|
||||||
|
str = string_to_SEE_string(interp, document->title);
|
||||||
|
SEE_SET_STRING(res, str);
|
||||||
|
} else if (p == s_url) {
|
||||||
|
string = get_uri_string(document->uri, URI_ORIGINAL);
|
||||||
|
str = string_to_SEE_string(interp, string);
|
||||||
|
mem_free_if(string);
|
||||||
|
SEE_SET_STRING(res, str);
|
||||||
|
} else if (p == s_location) {
|
||||||
|
SEE_OBJECT_GET(interp, interp->Global, s_location, res);
|
||||||
|
} else if (p == s_referrer) {
|
||||||
|
switch (get_opt_int("protocol.http.referer.policy")) {
|
||||||
|
case REFERER_NONE:
|
||||||
|
SEE_SET_UNDEFINED(res);
|
||||||
|
break;
|
||||||
|
case REFERER_FAKE:
|
||||||
|
str = string_to_SEE_string(interp,
|
||||||
|
get_opt_str("protocol.http.referer.fake"));
|
||||||
|
SEE_SET_STRING(res, str);
|
||||||
|
break;
|
||||||
|
case REFERER_TRUE:
|
||||||
|
if (ses->referrer) {
|
||||||
|
string = get_uri_string(ses->referrer, URI_HTTP_REFERRER);
|
||||||
|
str = string_to_SEE_string(interp, string);
|
||||||
|
mem_free_if(string);
|
||||||
|
SEE_SET_STRING(res, str);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case REFERER_SAME_URL:
|
||||||
|
string = get_uri_string(document->uri, URI_HTTP_REFERRER);
|
||||||
|
str = string_to_SEE_string(interp, string);
|
||||||
|
mem_free_if(string);
|
||||||
|
SEE_SET_STRING(res, str);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
} else if (p == s_forms) {
|
||||||
|
SEE_SET_OBJECT(res, doc->forms);
|
||||||
|
} else {
|
||||||
|
struct form *form;
|
||||||
|
unsigned char *string = SEE_string_to_unsigned_char(p);
|
||||||
|
struct form_view *form_view;
|
||||||
|
struct js_form *form_object;
|
||||||
|
|
||||||
|
foreach (form, document->forms) {
|
||||||
|
if (!form->name || strcasecmp(string, form->name))
|
||||||
|
continue;
|
||||||
|
mem_free_if(string);
|
||||||
|
form_view = find_form_view(doc_view, form);
|
||||||
|
form_object = js_get_form_object(interp, doc, form_view);
|
||||||
|
SEE_SET_OBJECT(res, (struct SEE_object *)form_object);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
document_put(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p, struct SEE_value *val, int attr)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct document *document = doc_view->document;
|
||||||
|
struct js_document_object *doc = (struct js_document_object *)o;
|
||||||
|
struct SEE_value res;
|
||||||
|
unsigned char *string;
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
if (p == s_forms) {
|
||||||
|
SEE_ToObject(interp, val, &res);
|
||||||
|
doc->forms = res.u.object;
|
||||||
|
} else if (p == s_title) {
|
||||||
|
string = SEE_value_to_unsigned_char(interp, val);
|
||||||
|
mem_free_set(&document->title, string);
|
||||||
|
print_screen_status(doc_view->session);
|
||||||
|
} else if (p == s_location || p == s_url) {
|
||||||
|
/* According to the specs this should be readonly but some
|
||||||
|
* broken sites still assign to it (i.e.
|
||||||
|
* http://www.e-handelsfonden.dk/validering.asp?URL=www.polyteknisk.dk).
|
||||||
|
* So emulate window.location. */
|
||||||
|
string = SEE_value_to_unsigned_char(interp, val);
|
||||||
|
location_goto(doc_view, string);
|
||||||
|
mem_free_if(string);
|
||||||
|
} else if (p == s_cookie) {
|
||||||
|
#ifdef CONFIG_COOKIES
|
||||||
|
string = SEE_value_to_unsigned_char(interp, val);
|
||||||
|
set_cookie(vs->uri, string);
|
||||||
|
mem_free_if(string);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
js_document_write(struct SEE_interpreter *interp, struct SEE_object *self,
|
||||||
|
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
|
||||||
|
struct SEE_value *res)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_LEDS
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
|
||||||
|
/* XXX: I don't know about you, but I have *ENOUGH* of those 'Undefined
|
||||||
|
* function' errors, I want to see just the useful ones. So just
|
||||||
|
* lighting a led and going away, no muss, no fuss. --pasky */
|
||||||
|
/* TODO: Perhaps we can introduce ecmascript.error_report_unsupported
|
||||||
|
* -> "Show information about the document using some valid,
|
||||||
|
* nevertheless unsupported methods/properties." --pasky too */
|
||||||
|
|
||||||
|
set_led_value(vs->doc_view->session->status.ecmascript_led, 'J');
|
||||||
|
#endif
|
||||||
|
checktime(interp);
|
||||||
|
SEE_SET_BOOLEAN(res, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
document_canput(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p)
|
||||||
|
{
|
||||||
|
checktime(interp);
|
||||||
|
if (p == s_location || p == s_url || p == s_cookie)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
document_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p)
|
||||||
|
{
|
||||||
|
checktime(interp);
|
||||||
|
/* all unknown properties return UNDEFINED value */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
init_js_document_object(struct ecmascript_interpreter *interpreter)
|
||||||
|
{
|
||||||
|
struct global_object *g = interpreter->backend_data;
|
||||||
|
struct SEE_interpreter *interp = &g->interp;
|
||||||
|
struct SEE_value v;
|
||||||
|
struct js_document_object *doc = SEE_NEW(interp,
|
||||||
|
struct js_document_object);
|
||||||
|
|
||||||
|
doc->object.objectclass = &js_document_object_class;
|
||||||
|
doc->object.objectclass->Class = s_document;
|
||||||
|
doc->object.Prototype = NULL;
|
||||||
|
|
||||||
|
SEE_SET_OBJECT(&v, (struct SEE_object *)doc);
|
||||||
|
SEE_OBJECT_PUT(interp, interp->Global, s_document, &v, 0);
|
||||||
|
|
||||||
|
doc->write = SEE_cfunction_make(interp, js_document_write, s_write, 1);
|
||||||
|
}
|
14
src/ecmascript/see/document.h
Normal file
14
src/ecmascript/see/document.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef EL__ECMASCRIPT_SEE_DOCUMENT_H
|
||||||
|
#define EL__ECMASCRIPT_SEE_DOCUMENT_H
|
||||||
|
|
||||||
|
struct ecmascript_interpreter;
|
||||||
|
|
||||||
|
struct js_document_object {
|
||||||
|
struct SEE_object object;
|
||||||
|
struct SEE_object *write;
|
||||||
|
struct SEE_object *forms;
|
||||||
|
};
|
||||||
|
|
||||||
|
void init_js_document_object(struct ecmascript_interpreter *);
|
||||||
|
|
||||||
|
#endif
|
964
src/ecmascript/see/form.c
Normal file
964
src/ecmascript/see/form.c
Normal file
@ -0,0 +1,964 @@
|
|||||||
|
/* The SEE form object implementation. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "elinks.h"
|
||||||
|
|
||||||
|
#include <see/see.h>
|
||||||
|
|
||||||
|
#include "bfu/dialog.h"
|
||||||
|
#include "cache/cache.h"
|
||||||
|
#include "cookies/cookies.h"
|
||||||
|
#include "dialogs/menu.h"
|
||||||
|
#include "dialogs/status.h"
|
||||||
|
#include "document/html/frames.h"
|
||||||
|
#include "document/document.h"
|
||||||
|
#include "document/forms.h"
|
||||||
|
#include "document/view.h"
|
||||||
|
#include "ecmascript/ecmascript.h"
|
||||||
|
#include "ecmascript/see/document.h"
|
||||||
|
#include "ecmascript/see/form.h"
|
||||||
|
#include "ecmascript/see/input.h"
|
||||||
|
#include "ecmascript/see/strings.h"
|
||||||
|
#include "ecmascript/see/window.h"
|
||||||
|
#include "intl/gettext/libintl.h"
|
||||||
|
#include "main/select.h"
|
||||||
|
#include "osdep/newwin.h"
|
||||||
|
#include "osdep/sysname.h"
|
||||||
|
#include "protocol/http/http.h"
|
||||||
|
#include "protocol/uri.h"
|
||||||
|
#include "session/history.h"
|
||||||
|
#include "session/location.h"
|
||||||
|
#include "session/session.h"
|
||||||
|
#include "session/task.h"
|
||||||
|
#include "terminal/tab.h"
|
||||||
|
#include "terminal/terminal.h"
|
||||||
|
#include "util/conv.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
#include "viewer/text/draw.h"
|
||||||
|
#include "viewer/text/form.h"
|
||||||
|
#include "viewer/text/link.h"
|
||||||
|
#include "viewer/text/vs.h"
|
||||||
|
|
||||||
|
static void input_get(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *);
|
||||||
|
static void input_put(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *, int);
|
||||||
|
static void js_input_blur(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
|
||||||
|
static void js_input_click(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
|
||||||
|
static void js_input_focus(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
|
||||||
|
static void js_input_select(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
|
||||||
|
static int input_canput(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
|
||||||
|
static int input_hasproperty(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
|
||||||
|
static struct js_input *js_get_input_object(struct SEE_interpreter *, struct js_form *, struct form_state *);
|
||||||
|
static struct js_input *js_get_form_control_object(struct SEE_interpreter *, struct js_form *, enum form_type, struct form_state *);
|
||||||
|
|
||||||
|
static void js_form_elems_item(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
|
||||||
|
static void js_form_elems_namedItem(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
|
||||||
|
static void form_elems_get(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *);
|
||||||
|
static int form_elems_hasproperty(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
|
||||||
|
|
||||||
|
static void js_forms_item(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
|
||||||
|
static void js_forms_namedItem(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
|
||||||
|
static void forms_get(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *);
|
||||||
|
static int forms_hasproperty(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
|
||||||
|
|
||||||
|
static void form_get(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *);
|
||||||
|
static void form_put(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *, int);
|
||||||
|
static int form_canput(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
|
||||||
|
static int form_hasproperty(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
|
||||||
|
static void js_form_reset(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
|
||||||
|
static void js_form_submit(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
|
||||||
|
|
||||||
|
|
||||||
|
struct SEE_objectclass js_input_object_class = {
|
||||||
|
NULL,
|
||||||
|
input_get,
|
||||||
|
input_put,
|
||||||
|
input_canput,
|
||||||
|
input_hasproperty,
|
||||||
|
SEE_no_delete,
|
||||||
|
SEE_no_defaultvalue,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SEE_objectclass js_form_elems_class = {
|
||||||
|
NULL,
|
||||||
|
form_elems_get,
|
||||||
|
SEE_no_put,
|
||||||
|
SEE_no_canput,
|
||||||
|
form_elems_hasproperty,
|
||||||
|
SEE_no_delete,
|
||||||
|
SEE_no_defaultvalue,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SEE_objectclass js_forms_object_class = {
|
||||||
|
NULL,
|
||||||
|
forms_get,
|
||||||
|
SEE_no_put,
|
||||||
|
SEE_no_canput,
|
||||||
|
forms_hasproperty,
|
||||||
|
SEE_no_delete,
|
||||||
|
SEE_no_defaultvalue,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SEE_objectclass js_form_class = {
|
||||||
|
NULL,
|
||||||
|
form_get,
|
||||||
|
form_put,
|
||||||
|
form_canput,
|
||||||
|
form_hasproperty,
|
||||||
|
SEE_no_delete,
|
||||||
|
SEE_no_defaultvalue,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
struct js_input {
|
||||||
|
struct SEE_object object;
|
||||||
|
struct js_form *parent;
|
||||||
|
struct form_state *fs;
|
||||||
|
struct SEE_object *blur;
|
||||||
|
struct SEE_object *click;
|
||||||
|
struct SEE_object *focus;
|
||||||
|
struct SEE_object *select;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct js_forms_object {
|
||||||
|
struct SEE_object object;
|
||||||
|
struct js_document_object *parent;
|
||||||
|
struct SEE_object *item;
|
||||||
|
struct SEE_object *namedItem;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct js_form_elems {
|
||||||
|
struct SEE_object object;
|
||||||
|
struct js_form *parent;
|
||||||
|
struct SEE_object *item;
|
||||||
|
struct SEE_object *namedItem;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
input_get(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p, struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct document *document = doc_view->document;
|
||||||
|
struct js_input *input = (struct js_input *)o;
|
||||||
|
struct js_form *parent = input->parent;
|
||||||
|
struct form_state *fs = input->fs;
|
||||||
|
struct form_control *fc = find_form_control(document, fs);
|
||||||
|
int linknum;
|
||||||
|
struct link *link = NULL;
|
||||||
|
struct SEE_string *str;
|
||||||
|
|
||||||
|
assert(fc);
|
||||||
|
assert(fc->form && fs);
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
linknum = get_form_control_link(document, fc);
|
||||||
|
/* Hiddens have no link. */
|
||||||
|
if (linknum >= 0) link = &document->links[linknum];
|
||||||
|
SEE_SET_UNDEFINED(res);
|
||||||
|
|
||||||
|
if (p == s_accessKey) {
|
||||||
|
struct string keystr;
|
||||||
|
if (!link)
|
||||||
|
return;
|
||||||
|
|
||||||
|
init_string(&keystr);
|
||||||
|
add_accesskey_to_string(&keystr, link->accesskey);
|
||||||
|
str = string_to_SEE_string(interp, keystr.source);
|
||||||
|
SEE_SET_STRING(res, str);
|
||||||
|
done_string(&keystr);
|
||||||
|
} else if (p == s_alt) {
|
||||||
|
str = string_to_SEE_string(interp, fc->alt);
|
||||||
|
SEE_SET_STRING(res, str);
|
||||||
|
} else if (p == s_checked) {
|
||||||
|
SEE_SET_BOOLEAN(res, fs->state);
|
||||||
|
} else if (p == s_defaultChecked) {
|
||||||
|
SEE_SET_BOOLEAN(res, fc->default_state);
|
||||||
|
} else if (p == s_defaultValue) {
|
||||||
|
str = string_to_SEE_string(interp, fc->default_value);
|
||||||
|
SEE_SET_STRING(res, str);
|
||||||
|
} else if (p == s_disabled) {
|
||||||
|
/* FIXME: <input readonly disabled> --pasky */
|
||||||
|
SEE_SET_BOOLEAN(res, fc->mode == FORM_MODE_DISABLED);
|
||||||
|
} else if (p == s_form) {
|
||||||
|
SEE_SET_OBJECT(res, (struct SEE_object *)parent);
|
||||||
|
} else if (p == s_maxLength) {
|
||||||
|
SEE_SET_NUMBER(res, fc->maxlength);
|
||||||
|
} else if (p == s_name) {
|
||||||
|
str = string_to_SEE_string(interp, fc->name);
|
||||||
|
SEE_SET_STRING(res, str);
|
||||||
|
} else if (p == s_readonly) {
|
||||||
|
/* FIXME: <input readonly disabled> --pasky */
|
||||||
|
SEE_SET_BOOLEAN(res, fc->mode == FORM_MODE_READONLY);
|
||||||
|
} else if (p == s_size) {
|
||||||
|
SEE_SET_NUMBER(res, fc->size);
|
||||||
|
} else if (p == s_src) {
|
||||||
|
if (link && link->where_img) {
|
||||||
|
str = string_to_SEE_string(interp, link->where_img);
|
||||||
|
SEE_SET_STRING(res, str);
|
||||||
|
}
|
||||||
|
} else if (p == s_tabindex) {
|
||||||
|
if (link) {
|
||||||
|
/* FIXME: This is WRONG. --pasky */
|
||||||
|
SEE_SET_NUMBER(res, link->number);
|
||||||
|
}
|
||||||
|
} else if (p == s_type) {
|
||||||
|
switch (fc->type) {
|
||||||
|
case FC_TEXT: str = s_text; break;
|
||||||
|
case FC_PASSWORD: str = s_password; break;
|
||||||
|
case FC_FILE: str = s_file; break;
|
||||||
|
case FC_CHECKBOX: str = s_checkbox; break;
|
||||||
|
case FC_RADIO: str = s_radio; break;
|
||||||
|
case FC_SUBMIT: str = s_submit; break;
|
||||||
|
case FC_IMAGE: str = s_image; break;
|
||||||
|
case FC_RESET: str = s_reset; break;
|
||||||
|
case FC_BUTTON: str = s_button; break;
|
||||||
|
case FC_HIDDEN: str = s_hidden; break;
|
||||||
|
default: str = NULL;
|
||||||
|
}
|
||||||
|
if (str) {
|
||||||
|
SEE_SET_STRING(res, str);
|
||||||
|
}
|
||||||
|
} else if (p == s_value) {
|
||||||
|
str = string_to_SEE_string(interp, fs->value);
|
||||||
|
SEE_SET_STRING(res, str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
input_put(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p, struct SEE_value *val, int attr)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct document *document = doc_view->document;
|
||||||
|
struct js_input *input = (struct js_input *)o;
|
||||||
|
struct form_state *fs = input->fs;
|
||||||
|
struct form_control *fc = find_form_control(document, fs);
|
||||||
|
int linknum;
|
||||||
|
struct link *link = NULL;
|
||||||
|
unsigned char *string = NULL;
|
||||||
|
|
||||||
|
assert(fc);
|
||||||
|
assert(fc->form && fs);
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
linknum = get_form_control_link(document, fc);
|
||||||
|
/* Hiddens have no link. */
|
||||||
|
if (linknum >= 0) link = &document->links[linknum];
|
||||||
|
|
||||||
|
if (p == s_accessKey) {
|
||||||
|
if (link) {
|
||||||
|
string = SEE_value_to_unsigned_char(interp, val);
|
||||||
|
if (!string)
|
||||||
|
return;
|
||||||
|
link->accesskey = accesskey_string_to_unicode(string);
|
||||||
|
mem_free(string);
|
||||||
|
}
|
||||||
|
} else if (p == s_alt) {
|
||||||
|
string = SEE_value_to_unsigned_char(interp, val);
|
||||||
|
mem_free_set(&fc->alt, string);
|
||||||
|
} else if (p == s_checked) {
|
||||||
|
if (fc->type != FC_CHECKBOX && fc->type != FC_RADIO)
|
||||||
|
return;
|
||||||
|
fs->state = SEE_ToUint32(interp, val);
|
||||||
|
} else if (p == s_disabled) {
|
||||||
|
/* FIXME: <input readonly disabled> --pasky */
|
||||||
|
SEE_uint32_t boo = SEE_ToUint32(interp, val);
|
||||||
|
fc->mode = (boo ? FORM_MODE_DISABLED
|
||||||
|
: (fc->mode == FORM_MODE_READONLY ? FORM_MODE_READONLY
|
||||||
|
: FORM_MODE_NORMAL));
|
||||||
|
} else if (p == s_maxLength) {
|
||||||
|
string = SEE_value_to_unsigned_char(interp, val);
|
||||||
|
if (!string)
|
||||||
|
return;
|
||||||
|
fc->maxlength = atol(string);
|
||||||
|
mem_free(string);
|
||||||
|
} else if (p == s_name) {
|
||||||
|
string = SEE_value_to_unsigned_char(interp, val);
|
||||||
|
mem_free_set(&fc->name, string);
|
||||||
|
} else if (p == s_readonly) {
|
||||||
|
SEE_uint32_t boo = SEE_ToUint32(interp, val);
|
||||||
|
fc->mode = (boo ? FORM_MODE_READONLY
|
||||||
|
: fc->mode == FORM_MODE_DISABLED ? FORM_MODE_DISABLED
|
||||||
|
: FORM_MODE_NORMAL);
|
||||||
|
} else if (p == s_src) {
|
||||||
|
if (link) {
|
||||||
|
string = SEE_value_to_unsigned_char(interp, val);
|
||||||
|
mem_free_set(&link->where_img, string);
|
||||||
|
}
|
||||||
|
} else if (p == s_value) {
|
||||||
|
if (fc->type == FC_FILE)
|
||||||
|
return;
|
||||||
|
string = SEE_value_to_unsigned_char(interp, val);
|
||||||
|
mem_free_set(&fs->value, string);
|
||||||
|
if (fc->type == FC_TEXT || fc->type == FC_PASSWORD)
|
||||||
|
fs->state = strlen(fs->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
js_input_blur(struct SEE_interpreter *interp, struct SEE_object *self,
|
||||||
|
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
|
||||||
|
struct SEE_value *res)
|
||||||
|
{
|
||||||
|
/* We are a text-mode browser and there *always* has to be something
|
||||||
|
* selected. So we do nothing for now. (That was easy.) */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
js_input_click(struct SEE_interpreter *interp, struct SEE_object *self,
|
||||||
|
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
|
||||||
|
struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct document *document = doc_view->document;
|
||||||
|
struct session *ses = doc_view->session;
|
||||||
|
struct js_input *input = (struct js_input *)thisobj;
|
||||||
|
struct form_state *fs = input->fs;
|
||||||
|
struct form_control *fc;
|
||||||
|
int linknum;
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
SEE_SET_BOOLEAN(res, 0);
|
||||||
|
assert(fs);
|
||||||
|
fc = find_form_control(document, fs);
|
||||||
|
assert(fc);
|
||||||
|
|
||||||
|
linknum = get_form_control_link(document, fc);
|
||||||
|
/* Hiddens have no link. */
|
||||||
|
if (linknum < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Restore old current_link afterwards? */
|
||||||
|
jump_to_link_number(ses, doc_view, linknum);
|
||||||
|
if (enter(ses, doc_view, 0) == FRAME_EVENT_REFRESH)
|
||||||
|
refresh_view(ses, doc_view, 0);
|
||||||
|
else
|
||||||
|
print_screen_status(ses);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
js_input_focus(struct SEE_interpreter *interp, struct SEE_object *self,
|
||||||
|
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
|
||||||
|
struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct document *document = doc_view->document;
|
||||||
|
struct session *ses = doc_view->session;
|
||||||
|
struct js_input *input = (struct js_input *)thisobj;
|
||||||
|
struct form_state *fs = input->fs;
|
||||||
|
struct form_control *fc;
|
||||||
|
int linknum;
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
assert(fs);
|
||||||
|
fc = find_form_control(document, fs);
|
||||||
|
assert(fc);
|
||||||
|
|
||||||
|
linknum = get_form_control_link(document, fc);
|
||||||
|
/* Hiddens have no link. */
|
||||||
|
if (linknum < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
jump_to_link_number(ses, doc_view, linknum);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
js_input_select(struct SEE_interpreter *interp, struct SEE_object *self,
|
||||||
|
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
|
||||||
|
struct SEE_value *res)
|
||||||
|
{
|
||||||
|
checktime(interp);
|
||||||
|
/* We support no text selecting yet. So we do nothing for now.
|
||||||
|
* (That was easy, too.) */
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
input_canput(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p)
|
||||||
|
{
|
||||||
|
checktime(interp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
input_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p)
|
||||||
|
{
|
||||||
|
/* all unknown properties return UNDEFINED value */
|
||||||
|
checktime(interp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct js_input *
|
||||||
|
js_get_input_object(struct SEE_interpreter *interp, struct js_form *jsform,
|
||||||
|
struct form_state *fs)
|
||||||
|
{
|
||||||
|
struct js_input *jsinput;
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
if (fs->ecmascript_obj)
|
||||||
|
return fs->ecmascript_obj;
|
||||||
|
|
||||||
|
/* jsform ('form') is input's parent */
|
||||||
|
/* FIXME: That is NOT correct since the real containing element
|
||||||
|
* should be its parent, but gimme DOM first. --pasky */
|
||||||
|
jsinput = SEE_NEW(interp, struct js_input);
|
||||||
|
|
||||||
|
jsinput->object.objectclass = &js_input_object_class;
|
||||||
|
jsinput->object.objectclass->Class = s_input;
|
||||||
|
jsinput->object.Prototype = NULL;
|
||||||
|
|
||||||
|
jsinput->blur = SEE_cfunction_make(interp, js_input_blur, s_blur, 0);
|
||||||
|
jsinput->click = SEE_cfunction_make(interp, js_input_click, s_click, 0);
|
||||||
|
jsinput->focus = SEE_cfunction_make(interp, js_input_focus, s_focus, 0);
|
||||||
|
jsinput->select = SEE_cfunction_make(interp, js_input_select, s_select, 0);
|
||||||
|
|
||||||
|
jsinput->fs = fs;
|
||||||
|
jsinput->parent = jsform;
|
||||||
|
|
||||||
|
fs->ecmascript_obj = jsinput;
|
||||||
|
return jsinput;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct js_input *
|
||||||
|
js_get_form_control_object(struct SEE_interpreter *interp, struct js_form *jsform,
|
||||||
|
enum form_type type, struct form_state *fs)
|
||||||
|
{
|
||||||
|
checktime(interp);
|
||||||
|
switch (type) {
|
||||||
|
case FC_TEXT:
|
||||||
|
case FC_PASSWORD:
|
||||||
|
case FC_FILE:
|
||||||
|
case FC_CHECKBOX:
|
||||||
|
case FC_RADIO:
|
||||||
|
case FC_SUBMIT:
|
||||||
|
case FC_IMAGE:
|
||||||
|
case FC_RESET:
|
||||||
|
case FC_BUTTON:
|
||||||
|
case FC_HIDDEN:
|
||||||
|
return js_get_input_object(interp, jsform, fs);
|
||||||
|
|
||||||
|
case FC_TEXTAREA:
|
||||||
|
case FC_SELECT:
|
||||||
|
/* TODO */
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
default:
|
||||||
|
INTERNAL("Weird fc->type %d", type);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
js_form_elems_item(struct SEE_interpreter *interp, struct SEE_object *self,
|
||||||
|
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
|
||||||
|
struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct document *document = doc_view->document;
|
||||||
|
struct js_form_elems *jsfe = (struct js_form_elems *)thisobj;
|
||||||
|
struct js_form *parent_form = jsfe->parent;
|
||||||
|
struct form_view *fv = parent_form->fv;
|
||||||
|
struct form *form = find_form_by_form_view(document, fv);
|
||||||
|
struct form_control *fc;
|
||||||
|
unsigned char *string;
|
||||||
|
int counter = -1;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
SEE_SET_UNDEFINED(res);
|
||||||
|
if (argc < 1)
|
||||||
|
return;
|
||||||
|
string = SEE_value_to_unsigned_char(interp, argv[0]);
|
||||||
|
if (!string)
|
||||||
|
return;
|
||||||
|
index = atol(string);
|
||||||
|
mem_free(string);
|
||||||
|
|
||||||
|
foreach (fc, form->items) {
|
||||||
|
counter++;
|
||||||
|
if (counter == index) {
|
||||||
|
struct js_input *fcobj = js_get_form_control_object(interp, parent_form, fc->type, find_form_state(doc_view, fc));
|
||||||
|
|
||||||
|
if (fcobj) {
|
||||||
|
SEE_SET_OBJECT(res, (struct SEE_object *)fcobj);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
js_form_elems_namedItem(struct SEE_interpreter *interp, struct SEE_object *self,
|
||||||
|
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
|
||||||
|
struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct document *document = doc_view->document;
|
||||||
|
struct js_form_elems *jsfe = (struct js_form_elems *)thisobj;
|
||||||
|
struct js_form *parent_form = jsfe->parent;
|
||||||
|
struct form_view *fv = parent_form->fv;
|
||||||
|
struct form *form = find_form_by_form_view(document, fv);
|
||||||
|
struct form_control *fc;
|
||||||
|
unsigned char *string;
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
SEE_SET_UNDEFINED(res);
|
||||||
|
if (argc < 1)
|
||||||
|
return;
|
||||||
|
string = SEE_value_to_unsigned_char(interp, argv[0]);
|
||||||
|
if (!string)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (fc, form->items) {
|
||||||
|
if (fc->name && !strcasecmp(string, fc->name)) {
|
||||||
|
struct js_input *fcobj = js_get_form_control_object(interp, parent_form, fc->type, find_form_state(doc_view, fc));
|
||||||
|
|
||||||
|
if (fcobj) {
|
||||||
|
SEE_SET_OBJECT(res, (struct SEE_object *)fcobj);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mem_free(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
form_elems_get(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p, struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct document *document = doc_view->document;
|
||||||
|
struct js_form_elems *jsfe = (struct js_form_elems *)o;
|
||||||
|
struct js_form *parent_form = jsfe->parent;
|
||||||
|
struct form_view *fv = parent_form->fv;
|
||||||
|
struct form *form = find_form_by_form_view(document, fv);
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
if (p == s_length) {
|
||||||
|
SEE_number_t length = list_size(&form->items);
|
||||||
|
SEE_SET_NUMBER(res, length);
|
||||||
|
} else {
|
||||||
|
unsigned char *string = SEE_string_to_unsigned_char(p);
|
||||||
|
struct SEE_value argv;
|
||||||
|
|
||||||
|
if (!string) {
|
||||||
|
SEE_SET_UNDEFINED(res);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SEE_SET_STRING(&argv, p);
|
||||||
|
if (string[0] >= '0' && string[1] <= '9') {
|
||||||
|
js_form_elems_item(interp, o, NULL, 1,
|
||||||
|
(struct SEE_value **)&argv, res);
|
||||||
|
} else {
|
||||||
|
js_form_elems_namedItem(interp, o, NULL, 1,
|
||||||
|
(struct SEE_value **)&argv, res);
|
||||||
|
}
|
||||||
|
mem_free(string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
form_elems_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p)
|
||||||
|
{
|
||||||
|
checktime(interp);
|
||||||
|
/* all unknown properties return UNDEFINED value */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
js_forms_item(struct SEE_interpreter *interp, struct SEE_object *self,
|
||||||
|
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
|
||||||
|
struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
struct js_forms_object *fo = (struct js_forms_object *)thisobj;
|
||||||
|
struct js_document_object *doc = fo->parent;
|
||||||
|
struct form_view *fv;
|
||||||
|
unsigned char *string;
|
||||||
|
int counter = -1;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
SEE_SET_UNDEFINED(res);
|
||||||
|
if (argc < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
string = SEE_value_to_unsigned_char(interp, argv[0]);
|
||||||
|
if (!string)
|
||||||
|
return;
|
||||||
|
index = atol(string);
|
||||||
|
mem_free(string);
|
||||||
|
|
||||||
|
foreach (fv, vs->forms) {
|
||||||
|
counter++;
|
||||||
|
if (counter == index) {
|
||||||
|
struct js_form *obj = js_get_form_object(interp, doc, fv);
|
||||||
|
|
||||||
|
SEE_SET_OBJECT(res, (struct SEE_object *)obj);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
js_forms_namedItem(struct SEE_interpreter *interp, struct SEE_object *self,
|
||||||
|
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
|
||||||
|
struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct document *document = doc_view->document;
|
||||||
|
struct js_forms_object *fo = (struct js_forms_object *)thisobj;
|
||||||
|
struct js_document_object *doc = fo->parent;
|
||||||
|
struct form *form;
|
||||||
|
unsigned char *string;
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
SEE_SET_UNDEFINED(res);
|
||||||
|
if (argc < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
string = SEE_value_to_unsigned_char(interp, argv[0]);
|
||||||
|
if (!string)
|
||||||
|
return;
|
||||||
|
foreach (form, document->forms) {
|
||||||
|
if (form->name && !strcasecmp(string, form->name)) {
|
||||||
|
struct form_view *fv = find_form_view(doc_view, form);
|
||||||
|
struct js_form *obj = js_get_form_object(interp,
|
||||||
|
doc, fv);
|
||||||
|
|
||||||
|
SEE_SET_OBJECT(res, (struct SEE_object *)obj);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mem_free(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
forms_get(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p, struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct document *document = doc_view->document;
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
if (p == s_length) {
|
||||||
|
SEE_number_t length = list_size(&document->forms);
|
||||||
|
SEE_SET_NUMBER(res, length);
|
||||||
|
} else {
|
||||||
|
unsigned char *string = SEE_string_to_unsigned_char(p);
|
||||||
|
struct SEE_value argv;
|
||||||
|
|
||||||
|
if (!string) {
|
||||||
|
SEE_SET_UNDEFINED(res);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SEE_SET_STRING(&argv, p);
|
||||||
|
if (string[0] >= '0' && string[1] <= '9') {
|
||||||
|
js_forms_item(interp, o, NULL, 1,
|
||||||
|
(struct SEE_value **)&argv, res);
|
||||||
|
} else {
|
||||||
|
js_forms_namedItem(interp, o, NULL, 1,
|
||||||
|
(struct SEE_value **)&argv, res);
|
||||||
|
}
|
||||||
|
mem_free(string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
forms_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p)
|
||||||
|
{
|
||||||
|
checktime(interp);
|
||||||
|
/* all unknown properties return UNDEFINED value */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
form_get(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p, struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct js_form *js_form = (struct js_form *)o;
|
||||||
|
struct form_view *fv = js_form->fv;
|
||||||
|
struct form *form = find_form_by_form_view(doc_view->document, fv);
|
||||||
|
struct SEE_string *str;
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
SEE_SET_UNDEFINED(res);
|
||||||
|
|
||||||
|
if (p == s_action) {
|
||||||
|
str = string_to_SEE_string(interp, form->action);
|
||||||
|
SEE_SET_STRING(res, str);
|
||||||
|
} else if (p == s_encoding) {
|
||||||
|
switch (form->method) {
|
||||||
|
case FORM_METHOD_GET:
|
||||||
|
case FORM_METHOD_POST:
|
||||||
|
/* "application/x-www-form-urlencoded" */
|
||||||
|
SEE_SET_STRING(res, s_application_);
|
||||||
|
break;
|
||||||
|
case FORM_METHOD_POST_MP:
|
||||||
|
/* "multipart/form-data" */
|
||||||
|
SEE_SET_STRING(res, s_multipart_);
|
||||||
|
break;
|
||||||
|
case FORM_METHOD_POST_TEXT_PLAIN:
|
||||||
|
/* "text/plain") */
|
||||||
|
SEE_SET_STRING(res, s_textplain);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (p == s_length) {
|
||||||
|
SEE_number_t num = list_size(&form->items);
|
||||||
|
SEE_SET_NUMBER(res, num);
|
||||||
|
} else if (p == s_method) {
|
||||||
|
switch (form->method) {
|
||||||
|
case FORM_METHOD_GET:
|
||||||
|
SEE_SET_STRING(res, s_GET);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FORM_METHOD_POST:
|
||||||
|
case FORM_METHOD_POST_MP:
|
||||||
|
case FORM_METHOD_POST_TEXT_PLAIN:
|
||||||
|
SEE_SET_STRING(res, s_POST);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (p == s_name) {
|
||||||
|
str = string_to_SEE_string(interp, form->name);
|
||||||
|
SEE_SET_STRING(res, str);
|
||||||
|
} else if (p == s_target) {
|
||||||
|
str = string_to_SEE_string(interp, form->target);
|
||||||
|
SEE_SET_STRING(res, str);
|
||||||
|
} else if (p == s_elements) {
|
||||||
|
struct js_form_elems *jsfe = SEE_NEW(interp, struct js_form_elems);
|
||||||
|
|
||||||
|
jsfe->object.objectclass = &js_form_elems_class;
|
||||||
|
jsfe->object.objectclass->Class = s_elements;
|
||||||
|
jsfe->object.Prototype = NULL;
|
||||||
|
jsfe->parent = js_form;
|
||||||
|
jsfe->item = SEE_cfunction_make(interp, js_form_elems_item, s_item, 1);
|
||||||
|
jsfe->namedItem = SEE_cfunction_make(interp, js_form_elems_namedItem, s_namedItem, 1);
|
||||||
|
SEE_SET_OBJECT(res, (struct SEE_object *)jsfe);
|
||||||
|
} else if (p == s_submit) {
|
||||||
|
SEE_SET_OBJECT(res, js_form->submit);
|
||||||
|
} else if (p == s_reset) {
|
||||||
|
SEE_SET_OBJECT(res, js_form->reset);
|
||||||
|
} else {
|
||||||
|
unsigned char *string = SEE_string_to_unsigned_char(p);
|
||||||
|
struct form_control *fc;
|
||||||
|
|
||||||
|
if (!string)
|
||||||
|
return;
|
||||||
|
foreach(fc, form->items) {
|
||||||
|
struct js_input *fcobj = NULL;
|
||||||
|
|
||||||
|
if (!fc->name || strcasecmp(string, fc->name))
|
||||||
|
continue;
|
||||||
|
fcobj = js_get_form_control_object(interp, js_form, fc->type, find_form_state(doc_view, fc));
|
||||||
|
|
||||||
|
if (fcobj) {
|
||||||
|
SEE_SET_OBJECT(res, (struct SEE_object *)fcobj);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mem_free(string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
form_put(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p, struct SEE_value *val, int attr)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct js_form *js_form = (struct js_form *)o;
|
||||||
|
struct form_view *fv = js_form->fv;
|
||||||
|
struct form *form = find_form_by_form_view(doc_view->document, fv);
|
||||||
|
unsigned char *string = SEE_value_to_unsigned_char(interp, val);
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
if (!string)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (p == s_action) {
|
||||||
|
mem_free_set(&form->action, string);
|
||||||
|
} else if (p == s_encoding) {
|
||||||
|
if (!strcasecmp(string, "application/x-www-form-urlencoded")) {
|
||||||
|
form->method = form->method == FORM_METHOD_GET ? FORM_METHOD_GET
|
||||||
|
: FORM_METHOD_POST;
|
||||||
|
} else if (!strcasecmp(string, "multipart/form-data")) {
|
||||||
|
form->method = FORM_METHOD_POST_MP;
|
||||||
|
} else if (!strcasecmp(string, "text/plain")) {
|
||||||
|
form->method = FORM_METHOD_POST_TEXT_PLAIN;
|
||||||
|
}
|
||||||
|
mem_free(string);
|
||||||
|
} else if (p == s_method) {
|
||||||
|
if (!strcasecmp(string, "GET")) {
|
||||||
|
form->method = FORM_METHOD_GET;
|
||||||
|
} else if (!strcasecmp(string, "POST")) {
|
||||||
|
form->method = FORM_METHOD_POST;
|
||||||
|
}
|
||||||
|
mem_free(string);
|
||||||
|
} else if (p == s_name) {
|
||||||
|
mem_free_set(&form->name, string);
|
||||||
|
} else if (p == s_target) {
|
||||||
|
mem_free_set(&form->target, string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
form_canput(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p)
|
||||||
|
{
|
||||||
|
checktime(interp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
form_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p)
|
||||||
|
{
|
||||||
|
checktime(interp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
js_form_reset(struct SEE_interpreter *interp, struct SEE_object *self,
|
||||||
|
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
|
||||||
|
struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct js_form *js_form = (struct js_form *)thisobj;
|
||||||
|
struct form_view *fv = js_form->fv;
|
||||||
|
struct form *form = find_form_by_form_view(doc_view->document, fv);
|
||||||
|
|
||||||
|
assert(form);
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
do_reset_form(doc_view, form);
|
||||||
|
draw_forms(doc_view->session->tab->term, doc_view);
|
||||||
|
SEE_SET_BOOLEAN(res, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
js_form_submit(struct SEE_interpreter *interp, struct SEE_object *self,
|
||||||
|
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
|
||||||
|
struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct session *ses = doc_view->session;
|
||||||
|
struct js_form *js_form = (struct js_form *)thisobj;
|
||||||
|
struct form_view *fv = js_form->fv;
|
||||||
|
struct form *form = find_form_by_form_view(doc_view->document, fv);
|
||||||
|
|
||||||
|
assert(form);
|
||||||
|
checktime(interp);
|
||||||
|
submit_given_form(ses, doc_view, form);
|
||||||
|
SEE_SET_BOOLEAN(res, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct js_form *js_get_form_object(struct SEE_interpreter *interp,
|
||||||
|
struct js_document_object *doc, struct form_view *fv)
|
||||||
|
{
|
||||||
|
struct js_form *js_form;
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
if (fv->ecmascript_obj)
|
||||||
|
return fv->ecmascript_obj;
|
||||||
|
|
||||||
|
/* jsdoc ('document') is fv's parent */
|
||||||
|
/* FIXME: That is NOT correct since the real containing element
|
||||||
|
* should be its parent, but gimme DOM first. --pasky */
|
||||||
|
js_form = SEE_NEW(interp, struct js_form);
|
||||||
|
js_form->object.objectclass = &js_form_class;
|
||||||
|
js_form->object.objectclass->Class = s_form;
|
||||||
|
js_form->object.Prototype = NULL; /* TODO: use prototype for form */
|
||||||
|
js_form->parent = doc;
|
||||||
|
js_form->reset = SEE_cfunction_make(interp, js_form_reset, s_reset, 0);
|
||||||
|
js_form->submit = SEE_cfunction_make(interp, js_form_submit, s_submit, 0);
|
||||||
|
js_form->fv = fv;
|
||||||
|
|
||||||
|
fv->ecmascript_obj = js_form;
|
||||||
|
return js_form;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
init_js_forms_object(struct ecmascript_interpreter *interpreter)
|
||||||
|
{
|
||||||
|
struct global_object *g = interpreter->backend_data;
|
||||||
|
struct SEE_interpreter *interp = &g->interp;
|
||||||
|
struct SEE_value v, document;
|
||||||
|
struct js_forms_object *forms = SEE_NEW(interp,
|
||||||
|
struct js_forms_object);
|
||||||
|
|
||||||
|
forms->object.objectclass = &js_forms_object_class;
|
||||||
|
forms->object.objectclass->Class = s_forms;
|
||||||
|
forms->object.Prototype = NULL;
|
||||||
|
|
||||||
|
SEE_OBJECT_GET(interp, interp->Global, s_document, &document);
|
||||||
|
SEE_SET_OBJECT(&v, (struct SEE_object *)forms);
|
||||||
|
SEE_OBJECT_PUT(interp, document.u.object, s_forms, &v, 0);
|
||||||
|
|
||||||
|
forms->item = SEE_cfunction_make(interp, js_forms_item, s_item, 1);
|
||||||
|
forms->namedItem = SEE_cfunction_make(interp, js_forms_namedItem,
|
||||||
|
s_namedItem, 1);
|
||||||
|
forms->parent = (struct js_document_object *)document.u.object;
|
||||||
|
}
|
19
src/ecmascript/see/form.h
Normal file
19
src/ecmascript/see/form.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef EL__ECMASCRIPT_SEE_FORM_H
|
||||||
|
#define EL__ECMASCRIPT_SEE_FORM_H
|
||||||
|
|
||||||
|
struct js_document_object;
|
||||||
|
struct ecmascript_interpreter;
|
||||||
|
struct form_view;
|
||||||
|
|
||||||
|
struct js_form {
|
||||||
|
struct SEE_object object;
|
||||||
|
struct js_document_object *parent;
|
||||||
|
struct form_view *fv;
|
||||||
|
struct SEE_object *reset;
|
||||||
|
struct SEE_object *submit;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct js_form *js_get_form_object(struct SEE_interpreter *, struct js_document_object*, struct form_view *);
|
||||||
|
void init_js_forms_object(struct ecmascript_interpreter *);
|
||||||
|
|
||||||
|
#endif
|
100
src/ecmascript/see/input.c
Normal file
100
src/ecmascript/see/input.c
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/* Input for SEE */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <see/see.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "ecmascript/see/input.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
|
||||||
|
static SEE_unicode_t input_elinks_next(struct SEE_input *);
|
||||||
|
static void input_elinks_close(struct SEE_input *);
|
||||||
|
|
||||||
|
static struct SEE_inputclass input_elinks_class = {
|
||||||
|
input_elinks_next,
|
||||||
|
input_elinks_close
|
||||||
|
};
|
||||||
|
|
||||||
|
struct input_elinks {
|
||||||
|
struct SEE_input inp;
|
||||||
|
unsigned char *s;
|
||||||
|
};
|
||||||
|
|
||||||
|
static SEE_unicode_t
|
||||||
|
input_elinks_next(struct SEE_input *inp)
|
||||||
|
{
|
||||||
|
struct input_elinks *input = (struct input_elinks*)inp;
|
||||||
|
SEE_unicode_t next;
|
||||||
|
|
||||||
|
next = input->inp.lookahead;
|
||||||
|
|
||||||
|
if (*input->s == '\0') {
|
||||||
|
input->inp.eof = 1;
|
||||||
|
} else {
|
||||||
|
input->inp.lookahead = *input->s++;
|
||||||
|
input->inp.eof = 0;
|
||||||
|
}
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
input_elinks_close(struct SEE_input *inp)
|
||||||
|
{
|
||||||
|
/* nothing */
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SEE_input *
|
||||||
|
SEE_input_elinks(struct SEE_interpreter *interp, unsigned char *s)
|
||||||
|
{
|
||||||
|
struct input_elinks *input;
|
||||||
|
|
||||||
|
input = SEE_NEW(interp, struct input_elinks);
|
||||||
|
input->inp.interpreter = interp;
|
||||||
|
input->inp.inputclass = &input_elinks_class;
|
||||||
|
input->inp.filename = NULL;
|
||||||
|
input->inp.first_lineno = 1;
|
||||||
|
input->s = s;
|
||||||
|
SEE_INPUT_NEXT((struct SEE_input *)input); /* prime */
|
||||||
|
return (struct SEE_input *)input;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *
|
||||||
|
SEE_string_to_unsigned_char(struct SEE_string *S)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned char *str = mem_alloc(S->length + 1);
|
||||||
|
|
||||||
|
if (!str)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < S->length; i++)
|
||||||
|
str[i] = (unsigned char)S->data[i];
|
||||||
|
str[S->length] = '\0';
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *
|
||||||
|
SEE_value_to_unsigned_char(struct SEE_interpreter *interp, struct SEE_value *val)
|
||||||
|
{
|
||||||
|
struct SEE_value result;
|
||||||
|
|
||||||
|
SEE_ToString(interp, val, &result);
|
||||||
|
return SEE_string_to_unsigned_char(result.u.string);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SEE_string *
|
||||||
|
string_to_SEE_string(struct SEE_interpreter *interp, unsigned char *s)
|
||||||
|
{
|
||||||
|
unsigned int len;
|
||||||
|
unsigned int i;
|
||||||
|
struct SEE_string *str;
|
||||||
|
|
||||||
|
len = s ? strlen(s) : 0;
|
||||||
|
str = SEE_string_new(interp, len);
|
||||||
|
str->length = len;
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
str->data[i] = s[i];
|
||||||
|
return str;
|
||||||
|
}
|
11
src/ecmascript/see/input.h
Normal file
11
src/ecmascript/see/input.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef EL__ECMASCRIPT_SEE_INPUT_H
|
||||||
|
#define EL__ECMASCRIPT_SEE_INPUT_H
|
||||||
|
|
||||||
|
#include <see/see.h>
|
||||||
|
|
||||||
|
struct SEE_input *SEE_input_elinks(struct SEE_interpreter *, unsigned char *);
|
||||||
|
unsigned char *SEE_string_to_unsigned_char(struct SEE_string *);
|
||||||
|
unsigned char *SEE_value_to_unsigned_char(struct SEE_interpreter *, struct SEE_value *);
|
||||||
|
struct SEE_string *string_to_SEE_string(struct SEE_interpreter *, unsigned char *);
|
||||||
|
|
||||||
|
#endif
|
363
src/ecmascript/see/location.c
Normal file
363
src/ecmascript/see/location.c
Normal file
@ -0,0 +1,363 @@
|
|||||||
|
/* The SEE location and history objects implementation. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "elinks.h"
|
||||||
|
|
||||||
|
#include <see/see.h>
|
||||||
|
|
||||||
|
#include "bfu/dialog.h"
|
||||||
|
#include "cache/cache.h"
|
||||||
|
#include "cookies/cookies.h"
|
||||||
|
#include "dialogs/menu.h"
|
||||||
|
#include "dialogs/status.h"
|
||||||
|
#include "document/html/frames.h"
|
||||||
|
#include "document/document.h"
|
||||||
|
#include "document/forms.h"
|
||||||
|
#include "document/view.h"
|
||||||
|
#include "ecmascript/ecmascript.h"
|
||||||
|
#include "ecmascript/see/input.h"
|
||||||
|
#include "ecmascript/see/location.h"
|
||||||
|
#include "ecmascript/see/strings.h"
|
||||||
|
#include "ecmascript/see/window.h"
|
||||||
|
#include "intl/gettext/libintl.h"
|
||||||
|
#include "main/select.h"
|
||||||
|
#include "osdep/newwin.h"
|
||||||
|
#include "osdep/sysname.h"
|
||||||
|
#include "protocol/http/http.h"
|
||||||
|
#include "protocol/uri.h"
|
||||||
|
#include "session/history.h"
|
||||||
|
#include "session/location.h"
|
||||||
|
#include "session/session.h"
|
||||||
|
#include "session/task.h"
|
||||||
|
#include "terminal/tab.h"
|
||||||
|
#include "terminal/terminal.h"
|
||||||
|
#include "util/conv.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
#include "viewer/text/draw.h"
|
||||||
|
#include "viewer/text/form.h"
|
||||||
|
#include "viewer/text/link.h"
|
||||||
|
#include "viewer/text/vs.h"
|
||||||
|
|
||||||
|
static void delayed_goto(void *);
|
||||||
|
static void history_get(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *);
|
||||||
|
static int history_hasproperty(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
|
||||||
|
static void js_history_back(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
|
||||||
|
static void js_history_forward(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
|
||||||
|
static void js_history_go(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
|
||||||
|
static void js_location_toString(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
|
||||||
|
static void location_get(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *);
|
||||||
|
static void location_put(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *, int);
|
||||||
|
static int location_hasproperty(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
|
||||||
|
static int location_canput(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
|
||||||
|
|
||||||
|
void location_goto(struct document_view *, unsigned char *);
|
||||||
|
|
||||||
|
struct js_history_object {
|
||||||
|
struct SEE_object object;
|
||||||
|
struct SEE_object *back;
|
||||||
|
struct SEE_object *forward;
|
||||||
|
struct SEE_object *go;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct js_location_object {
|
||||||
|
struct SEE_object object;
|
||||||
|
struct SEE_object *toString;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct delayed_goto {
|
||||||
|
/* It might look more convenient to pass doc_view around but it could
|
||||||
|
* disappear during wild dances inside of frames or so. */
|
||||||
|
struct view_state *vs;
|
||||||
|
struct uri *uri;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SEE_objectclass js_history_object_class = {
|
||||||
|
NULL,
|
||||||
|
history_get,
|
||||||
|
SEE_no_put,
|
||||||
|
SEE_no_canput,
|
||||||
|
history_hasproperty,
|
||||||
|
SEE_no_delete,
|
||||||
|
SEE_no_defaultvalue,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SEE_objectclass js_location_object_class = {
|
||||||
|
NULL,
|
||||||
|
location_get,
|
||||||
|
location_put,
|
||||||
|
location_canput,
|
||||||
|
location_hasproperty,
|
||||||
|
SEE_no_delete,
|
||||||
|
SEE_no_defaultvalue,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
delayed_goto(void *data)
|
||||||
|
{
|
||||||
|
struct delayed_goto *deg = data;
|
||||||
|
|
||||||
|
assert(deg);
|
||||||
|
if (deg->vs->doc_view
|
||||||
|
&& deg->vs->doc_view == deg->vs->doc_view->session->doc_view) {
|
||||||
|
goto_uri_frame(deg->vs->doc_view->session, deg->uri,
|
||||||
|
deg->vs->doc_view->name,
|
||||||
|
CACHE_MODE_NORMAL);
|
||||||
|
}
|
||||||
|
done_uri(deg->uri);
|
||||||
|
mem_free(deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
location_goto(struct document_view *doc_view, unsigned char *url)
|
||||||
|
{
|
||||||
|
unsigned char *new_abs_url;
|
||||||
|
struct uri *new_uri;
|
||||||
|
struct delayed_goto *deg;
|
||||||
|
|
||||||
|
/* Workaround for bug 611. Does not crash, but may lead to infinite loop.*/
|
||||||
|
if (!doc_view) return;
|
||||||
|
new_abs_url = join_urls(doc_view->document->uri,
|
||||||
|
trim_chars(url, ' ', 0));
|
||||||
|
if (!new_abs_url)
|
||||||
|
return;
|
||||||
|
new_uri = get_uri(new_abs_url, 0);
|
||||||
|
mem_free(new_abs_url);
|
||||||
|
if (!new_uri)
|
||||||
|
return;
|
||||||
|
deg = mem_calloc(1, sizeof(*deg));
|
||||||
|
if (!deg) {
|
||||||
|
done_uri(new_uri);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assert(doc_view->vs);
|
||||||
|
deg->vs = doc_view->vs;
|
||||||
|
deg->uri = new_uri;
|
||||||
|
/* It does not seem to be very safe inside of frames to
|
||||||
|
* call goto_uri() right away. */
|
||||||
|
register_bottom_half(delayed_goto, deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
history_get(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p, struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct js_history_object *history = (struct js_history_object *)o;
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
if (p == s_back) {
|
||||||
|
SEE_SET_OBJECT(res, history->back);
|
||||||
|
} else if (p == s_forward) {
|
||||||
|
SEE_SET_OBJECT(res, history->forward);
|
||||||
|
} else if (p == s_go) {
|
||||||
|
SEE_SET_OBJECT(res, history->go);
|
||||||
|
} else {
|
||||||
|
SEE_SET_UNDEFINED(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
history_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p)
|
||||||
|
{
|
||||||
|
checktime(interp);
|
||||||
|
if (p == s_back || p == s_forward || p == s_go)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
js_history_back(struct SEE_interpreter *interp, struct SEE_object *self,
|
||||||
|
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
|
||||||
|
struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct session *ses = doc_view->session;
|
||||||
|
|
||||||
|
SEE_SET_NULL(res);
|
||||||
|
go_back(ses);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
js_history_forward(struct SEE_interpreter *interp, struct SEE_object *self,
|
||||||
|
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
|
||||||
|
struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct session *ses = doc_view->session;
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
SEE_SET_NULL(res);
|
||||||
|
go_unback(ses);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
js_history_go(struct SEE_interpreter *interp, struct SEE_object *self,
|
||||||
|
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
|
||||||
|
struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct session *ses = doc_view->session;
|
||||||
|
unsigned char *str;
|
||||||
|
int index;
|
||||||
|
struct location *loc;
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
SEE_SET_NULL(res);
|
||||||
|
if (argc < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
str = SEE_value_to_unsigned_char(interp, argv[0]);
|
||||||
|
if (!str)
|
||||||
|
return;
|
||||||
|
|
||||||
|
index = atol(str);
|
||||||
|
mem_free(str);
|
||||||
|
|
||||||
|
for (loc = cur_loc(ses);
|
||||||
|
loc != (struct location *) &ses->history.history;
|
||||||
|
loc = index > 0 ? loc->next : loc->prev) {
|
||||||
|
if (!index) {
|
||||||
|
go_history(ses, loc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
index += index > 0 ? -1 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
js_location_toString(struct SEE_interpreter *interp, struct SEE_object *self,
|
||||||
|
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
|
||||||
|
struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
unsigned char *string = get_uri_string(vs->uri, URI_ORIGINAL);
|
||||||
|
struct SEE_string *str = string_to_SEE_string(interp, string);
|
||||||
|
|
||||||
|
mem_free_if(string);
|
||||||
|
checktime(interp);
|
||||||
|
|
||||||
|
SEE_SET_STRING(res, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
location_get(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p, struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct js_location_object *loc = (struct js_location_object *)o;
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
if (p == s_toString || p == s_toLocaleString) {
|
||||||
|
SEE_SET_OBJECT(res, loc->toString);
|
||||||
|
} else if (p == s_href) {
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
unsigned char *string = get_uri_string(vs->uri, URI_ORIGINAL);
|
||||||
|
struct SEE_string *str = string_to_SEE_string(interp, string);
|
||||||
|
|
||||||
|
mem_free_if(string);
|
||||||
|
SEE_SET_STRING(res, str);
|
||||||
|
} else {
|
||||||
|
SEE_SET_UNDEFINED(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
location_put(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p, struct SEE_value *val, int attr)
|
||||||
|
{
|
||||||
|
checktime(interp);
|
||||||
|
if (p == s_href) {
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
unsigned char *url = SEE_value_to_unsigned_char(interp, val);
|
||||||
|
|
||||||
|
location_goto(doc_view, url);
|
||||||
|
mem_free(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
location_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p)
|
||||||
|
{
|
||||||
|
checktime(interp);
|
||||||
|
if (p == s_toString || p == s_toLocaleString || p == s_href)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
location_canput(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p)
|
||||||
|
{
|
||||||
|
checktime(interp);
|
||||||
|
if (p == s_href)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
init_js_history_object(struct ecmascript_interpreter *interpreter)
|
||||||
|
{
|
||||||
|
struct global_object *g = interpreter->backend_data;
|
||||||
|
struct SEE_interpreter *interp = &g->interp;
|
||||||
|
struct SEE_value v;
|
||||||
|
struct js_history_object *history = SEE_NEW(interp,
|
||||||
|
struct js_history_object);
|
||||||
|
|
||||||
|
history->object.objectclass = &js_history_object_class;
|
||||||
|
history->object.objectclass->Class = s_history;
|
||||||
|
history->object.Prototype = NULL;
|
||||||
|
|
||||||
|
SEE_SET_OBJECT(&v, (struct SEE_object *)history);
|
||||||
|
SEE_OBJECT_PUT(interp, interp->Global, s_history, &v, 0);
|
||||||
|
|
||||||
|
history->back = SEE_cfunction_make(interp, js_history_back, s_back, 0);
|
||||||
|
history->forward = SEE_cfunction_make(interp, js_history_forward, s_forward, 0);
|
||||||
|
history->go = SEE_cfunction_make(interp, js_history_go, s_go, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
init_js_location_object(struct ecmascript_interpreter *interpreter)
|
||||||
|
{
|
||||||
|
struct global_object *g = interpreter->backend_data;
|
||||||
|
struct SEE_interpreter *interp = &g->interp;
|
||||||
|
struct SEE_value v;
|
||||||
|
struct js_location_object *loc = SEE_NEW(interp,
|
||||||
|
struct js_location_object);
|
||||||
|
|
||||||
|
loc->object.objectclass = &js_location_object_class;
|
||||||
|
loc->object.objectclass->Class = s_location;
|
||||||
|
loc->object.Prototype = NULL;
|
||||||
|
|
||||||
|
SEE_SET_OBJECT(&v, (struct SEE_object *)loc);
|
||||||
|
SEE_OBJECT_PUT(interp, interp->Global, s_location, &v, 0);
|
||||||
|
|
||||||
|
loc->toString = SEE_cfunction_make(interp, js_location_toString, s_toString, 0);
|
||||||
|
}
|
9
src/ecmascript/see/location.h
Normal file
9
src/ecmascript/see/location.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef EL__ECMASCRIPT_SEE_LOCATION_H
|
||||||
|
#define EL__ECMASCRIPT_SEE_LOCATION_H
|
||||||
|
|
||||||
|
struct ecmascript_interpreter;
|
||||||
|
|
||||||
|
void init_js_history_object(struct ecmascript_interpreter *);
|
||||||
|
void init_js_location_object(struct ecmascript_interpreter *);
|
||||||
|
|
||||||
|
#endif
|
150
src/ecmascript/see/navigator.c
Normal file
150
src/ecmascript/see/navigator.c
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/* The SEE navigator objects implementation. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "elinks.h"
|
||||||
|
|
||||||
|
#include <see/see.h>
|
||||||
|
|
||||||
|
#include "bfu/dialog.h"
|
||||||
|
#include "cache/cache.h"
|
||||||
|
#include "cookies/cookies.h"
|
||||||
|
#include "dialogs/menu.h"
|
||||||
|
#include "dialogs/status.h"
|
||||||
|
#include "document/html/frames.h"
|
||||||
|
#include "document/document.h"
|
||||||
|
#include "document/forms.h"
|
||||||
|
#include "document/view.h"
|
||||||
|
#include "ecmascript/ecmascript.h"
|
||||||
|
#include "ecmascript/see/input.h"
|
||||||
|
#include "ecmascript/see/navigator.h"
|
||||||
|
#include "ecmascript/see/strings.h"
|
||||||
|
#include "ecmascript/see/window.h"
|
||||||
|
#include "intl/gettext/libintl.h"
|
||||||
|
#include "main/select.h"
|
||||||
|
#include "osdep/newwin.h"
|
||||||
|
#include "osdep/sysname.h"
|
||||||
|
#include "protocol/http/http.h"
|
||||||
|
#include "protocol/uri.h"
|
||||||
|
#include "session/history.h"
|
||||||
|
#include "session/location.h"
|
||||||
|
#include "session/session.h"
|
||||||
|
#include "session/task.h"
|
||||||
|
#include "terminal/tab.h"
|
||||||
|
#include "terminal/terminal.h"
|
||||||
|
#include "util/conv.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
#include "viewer/text/draw.h"
|
||||||
|
#include "viewer/text/form.h"
|
||||||
|
#include "viewer/text/link.h"
|
||||||
|
#include "viewer/text/vs.h"
|
||||||
|
|
||||||
|
static void navigator_get(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *);
|
||||||
|
static int navigator_hasproperty(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
|
||||||
|
|
||||||
|
struct SEE_objectclass js_navigator_object_class = {
|
||||||
|
NULL,
|
||||||
|
navigator_get,
|
||||||
|
SEE_no_put,
|
||||||
|
SEE_no_canput,
|
||||||
|
navigator_hasproperty,
|
||||||
|
SEE_no_delete,
|
||||||
|
SEE_no_defaultvalue,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
navigator_get(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p, struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct SEE_string *str;
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
SEE_SET_UNDEFINED(res);
|
||||||
|
if (p == s_appCodeName) {
|
||||||
|
SEE_SET_STRING(res, s_Mozilla);
|
||||||
|
} else if (p == s_appName) {
|
||||||
|
SEE_SET_STRING(res, s_ELinks_);
|
||||||
|
} else if (p == s_appVersion) {
|
||||||
|
str = string_to_SEE_string(interp, VERSION);
|
||||||
|
SEE_SET_STRING(res, str);
|
||||||
|
} else if (p == s_language) {
|
||||||
|
#ifdef CONFIG_NLS
|
||||||
|
if (get_opt_bool("protocol.http.accept_ui_language")) {
|
||||||
|
str = string_to_SEE_string(interp,
|
||||||
|
language_to_iso639(current_language));
|
||||||
|
SEE_SET_STRING(res, str);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else if (p == s_platform) {
|
||||||
|
str = string_to_SEE_string(interp, system_name);
|
||||||
|
SEE_SET_STRING(res, str);
|
||||||
|
} else if (p == s_userAgent) {
|
||||||
|
/* FIXME: Code duplication. */
|
||||||
|
unsigned char *optstr = get_opt_str("protocol.http.user_agent");
|
||||||
|
|
||||||
|
if (*optstr && strcmp(optstr, " ")) {
|
||||||
|
unsigned char *ustr, ts[64] = "";
|
||||||
|
static unsigned char custr[256];
|
||||||
|
|
||||||
|
if (!list_empty(terminals)) {
|
||||||
|
unsigned int tslen = 0;
|
||||||
|
struct terminal *term = terminals.prev;
|
||||||
|
|
||||||
|
ulongcat(ts, &tslen, term->width, 3, 0);
|
||||||
|
ts[tslen++] = 'x';
|
||||||
|
ulongcat(ts, &tslen, term->height, 3, 0);
|
||||||
|
}
|
||||||
|
ustr = subst_user_agent(optstr, VERSION_STRING, system_name, ts);
|
||||||
|
|
||||||
|
if (ustr) {
|
||||||
|
safe_strncpy(custr, ustr, 256);
|
||||||
|
mem_free(ustr);
|
||||||
|
str = string_to_SEE_string(interp, custr);
|
||||||
|
SEE_SET_STRING(res, str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
navigator_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p)
|
||||||
|
{
|
||||||
|
checktime(interp);
|
||||||
|
if (p == s_appCodeName || p == s_appName || p == s_appVersion
|
||||||
|
|| p == s_language || p == s_platform || p == s_userAgent)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
init_js_navigator_object(struct ecmascript_interpreter *interpreter)
|
||||||
|
{
|
||||||
|
struct global_object *g = interpreter->backend_data;
|
||||||
|
struct SEE_interpreter *interp = &g->interp;
|
||||||
|
struct SEE_value v;
|
||||||
|
struct SEE_object *navigator;
|
||||||
|
|
||||||
|
navigator = SEE_NEW(interp, struct SEE_object);
|
||||||
|
|
||||||
|
navigator->objectclass = &js_navigator_object_class;
|
||||||
|
navigator->objectclass->Class = s_navigator;
|
||||||
|
navigator->Prototype = NULL;
|
||||||
|
|
||||||
|
SEE_SET_OBJECT(&v, navigator);
|
||||||
|
SEE_OBJECT_PUT(interp, interp->Global, s_navigator, &v, 0);
|
||||||
|
}
|
8
src/ecmascript/see/navigator.h
Normal file
8
src/ecmascript/see/navigator.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#ifndef EL__ECMASCRIPT_SEE_NAVIGATOR_H
|
||||||
|
#define EL__ECMASCRIPT_SEE_NAVIGATOR_H
|
||||||
|
|
||||||
|
struct ecmascript_interpreter;
|
||||||
|
|
||||||
|
void init_js_navigator_object(struct ecmascript_interpreter *);
|
||||||
|
|
||||||
|
#endif
|
379
src/ecmascript/see/strings.c
Normal file
379
src/ecmascript/see/strings.c
Normal file
@ -0,0 +1,379 @@
|
|||||||
|
#include <see/see.h>
|
||||||
|
|
||||||
|
struct SEE_string *s_window;
|
||||||
|
struct SEE_string *s_closed;
|
||||||
|
struct SEE_string *s_parent;
|
||||||
|
struct SEE_string *s_self;
|
||||||
|
struct SEE_string *s_top;
|
||||||
|
struct SEE_string *s_alert;
|
||||||
|
struct SEE_string *s_open;
|
||||||
|
|
||||||
|
struct SEE_string *s_menubar;
|
||||||
|
|
||||||
|
struct SEE_string *s_statusbar;
|
||||||
|
struct SEE_string *s_visible;
|
||||||
|
|
||||||
|
struct SEE_string *s_navigator;
|
||||||
|
struct SEE_string *s_appCodeName;
|
||||||
|
struct SEE_string *s_appName;
|
||||||
|
struct SEE_string *s_appVersion;
|
||||||
|
struct SEE_string *s_language;
|
||||||
|
struct SEE_string *s_platform;
|
||||||
|
struct SEE_string *s_userAgent;
|
||||||
|
|
||||||
|
struct SEE_string *s_history;
|
||||||
|
struct SEE_string *s_back;
|
||||||
|
struct SEE_string *s_forward;
|
||||||
|
struct SEE_string *s_go;
|
||||||
|
|
||||||
|
struct SEE_string *s_location;
|
||||||
|
struct SEE_string *s_href;
|
||||||
|
struct SEE_string *s_toString;
|
||||||
|
struct SEE_string *s_toLocaleString;
|
||||||
|
|
||||||
|
struct SEE_string *s_input;
|
||||||
|
struct SEE_string *s_accessKey;
|
||||||
|
struct SEE_string *s_alt;
|
||||||
|
struct SEE_string *s_checked;
|
||||||
|
struct SEE_string *s_defaultChecked;
|
||||||
|
struct SEE_string *s_defaultValue;
|
||||||
|
struct SEE_string *s_disabled;
|
||||||
|
struct SEE_string *s_form;
|
||||||
|
struct SEE_string *s_maxLength;
|
||||||
|
struct SEE_string *s_name;
|
||||||
|
struct SEE_string *s_readonly;
|
||||||
|
struct SEE_string *s_size;
|
||||||
|
struct SEE_string *s_src;
|
||||||
|
struct SEE_string *s_tabindex;
|
||||||
|
struct SEE_string *s_type;
|
||||||
|
struct SEE_string *s_value;
|
||||||
|
struct SEE_string *s_blur;
|
||||||
|
struct SEE_string *s_click;
|
||||||
|
struct SEE_string *s_focus;
|
||||||
|
struct SEE_string *s_select;
|
||||||
|
|
||||||
|
struct SEE_string *s_elements;
|
||||||
|
struct SEE_string *s_item;
|
||||||
|
struct SEE_string *s_namedItem;
|
||||||
|
struct SEE_string *s_length;
|
||||||
|
|
||||||
|
struct SEE_string *s_action;
|
||||||
|
struct SEE_string *s_encoding;
|
||||||
|
struct SEE_string *s_method;
|
||||||
|
struct SEE_string *s_target;
|
||||||
|
struct SEE_string *s_reset;
|
||||||
|
struct SEE_string *s_submit;
|
||||||
|
|
||||||
|
struct SEE_string *s_forms;
|
||||||
|
|
||||||
|
struct SEE_string *s_document;
|
||||||
|
struct SEE_string *s_referrer;
|
||||||
|
struct SEE_string *s_title;
|
||||||
|
struct SEE_string *s_url;
|
||||||
|
struct SEE_string *s_write;
|
||||||
|
|
||||||
|
struct SEE_string *s_Mozilla;
|
||||||
|
struct SEE_string *s_ELinks_;
|
||||||
|
struct SEE_string *s_cookie;
|
||||||
|
|
||||||
|
struct SEE_string *s_GET;
|
||||||
|
struct SEE_string *s_POST;
|
||||||
|
struct SEE_string *s_application_;
|
||||||
|
struct SEE_string *s_multipart_;
|
||||||
|
struct SEE_string *s_textplain;
|
||||||
|
|
||||||
|
struct SEE_string *s_text;
|
||||||
|
struct SEE_string *s_password;
|
||||||
|
struct SEE_string *s_file;
|
||||||
|
struct SEE_string *s_checkbox;
|
||||||
|
struct SEE_string *s_radio;
|
||||||
|
struct SEE_string *s_image;
|
||||||
|
struct SEE_string *s_button;
|
||||||
|
struct SEE_string *s_hidden;
|
||||||
|
|
||||||
|
struct SEE_string *s_timeout;
|
||||||
|
|
||||||
|
void
|
||||||
|
init_intern_strings(void)
|
||||||
|
{
|
||||||
|
static SEE_char_t SA_window[] = {'w','i','n','d','o','w'};
|
||||||
|
static struct SEE_string S_window = SEE_STRING_DECL(SA_window);
|
||||||
|
static SEE_char_t SA_closed[] = {'c','l','o','s','e','d'};
|
||||||
|
static struct SEE_string S_closed = SEE_STRING_DECL(SA_closed);
|
||||||
|
static SEE_char_t SA_parent[] = {'p','a','r','e','n','t'};
|
||||||
|
static struct SEE_string S_parent = SEE_STRING_DECL(SA_parent);
|
||||||
|
static SEE_char_t SA_self[] = {'s','e','l','f'};
|
||||||
|
static struct SEE_string S_self = SEE_STRING_DECL(SA_self);
|
||||||
|
static SEE_char_t SA_top[] = {'t','o','p'};
|
||||||
|
static struct SEE_string S_top = SEE_STRING_DECL(SA_top);
|
||||||
|
static SEE_char_t SA_alert[] ={'a','l','e','r','t'};
|
||||||
|
static struct SEE_string S_alert = SEE_STRING_DECL(SA_alert);
|
||||||
|
static SEE_char_t SA_open[] ={'o','p','e','n'};
|
||||||
|
static struct SEE_string S_open = SEE_STRING_DECL(SA_open);
|
||||||
|
|
||||||
|
static SEE_char_t SA_menubar[] = {'m','e','n','u','b','a','r'};
|
||||||
|
static struct SEE_string S_menubar = SEE_STRING_DECL(SA_menubar);
|
||||||
|
|
||||||
|
static SEE_char_t SA_statusbar[] = {'s','t','a','t','u','s','b','a','r'};
|
||||||
|
static struct SEE_string S_statusbar = SEE_STRING_DECL(SA_statusbar);
|
||||||
|
static SEE_char_t SA_visible[] = {'v','i','s','i','b','l','e'};
|
||||||
|
static struct SEE_string S_visible = SEE_STRING_DECL(SA_visible);
|
||||||
|
|
||||||
|
static SEE_char_t SA_navigator[] ={'n','a','v','i','g','a','t','o','r'};
|
||||||
|
static struct SEE_string S_navigator = SEE_STRING_DECL(SA_navigator);
|
||||||
|
static SEE_char_t SA_appCodeName[] ={'a','p','p','C','o','d','e','N','a','m','e'};
|
||||||
|
static struct SEE_string S_appCodeName = SEE_STRING_DECL(SA_appCodeName);
|
||||||
|
static SEE_char_t SA_appName[] ={'a','p','p','N','a','m','e'};
|
||||||
|
static struct SEE_string S_appName = SEE_STRING_DECL(SA_appName);
|
||||||
|
static SEE_char_t SA_appVersion[] ={'a','p','p','V','e','r','s','i','o','n'};
|
||||||
|
static struct SEE_string S_appVersion = SEE_STRING_DECL(SA_appVersion);
|
||||||
|
static SEE_char_t SA_language[] ={'l','a','n','g','u','a','g','e'};
|
||||||
|
static struct SEE_string S_language = SEE_STRING_DECL(SA_language);
|
||||||
|
static SEE_char_t SA_platform[] ={'p','l','a','t','f','o','r','m'};
|
||||||
|
static struct SEE_string S_platform = SEE_STRING_DECL(SA_platform);
|
||||||
|
static SEE_char_t SA_userAgent[] ={'u','s','e','r','A','g','e','n','t'};
|
||||||
|
static struct SEE_string S_userAgent = SEE_STRING_DECL(SA_userAgent);
|
||||||
|
|
||||||
|
static SEE_char_t SA_history[] ={'h','i','s','t','o','r','y'};
|
||||||
|
static struct SEE_string S_history = SEE_STRING_DECL(SA_history);
|
||||||
|
static SEE_char_t SA_back[] ={'b','a','c','k'};
|
||||||
|
static struct SEE_string S_back = SEE_STRING_DECL(SA_back);
|
||||||
|
static SEE_char_t SA_forward[] ={'f','o','r','w','a','r','d'};
|
||||||
|
static struct SEE_string S_forward = SEE_STRING_DECL(SA_forward);
|
||||||
|
static SEE_char_t SA_go[] ={'g','o'};
|
||||||
|
static struct SEE_string S_go = SEE_STRING_DECL(SA_go);
|
||||||
|
|
||||||
|
static SEE_char_t SA_location[] ={'l','o','c','a','t','i','o','n'};
|
||||||
|
static struct SEE_string S_location = SEE_STRING_DECL(SA_location);
|
||||||
|
static SEE_char_t SA_href[] ={'h','r','e','f'};
|
||||||
|
static struct SEE_string S_href = SEE_STRING_DECL(SA_href);
|
||||||
|
static SEE_char_t SA_toString[] ={'t','o','S','t','r','i','n','g'};
|
||||||
|
static struct SEE_string S_toString = SEE_STRING_DECL(SA_toString);
|
||||||
|
static SEE_char_t SA_toLocaleString[] ={'t','o','L','o','c','a','l','e','S','t','r','i','n','g'};
|
||||||
|
static struct SEE_string S_toLocaleString = SEE_STRING_DECL(SA_toLocaleString);
|
||||||
|
|
||||||
|
static SEE_char_t SA_input[] ={'i','n','p','u','t'};
|
||||||
|
static struct SEE_string S_input = SEE_STRING_DECL(SA_input);
|
||||||
|
static SEE_char_t SA_accessKey[] ={'a','c','c','e','s','s','K','e','y'};
|
||||||
|
static struct SEE_string S_accessKey = SEE_STRING_DECL(SA_accessKey);
|
||||||
|
static SEE_char_t SA_alt[] ={'a','l','t'};
|
||||||
|
static struct SEE_string S_alt = SEE_STRING_DECL(SA_alt);
|
||||||
|
static SEE_char_t SA_checked[] ={'c','h','e','c','k','e','d'};
|
||||||
|
static struct SEE_string S_checked = SEE_STRING_DECL(SA_checked);
|
||||||
|
static SEE_char_t SA_defaultChecked[] ={'d','e','f','a','u','l','t','C','h','e','c','k','e','d'};
|
||||||
|
static struct SEE_string S_defaultChecked = SEE_STRING_DECL(SA_defaultChecked);
|
||||||
|
static SEE_char_t SA_defaultValue[] ={'d','e','f','a','u','l','t','V','a','l','u','e'};
|
||||||
|
static struct SEE_string S_defaultValue = SEE_STRING_DECL(SA_defaultValue);
|
||||||
|
static SEE_char_t SA_disabled[] ={'d','i','s','a','b','l','e','d'};
|
||||||
|
static struct SEE_string S_disabled = SEE_STRING_DECL(SA_disabled);
|
||||||
|
static SEE_char_t SA_form[] ={'f','o','r','m'};
|
||||||
|
static struct SEE_string S_form = SEE_STRING_DECL(SA_form);
|
||||||
|
static SEE_char_t SA_maxLength[] ={'m','a','x','L','e','n','g','t','h'};
|
||||||
|
static struct SEE_string S_maxLength = SEE_STRING_DECL(SA_maxLength);
|
||||||
|
static SEE_char_t SA_name[] ={'n','a','m','e'};
|
||||||
|
static struct SEE_string S_name = SEE_STRING_DECL(SA_name);
|
||||||
|
static SEE_char_t SA_readonly[] ={'r','e','a','d','o','n','l','y'};
|
||||||
|
static struct SEE_string S_readonly = SEE_STRING_DECL(SA_readonly);
|
||||||
|
static SEE_char_t SA_size[] ={'s','i','z','e'};
|
||||||
|
static struct SEE_string S_size = SEE_STRING_DECL(SA_size);
|
||||||
|
static SEE_char_t SA_src[] ={'s','r','c'};
|
||||||
|
static struct SEE_string S_src = SEE_STRING_DECL(SA_src);
|
||||||
|
static SEE_char_t SA_tabindex[] ={'t','a','b','i','n','d','e','x'};
|
||||||
|
static struct SEE_string S_tabindex = SEE_STRING_DECL(SA_tabindex);
|
||||||
|
static SEE_char_t SA_type[] ={'t','y','p','e'};
|
||||||
|
static struct SEE_string S_type = SEE_STRING_DECL(SA_type);
|
||||||
|
static SEE_char_t SA_value[] ={'v','a','l','u','e'};
|
||||||
|
static struct SEE_string S_value = SEE_STRING_DECL(SA_value);
|
||||||
|
static SEE_char_t SA_blur[] ={'b','l','u','r'};
|
||||||
|
static struct SEE_string S_blur = SEE_STRING_DECL(SA_blur);
|
||||||
|
static SEE_char_t SA_click[] ={'c','l','i','c','k'};
|
||||||
|
static struct SEE_string S_click = SEE_STRING_DECL(SA_click);
|
||||||
|
static SEE_char_t SA_focus[] ={'f','o','c','u','s'};
|
||||||
|
static struct SEE_string S_focus = SEE_STRING_DECL(SA_focus);
|
||||||
|
static SEE_char_t SA_select[] ={'s','e','l','e','c','t'};
|
||||||
|
static struct SEE_string S_select = SEE_STRING_DECL(SA_select);
|
||||||
|
|
||||||
|
static SEE_char_t SA_elements[] ={'e','l','e','m','e','n','t','s'};
|
||||||
|
static struct SEE_string S_elements = SEE_STRING_DECL(SA_elements);
|
||||||
|
static SEE_char_t SA_item[] ={'i','t','e','m'};
|
||||||
|
static struct SEE_string S_item = SEE_STRING_DECL(SA_item);
|
||||||
|
static SEE_char_t SA_namedItem[] ={'n','a','m','e','d','I','t','e','m'};
|
||||||
|
static struct SEE_string S_namedItem = SEE_STRING_DECL(SA_namedItem);
|
||||||
|
static SEE_char_t SA_length[] ={'l','e','n','g','t','h'};
|
||||||
|
static struct SEE_string S_length = SEE_STRING_DECL(SA_length);
|
||||||
|
|
||||||
|
static SEE_char_t SA_action[] ={'a','c','t','i','o','n'};
|
||||||
|
static struct SEE_string S_action = SEE_STRING_DECL(SA_action);
|
||||||
|
static SEE_char_t SA_encoding[] ={'e','n','c','o','d','i','g'};
|
||||||
|
static struct SEE_string S_encoding = SEE_STRING_DECL(SA_encoding);
|
||||||
|
static SEE_char_t SA_method[] ={'m','e','t','h','o','d'};
|
||||||
|
static struct SEE_string S_method = SEE_STRING_DECL(SA_method);
|
||||||
|
static SEE_char_t SA_target[] ={'t','a','r','g','e','t'};
|
||||||
|
static struct SEE_string S_target = SEE_STRING_DECL(SA_target);
|
||||||
|
static SEE_char_t SA_reset[] ={'r','e','s','e','t'};
|
||||||
|
static struct SEE_string S_reset = SEE_STRING_DECL(SA_reset);
|
||||||
|
static SEE_char_t SA_submit[] ={'s','u','b','m','i','t'};
|
||||||
|
static struct SEE_string S_submit = SEE_STRING_DECL(SA_submit);
|
||||||
|
|
||||||
|
static SEE_char_t SA_forms[] ={'f','o','r','m','s'};
|
||||||
|
static struct SEE_string S_forms = SEE_STRING_DECL(SA_forms);
|
||||||
|
|
||||||
|
static SEE_char_t SA_document[] = {'d','o','c','u','m','e','n','t'};
|
||||||
|
static struct SEE_string S_document = SEE_STRING_DECL(SA_document);
|
||||||
|
static SEE_char_t SA_referrer[] ={'r','e','f','e','r','r','e','r'};
|
||||||
|
static struct SEE_string S_referrer = SEE_STRING_DECL(SA_referrer);
|
||||||
|
static SEE_char_t SA_title[] ={'t','i','t','l','e'};
|
||||||
|
static struct SEE_string S_title = SEE_STRING_DECL(SA_title);
|
||||||
|
static SEE_char_t SA_url[] ={'u','r','l'};
|
||||||
|
static struct SEE_string S_url = SEE_STRING_DECL(SA_url);
|
||||||
|
static SEE_char_t SA_write[] = {'w','r','i','t','e'};
|
||||||
|
static struct SEE_string S_write = SEE_STRING_DECL(SA_write);
|
||||||
|
|
||||||
|
static SEE_char_t SA_Mozilla[] = {'M','o','z','i','l','l','a'};
|
||||||
|
static struct SEE_string S_Mozilla = SEE_STRING_DECL(SA_Mozilla);
|
||||||
|
static SEE_char_t SA_ELinks_[] = {'E','L','i','n','k','s',' ','(',
|
||||||
|
'r','o','u','g','h','l','y',' ','c','o','m','p','a','t','i','b','l','e',
|
||||||
|
' ','w','i','t','h',' ','N','e','t','s','c','a','p','e',' ',
|
||||||
|
'N','a','v','i','g','a','t','o','r',',',' ','M','o','z','i','l','l','a',
|
||||||
|
' ','a','n','d',' ','M','i','c','r','o','s','o','f','t',' ',
|
||||||
|
'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r',')'};
|
||||||
|
static struct SEE_string S_ELinks_ = SEE_STRING_DECL(SA_ELinks_);
|
||||||
|
|
||||||
|
static SEE_char_t SA_cookie[] = {'c','o','o','k','i','e'};
|
||||||
|
static struct SEE_string S_cookie = SEE_STRING_DECL(SA_cookie);
|
||||||
|
|
||||||
|
static SEE_char_t SA_GET[] = {'G','E','T'};
|
||||||
|
static struct SEE_string S_GET = SEE_STRING_DECL(SA_GET);
|
||||||
|
static SEE_char_t SA_POST[] = {'P','O','S','T'};
|
||||||
|
static struct SEE_string S_POST = SEE_STRING_DECL(SA_POST);
|
||||||
|
|
||||||
|
static SEE_char_t SA_application_[] = {'a','p','p','l','i','c','a','t',
|
||||||
|
'i','o','n','/','x','-','w','w','w','-','f','o','r','m','-','u','r','l',
|
||||||
|
'e','n','c','o','d','e','d'};
|
||||||
|
static struct SEE_string S_application_ = SEE_STRING_DECL(SA_application_);
|
||||||
|
static SEE_char_t SA_multipart_[] = {'m','u','l','t','i','p','a','r','t','/',
|
||||||
|
'f','o','r','m','-','d','a','t','a'};
|
||||||
|
static struct SEE_string S_multipart_ = SEE_STRING_DECL(SA_multipart_);
|
||||||
|
static SEE_char_t SA_textplain[] = {'t','e','x','t','/','p','l','a','i','n'};
|
||||||
|
static struct SEE_string S_textplain = SEE_STRING_DECL(SA_textplain);
|
||||||
|
|
||||||
|
static SEE_char_t SA_text[] = {'t','e','x','t'};
|
||||||
|
static struct SEE_string S_text = SEE_STRING_DECL(SA_text);
|
||||||
|
|
||||||
|
static SEE_char_t SA_password[] = {'p','a','s','s','w','o','r','d'};
|
||||||
|
static struct SEE_string S_password = SEE_STRING_DECL(SA_password);
|
||||||
|
|
||||||
|
static SEE_char_t SA_file[] = {'f','i','l','e'};
|
||||||
|
static struct SEE_string S_file = SEE_STRING_DECL(SA_file);
|
||||||
|
|
||||||
|
static SEE_char_t SA_checkbox[] = {'c','h','e','c','k','b','o','x'};
|
||||||
|
static struct SEE_string S_checkbox = SEE_STRING_DECL(SA_checkbox);
|
||||||
|
|
||||||
|
static SEE_char_t SA_radio[] = {'r','a','d','i','o'};
|
||||||
|
static struct SEE_string S_radio = SEE_STRING_DECL(SA_radio);
|
||||||
|
|
||||||
|
static SEE_char_t SA_image[] = {'i','m','a','g','e'};
|
||||||
|
static struct SEE_string S_image = SEE_STRING_DECL(SA_image);
|
||||||
|
|
||||||
|
static SEE_char_t SA_button[] = {'b','u','t','t','o','n'};
|
||||||
|
static struct SEE_string S_button = SEE_STRING_DECL(SA_button);
|
||||||
|
|
||||||
|
static SEE_char_t SA_hidden[] = {'h','i','d','d','e','n'};
|
||||||
|
static struct SEE_string S_hidden = SEE_STRING_DECL(SA_hidden);
|
||||||
|
|
||||||
|
static SEE_char_t SA_timeout[] = {'t','i','m','e','o','u','t'};
|
||||||
|
static struct SEE_string S_timeout = SEE_STRING_DECL(SA_timeout);
|
||||||
|
|
||||||
|
SEE_intern_global(s_window = &S_window);
|
||||||
|
SEE_intern_global(s_closed = &S_closed);
|
||||||
|
SEE_intern_global(s_parent = &S_parent);
|
||||||
|
SEE_intern_global(s_self = &S_self);
|
||||||
|
SEE_intern_global(s_top = &S_top);
|
||||||
|
SEE_intern_global(s_alert = &S_alert);
|
||||||
|
SEE_intern_global(s_open = &S_open);
|
||||||
|
|
||||||
|
SEE_intern_global(s_menubar = &S_menubar);
|
||||||
|
SEE_intern_global(s_statusbar = &S_statusbar);
|
||||||
|
SEE_intern_global(s_visible = &S_visible);
|
||||||
|
|
||||||
|
SEE_intern_global(s_navigator = &S_navigator);
|
||||||
|
SEE_intern_global(s_appCodeName = &S_appCodeName);
|
||||||
|
SEE_intern_global(s_appName = &S_appName);
|
||||||
|
SEE_intern_global(s_appVersion = &S_appVersion);
|
||||||
|
SEE_intern_global(s_language = &S_language);
|
||||||
|
SEE_intern_global(s_platform = &S_platform);
|
||||||
|
SEE_intern_global(s_userAgent = &S_userAgent);
|
||||||
|
|
||||||
|
SEE_intern_global(s_history = &S_history);
|
||||||
|
SEE_intern_global(s_back = &S_back);
|
||||||
|
SEE_intern_global(s_forward = &S_forward);
|
||||||
|
SEE_intern_global(s_go = &S_go);
|
||||||
|
|
||||||
|
SEE_intern_global(s_location = &S_location);
|
||||||
|
SEE_intern_global(s_href = &S_href);
|
||||||
|
SEE_intern_global(s_toString = &S_toString);
|
||||||
|
SEE_intern_global(s_toLocaleString = &S_toLocaleString);
|
||||||
|
|
||||||
|
SEE_intern_global(s_input = &S_input);
|
||||||
|
SEE_intern_global(s_accessKey = &S_accessKey);
|
||||||
|
SEE_intern_global(s_alt = &S_alt);
|
||||||
|
SEE_intern_global(s_checked = &S_checked);
|
||||||
|
SEE_intern_global(s_defaultChecked = &S_defaultChecked);
|
||||||
|
SEE_intern_global(s_defaultValue = &S_defaultValue);
|
||||||
|
SEE_intern_global(s_disabled = &S_disabled);
|
||||||
|
SEE_intern_global(s_form = &S_form);
|
||||||
|
SEE_intern_global(s_maxLength = &S_maxLength);
|
||||||
|
SEE_intern_global(s_name = &S_name);
|
||||||
|
SEE_intern_global(s_readonly = &S_readonly);
|
||||||
|
SEE_intern_global(s_size = &S_size);
|
||||||
|
SEE_intern_global(s_src = &S_src);
|
||||||
|
SEE_intern_global(s_tabindex = &S_tabindex);
|
||||||
|
SEE_intern_global(s_type = &S_type);
|
||||||
|
SEE_intern_global(s_value = &S_value);
|
||||||
|
SEE_intern_global(s_blur = &S_blur);
|
||||||
|
SEE_intern_global(s_click = &S_click);
|
||||||
|
SEE_intern_global(s_focus = &S_focus);
|
||||||
|
SEE_intern_global(s_select = &S_select);
|
||||||
|
|
||||||
|
SEE_intern_global(s_elements = &S_elements);
|
||||||
|
SEE_intern_global(s_item = &S_item);
|
||||||
|
SEE_intern_global(s_namedItem = &S_namedItem);
|
||||||
|
SEE_intern_global(s_length = &S_length);
|
||||||
|
|
||||||
|
SEE_intern_global(s_action = &S_action);
|
||||||
|
SEE_intern_global(s_encoding = &S_encoding);
|
||||||
|
SEE_intern_global(s_method = &S_method);
|
||||||
|
SEE_intern_global(s_target = &S_target);
|
||||||
|
SEE_intern_global(s_reset = &S_reset);
|
||||||
|
SEE_intern_global(s_submit = &S_submit);
|
||||||
|
|
||||||
|
SEE_intern_global(s_forms = &S_forms);
|
||||||
|
|
||||||
|
SEE_intern_global(s_document = &S_document);
|
||||||
|
SEE_intern_global(s_referrer = &S_referrer);
|
||||||
|
SEE_intern_global(s_title = &S_title);
|
||||||
|
SEE_intern_global(s_url = &S_url);
|
||||||
|
SEE_intern_global(s_write = &S_write);
|
||||||
|
|
||||||
|
SEE_intern_global(s_Mozilla = &S_Mozilla);
|
||||||
|
SEE_intern_global(s_ELinks_ = &S_ELinks_);
|
||||||
|
SEE_intern_global(s_cookie = &S_cookie);
|
||||||
|
|
||||||
|
SEE_intern_global(s_GET = &S_GET);
|
||||||
|
SEE_intern_global(s_POST = &S_POST);
|
||||||
|
|
||||||
|
SEE_intern_global(s_application_ = &S_application_);
|
||||||
|
SEE_intern_global(s_multipart_ = &S_multipart_);
|
||||||
|
SEE_intern_global(s_textplain = &S_textplain);
|
||||||
|
|
||||||
|
SEE_intern_global(s_text = &S_text);
|
||||||
|
SEE_intern_global(s_password = &S_password);
|
||||||
|
SEE_intern_global(s_file = &S_file);
|
||||||
|
SEE_intern_global(s_checkbox = &S_checkbox);
|
||||||
|
SEE_intern_global(s_radio = &S_radio);
|
||||||
|
SEE_intern_global(s_image = &S_image);
|
||||||
|
SEE_intern_global(s_button = &S_button);
|
||||||
|
SEE_intern_global(s_hidden = &S_hidden);
|
||||||
|
|
||||||
|
SEE_intern_global(s_timeout = &S_timeout);
|
||||||
|
}
|
101
src/ecmascript/see/strings.h
Normal file
101
src/ecmascript/see/strings.h
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
|
||||||
|
#ifndef EL__ECMASCRIPT_SEE_STRINGS_H
|
||||||
|
#define EL__ECMASCRIPT_SEE_STRINGS_H
|
||||||
|
|
||||||
|
#include <see/see.h>
|
||||||
|
|
||||||
|
void init_intern_strings(void);
|
||||||
|
|
||||||
|
extern struct SEE_string *s_window;
|
||||||
|
extern struct SEE_string *s_closed;
|
||||||
|
extern struct SEE_string *s_parent;
|
||||||
|
extern struct SEE_string *s_self;
|
||||||
|
extern struct SEE_string *s_top;
|
||||||
|
extern struct SEE_string *s_alert;
|
||||||
|
extern struct SEE_string *s_open;
|
||||||
|
|
||||||
|
extern struct SEE_string *s_menubar;
|
||||||
|
|
||||||
|
extern struct SEE_string *s_statusbar;
|
||||||
|
extern struct SEE_string *s_visible;
|
||||||
|
|
||||||
|
extern struct SEE_string *s_navigator;
|
||||||
|
extern struct SEE_string *s_appCodeName;
|
||||||
|
extern struct SEE_string *s_appName;
|
||||||
|
extern struct SEE_string *s_appVersion;
|
||||||
|
extern struct SEE_string *s_language;
|
||||||
|
extern struct SEE_string *s_platform;
|
||||||
|
extern struct SEE_string *s_userAgent;
|
||||||
|
|
||||||
|
extern struct SEE_string *s_history;
|
||||||
|
extern struct SEE_string *s_back;
|
||||||
|
extern struct SEE_string *s_forward;
|
||||||
|
extern struct SEE_string *s_go;
|
||||||
|
|
||||||
|
extern struct SEE_string *s_location;
|
||||||
|
extern struct SEE_string *s_href;
|
||||||
|
extern struct SEE_string *s_toString;
|
||||||
|
extern struct SEE_string *s_toLocaleString;
|
||||||
|
|
||||||
|
extern struct SEE_string *s_input;
|
||||||
|
extern struct SEE_string *s_accessKey;
|
||||||
|
extern struct SEE_string *s_alt;
|
||||||
|
extern struct SEE_string *s_checked;
|
||||||
|
extern struct SEE_string *s_defaultChecked;
|
||||||
|
extern struct SEE_string *s_defaultValue;
|
||||||
|
extern struct SEE_string *s_disabled;
|
||||||
|
extern struct SEE_string *s_form;
|
||||||
|
extern struct SEE_string *s_maxLength;
|
||||||
|
extern struct SEE_string *s_name;
|
||||||
|
extern struct SEE_string *s_readonly;
|
||||||
|
extern struct SEE_string *s_size;
|
||||||
|
extern struct SEE_string *s_src;
|
||||||
|
extern struct SEE_string *s_tabindex;
|
||||||
|
extern struct SEE_string *s_type;
|
||||||
|
extern struct SEE_string *s_value;
|
||||||
|
extern struct SEE_string *s_blur;
|
||||||
|
extern struct SEE_string *s_click;
|
||||||
|
extern struct SEE_string *s_focus;
|
||||||
|
extern struct SEE_string *s_select;
|
||||||
|
|
||||||
|
extern struct SEE_string *s_elements;
|
||||||
|
extern struct SEE_string *s_item;
|
||||||
|
extern struct SEE_string *s_namedItem;
|
||||||
|
extern struct SEE_string *s_length;
|
||||||
|
|
||||||
|
extern struct SEE_string *s_action;
|
||||||
|
extern struct SEE_string *s_encoding;
|
||||||
|
extern struct SEE_string *s_method;
|
||||||
|
extern struct SEE_string *s_target;
|
||||||
|
extern struct SEE_string *s_reset;
|
||||||
|
extern struct SEE_string *s_submit;
|
||||||
|
|
||||||
|
extern struct SEE_string *s_forms;
|
||||||
|
|
||||||
|
extern struct SEE_string *s_document;
|
||||||
|
extern struct SEE_string *s_referrer;
|
||||||
|
extern struct SEE_string *s_title;
|
||||||
|
extern struct SEE_string *s_url;
|
||||||
|
extern struct SEE_string *s_write;
|
||||||
|
|
||||||
|
extern struct SEE_string *s_Mozilla;
|
||||||
|
extern struct SEE_string *s_ELinks_;
|
||||||
|
extern struct SEE_string *s_cookie;
|
||||||
|
|
||||||
|
extern struct SEE_string *s_GET;
|
||||||
|
extern struct SEE_string *s_POST;
|
||||||
|
extern struct SEE_string *s_application_;
|
||||||
|
extern struct SEE_string *s_multipart_;
|
||||||
|
extern struct SEE_string *s_textplain;
|
||||||
|
|
||||||
|
extern struct SEE_string *s_text;
|
||||||
|
extern struct SEE_string *s_password;
|
||||||
|
extern struct SEE_string *s_file;
|
||||||
|
extern struct SEE_string *s_checkbox;
|
||||||
|
extern struct SEE_string *s_radio;
|
||||||
|
extern struct SEE_string *s_image;
|
||||||
|
extern struct SEE_string *s_button;
|
||||||
|
extern struct SEE_string *s_hidden;
|
||||||
|
|
||||||
|
extern struct SEE_string *s_timeout;
|
||||||
|
#endif
|
206
src/ecmascript/see/unibar.c
Normal file
206
src/ecmascript/see/unibar.c
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
/* The SEE location and history objects implementation. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "elinks.h"
|
||||||
|
|
||||||
|
#include <see/see.h>
|
||||||
|
|
||||||
|
#include "bfu/dialog.h"
|
||||||
|
#include "cache/cache.h"
|
||||||
|
#include "cookies/cookies.h"
|
||||||
|
#include "dialogs/menu.h"
|
||||||
|
#include "dialogs/status.h"
|
||||||
|
#include "document/html/frames.h"
|
||||||
|
#include "document/document.h"
|
||||||
|
#include "document/forms.h"
|
||||||
|
#include "document/view.h"
|
||||||
|
#include "ecmascript/ecmascript.h"
|
||||||
|
#include "ecmascript/see/input.h"
|
||||||
|
#include "ecmascript/see/strings.h"
|
||||||
|
#include "ecmascript/see/unibar.h"
|
||||||
|
#include "ecmascript/see/window.h"
|
||||||
|
#include "intl/gettext/libintl.h"
|
||||||
|
#include "main/select.h"
|
||||||
|
#include "osdep/newwin.h"
|
||||||
|
#include "osdep/sysname.h"
|
||||||
|
#include "protocol/http/http.h"
|
||||||
|
#include "protocol/uri.h"
|
||||||
|
#include "session/history.h"
|
||||||
|
#include "session/location.h"
|
||||||
|
#include "session/session.h"
|
||||||
|
#include "session/task.h"
|
||||||
|
#include "terminal/tab.h"
|
||||||
|
#include "terminal/terminal.h"
|
||||||
|
#include "util/conv.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
#include "viewer/text/draw.h"
|
||||||
|
#include "viewer/text/form.h"
|
||||||
|
#include "viewer/text/link.h"
|
||||||
|
#include "viewer/text/vs.h"
|
||||||
|
|
||||||
|
static void unibar_get(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *);
|
||||||
|
static void unibar_put(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *, int);
|
||||||
|
static int unibar_canput(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
|
||||||
|
static int unibar_hasproperty(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
|
||||||
|
|
||||||
|
struct js_unibar_object {
|
||||||
|
struct SEE_object object;
|
||||||
|
unsigned char bar;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SEE_objectclass js_menubar_object_class = {
|
||||||
|
NULL,
|
||||||
|
unibar_get,
|
||||||
|
unibar_put,
|
||||||
|
unibar_canput,
|
||||||
|
unibar_hasproperty,
|
||||||
|
SEE_no_delete,
|
||||||
|
SEE_no_defaultvalue,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SEE_objectclass js_statusbar_object_class = {
|
||||||
|
NULL,
|
||||||
|
unibar_get,
|
||||||
|
unibar_put,
|
||||||
|
unibar_canput,
|
||||||
|
unibar_hasproperty,
|
||||||
|
SEE_no_delete,
|
||||||
|
SEE_no_defaultvalue,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
unibar_get(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p, struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct session_status *status = &doc_view->session->status;
|
||||||
|
struct js_unibar_object *obj = (struct js_unibar_object *)o;
|
||||||
|
unsigned char bar = obj->bar;
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
if (p == s_visible) {
|
||||||
|
#define unibar_fetch(bar) \
|
||||||
|
SEE_SET_BOOLEAN(res, status->force_show_##bar##_bar >= 0 \
|
||||||
|
? status->force_show_##bar##_bar \
|
||||||
|
: status->show_##bar##_bar)
|
||||||
|
switch (bar) {
|
||||||
|
case 's':
|
||||||
|
unibar_fetch(status);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
unibar_fetch(title);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SEE_SET_BOOLEAN(res, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#undef unibar_fetch
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SEE_SET_UNDEFINED(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
unibar_put(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p, struct SEE_value *val, int attr)
|
||||||
|
{
|
||||||
|
checktime(interp);
|
||||||
|
if (p == s_location) {
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
struct view_state *vs = g->win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct session_status *status = &doc_view->session->status;
|
||||||
|
struct js_unibar_object *obj = (struct js_unibar_object *)o;
|
||||||
|
unsigned char bar = obj->bar;
|
||||||
|
|
||||||
|
switch (bar) {
|
||||||
|
case 's':
|
||||||
|
status->force_show_status_bar =
|
||||||
|
SEE_ToUint32(interp, val);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
status->force_show_title_bar =
|
||||||
|
SEE_ToUint32(interp, val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
unibar_canput(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p)
|
||||||
|
{
|
||||||
|
checktime(interp);
|
||||||
|
if (p == s_visible)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
unibar_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p)
|
||||||
|
{
|
||||||
|
checktime(interp);
|
||||||
|
if (p == s_visible)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
init_js_menubar_object(struct ecmascript_interpreter *interpreter)
|
||||||
|
{
|
||||||
|
struct global_object *g = interpreter->backend_data;
|
||||||
|
struct SEE_interpreter *interp = &g->interp;
|
||||||
|
struct SEE_value v;
|
||||||
|
struct js_unibar_object *menu;
|
||||||
|
|
||||||
|
menu = SEE_NEW(interp, struct js_unibar_object);
|
||||||
|
|
||||||
|
menu->object.objectclass = &js_menubar_object_class;
|
||||||
|
menu->object.objectclass->Class = s_menubar;
|
||||||
|
menu->object.Prototype = NULL;
|
||||||
|
menu->bar = 't';
|
||||||
|
|
||||||
|
SEE_SET_OBJECT(&v, (struct SEE_object *)menu);
|
||||||
|
SEE_OBJECT_PUT(interp, interp->Global, s_menubar, &v, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
init_js_statusbar_object(struct ecmascript_interpreter *interpreter)
|
||||||
|
{
|
||||||
|
struct global_object *g = interpreter->backend_data;
|
||||||
|
struct SEE_interpreter *interp = &g->interp;
|
||||||
|
struct SEE_value v;
|
||||||
|
struct js_unibar_object *status;
|
||||||
|
|
||||||
|
status = SEE_NEW(interp, struct js_unibar_object);
|
||||||
|
|
||||||
|
status->object.objectclass = &js_statusbar_object_class;
|
||||||
|
status->object.objectclass->Class = s_statusbar;
|
||||||
|
status->object.Prototype = NULL;
|
||||||
|
status->bar = 's';
|
||||||
|
|
||||||
|
SEE_SET_OBJECT(&v, (struct SEE_object *)status);
|
||||||
|
SEE_OBJECT_PUT(interp, interp->Global, s_statusbar, &v, 0);
|
||||||
|
}
|
9
src/ecmascript/see/unibar.h
Normal file
9
src/ecmascript/see/unibar.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef EL__ECMASCRIPT_SEE_UNIBAR_H
|
||||||
|
#define EL__ECMASCRIPT_SEE_UNIBAR_H
|
||||||
|
|
||||||
|
struct emascript_interpreter;
|
||||||
|
|
||||||
|
void init_js_menubar_object(struct ecmascript_interpreter *);
|
||||||
|
void init_js_statusbar_object(struct ecmascript_interpreter *);
|
||||||
|
|
||||||
|
#endif
|
371
src/ecmascript/see/window.c
Normal file
371
src/ecmascript/see/window.c
Normal file
@ -0,0 +1,371 @@
|
|||||||
|
/* The SEE window object implementation. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "elinks.h"
|
||||||
|
|
||||||
|
#include <see/see.h>
|
||||||
|
|
||||||
|
#include "bfu/dialog.h"
|
||||||
|
#include "cache/cache.h"
|
||||||
|
#include "cookies/cookies.h"
|
||||||
|
#include "dialogs/menu.h"
|
||||||
|
#include "dialogs/status.h"
|
||||||
|
#include "document/html/frames.h"
|
||||||
|
#include "document/document.h"
|
||||||
|
#include "document/forms.h"
|
||||||
|
#include "document/view.h"
|
||||||
|
#include "ecmascript/ecmascript.h"
|
||||||
|
#include "ecmascript/see/input.h"
|
||||||
|
#include "ecmascript/see/strings.h"
|
||||||
|
#include "ecmascript/see/window.h"
|
||||||
|
#include "intl/gettext/libintl.h"
|
||||||
|
#include "main/select.h"
|
||||||
|
#include "osdep/newwin.h"
|
||||||
|
#include "osdep/sysname.h"
|
||||||
|
#include "protocol/http/http.h"
|
||||||
|
#include "protocol/uri.h"
|
||||||
|
#include "session/history.h"
|
||||||
|
#include "session/location.h"
|
||||||
|
#include "session/session.h"
|
||||||
|
#include "session/task.h"
|
||||||
|
#include "terminal/tab.h"
|
||||||
|
#include "terminal/terminal.h"
|
||||||
|
#include "util/conv.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
#include "viewer/text/draw.h"
|
||||||
|
#include "viewer/text/form.h"
|
||||||
|
#include "viewer/text/link.h"
|
||||||
|
#include "viewer/text/vs.h"
|
||||||
|
|
||||||
|
static struct js_window_object *js_get_global_object(void *);
|
||||||
|
static struct js_window_object *js_try_resolve_frame(struct document_view *, unsigned char *);
|
||||||
|
static void delayed_open(void *);
|
||||||
|
static void delayed_goto_uri_frame(void *);
|
||||||
|
static void window_get(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *);
|
||||||
|
static void window_put(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *, int);
|
||||||
|
static int window_canput(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
|
||||||
|
static int window_hasproperty(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
|
||||||
|
static void js_window_alert(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
|
||||||
|
static void js_window_open(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
|
||||||
|
|
||||||
|
void location_goto(struct document_view *, unsigned char *);
|
||||||
|
|
||||||
|
struct delayed_open {
|
||||||
|
struct session *ses;
|
||||||
|
struct uri *uri;
|
||||||
|
unsigned char *target;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SEE_objectclass js_window_object_class = {
|
||||||
|
NULL,
|
||||||
|
window_get,
|
||||||
|
window_put,
|
||||||
|
window_canput,
|
||||||
|
window_hasproperty,
|
||||||
|
SEE_no_delete,
|
||||||
|
SEE_no_defaultvalue,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct js_window_object *
|
||||||
|
js_get_global_object(void *data)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)data;
|
||||||
|
return g->win;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct js_window_object *
|
||||||
|
js_try_resolve_frame(struct document_view *doc_view, unsigned char *id)
|
||||||
|
{
|
||||||
|
struct session *ses = doc_view->session;
|
||||||
|
struct frame *target;
|
||||||
|
|
||||||
|
assert(ses);
|
||||||
|
target = ses_find_frame(ses, id);
|
||||||
|
if (!target) return NULL;
|
||||||
|
if (target->vs.ecmascript_fragile)
|
||||||
|
ecmascript_reset_state(&target->vs);
|
||||||
|
if (!target->vs.ecmascript) return NULL;
|
||||||
|
return js_get_global_object(target->vs.ecmascript->backend_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
delayed_open(void *data)
|
||||||
|
{
|
||||||
|
struct delayed_open *deo = data;
|
||||||
|
|
||||||
|
assert(deo);
|
||||||
|
open_uri_in_new_tab(deo->ses, deo->uri, 0, 0);
|
||||||
|
done_uri(deo->uri);
|
||||||
|
mem_free(deo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
delayed_goto_uri_frame(void *data)
|
||||||
|
{
|
||||||
|
struct delayed_open *deo = data;
|
||||||
|
|
||||||
|
assert(deo);
|
||||||
|
goto_uri_frame(deo->ses, deo->uri, deo->target, CACHE_MODE_NORMAL);
|
||||||
|
done_uri(deo->uri);
|
||||||
|
mem_free(deo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
window_get(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p, struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct js_window_object *win = (struct js_window_object *)o;
|
||||||
|
struct view_state *vs = win->vs;
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
if (p == s_closed) {
|
||||||
|
SEE_SET_BOOLEAN(res, 0);
|
||||||
|
} else if (p == s_self) {
|
||||||
|
SEE_SET_OBJECT(res, o);
|
||||||
|
} else if (p == s_top || p == s_parent) {
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct document_view *top_view = doc_view->session->doc_view;
|
||||||
|
struct js_window_object *newjsframe;
|
||||||
|
|
||||||
|
assert(top_view && top_view->vs);
|
||||||
|
if (top_view->vs->ecmascript_fragile)
|
||||||
|
ecmascript_reset_state(top_view->vs);
|
||||||
|
if (!top_view->vs->ecmascript) {
|
||||||
|
SEE_SET_UNDEFINED(res);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
newjsframe = js_get_global_object(
|
||||||
|
top_view->vs->ecmascript->backend_data);
|
||||||
|
|
||||||
|
/* Keep this unrolled this way. Will have to check document.domain
|
||||||
|
* JS property. */
|
||||||
|
/* Note that this check is perhaps overparanoid. If top windows
|
||||||
|
* is alien but some other child window is not, we should still
|
||||||
|
* let the script walk thru. That'd mean moving the check to
|
||||||
|
* other individual properties in this switch. */
|
||||||
|
if (compare_uri(vs->uri, top_view->vs->uri, URI_HOST)) {
|
||||||
|
SEE_SET_OBJECT(res, (struct SEE_object *)newjsframe);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (p == s_alert) {
|
||||||
|
SEE_SET_OBJECT(res, win->alert);
|
||||||
|
} else if (p == s_open) {
|
||||||
|
SEE_SET_OBJECT(res, win->open);
|
||||||
|
} else {
|
||||||
|
unsigned char *frame = SEE_string_to_unsigned_char(p);
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct js_window_object *obj =
|
||||||
|
js_try_resolve_frame(doc_view, frame);
|
||||||
|
|
||||||
|
mem_free_if(frame);
|
||||||
|
if (obj) {
|
||||||
|
SEE_SET_OBJECT(res, (struct SEE_object *)obj);
|
||||||
|
} else {
|
||||||
|
SEE_SET_UNDEFINED(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
window_put(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p, struct SEE_value *val, int attr)
|
||||||
|
{
|
||||||
|
checktime(interp);
|
||||||
|
if (p == s_location) {
|
||||||
|
struct js_window_object *win = (struct js_window_object *)o;
|
||||||
|
struct view_state *vs = win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
unsigned char *str = SEE_value_to_unsigned_char(interp, val);
|
||||||
|
|
||||||
|
if (str) {
|
||||||
|
location_goto(doc_view, str);
|
||||||
|
mem_free(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
window_canput(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p)
|
||||||
|
{
|
||||||
|
checktime(interp);
|
||||||
|
if (p == s_location)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
window_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
|
struct SEE_string *p)
|
||||||
|
{
|
||||||
|
checktime(interp);
|
||||||
|
/* all unknown properties return UNDEFINED value */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
js_window_alert(struct SEE_interpreter *interp, struct SEE_object *self,
|
||||||
|
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
|
||||||
|
struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct js_window_object *win = (struct js_window_object *)thisobj;
|
||||||
|
struct view_state *vs = win->vs;
|
||||||
|
unsigned char *string;
|
||||||
|
|
||||||
|
checktime(interp);
|
||||||
|
SEE_SET_BOOLEAN(res, 1);
|
||||||
|
if (argc < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
string = SEE_value_to_unsigned_char(interp, argv[0]);
|
||||||
|
if (!string || !*string)
|
||||||
|
return;
|
||||||
|
|
||||||
|
info_box(vs->doc_view->session->tab->term, MSGBOX_FREE_TEXT,
|
||||||
|
N_("JavaScript Alert"), ALIGN_CENTER, string);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
js_window_open(struct SEE_interpreter *interp, struct SEE_object *self,
|
||||||
|
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
|
||||||
|
struct SEE_value *res)
|
||||||
|
{
|
||||||
|
struct js_window_object *win = (struct js_window_object*)thisobj;
|
||||||
|
struct view_state *vs = win->vs;
|
||||||
|
struct document_view *doc_view = vs->doc_view;
|
||||||
|
struct session *ses = doc_view->session;
|
||||||
|
unsigned char *target = "";
|
||||||
|
unsigned char *url, *url2;
|
||||||
|
struct uri *uri;
|
||||||
|
#if 0
|
||||||
|
static time_t ratelimit_start;
|
||||||
|
static int ratelimit_count;
|
||||||
|
#endif
|
||||||
|
checktime(interp);
|
||||||
|
SEE_SET_UNDEFINED(res);
|
||||||
|
if (get_opt_bool("ecmascript.block_window_opening")) {
|
||||||
|
#ifdef CONFIG_LEDS
|
||||||
|
set_led_value(ses->status.popup_led, 'P');
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc < 1) return;
|
||||||
|
#if 0
|
||||||
|
/* Ratelimit window opening. Recursive window.open() is very nice.
|
||||||
|
* We permit at most 20 tabs in 2 seconds. The ratelimiter is very
|
||||||
|
* rough but shall suffice against the usual cases. */
|
||||||
|
|
||||||
|
if (!ratelimit_start || time(NULL) - ratelimit_start > 2) {
|
||||||
|
ratelimit_start = time(NULL);
|
||||||
|
ratelimit_count = 0;
|
||||||
|
} else {
|
||||||
|
ratelimit_count++;
|
||||||
|
if (ratelimit_count > 20)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
url = SEE_value_to_unsigned_char(interp, argv[0]);
|
||||||
|
if (!url) return;
|
||||||
|
|
||||||
|
/* TODO: Support for window naming and perhaps some window features? */
|
||||||
|
|
||||||
|
url2 = join_urls(doc_view->document->uri,
|
||||||
|
trim_chars(url, ' ', 0));
|
||||||
|
mem_free(url);
|
||||||
|
if (!url2) return;
|
||||||
|
uri = get_uri(url2, 0);
|
||||||
|
mem_free(url2);
|
||||||
|
if (!uri) return;
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
target = SEE_value_to_unsigned_char(interp, argv[1]);
|
||||||
|
|
||||||
|
if (target && *target && strcasecmp(target, "_blank")) {
|
||||||
|
struct delayed_open *deo = mem_calloc(1, sizeof(*deo));
|
||||||
|
|
||||||
|
if (deo) {
|
||||||
|
deo->ses = ses;
|
||||||
|
deo->uri = get_uri_reference(uri);
|
||||||
|
deo->target = target;
|
||||||
|
register_bottom_half(delayed_goto_uri_frame, deo);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!get_cmd_opt_bool("no-connect")
|
||||||
|
&& !get_cmd_opt_bool("no-home")
|
||||||
|
&& !get_cmd_opt_bool("anonymous")
|
||||||
|
&& can_open_in_new(ses->tab->term)) {
|
||||||
|
open_uri_in_new_window(ses, uri, NULL, ENV_ANY,
|
||||||
|
CACHE_MODE_NORMAL, TASK_NONE);
|
||||||
|
} else {
|
||||||
|
/* When opening a new tab, we might get rerendered, losing our
|
||||||
|
* context and triggerring a disaster, so postpone that. */
|
||||||
|
struct delayed_open *deo = mem_calloc(1, sizeof(*deo));
|
||||||
|
|
||||||
|
if (deo) {
|
||||||
|
deo->ses = ses;
|
||||||
|
deo->uri = get_uri_reference(uri);
|
||||||
|
register_bottom_half(delayed_open, deo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
done_uri(uri);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
init_js_window_object(struct ecmascript_interpreter *interpreter)
|
||||||
|
{
|
||||||
|
struct global_object *g = interpreter->backend_data;
|
||||||
|
struct SEE_interpreter *interp = &g->interp;
|
||||||
|
struct SEE_value v;
|
||||||
|
|
||||||
|
g->win = SEE_NEW(interp, struct js_window_object);
|
||||||
|
|
||||||
|
g->win->object.objectclass = &js_window_object_class;
|
||||||
|
g->win->object.objectclass->Class = s_window;
|
||||||
|
g->win->object.Prototype = NULL;
|
||||||
|
g->win->vs = interpreter->vs;
|
||||||
|
|
||||||
|
SEE_SET_OBJECT(&v, (struct SEE_object *)g->win);
|
||||||
|
SEE_OBJECT_PUT(interp, interp->Global, s_window, &v, 0);
|
||||||
|
|
||||||
|
g->win->alert = SEE_cfunction_make(interp, js_window_alert, s_alert, 1);
|
||||||
|
g->win->open = SEE_cfunction_make(interp, js_window_open, s_open, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
checktime(struct SEE_interpreter *interp)
|
||||||
|
{
|
||||||
|
struct global_object *g = (struct global_object *)interp;
|
||||||
|
|
||||||
|
if (time(NULL) - g->exec_start > g->max_exec_time) {
|
||||||
|
struct terminal *term = g->win->vs->doc_view->session->tab->term;
|
||||||
|
/* A killer script! Alert! */
|
||||||
|
ecmascript_timeout_dialog(term, g->max_exec_time);
|
||||||
|
SEE_error_throw_string(interp, interp->Error, s_timeout);
|
||||||
|
}
|
||||||
|
}
|
27
src/ecmascript/see/window.h
Normal file
27
src/ecmascript/see/window.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef EL__ECMASCRIPT_SEE_WINDOW_H
|
||||||
|
#define EL__ECMASCRIPT_SEE_WINDOW_H
|
||||||
|
|
||||||
|
struct SEE_object;
|
||||||
|
struct SEE_interpreter;
|
||||||
|
struct string;
|
||||||
|
struct view_state;
|
||||||
|
|
||||||
|
|
||||||
|
struct js_window_object {
|
||||||
|
struct SEE_object object;
|
||||||
|
struct view_state *vs;
|
||||||
|
struct SEE_object *alert;
|
||||||
|
struct SEE_object *open;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct global_object {
|
||||||
|
struct SEE_interpreter interp;
|
||||||
|
struct js_window_object *win;
|
||||||
|
int exec_start;
|
||||||
|
int max_exec_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
void init_js_window_object(struct ecmascript_interpreter *);
|
||||||
|
void checktime(struct SEE_interpreter *interp);
|
||||||
|
|
||||||
|
#endif
|
@ -61,6 +61,76 @@
|
|||||||
|
|
||||||
static JSRuntime *jsrt;
|
static JSRuntime *jsrt;
|
||||||
|
|
||||||
|
void
|
||||||
|
ecmascript_init(struct module *module)
|
||||||
|
{
|
||||||
|
spidermonkey_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ecmascript_done(struct module *module)
|
||||||
|
{
|
||||||
|
spidermonkey_done();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ecmascript_interpreter *
|
||||||
|
ecmascript_get_interpreter(struct view_state *vs)
|
||||||
|
{
|
||||||
|
struct ecmascript_interpreter *interpreter;
|
||||||
|
|
||||||
|
assert(vs);
|
||||||
|
|
||||||
|
interpreter = mem_calloc(1, sizeof(*interpreter));
|
||||||
|
if (!interpreter)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
interpreter->vs = vs;
|
||||||
|
init_list(interpreter->onload_snippets);
|
||||||
|
spidermonkey_get_interpreter(interpreter);
|
||||||
|
|
||||||
|
return interpreter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ecmascript_put_interpreter(struct ecmascript_interpreter *interpreter)
|
||||||
|
{
|
||||||
|
assert(interpreter);
|
||||||
|
spidermonkey_put_interpreter(interpreter);
|
||||||
|
free_string_list(&interpreter->onload_snippets);
|
||||||
|
mem_free(interpreter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ecmascript_eval(struct ecmascript_interpreter *interpreter,
|
||||||
|
struct string *code)
|
||||||
|
{
|
||||||
|
if (!get_ecmascript_enable())
|
||||||
|
return;
|
||||||
|
assert(interpreter);
|
||||||
|
spidermonkey_eval(interpreter, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *
|
||||||
|
ecmascript_eval_stringback(struct ecmascript_interpreter *interpreter,
|
||||||
|
struct string *code)
|
||||||
|
{
|
||||||
|
if (!get_ecmascript_enable())
|
||||||
|
return NULL;
|
||||||
|
assert(interpreter);
|
||||||
|
return spidermonkey_eval_stringback(interpreter, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ecmascript_eval_boolback(struct ecmascript_interpreter *interpreter,
|
||||||
|
struct string *code)
|
||||||
|
{
|
||||||
|
if (!get_ecmascript_enable())
|
||||||
|
return -1;
|
||||||
|
assert(interpreter);
|
||||||
|
return spidermonkey_eval_boolback(interpreter, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
error_reporter(JSContext *ctx, const char *message, JSErrorReport *report)
|
error_reporter(JSContext *ctx, const char *message, JSErrorReport *report)
|
||||||
{
|
{
|
||||||
@ -123,14 +193,7 @@ safeguard(JSContext *ctx, JSScript *script)
|
|||||||
struct terminal *term = interpreter->vs->doc_view->session->tab->term;
|
struct terminal *term = interpreter->vs->doc_view->session->tab->term;
|
||||||
|
|
||||||
/* A killer script! Alert! */
|
/* A killer script! Alert! */
|
||||||
info_box(term, MSGBOX_FREE_TEXT,
|
ecmascript_timeout_dialog(term, max_exec_time);
|
||||||
N_("JavaScript Emergency"), ALIGN_LEFT,
|
|
||||||
msg_text(term,
|
|
||||||
N_("A script embedded in the current document was running\n"
|
|
||||||
"for more than %d seconds. This probably means there is\n"
|
|
||||||
"a bug in the script and it could have halted the whole\n"
|
|
||||||
"ELinks, so the script execution was interrupted."),
|
|
||||||
max_exec_time));
|
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
}
|
}
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
|
@ -225,7 +225,7 @@ save_formhist_to_file(void)
|
|||||||
file = straconcat(elinks_home, FORMS_HISTORY_FILENAME, NULL);
|
file = straconcat(elinks_home, FORMS_HISTORY_FILENAME, NULL);
|
||||||
if (!file) return 0;
|
if (!file) return 0;
|
||||||
|
|
||||||
ssi = secure_open(file, 0177);
|
ssi = secure_open(file);
|
||||||
mem_free(file);
|
mem_free(file);
|
||||||
if (!ssi) return 0;
|
if (!ssi) return 0;
|
||||||
|
|
||||||
|
@ -369,7 +369,7 @@ write_global_history(void)
|
|||||||
file_name = straconcat(elinks_home, GLOBAL_HISTORY_FILENAME, NULL);
|
file_name = straconcat(elinks_home, GLOBAL_HISTORY_FILENAME, NULL);
|
||||||
if (!file_name) return;
|
if (!file_name) return;
|
||||||
|
|
||||||
ssi = secure_open(file_name, 0177); /* rw for user only */
|
ssi = secure_open(file_name);
|
||||||
mem_free(file_name);
|
mem_free(file_name);
|
||||||
if (!ssi) return;
|
if (!ssi) return;
|
||||||
|
|
||||||
|
2004
src/intl/entity.inc
2004
src/intl/entity.inc
File diff suppressed because it is too large
Load Diff
@ -267,7 +267,7 @@ get_address(struct socket_info *info, enum addr_type type)
|
|||||||
info->addr = (struct sockaddr *) sin;
|
info->addr = (struct sockaddr *) sin;
|
||||||
info->size = sizeof(*sin);
|
info->size = sizeof(*sin);
|
||||||
|
|
||||||
return AF_INET;
|
return PF_INET;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -371,14 +371,14 @@ elinks_usleep(unsigned long useconds)
|
|||||||
static int
|
static int
|
||||||
bind_to_af_unix(void)
|
bind_to_af_unix(void)
|
||||||
{
|
{
|
||||||
mode_t saved_mask = umask(0177);
|
mode_t saved_mask = umask(S_IXUSR | S_IRWXG | S_IRWXO);
|
||||||
int attempts = 0;
|
int attempts = 0;
|
||||||
int af = get_address(&s_info_listen, ADDR_IP_SERVER);
|
int pf = get_address(&s_info_listen, ADDR_IP_SERVER);
|
||||||
|
|
||||||
if (af == -1) goto free_and_error;
|
if (pf == -1) goto free_and_error;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
s_info_listen.fd = socket(af, SOCK_STREAM, 0);
|
s_info_listen.fd = socket(pf, SOCK_STREAM, 0);
|
||||||
if (s_info_listen.fd == -1) {
|
if (s_info_listen.fd == -1) {
|
||||||
report_af_unix_error("socket()", errno);
|
report_af_unix_error("socket()", errno);
|
||||||
goto free_and_error;
|
goto free_and_error;
|
||||||
@ -435,12 +435,12 @@ static int
|
|||||||
connect_to_af_unix(void)
|
connect_to_af_unix(void)
|
||||||
{
|
{
|
||||||
int attempts = 0;
|
int attempts = 0;
|
||||||
int af = get_address(&s_info_connect, ADDR_IP_CLIENT);
|
int pf = get_address(&s_info_connect, ADDR_IP_CLIENT);
|
||||||
|
|
||||||
while (af != -1 && attempts++ < MAX_CONNECT_TRIES) {
|
while (pf != -1 && attempts++ < MAX_CONNECT_TRIES) {
|
||||||
int saved_errno;
|
int saved_errno;
|
||||||
|
|
||||||
s_info_connect.fd = socket(af, SOCK_STREAM, 0);
|
s_info_connect.fd = socket(pf, SOCK_STREAM, 0);
|
||||||
if (s_info_connect.fd == -1) {
|
if (s_info_connect.fd == -1) {
|
||||||
report_af_unix_error("socket()", errno);
|
report_af_unix_error("socket()", errno);
|
||||||
break;
|
break;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user