mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
Merge branch 'elinks-0.12' into elinks-0.13
Conflicts: NEWS configure.in The following files also conflicted, but they had not been manually edited in the elinks-0.12 branch after the previous merge, so I just kept the 0.13.GIT versions: doc/man/man1/elinks.1.in doc/man/man5/elinks.conf.5 doc/man/man5/elinkskeys.5 po/fr.po po/pl.po
This commit is contained in:
commit
988cec481b
8
AUTHORS
8
AUTHORS
@ -282,9 +282,11 @@ Julian Kinraid <jkinraid@clear.net.nz>
|
||||
QNX-related fixes
|
||||
|
||||
Kalle Olavi Niemitalo <kon@iki.fi>
|
||||
HTTP Accept-Charset header fix
|
||||
Finnish translation update
|
||||
Fixed unnecessary or possibly skipped calls to bind_textdomain_codeset()
|
||||
Scanning PO files for accelerator conflicts (msgaccel)
|
||||
UTF-8 and terminal support enhancements
|
||||
Build system fixes
|
||||
Finnish translation updates
|
||||
Random hacking
|
||||
|
||||
Kaloian Doganov <kaloian@europe.com>
|
||||
Bulgarian translation
|
||||
|
@ -1,7 +1,7 @@
|
||||
The ChangeLog file has been removed. You can get the equivalent information
|
||||
by doing
|
||||
|
||||
$ cg log
|
||||
$ git log
|
||||
|
||||
in a checked out GIT tree, or using the gitweb interface available at:
|
||||
|
||||
|
16
INSTALL
16
INSTALL
@ -11,26 +11,20 @@ ECMAScript (that's JavaScript) support.
|
||||
|
||||
##########
|
||||
|
||||
In order to check out the latest tree from GIT (using Cogito):
|
||||
In order to check out the latest tree from GIT:
|
||||
|
||||
$ cg clone check_file_SITES_for_value_of_this
|
||||
$ git clone check_file_SITES_for_value_of_this
|
||||
$ cd elinks
|
||||
|
||||
To update your existing tree to the latest GIT version, do:
|
||||
|
||||
$ cg update
|
||||
|
||||
If you downloaded a nightly snapshot, and want to check out the latest tree
|
||||
from GIT in it, use the command:
|
||||
|
||||
$ cg clone -s check_file_SITES_for_value_of_this
|
||||
$ git pull
|
||||
|
||||
Note that if you obtained the sources directly from GIT, you NEED to run
|
||||
./autogen.sh! (It should be enough to do it once - however, if you have build
|
||||
problems, try running this first.) Also, you obviously need GNU make and
|
||||
autoconf installed on your system (note that autoconf-2.13 is supported, newer
|
||||
ones may cause problems thanks to the autoconf developers who don't know how to
|
||||
maintain backwards compatibility). Otherwise, you have to use the nightly GIT
|
||||
autoconf installed on your system (for the supported versions of autoconf,
|
||||
see AC_PREREQ in configure.in). Otherwise, you have to use the nightly GIT
|
||||
snapshot - you don't need to do this there.
|
||||
|
||||
|
||||
|
@ -229,7 +229,7 @@ export TEST_LIB
|
||||
TESTS = $(wildcard $(srcdir)test-*)
|
||||
|
||||
$(TESTS): $(addsuffix .o,$(TEST_PROGS)) $(TEST_PROGS)
|
||||
@echo "*** $(notdir $@) ***"; \
|
||||
@-echo "*** $(notdir $@) ***"; \
|
||||
$(call shellquote,$(SHELL)) $@ $(TEST_OPTS)
|
||||
|
||||
test-default: $(TESTS)
|
||||
|
187
NEWS
187
NEWS
@ -56,21 +56,26 @@ have already been considered.
|
||||
- critical bug 1009: assertion failure in add_snippets()
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
ELinks 0.12.GIT now:
|
||||
--------------------
|
||||
ELinks 0.12pre1.GIT now:
|
||||
------------------------
|
||||
|
||||
To be released as ELinks 0.12.0.
|
||||
To be released as 0.12pre2, 0.12rc1, or even 0.12.0. This branch
|
||||
generally also includes the bug fixes made in ELinks 0.11.4.GIT.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
This list now contains all the important changes from ELinks 0.11.0 to
|
||||
ELinks 0.12.GIT (4672bad9c73321019c1a2a7695761b8188bd1a8f) and related
|
||||
bug numbers. Each section is sorted by severity and grouped by topic.
|
||||
* minor bug 951: SpiderMonkey scripting objects used to prevent ELinks
|
||||
from removing files from the memory cache
|
||||
|
||||
The list no doubt includes several changes that are not really
|
||||
important enough. Please move them to the separate "should be removed
|
||||
from NEWS" list below, or coalesce several changes into one entry (but
|
||||
do list all bug numbers).
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
Bugs that should be removed from NEWS before the 0.12.0 release:
|
||||
|
||||
* bug 955: Reset buttons no longer run FORM/@onsubmit, and
|
||||
``harmless'' buttons no longer submit the form. ELinks 0.12pre1
|
||||
was the first release that had these bugs.
|
||||
|
||||
ELinks 0.12pre1:
|
||||
----------------
|
||||
|
||||
Released on 2008-07-01. This release also included all the bug fixes
|
||||
of ELinks 0.11.4, but not the ones made in 0.11.4.GIT.
|
||||
|
||||
Notable new features:
|
||||
|
||||
@ -118,6 +123,8 @@ Miscellaneous:
|
||||
decompression, and add deflate and LZMA (requires LZMA Utils)
|
||||
* major bug 503: various fixes in parsing and updating of elinks.conf
|
||||
* Debian bug 257762: turn terminal transparency off by default
|
||||
* bug 770: when the user chooses to resume an HTTP download, abort the
|
||||
automatically started one and start a new one with the right range
|
||||
* bug 724: better parsing of escape sequences and control
|
||||
sequences from the terminal
|
||||
* bug 948: fix wrong UTF-8 output after the charset menu was used
|
||||
@ -221,137 +228,20 @@ Changes in the experimental SGML/DOM implementation:
|
||||
* enhancement: incremental parsing
|
||||
* and more.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
The following changes should be removed from NEWS before ELinks 0.12.0
|
||||
is released. They are currently listed here just to show that they
|
||||
have already been considered.
|
||||
ELinks 0.11.4.GIT now:
|
||||
----------------------
|
||||
|
||||
* Not clear whether the bugs have been fixed:
|
||||
- (bugfix 674) Reproduceable crashes while trying to unsubscribe
|
||||
from a community on Orkut
|
||||
- (bugfix 770) Download resuming simply restarts the download
|
||||
* Only partially fixed bugs:
|
||||
- (bugfix 764) int/long type punning in options
|
||||
- (bugfix 890) Change colors 0-15 to match xterm defaults.
|
||||
The bug report also requests asking xterm to report its palette,
|
||||
but that part will be delayed to 0.13 or later.
|
||||
- (bugfix 784) attributes corrupt character entity references if
|
||||
terminal charset != document charset
|
||||
* Fixed bugs that were not in previous versions:
|
||||
- (bugfix) Fix a crash when adding a server in the cookie manager.
|
||||
- (bugfix) cookies: "Add Server" ignores "cookies.accept_policy".
|
||||
- (bugfix) Fix data: protocol.
|
||||
- (bugfix 747) Properly deselect the main menu instead of crashing
|
||||
- (bugfix 778) ELinks crashes on binary files when
|
||||
document.plain.display_links is set
|
||||
- (bugfix 782) UTF-8 buffer overwritten while in use
|
||||
- (bugfix) switch_to_tab: Prevent "tab number out of range"
|
||||
assertion failure.
|
||||
- (bugfix) Fixed about:
|
||||
- (bugfix 821) I cannot enter national characters in dialog boxes
|
||||
- (bugfix 834) Gzip decompression doesn't work
|
||||
- (bugfix) Fix out-of-bound access to the quote_char buffer
|
||||
- (bugfix 827) Crash with term charset set to Unicode and UTF-8 I/O
|
||||
disabled
|
||||
- (bugfix 826) too small table for double-cell characters
|
||||
- (bugfix 902) crash: "overflow detected realloc()" in realloc_line
|
||||
- (bugfix 912) wrong color in one cell of an HTML input field
|
||||
- (bugfix 835) Text in textarea is unaffected by horizontal
|
||||
scrolling of document in UTF-8 mode
|
||||
- (bugfix 823) Big textarea is too slow with CONFIG_UTF8
|
||||
- (bugfix 754) Pressing ESC do not pop up main menu anymore.
|
||||
- (bugfix 794) tab-close-all-but-current crashes
|
||||
- (bugfix 781) document->buf can overflow with UTF-8 enabled
|
||||
- (bugfix 882) C1 controls pass through to the terminal if written
|
||||
as entity references
|
||||
- (bugfix 935) Yes and No buttons override the bottom border of the
|
||||
dialog.
|
||||
- (bugfix in SEE) Use frame->name instead of target avoiding
|
||||
possible segfault.
|
||||
- (bugfix 957) crash within js_Interpret: cx->fp points to freed
|
||||
memory
|
||||
- (bugfix 920) assertion priority >= prev_priority failed: queue is
|
||||
not sorted
|
||||
- (bugfix 968) assertion width > 0 failed in copy_chars called from
|
||||
justify_line
|
||||
- bug 1015: incompatible pointer type for PyString_AsStringAndSize
|
||||
- bug 917: Going to unopened /dev/fd/ kills select_loop
|
||||
* Already backported to a previous release but not listed there:
|
||||
- (enhancement) Activate link only when onClick returns true.
|
||||
Fixed bug 786 in ELinks 0.11.2.
|
||||
- when the configure script cleans old object files, this no longer
|
||||
causes it to loop. Commit 564b67883b189a05839bcd2a30d8d4c6eb89c66d
|
||||
in ELinks 0.11.1.
|
||||
- don't include <sys/param.h> for MIN and MAX because it may interfere with
|
||||
CONFIG_IPV6 on Linux. Commit 63797ae9b331efd91be27512bd9d5b2e2ff74741
|
||||
in ELinks 0.11.1.
|
||||
- Debian bug 400872: include <sys/types.h> for off_t.
|
||||
(Related to bug 936 but not the same.)
|
||||
Commit 135a79a3c309af36cf963f1d3c34b07f296fa2f7 in ELinks 0.11.3.
|
||||
- bug 107: recognize "localhost" in file: URIs. Cannot reproduce in
|
||||
earlier versions.
|
||||
- fix compilation under gcc 4.x. Backported from gentoo portage.
|
||||
Commit bcabd8b7951f3319199811088e607501296ee573 in ELinks 0.11.3.
|
||||
- enhancement: avoid compilation of vernum.c in 'make install'
|
||||
- bug 991: quote spaces in file names passed to external handlers
|
||||
* Reverted changes:
|
||||
- (new feature) document.write, reverted in
|
||||
2c087e52e74528a720621186b91880463e039d50
|
||||
- (enhancement) restore Linux console mode (UTF-8 or not), reverted
|
||||
in 10d72cae7eafa6b90db1c8f303deb200555734c2
|
||||
- (enhancement) wcwidth, reverted in
|
||||
d050cb67aa37390ab938b0a308c7541f19578506
|
||||
- (new feature) Let plain text change colors with ESC [ 31 m or
|
||||
similar control sequences, reverted in
|
||||
2a6125e3d0407b588eb286d4d0ff5c98c23ebda9
|
||||
- (enhancement) Support for pasting from GNU screen clipboard,
|
||||
reverted in 763f03f146cc1391b303c8074556f0ddea1e3c7a
|
||||
- enhancement 121: if a mailcap entry indicates 'copiousoutput',
|
||||
ELinks itself acts as a pager
|
||||
* Unimportant changes:
|
||||
- (enhancement) If select fails, save its errno.
|
||||
- (bugfix) Use PF_* instead of AF_* as first parameter of socket(2).
|
||||
(commits 8b7657deaf6037736d0abe88bae1865fec55fe93 in 0.12.GIT
|
||||
and d9b56bad7d528a87376768572c2601c57d8afb02 in 0.11.0.GIT)
|
||||
- (bugfix) Better error handling in save_form_data_to_file and
|
||||
save_textarea_file.
|
||||
(commit 6bdc34cfbcade0c25922c1ad96c753cc7d1c9949 and nearby)
|
||||
- (bugfix) Do not call toupper with potentially out-of-range values.
|
||||
(commit 9e30ee631ced843f26a264c351cfa1716e7e1941)
|
||||
- (bugfix) If ELinks logs debug information to a file, it now opens
|
||||
that in binary mode. (commit 4ced25779dca68c0e15ce1e695ce191b536bb05d)
|
||||
- (bugfix) Kill the ESC timer when blocking the terminal.
|
||||
(commit 539f756438fca4264ab937b2ccfba2351e916a16)
|
||||
- (bugfix) Don't claim that the authentication is for HTTP.
|
||||
(commit ef2f6383c6f0bed576e6f69030eacc4931b42a27)
|
||||
- (enhancement) Reject invalid UTF-8 input from documents and
|
||||
terminals
|
||||
- (bugfix) Decode UTF-8 only from bytes, not from codes of special
|
||||
keys.
|
||||
- (enhancement) "Resize terminal" tries to use the window size
|
||||
increment.
|
||||
- (bugfix) Subprocess forked for SIGTSTP calls _exit, not exit.
|
||||
- (enhancement) Tell the user how to move bookmarks.
|
||||
- (enhancement) Localization updates. For this to be important, we
|
||||
should at least list the languages.
|
||||
- (enhancement) Ctrl+characters don't trigger hotkeys in menus and
|
||||
dialogs.
|
||||
- (bitrot) Fix two warnings on Mac OS X.
|
||||
* don't use cmp -b, which FreeBSD doesn't support. This is commit
|
||||
7a5f699a88c5fc89c510854b04702c16c30ece5a in src/dom/test/ which
|
||||
is run only by "make test" rather than "make".
|
||||
* support much longer locale-specific timestamps when formatting a
|
||||
directory listing. LC_TIME=fi_FI.UTF-8 now works. Let's treat
|
||||
this as part of the UTF-8 support.
|
||||
* enhancement in user SMJS: elinks.alert no longer displays as an
|
||||
"error"
|
||||
* Really retry forever when connection.retries = 0
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
To be released as 0.11.5.
|
||||
|
||||
ELinks 0.11.4rc1.GIT now:
|
||||
-------------------------
|
||||
* critical bug 1027 in user SMJS: make elinks.keymaps treat null and
|
||||
"none" as equivalent actions, avoiding a segfault
|
||||
* major bug 503: various fixes in parsing and updating of elinks.conf
|
||||
* build bug 1021: fixed uninitialized variable in http_got_header
|
||||
|
||||
To be released as 0.11.4.
|
||||
ELinks 0.11.4:
|
||||
--------------
|
||||
|
||||
Released on 2008-06-20.
|
||||
|
||||
* critical bug 755: fix crashes due to dangling pointers to struct
|
||||
form_state
|
||||
@ -360,8 +250,10 @@ To be released as 0.11.4.
|
||||
* critical bug 945: don't crash if a Lua script calls e.g. error(nil)
|
||||
* critical bug 1003: don't crash if a smart URI rewrite template gets
|
||||
too few parameters
|
||||
* major bug 956: don't reuse pointers to SpiderMonkey objects that may
|
||||
have been collected as garbage. This fix causes bug 954.
|
||||
* critical bug 1016: avoid JSFunctionSpec for better compatibility
|
||||
across versions of SpiderMonkey
|
||||
* critical bugs 674, 956: don't reuse pointers to SpiderMonkey objects
|
||||
that may have been collected as garbage. This fix causes bug 954.
|
||||
* CVE-2007-2027: check if the program path contains "src/" before
|
||||
using ../po files
|
||||
* important Debian bug 380347: prevent a buffer overflow in entity_cache
|
||||
@ -369,7 +261,6 @@ To be released as 0.11.4.
|
||||
* major bug 788: don't read STRLEN n_a, which isn't initialized by
|
||||
POPpx of Perl v5.8.8 and later
|
||||
* fix query parsing in file: URIs for local CGI (was broken in 0.11.3)
|
||||
* bug 451: fix incompatible pointer type in PERL_SYS_INIT3 call
|
||||
* bug 691: don't look up bogus IPv4 addresses based on characters of a
|
||||
hostname
|
||||
* bug 712: GnuTLS works on https://www-s.uiuc.edu/[]
|
||||
@ -378,6 +269,7 @@ To be released as 0.11.4.
|
||||
* bug 939: fix FSP directory listing (some compiler options left it empty)
|
||||
* bug 978: Python's webbrowser.open_new_tab(URL) works since now
|
||||
* bug 1012: compile with -fno-strict-overflow or -fwrapv if available
|
||||
* bug 1014: fix incompatible pointer type in Perl_sys_init3 call
|
||||
* minor bug 54, Debian bug 338402: don't force the terminal to 8 bits
|
||||
with no parity, and don't disable XON/XOFF flow control either
|
||||
* minor bug 951 in user SMJS: garbage-collect SMJS objects on 'File ->
|
||||
@ -407,15 +299,6 @@ To be released as 0.11.4.
|
||||
* minor build bug 960: fix errors in loadmsgcat.c if mmap() exists but
|
||||
munmap() doesn't
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
The following changes should be removed from NEWS before ELinks 0.11.4
|
||||
is released. They are currently listed here just to show that they
|
||||
have already been considered.
|
||||
|
||||
* Fixed bugs that were not in previous versions:
|
||||
- bug 975: fix int/size_t pointer type mismatch in Perl interface
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
ELinks 0.11.3:
|
||||
--------------
|
||||
|
||||
|
12
SITES
12
SITES
@ -5,16 +5,11 @@ Fan sites:
|
||||
http://starshine.org/xteddy/thomas/elinks/ (tips'n'tricks)
|
||||
|
||||
DEBs:
|
||||
http://packages.debian.org/testing/web/elinks.html
|
||||
http://packages.debian.org/unstable/web/elinks.html
|
||||
http://packages.debian.org/search?keywords=elinks
|
||||
|
||||
RPMs:
|
||||
http://rpmfind.net/linux/rpm2html/search.php?query=elinks
|
||||
|
||||
RISC OS binaries:
|
||||
http://www.riscos.info/unix/indexes/browser.html
|
||||
|
||||
|
||||
GIT root:
|
||||
http://elinks.cz/elinks.git
|
||||
git+ssh://pasky.or.cz/srv/git/elinks.git (only for developers)
|
||||
@ -23,7 +18,6 @@ Mailing list:
|
||||
http://elinks.cz/community.html#mailinglist
|
||||
elinks-users@linuxfromscratch.org (user discussion, announcements)
|
||||
elinks-dev@linuxfromscratch.org (weird development and sorcery talks)
|
||||
listar@linuxfromscratch.org (Subject: subscribe elinks-users)
|
||||
|
||||
|
||||
If you want to see the original Links as well, try:
|
||||
@ -33,11 +27,9 @@ Primary site:
|
||||
|
||||
Mirrors:
|
||||
http://links.sourceforge.net/download/
|
||||
ftp://ftp.fu-berlin.de/unix/network/www/links/
|
||||
|
||||
DEBs:
|
||||
http://packages.debian.org/stable/web/links.html
|
||||
http://packages.debian.org/unstable/web/links.html
|
||||
http://packages.debian.org/search?keywords=links
|
||||
|
||||
RPMs:
|
||||
http://rpmfind.net/linux/rpm2html/search.php?query=links
|
||||
|
@ -4,8 +4,12 @@
|
||||
#
|
||||
# Note that this will download about 80M.
|
||||
|
||||
if [ -z "`which wget 2>/dev/null`" ]; then
|
||||
echo "Error: You need to have wget installed so that I can fetch the history." >&2
|
||||
if [ -n "`which wget 2>/dev/null`" ]; then
|
||||
downloader="wget -c"
|
||||
elif [ -n "`which curl 2>/dev/null`" ]; then
|
||||
downloader="curl -C - -O"
|
||||
else
|
||||
echo "Error: You need to have wget or curl installed so that I can fetch the history." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@ -24,8 +28,8 @@ echo "ELinks history converted from CVS. Keep this pack separate to speed up gi
|
||||
# pack-0d6c5c67aab3b9d5d9b245da5929c15d79124a48.idx is 3163784 bytes long.
|
||||
# Downloading it takes less than 6 seconds here, whereas generating it
|
||||
# with git index-pack takes over 4 minutes (750 MHz Duron, git 1.5.4.1).
|
||||
wget -c http://elinks.cz/elinks-history.git/objects/pack/pack-0d6c5c67aab3b9d5d9b245da5929c15d79124a48.idx
|
||||
wget -c http://elinks.cz/elinks-history.git/objects/pack/pack-0d6c5c67aab3b9d5d9b245da5929c15d79124a48.pack
|
||||
$downloader http://elinks.cz/elinks-history.git/objects/pack/pack-0d6c5c67aab3b9d5d9b245da5929c15d79124a48.idx
|
||||
$downloader http://elinks.cz/elinks-history.git/objects/pack/pack-0d6c5c67aab3b9d5d9b245da5929c15d79124a48.pack
|
||||
|
||||
echo "[grafthistory] Setting up the grafts"
|
||||
cd ../..
|
||||
|
@ -20,10 +20,12 @@
|
||||
|
||||
# set -x
|
||||
|
||||
echo "-------------------------------------------------"
|
||||
echo "Date: $(date)"
|
||||
echo "Args: $*"
|
||||
echo "-------------------------------------------------"
|
||||
cat <<EOF
|
||||
-------------------------------------------------
|
||||
Date: $(date)
|
||||
Args: $*
|
||||
-------------------------------------------------
|
||||
EOF
|
||||
|
||||
# Variables used in this script:
|
||||
# $GIT_DIR = option -g GIT_DIR; passed in environment to Git
|
||||
@ -55,30 +57,30 @@ do
|
||||
(d) docdir=$OPTARG ;;
|
||||
(o) outdir=$OPTARG ;;
|
||||
("?") exit 1 ;;
|
||||
(*) echo >&2 "$0:$LINENO: bug found"
|
||||
(*) printf >&2 "%s:%d: bug found\n" "$0" "$LINENO"
|
||||
exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ $OPTIND -le $# ]
|
||||
then
|
||||
echo >&2 "$0: too many non-option arguments"
|
||||
printf >&2 "%s: too many non-option arguments\n" "$0"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$GIT_DIR" ]
|
||||
then
|
||||
echo >&2 "$0: Must specify -g GIT_DIR option"
|
||||
printf >&2 "%s: Must specify -g GIT_DIR option\n" "$0"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$outdir" ]
|
||||
then
|
||||
echo >&2 "$0: Must specify -o OUTDIR option"
|
||||
printf >&2 "%s: Must specify -o OUTDIR option\n" "$0"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$rev" ]
|
||||
then
|
||||
echo >&2 "$0: Must specify -r REVISION option"
|
||||
printf >&2 "%s: Must specify -r REVISION option\n" "$0"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$label" ]
|
||||
@ -86,7 +88,7 @@ then
|
||||
label=$rev
|
||||
fi
|
||||
|
||||
commit=$(GIT_DIR=$GIT_DIR cg-object-id -c "$rev") || exit 1
|
||||
commit=$(git --git-dir="$GIT_DIR" rev-parse --verify "$rev^{commit}") || exit 1
|
||||
|
||||
if [ "$snap" ]
|
||||
then
|
||||
@ -102,16 +104,19 @@ tmpdir=$(mktemp -d -t elinks-dist-XXXXXXXX) || exit 1
|
||||
# To make it easier to compare build logs, put the source first in an
|
||||
# "elinks" directory, and only move to "$tartopdir" when finished.
|
||||
|
||||
GIT_DIR=$GIT_DIR cg-export -r "$rev" -- "$tmpdir/elinks"
|
||||
git --git-dir="$GIT_DIR" archive --format=tar --prefix="elinks/" "$rev" |
|
||||
(cd -- "$tmpdir" && tar -xf -)
|
||||
mkdir -- "$tmpdir/elinks/.git"
|
||||
printf "%s\n" "$commit" > "$tmpdir/elinks/.git/HEAD"
|
||||
printf "%s\n" "$commit" > "$tmpdir/elinks/git-commit-id"
|
||||
|
||||
(set -e
|
||||
cd -- "$tmpdir/elinks"
|
||||
./autogen.sh
|
||||
mkdir build
|
||||
cd build
|
||||
../configure
|
||||
# Enable lots of features so that their options will appear in elinks
|
||||
# --config-help and doc/html/elinks.conf.5.html.
|
||||
../configure --enable-bittorrent --enable-cgi --enable-fsp --enable-nntp
|
||||
make -C po
|
||||
mv po/*.gmo ../po/
|
||||
mv contrib/elinks.spec ../contrib/
|
||||
@ -122,6 +127,18 @@ if [ -n "$docdir" ]; then
|
||||
cp -r -- "$docdir"/*.html* "$tmpdir/elinks/doc/html/"
|
||||
# mkdir doc/pdf
|
||||
# cp "$docdir"/*.pdf doc/pdf
|
||||
else
|
||||
make -C "$tmpdir/elinks/build"
|
||||
make -C "$tmpdir/elinks/build/doc" html
|
||||
mkdir -- "$tmpdir/elinks/doc/html"
|
||||
mv -- "$tmpdir/elinks/build/doc"/*.html* "$tmpdir/elinks/doc/html/"
|
||||
# <http://translationproject.org/html/maintainers.html>:
|
||||
# "this tarball should contain an up to date POT file."
|
||||
# Build that here. The Makefile also creates potfiles.list
|
||||
# in the source directory; that one we don't need.
|
||||
# Use rm -f so it's not an error if the file is not there.
|
||||
make -C "$tmpdir/elinks/build/po" ../../po/elinks.pot
|
||||
rm -f -- "$tmpdir/elinks/po/potfiles.list"
|
||||
fi
|
||||
|
||||
rm -rf -- "$tmpdir/elinks/build"
|
||||
@ -130,13 +147,14 @@ mv -- "$tmpdir/elinks" "$tmpdir/$tartopdir"
|
||||
(set -e
|
||||
cd -- "$tmpdir"
|
||||
tar cf "$tarbasename.tar" "$tartopdir"
|
||||
md5sum --binary -- "$tarbasename.tar" > "$tarbasename.md5"
|
||||
bzip2 --keep -- "$tarbasename.tar"
|
||||
gzip -9 -- "$tarbasename.tar"
|
||||
md5sum --binary -- "$tarbasename.tar.gz" "$tarbasename.tar.bz2" >> "$tarbasename.md5"
|
||||
md5sum --binary -- "$tarbasename.tar.gz" > "$tarbasename.tar.gz.md5"
|
||||
md5sum --binary -- "$tarbasename.tar.bz2" > "$tarbasename.tar.bz2.md5"
|
||||
) || exit 1
|
||||
|
||||
mv -- "$tmpdir/$tarbasename.tar.gz" "$outdir"
|
||||
mv -- "$tmpdir/$tarbasename.tar.bz2" "$outdir"
|
||||
mv -- "$tmpdir/$tarbasename.md5" "$outdir"
|
||||
mv -- "$tmpdir/$tarbasename.tar.gz" "$outdir"
|
||||
mv -- "$tmpdir/$tarbasename.tar.bz2" "$outdir"
|
||||
mv -- "$tmpdir/$tarbasename.tar.gz.md5" "$outdir"
|
||||
mv -- "$tmpdir/$tarbasename.tar.bz2.md5" "$outdir"
|
||||
rm -rf -- "$tmpdir"
|
||||
|
@ -1,161 +1,15 @@
|
||||
Methods
|
||||
-------
|
||||
Most of the SpiderMonkey scripting interface is documented in the
|
||||
ELinks manual. This README describes only features added by
|
||||
contrib/smjs/*.js.
|
||||
|
||||
do_file(path)
|
||||
|
||||
Load and evaluate the file with the given path (string). For example:
|
||||
Multiple functions in the same hook
|
||||
-----------------------------------
|
||||
|
||||
do_file("/home/me/.elinks/hooks.js");
|
||||
|
||||
will reload your hooks file.
|
||||
|
||||
|
||||
elinks.alert(message)
|
||||
|
||||
Display the given message (string) in a message box. For example:
|
||||
|
||||
elinks.alert("Hello, world!");
|
||||
|
||||
will display a friendly greeting.
|
||||
|
||||
|
||||
elinks.execute(command)
|
||||
|
||||
Execute the given command (string) on the current terminal. For example:
|
||||
|
||||
var quoted_uri = "'" + elinks.location.replace(/'/g, "'\\''") + "'";
|
||||
elinks.execute("firefox " + quoted_uri);
|
||||
|
||||
will run Firefox with the URI of the current document.
|
||||
|
||||
Note: one must be very careful with elinks.execute, because depending
|
||||
on the OS, the command may be subject to interpretation by a command shell
|
||||
language. When constructing the command string, be sure to quote any
|
||||
dubious parts (such as the URI of the current document, as above).
|
||||
|
||||
|
||||
elinks.load_uri(uri, callback)
|
||||
|
||||
Load the given URI (string). When the URI completes loading, ELinks calls
|
||||
the given callback (function). The callback is passed the cache object
|
||||
that corresponds to the URI. For example:
|
||||
|
||||
elinks.load_uri("http://www.eldar.org/cgi-bin/fortune.pl?text_format=yes",
|
||||
function (cached) { elinks.alert(cached.content); });
|
||||
|
||||
displays a fortune.
|
||||
|
||||
|
||||
Properties
|
||||
----------
|
||||
|
||||
elinks.home (string)
|
||||
|
||||
ELinks's 'home' directory, where it stores its configuration files.
|
||||
Read-only. For example,
|
||||
|
||||
do_file(elinks.home + "hooks.js");
|
||||
|
||||
will reload your hooks file.
|
||||
|
||||
|
||||
elinks.location (string)
|
||||
|
||||
The URI of the currently open document. This can be read to get a string
|
||||
with the URI or set to load a different document. For example,
|
||||
|
||||
elinks.location = elinks.location + "/..";
|
||||
|
||||
will go up a directory (if the URI doesn't end in a file).
|
||||
|
||||
|
||||
elinks.bookmarks (hash)
|
||||
|
||||
This is a hash, the elements of which correspond to the bookmarks.
|
||||
One can delve into the bookmarks hierarchy in a reasonably nifty
|
||||
fashion, just by using standard ECMAScript syntax:
|
||||
|
||||
elinks.bookmarks.x.children.y.children.z.children.foo.title
|
||||
|
||||
gets the title of the bookmark titled 'foo' under the folder 'z',
|
||||
which is a subfolder of 'y', which is a subfolder of 'x'.
|
||||
|
||||
A bookmark object has these properties:
|
||||
|
||||
item.title (string)
|
||||
|
||||
This is the title of the bookmark. It can be read and set.
|
||||
|
||||
item.url (string)
|
||||
|
||||
This is the URI of the bookmark. It can be read and set.
|
||||
|
||||
item.children (hash)
|
||||
|
||||
This is a hash, the elements of which are the bookmarks that
|
||||
are children to the item. It is read-only.
|
||||
|
||||
|
||||
elinks.globhist (hash)
|
||||
|
||||
This is a hash, the elements of which correspond to entries in ELinks's
|
||||
global history. The hash is indexed by URI. For example,
|
||||
|
||||
elinks.globhist["file:///"]
|
||||
|
||||
will get you the history item for your root directory.
|
||||
|
||||
A history item has these properties:
|
||||
|
||||
item.title (string)
|
||||
|
||||
This is the title of the history item. It can be read and set.
|
||||
|
||||
item.url (string)
|
||||
|
||||
This is the URI of the history item. It can be read and set.
|
||||
|
||||
item.last_visit (number)
|
||||
|
||||
This is the UNIX time of the last visit time for the item. UNIX time
|
||||
is the number of seconds that have passed between the UNIX epoch (which
|
||||
is 1970-01-01 00:00:00 UTC) and the represented time. Note that this is
|
||||
_seconds_ since the epoch, whereas ECMAScript likes to use _milliseconds_
|
||||
since the epoch. This property can be set or read.
|
||||
|
||||
|
||||
elinks.keybinding (hash)
|
||||
|
||||
This is a hash, the elements of which correspond to ELinks's keymaps.
|
||||
Currently, there are three: elinks.keybinding.main, elinks.keybinding.edit,
|
||||
and elinks.keybinding.menu. These elements are also hashes, the elements of
|
||||
which correspond to bindings. For example, elinks.keymaps.main["q"] is
|
||||
the binding to the 'q' key in the main map. These bindings can be red,
|
||||
to get the name of the action to which the key is bound, or set, either
|
||||
to a string with the name of the ELinks action or to a function, which will
|
||||
thenceforth be called when the key is pressed. For example,
|
||||
|
||||
elinks.keymaps.main["!"] = function () { elinks.alert("Hello!"); }
|
||||
|
||||
binds the '!' key in the main map to a function that displays a friendly
|
||||
alert.
|
||||
|
||||
elinks.keymaps.main["/"] = "search-typeahead-text";
|
||||
|
||||
changes the '/' key to use the nice typeahead search function instead of
|
||||
opening that ugly old search dialogue box.
|
||||
|
||||
|
||||
Hooks
|
||||
-----
|
||||
|
||||
These are actually properties, but a special case: one assigns functions
|
||||
to them, which functions are called at certain events.
|
||||
|
||||
Note that the default hooks file assigns functions that provide a mechanism
|
||||
to register multiple functions to each hook. When these default hooks are
|
||||
called, they iterate over all functions that are registered to them, calling
|
||||
each one in serial.
|
||||
The default hooks file contrib/smjs/hooks.js assigns functions that
|
||||
provide a mechanism to register multiple functions to each hook. When
|
||||
these default hooks are called, they iterate over all functions that
|
||||
are registered to them, calling each one in serial.
|
||||
|
||||
If you want to register a preformat_html hook, for example,
|
||||
the preferred way to do so is not this:
|
||||
@ -171,78 +25,8 @@ elinks.preformat_html function will iterate.
|
||||
|
||||
If any function in that array returns false, the default hook
|
||||
will stop iteration, not calling any more handlers. This applies
|
||||
to all of the default hooks.
|
||||
to all of the default hooks:
|
||||
|
||||
|
||||
elinks.preformat_html(cached, vs)
|
||||
|
||||
This function is called every time a document is loaded, before the document
|
||||
is actually rendered, to give scripts the opportunity to modify it. The
|
||||
first parameter is the cache object and the second is the view_state object
|
||||
(documented below). As explained above, it is preferred to add your hook
|
||||
to elinks.preformat_html_hooks rather than to assign it to
|
||||
elinks.preformat_html.
|
||||
|
||||
|
||||
elinks.goto_url_hook(url)
|
||||
|
||||
This function is called every time the user enters something
|
||||
in the Go to URL box. The url (string) can be modified or not,
|
||||
and the returned string is substituted for what the user entered.
|
||||
If the value false is returned, the URL is not changed and further hooks
|
||||
in ELinks are not run. As explained above, it is preferred to add your hook
|
||||
to elinks.goto_url_hooks rather than to assign it to elinks.goto_url_hook.
|
||||
|
||||
|
||||
elinks.follow_url_hook(url)
|
||||
|
||||
This function is called every time the user tries to load a document,
|
||||
whether by following a link, by entering a URI in the Go to URL box,
|
||||
by setting elinks.location, or whatever. It behaves the same as
|
||||
elinks.goto_url_hook above. As explained above, it is preferred to add your
|
||||
hook to elinks.follow_url_hooks rather than to assign it to
|
||||
elinks.follow_url_hook.
|
||||
|
||||
Other Objects
|
||||
-------------
|
||||
|
||||
cache
|
||||
|
||||
The cache object mentioned in the descriptions of elinks.load_uri and
|
||||
elinks.preformat_html is a wrapper for the internal ELinks cache object.
|
||||
Its properties are:
|
||||
|
||||
cached.content (string)
|
||||
|
||||
This is the content received from the server. It can be read and set.
|
||||
|
||||
cached.type (string)
|
||||
|
||||
This is the MIME type of the cache entry. It can be read and set.
|
||||
|
||||
cached.length (number)
|
||||
|
||||
This is the length of cached.content. It is read-only.
|
||||
|
||||
cached.head (string)
|
||||
|
||||
This is the header received from the server. It can be read and set.
|
||||
|
||||
cached.uri (string)
|
||||
|
||||
This is the URI of the cache entry. It is read-only.
|
||||
|
||||
view_state
|
||||
|
||||
The view_state object mentioned in the description of elinks.preformat_html
|
||||
is a wrapper for the internal ELinks view_state object. The view state holds
|
||||
information on how the current document is being displayed.
|
||||
|
||||
vs.plain (boolean)
|
||||
|
||||
Whether the current document is rendered as HTML or displayed
|
||||
as plaintext. This can be read and set.
|
||||
|
||||
vs.uri (string)
|
||||
|
||||
This is the URI of the current document. It is read-only.
|
||||
- elinks.preformat_html_hooks
|
||||
- elinks.goto_url_hooks
|
||||
- elinks.follow_url_hooks
|
||||
|
@ -113,26 +113,6 @@ Description:
|
||||
|
||||
Open Lua console dialog.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Name: flush-caches
|
||||
Managed By: The scripting subsystem/backends
|
||||
Triggered When:
|
||||
|
||||
Elinks is going to free its caches. This happens when the user chooses
|
||||
ACT_MAIN_CACHE_MINIMIZE, but currently also on ACT_MAIN_FORGET_CREDENTIALS
|
||||
and when ELinks is quitting.
|
||||
|
||||
Arguments:
|
||||
|
||||
None
|
||||
|
||||
Description:
|
||||
|
||||
If scripting backends hold pointers to cache entries, they should try
|
||||
to release those pointers so that ELinks can free the entries. This
|
||||
may involve a full garbage collection. Also, if backends have some
|
||||
caches of their own, they should flush them.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Name: follow-url
|
||||
Managed By: The scripting subsystem/backends
|
||||
@ -249,6 +229,9 @@ Description:
|
||||
add_fragment(cached, 0, new_string, new_len);
|
||||
normalize_cache_entry(cached, new_len);
|
||||
|
||||
The caller must ensure that there is a reference to cached, so that
|
||||
calling garbage_collection() from the event handler cannot free it.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Name: quit
|
||||
Managed By: The scripting subsystem/backends
|
||||
|
34
doc/faq.txt
34
doc/faq.txt
@ -3,7 +3,7 @@ Frequently Asked Questions
|
||||
:Description: FAQ for the ELinks project
|
||||
|
||||
This is an attempt to capture some of the questions that appear once in a
|
||||
while on the mailing list.
|
||||
while on the mailing list or on IRC.
|
||||
|
||||
|
||||
[[instances]]
|
||||
@ -142,3 +142,35 @@ The new ELinks versions (from 0.9.0 on) send:
|
||||
You should therefore check against something like /^ELinks[\/ ]/, since more
|
||||
fields can be added inside the parenthesis in subsequent versions. Note that
|
||||
users can change their User-Agent through the options system.
|
||||
|
||||
|
||||
[[droppings]]
|
||||
ELinks doesn't erase characters from the screen when it should!
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When you scroll a web page, you may see ELinks leave some characters
|
||||
on the screen even though it should have erased them. Pressing Ctrl+L
|
||||
usually removes these droppings until you scroll again. There are
|
||||
a few possible reasons:
|
||||
|
||||
- ELinks 0.11.* in a UTF-8 locale. By default, ELinks guesses the
|
||||
charset of the terminal from the environment variables LANG,
|
||||
LC_CTYPE, and LC_ALL. ELinks 0.11 versions do not support UTF-8
|
||||
as this charset. To use ELinks 0.11 on a UTF-8 terminal, you
|
||||
should instead enable UTF-8 I/O via the Setup -> Terminal options
|
||||
dialog box, and choose a charset from Setup -> Character set.
|
||||
This limitation has been removed in ELinks 0.12pre1.
|
||||
|
||||
- Web pages may use nonspacing combining characters or Unicode control
|
||||
characters that ELinks does not recognize as such. This happens
|
||||
especially on http://en.wikipedia.org/wiki/Special:RecentChanges[],
|
||||
where the server generates U+200E LEFT-TO-RIGHT MARK characters.
|
||||
ELinks 0.13.GIT now has some support for these characters; see
|
||||
http://bugzilla.elinks.cz/show_bug.cgi?id=824[ELinks bug 824].
|
||||
|
||||
- Some versions of the Terminal application in Mac OS X appear to
|
||||
have a setting that makes line-drawing characters take up the
|
||||
space of two ASCII letters. ELinks does not expect this.
|
||||
To avoid the incompatibility, either disable the setting in the
|
||||
Terminal application or select "No frames" in the Terminal options
|
||||
dialog box of ELinks.
|
||||
|
@ -59,3 +59,5 @@ include::exmode.txt[]
|
||||
include::bittorrent.txt[]
|
||||
|
||||
include::lua-scripting.txt[]
|
||||
|
||||
include::smjs-scripting.txt[]
|
||||
|
@ -4,14 +4,13 @@ Release check list
|
||||
When releasing a new version
|
||||
----------------------------
|
||||
|
||||
1. Tasks in the elinks module:
|
||||
1. Tasks in the elinks module (part 1):
|
||||
|
||||
- Go over the changes since the last release. Use git-shortlog as a template.
|
||||
Write a small changelog highlighting the most important changes. Changes
|
||||
by new contributors are always important!
|
||||
- Update NEWS file and commit. Remember to add the new version number!
|
||||
Don't add the release date yet though; it will be added after the release,
|
||||
from the date in the mailing list archives.
|
||||
Don't add the release date yet though; you will add it in a later step.
|
||||
- Change VERSION in the top of configure.in to hold the new version number.
|
||||
- Update the manpages so the will have the new release number by first
|
||||
building the source, followed by making the `update-man' target in doc/.
|
||||
@ -22,58 +21,73 @@ When releasing a new version
|
||||
|
||||
$ git tag -s -F changelog.file elinks-X.X.X
|
||||
|
||||
- Run script to create new tarballs (both .gz and .bz2).
|
||||
|
||||
$ contrib/mkdist -g "$PWD/.git" -r elinks-X.X.X -l X.X.X
|
||||
|
||||
This step also builds the elinks binary and documentation based on
|
||||
the label, and that might fail because of some bug, so it's best to
|
||||
do this before pushing anything.
|
||||
|
||||
- Create ASCII armored signature files.
|
||||
|
||||
$ gpg -b --armor elinks-X.X.X.tar.bz2
|
||||
$ gpg -b --armor elinks-X.X.X.tar.gz
|
||||
|
||||
- Append ".GIT" to the VERSION variable in the top of configure.in.
|
||||
- Commit only this change.
|
||||
- Push these changes plus tag using:
|
||||
|
||||
$ git push
|
||||
$ git push --tags
|
||||
$ git push tag elinks-X.X.X
|
||||
|
||||
2. Tasks on http://elinks.cz/ (part 1):
|
||||
|
||||
- Wait until the tag etc. has been synced or force a sync of the repository
|
||||
at http://elinks.cz/elinks.git/.
|
||||
- Run script to create new tarballs (both .gz and .bz2).
|
||||
|
||||
$ mkdist elinks-X.X.X X.X.X -r
|
||||
|
||||
3. Tasks on localhost:
|
||||
|
||||
- Download new tarballs and create ASCII armored signature files.
|
||||
- Copy the elinks-X.X.X.tar.* files to http://elinks.cz/download/.
|
||||
- Send announcement to elinks-users mailing list. Do not format it
|
||||
as multipart/signed because the linuxfromscratch archive does not
|
||||
display such messages properly.
|
||||
- Wait for the announcement to hit the elinks-users mailing list archive.
|
||||
|
||||
$ gpg -b --armor elinks-X.X.X.tar.bz2
|
||||
$ gpg -b --armor elinks-X.X.X.tar.gz
|
||||
4. Tasks in the elinks module (part 2):
|
||||
|
||||
- Copy the elinks-X.X.X.tar.*.asc files to http://elinks.cz/download/.
|
||||
- Send announcement to elinks-users mailing list.
|
||||
- Add the release date from the mailing list archive to NEWS.
|
||||
- Commit and push that change.
|
||||
|
||||
4. Tasks in the elinks-web module:
|
||||
5. Tasks in the elinks-web module:
|
||||
|
||||
- Change the version and release data in the start of website.conf.
|
||||
- Wait for the announcement to hit the elinks-users mailing list archive.
|
||||
Also change download.txt if necessary.
|
||||
- Add paraphrased version of the first paragraph of the release announcement
|
||||
as a news entry in news/latest.txt. Make the entry link to both the
|
||||
archived announcement from linuxfromscratch.org and gmane.org using the
|
||||
"magic numbers" expanded by the macro. Possibly, move the cut-off markers
|
||||
that control which news entries to display on the front page.
|
||||
- Rebuild index.html, download.html, news.html, and news.rss.
|
||||
- Rebuild index.html, download.html, news.html, news.rss, and release.html.
|
||||
- Update bugzilla/milestones/elinks.html if the release corresponds
|
||||
to a reached milestone.
|
||||
- Commit the updates HTML and asciidoc files.
|
||||
- Push the commits.
|
||||
|
||||
5. Tasks on http://elinks.cz/ (part 2):
|
||||
6. Tasks on http://elinks.cz/ (part 2):
|
||||
|
||||
- Wait until the elinks-web module has been synced or force a sync of the
|
||||
repository.
|
||||
- Checkout the new updated webpages.
|
||||
|
||||
6. Tasks on http://bugzilla.elinks.cz/:
|
||||
7. Tasks on http://bugzilla.elinks.cz/:
|
||||
|
||||
- Add the new version.
|
||||
- Add a comment to each bug fixed in this version. If some of them
|
||||
are already VERIFIED, change them to CLOSED, unless they are also
|
||||
waiting for a release in another branch.
|
||||
|
||||
7. Tasks external sites and resources:
|
||||
8. Tasks external sites and resources:
|
||||
|
||||
- Add a new release to the freshmeat.net page.
|
||||
- Change topic of #elinks
|
||||
|
396
doc/smjs-scripting.txt
Normal file
396
doc/smjs-scripting.txt
Normal file
@ -0,0 +1,396 @@
|
||||
[[smjs-scripting]]
|
||||
Scripting ELinks with ECMAScript
|
||||
--------------------------------
|
||||
|
||||
As a user of ELinks, you can control its behaviour by writing scripts
|
||||
in ECMAScript. Unlike <<ecmascript,scripts in SCRIPT elements of
|
||||
HTML>>, these user scripts run with all the permissions of your user
|
||||
account, the same as with <<lua-scripting,Lua>>. The object model is
|
||||
very different too.
|
||||
|
||||
Support for ECMAScript user scripts was first added in ELinks 0.11.0.
|
||||
The `configure` script enables it by default if the required SpiderMonkey
|
||||
library has been installed, but you can disable it with `configure
|
||||
\--disable-sm-scripting` or by <<CONFIG-SCRIPTING-SPIDERMONKEY,editing
|
||||
features.conf>>.
|
||||
|
||||
WARNING: ECMAScript scripting is still a bit experimental: there seem to be
|
||||
ways to crash ELinks with it, and the object model may change. However, if
|
||||
you don't have a `hooks.js` file, there is not much risk in enabling the
|
||||
feature at compile time.
|
||||
|
||||
When ELinks starts up, it evaluates the ECMAScript file `hooks.js` in
|
||||
your ELinks configuration directory (thus normally `~/.elinks/hooks.js`
|
||||
on Unix-like systems), or if the file does not exist there, then in
|
||||
the system-wide ELinks configuration directory (the location depends
|
||||
on how ELinks was built, but `/etc/elinks/hooks.js` is typical).
|
||||
|
||||
In the ELinks source tree, the `contrib/smjs` directory contains some
|
||||
examples about scripting ELinks with ECMAScript. Please see the
|
||||
`README` file in that directory for details.
|
||||
|
||||
|
||||
[[smjs-global-object]]
|
||||
Global Object
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The global object provided to ECMAScript user scripts contains the standard
|
||||
ECMAScript classes, as well as the following:
|
||||
|
||||
|
||||
[[smjs-global-methods]]
|
||||
Global Object Methods
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
[[smjs-global.do_file]] do_file(path)::
|
||||
Load and evaluate the file with the given path (string). For example:
|
||||
+
|
||||
--
|
||||
----------------------------------------------------------------------
|
||||
do_file("/home/me/.elinks/hooks.js");
|
||||
----------------------------------------------------------------------
|
||||
|
||||
will reload your hooks file.
|
||||
|
||||
*Compatibility:* ELinks 0.11.0
|
||||
--
|
||||
|
||||
|
||||
[[smjs-global-properties]]
|
||||
Global Object Properties
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
[[smjs-global.elinks]] elinks (elinks)::
|
||||
A reference to the <<smjs-elinks-object,ELinks object>>.
|
||||
+
|
||||
*Compatibility:* ELinks 0.11.0
|
||||
|
||||
|
||||
[[smjs-elinks-object]]
|
||||
ELinks Object
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The global <<smjs-global.elinks,'elinks'>> property refers to this object.
|
||||
|
||||
|
||||
[[smjs-elinks-methods]]
|
||||
ELinks Object Methods
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
[[smjs-elinks.alert]] elinks.alert(message)::
|
||||
Display the given message (string) in a message box. For example:
|
||||
+
|
||||
--
|
||||
----------------------------------------------------------------------
|
||||
elinks.alert("Hello, world!");
|
||||
----------------------------------------------------------------------
|
||||
|
||||
will display a friendly greeting.
|
||||
|
||||
*Compatibility:* ELinks 0.11.0
|
||||
--
|
||||
|
||||
[[smjs-elinks.execute]] elinks.execute(command)::
|
||||
Execute the given command (string) on the current terminal.
|
||||
For example:
|
||||
+
|
||||
--
|
||||
----------------------------------------------------------------------
|
||||
var quoted_uri = "'" + elinks.location.replace(/'/g, "'\\''") + "'";
|
||||
elinks.execute("firefox " + quoted_uri);
|
||||
----------------------------------------------------------------------
|
||||
|
||||
will run Firefox with the URI of the current document.
|
||||
|
||||
*Compatibility:* ELinks 0.12pre1
|
||||
|
||||
WARNING: One must be very careful with 'elinks.execute', because depending
|
||||
on the OS, the command may be subject to interpretation by a command
|
||||
shell language. When constructing the command string, be sure to quote
|
||||
any dubious parts (such as the URI of the current document, as above).
|
||||
--
|
||||
|
||||
[[smjs-elinks.load_uri]] elinks.load_uri(uri, callback)::
|
||||
Load the given URI (string). When the URI completes loading, ELinks
|
||||
calls the given callback (function). The callback is passed the
|
||||
<<smjs-cache_entry-object,cache object>> that corresponds to the URI.
|
||||
For example:
|
||||
+
|
||||
--
|
||||
----------------------------------------------------------------------
|
||||
elinks.load_uri("http://www.eldar.org/cgi-bin/fortune.pl?text_format=yes",
|
||||
function (cached) { elinks.alert(cached.content); });
|
||||
----------------------------------------------------------------------
|
||||
|
||||
displays a fortune.
|
||||
|
||||
The <<smjs-cache_entry-object,cache object>> will not expire until after the
|
||||
callback returns.
|
||||
|
||||
*Compatibility:* ELinks 0.12pre1
|
||||
--
|
||||
|
||||
|
||||
[[smjs-elinks-properties]]
|
||||
ELinks Object Properties
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
[[smjs-elinks.home]] elinks.home (string)::
|
||||
ELinks's ``home'' directory, where it stores its configuration files.
|
||||
Read-only. For example,
|
||||
+
|
||||
--
|
||||
----------------------------------------------------------------------
|
||||
do_file(elinks.home + "hooks.js");
|
||||
----------------------------------------------------------------------
|
||||
|
||||
will reload your hooks file.
|
||||
|
||||
*Compatibility:* ELinks 0.11.0
|
||||
--
|
||||
|
||||
[[smjs-elinks.location]] elinks.location (string)::
|
||||
The URI of the currently open document. This can be read to get a
|
||||
string with the URI or set to load a different document.
|
||||
For example,
|
||||
+
|
||||
--
|
||||
----------------------------------------------------------------------
|
||||
elinks.location = elinks.location + "/..";
|
||||
----------------------------------------------------------------------
|
||||
|
||||
will go up a directory (if the URI doesn't end in a file).
|
||||
|
||||
*Compatibility:* ELinks 0.11.0
|
||||
--
|
||||
|
||||
[[smjs-elinks.bookmarks]] elinks.bookmarks (hash)::
|
||||
This is a hash, the elements of which correspond to the bookmarks.
|
||||
One can delve into the bookmarks hierarchy in a reasonably nifty
|
||||
fashion, just by using standard ECMAScript syntax:
|
||||
+
|
||||
--
|
||||
----------------------------------------------------------------------
|
||||
elinks.bookmarks.x.children.y.children.z.children.foo.title
|
||||
----------------------------------------------------------------------
|
||||
|
||||
gets the title of the bookmark titled ``foo'' under the folder ``z'',
|
||||
which is a subfolder of ``y'', which is a subfolder of ``x''.
|
||||
|
||||
*Compatibility:* ELinks 0.11.0
|
||||
|
||||
[[smjs-bookmark-properties]]
|
||||
A bookmark object has these properties:
|
||||
|
||||
[[smjs-bookmark.title]] item.title (string)::
|
||||
This is the title of the bookmark. It can be read and set.
|
||||
|
||||
[[smjs-bookmark.url]] item.url (string)::
|
||||
This is the URI of the bookmark. It can be read and set.
|
||||
|
||||
[[smjs-bookmark.children]] item.children (hash)::
|
||||
This is a hash, the elements of which are the bookmarks that
|
||||
are children to the item. It is read-only.
|
||||
--
|
||||
|
||||
[[smjs-elinks.globhist]] elinks.globhist (hash)::
|
||||
This is a hash, the elements of which correspond to entries in ELinks's
|
||||
global history. The hash is indexed by URI. For example,
|
||||
+
|
||||
--
|
||||
----------------------------------------------------------------------
|
||||
elinks.globhist["file:///"]
|
||||
----------------------------------------------------------------------
|
||||
|
||||
will get you the history item for your root directory.
|
||||
|
||||
*Compatibility:* ELinks 0.12pre1
|
||||
|
||||
[[smjs-global_history_item-properties]]
|
||||
A history item has these properties:
|
||||
|
||||
[[smjs-global_history_item.title]] item.title (string)::
|
||||
This is the title of the history item. It can be read and set.
|
||||
|
||||
[[smjs-global_history_item.url]] item.url (string)::
|
||||
This is the URI of the history item. It can be read and set.
|
||||
|
||||
[[smjs-global_history_item.last_visit]] item.last_visit (number)::
|
||||
This is the UNIX time of the last visit time for the item. UNIX time
|
||||
is the number of seconds that have passed between the UNIX epoch
|
||||
(which is 1970-01-01 00:00:00 UTC) and the represented time. Note that
|
||||
this is 'seconds' since the epoch, whereas ECMAScript likes to use
|
||||
'milliseconds' since the epoch. This property can be set or read.
|
||||
--
|
||||
|
||||
[[smjs-elinks.action]] elinks.action (hash)::
|
||||
This hash lets you call the built-in actions of ELinks. For example,
|
||||
you can call `elinks.action.auth_manager()` to open the authentication
|
||||
manager. The names of the actions are the same as in elinks.conf or
|
||||
in the keybinding manager, except they have underscores instead of
|
||||
dashes in order to make them valid ECMAScript identifiers.
|
||||
+
|
||||
--
|
||||
*Compatibility:* ELinks 0.12pre1
|
||||
|
||||
NOTE: When you read an action function from this hash, ELinks binds it to the
|
||||
current tab; any later calls to the function affect that tab. This may be
|
||||
changed in a future version. It is safest to call the function right away,
|
||||
rather than save it in a variable and call it later.
|
||||
--
|
||||
|
||||
[[smjs-elinks.keymaps]] elinks.keymaps (hash)::
|
||||
This is a hash, the elements of which correspond to ELinks's keymaps.
|
||||
Currently, there are three: 'elinks.keymaps.main', 'elinks.keymaps.edit',
|
||||
and 'elinks.keymaps.menu'. These elements are also hashes, the elements of
|
||||
which correspond to bindings. For example, `elinks.keymaps.main["q"]` is
|
||||
the binding to the ``q'' key in the main map. These bindings can be read,
|
||||
to get the name of the action to which the key is bound, or set to one of:
|
||||
+
|
||||
--
|
||||
- A string with the name of the ELinks action.
|
||||
- A function, which will thenceforth be called when the key is pressed.
|
||||
- The string `"none"`, to unbind the key. You can also use the `null`
|
||||
value for this purpose, but that crashes ELinks 0.11.4 and 0.12pre1
|
||||
(http://bugzilla.elinks.cz/show_bug.cgi?id=1027[bug 1027]),
|
||||
so it may be best to use the string for now.
|
||||
--
|
||||
+
|
||||
--
|
||||
For example,
|
||||
|
||||
----------------------------------------------------------------------
|
||||
elinks.keymaps.main["!"] = function () { elinks.alert("Hello!"); }
|
||||
----------------------------------------------------------------------
|
||||
|
||||
binds the ``!'' key in the main map to a function that displays a friendly
|
||||
alert.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
elinks.keymaps.main["/"] = "search-typeahead-text";
|
||||
----------------------------------------------------------------------
|
||||
|
||||
changes the ``/'' key to use the nice typeahead search function instead of
|
||||
opening that ugly old search dialogue box.
|
||||
|
||||
*Compatibility:* ELinks 0.11.0, unless you use `null`.
|
||||
|
||||
NOTE: Do not read a function from <<smjs-elinks.action,'elinks.action'>>,
|
||||
e.g. `elinks.action.search_typeahead_text`, and place it in a keymap.
|
||||
ELinks binds such functions to the current tab when the script reads
|
||||
them from 'elinks.action', so they will not work right in other tabs.
|
||||
Use the name of the action instead.
|
||||
--
|
||||
|
||||
[[smjs-elinks.vs]] elinks.vs (view_state)::
|
||||
This property refers to the <<smjs-view_state-object,view-state
|
||||
object>> for the current document, if any.
|
||||
+
|
||||
*Compatibility:* ELinks 0.12pre1
|
||||
|
||||
|
||||
[[smjs-elinks-hooks]]
|
||||
ELinks Object Hooks
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
These are actually properties, but a special case: one assigns functions
|
||||
to them, which functions are called at certain events.
|
||||
|
||||
In the ELinks source tree, `contrib/smjs/hooks.js` provides a mechanism
|
||||
with which multiple scripts can add their functions to the same hooks.
|
||||
Please see `contrib/smjs/README` for details.
|
||||
|
||||
[[smjs-elinks.preformat_html]] elinks.preformat_html(cached, vs)::
|
||||
This function is called every time a document is loaded, before the
|
||||
document is actually rendered, to give scripts the opportunity to
|
||||
modify it. The first parameter is the <<smjs-cache_entry-object,cache
|
||||
object>> and the second is the <<smjs-view_state-object,view-state
|
||||
object>>.
|
||||
+
|
||||
--
|
||||
The <<smjs-cache_entry-object,cache object>> will not expire until after this
|
||||
function returns.
|
||||
|
||||
*Compatibility:* ELinks 0.11.1 as described. ELinks 0.11.0 did not provide
|
||||
the 'vs' argument.
|
||||
--
|
||||
|
||||
[[smjs-elinks.goto_url_hook]] elinks.goto_url_hook(url)::
|
||||
This function is called every time the user enters something in the
|
||||
'Go to URL' box. The url (string) can be modified or not, and the
|
||||
returned string is substituted for what the user entered. If the
|
||||
value `false` is returned, the URL is not changed and further hooks
|
||||
in ELinks are not run.
|
||||
+
|
||||
*Compatibility:* ELinks 0.11.0
|
||||
|
||||
[[smjs-elinks.follow_url_hook]] elinks.follow_url_hook(url)::
|
||||
This function is called every time the user tries to load a document,
|
||||
whether by following a link, by entering a URI in the Go to URL box,
|
||||
by setting <<smjs-elinks.location,'elinks.location'>>, or whatever.
|
||||
It behaves the same as <<smjs-elinks.goto_url_hook,'elinks.goto_url_hook'>>
|
||||
above.
|
||||
+
|
||||
*Compatibility:* ELinks 0.11.0
|
||||
|
||||
|
||||
[[smjs-cache_entry-object]]
|
||||
Cache Object
|
||||
~~~~~~~~~~~~
|
||||
|
||||
The cache object mentioned in the descriptions of
|
||||
<<smjs-elinks.load_uri,'elinks.load_uri'>> and
|
||||
<<smjs-elinks.preformat_html,'elinks.preformat_html'>> is a wrapper for the
|
||||
internal ELinks cache object. ELinks passes the ECMAScript cache object as an
|
||||
argument to your ECMAScript function, and keeps the corresponding document in
|
||||
the cache until the function returns. After that, ELinks may remove the
|
||||
document from the cache, even if the function has saved the cache object to
|
||||
some global variable. Such an expired cache object does not work but it does
|
||||
not crash ELinks either.
|
||||
|
||||
*Compatibility:* ELinks 0.11.0
|
||||
|
||||
|
||||
[[smjs-cache_entry-properties]]
|
||||
Cache Object Properties
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
[[smjs-cache_entry.content]] cached.content (string)::
|
||||
This is the content received from the server. It can be read and set.
|
||||
|
||||
[[smjs-cache_entry.type]] cached.type (string)::
|
||||
This is the MIME type of the cache entry. It can be read and set.
|
||||
|
||||
[[smjs-cache_entry.length]] cached.length (number)::
|
||||
This is the length of cached.content. It is read-only.
|
||||
|
||||
[[smjs-cache_entry.head]] cached.head (string)::
|
||||
This is the header received from the server. It can be read and set.
|
||||
|
||||
[[smjs-cache_entry.uri]] cached.uri (string)::
|
||||
This is the URI of the cache entry. It is read-only.
|
||||
|
||||
|
||||
[[smjs-view_state-object]]
|
||||
View-state Object
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
The view-state object mentioned in the descriptions of
|
||||
<<smjs-elinks.preformat_html,'elinks.preformat_html'>> and
|
||||
<<smjs-elinks.vs,'elinks.vs'>> is a wrapper for the internal ELinks view_state
|
||||
object. The view state holds information on how the current document is being
|
||||
displayed.
|
||||
|
||||
*Compatibility:* ELinks 0.11.1
|
||||
|
||||
|
||||
[[smjs-view_state-properties]]
|
||||
View-state Object Properties
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
[[smjs.view_state.plain]] vs.plain (boolean)::
|
||||
Whether the current document is rendered as HTML or displayed
|
||||
as plaintext. This can be read and set.
|
||||
|
||||
[[smjs.view_state.uri]] vs.uri (string)::
|
||||
This is the URI of the current document. It is read-only.
|
29
po/Makefile
29
po/Makefile
@ -1,6 +1,13 @@
|
||||
top_builddir=..
|
||||
include $(top_builddir)/Makefile.config
|
||||
|
||||
# We prefer the capitalized name for Project-Id-Version.
|
||||
ifeq ($(PACKAGE), elinks)
|
||||
PRETTY_PACKAGE = ELinks
|
||||
else
|
||||
PRETTY_PACKAGE = $(PACKAGE)
|
||||
endif
|
||||
|
||||
# Where to install the catalog files.
|
||||
localedir = $(datadir)/locale
|
||||
|
||||
@ -48,14 +55,17 @@ all-local: $(CATALOGS)
|
||||
# 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!
|
||||
|
||||
$(srcdir)$(POTFILES_ABS_LIST): $(POTFILES_REL)
|
||||
$(POTFILES_ABS_LIST): $(POTFILES_REL)
|
||||
@( cd $(top_srcdir); \
|
||||
find src/ -type f -name '*.[ch]' -o -name options.inc -o -name 'actions-*.inc' | sort ) \
|
||||
> $(srcdir)$(POTFILES_ABS_LIST)
|
||||
> $(POTFILES_ABS_LIST)
|
||||
|
||||
$(srcdir)$(PACKAGE).pot: $(srcdir)$(POTFILES_ABS_LIST) $(srcdir)perl/msgaccel-prepare
|
||||
# xgettext --flag requires GNU gettext 0.13 or later;
|
||||
# --msgid-bugs-address requires 0.12 or later.
|
||||
$(srcdir)$(PACKAGE).pot: $(POTFILES_ABS_LIST) $(srcdir)perl/msgaccel-prepare
|
||||
$(XGETTEXT) --default-domain=$(PACKAGE) \
|
||||
--directory=$(top_srcdir) \
|
||||
--msgid-bugs-address=elinks-users@linuxfromscratch.org \
|
||||
--add-comments --language=C \
|
||||
--keyword=_ --keyword=N_ --keyword=n_:1,2 --keyword=N__ \
|
||||
--flag=msg_text:2:c-format --flag=die:1:c-format \
|
||||
@ -75,10 +85,13 @@ $(srcdir)$(PACKAGE).pot: $(srcdir)$(POTFILES_ABS_LIST) $(srcdir)perl/msgaccel-pr
|
||||
--flag=_:1:pass-c-format --flag=N_:1:pass-c-format \
|
||||
--flag=n_:1:pass-c-format --flag=n_:2:pass-c-format \
|
||||
--flag=N__:1:pass-c-format \
|
||||
-f $(srcdir)$(POTFILES_ABS_LIST) \
|
||||
&& test -f $(PACKAGE).po \
|
||||
&& $(PERL) -I"$(srcdir)perl" $(srcdir)perl/msgaccel-prepare -S"$(top_srcdir)" $(PACKAGE).po \
|
||||
&& mv -f $(PACKAGE).po $(srcdir)$(PACKAGE).pot
|
||||
-f $(POTFILES_ABS_LIST)
|
||||
test -f $(PACKAGE).po
|
||||
$(PERL) -I"$(srcdir)perl" $(srcdir)perl/msgaccel-prepare -S"$(top_srcdir)" $(PACKAGE).po
|
||||
# GNU gettext 0.17 supports xgettext --package-version but is GPLv3+.
|
||||
# This rule already requires Perl so use that instead.
|
||||
$(PERL) -pi -e 's/(^"Project-Id-Version: )PACKAGE VERSION/$$1$(PRETTY_PACKAGE) $(VERSION)/i and $$found=1 unless $$found' $(PACKAGE).po
|
||||
mv -f $(PACKAGE).po $(srcdir)$(PACKAGE).pot
|
||||
|
||||
|
||||
### Updating po and gmo files
|
||||
@ -131,6 +144,6 @@ uninstall-local:
|
||||
)
|
||||
|
||||
clean-local:
|
||||
@rm -f $(PACKAGE).po *.new.po $(srcdir)$(POTFILES_ABS_LIST)
|
||||
@rm -f $(PACKAGE).po *.new.po $(POTFILES_ABS_LIST)
|
||||
|
||||
include $(top_srcdir)/Makefile.lib
|
||||
|
599
po/pt_BR.po
599
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
6
src/cache/cache.c
vendored
6
src/cache/cache.c
vendored
@ -18,6 +18,9 @@
|
||||
#include "protocol/protocol.h"
|
||||
#include "protocol/proxy.h"
|
||||
#include "protocol/uri.h"
|
||||
#ifdef CONFIG_SCRIPTING_SPIDERMONKEY
|
||||
# include "scripting/smjs/smjs.h"
|
||||
#endif
|
||||
#include "util/error.h"
|
||||
#include "util/memory.h"
|
||||
#include "util/string.h"
|
||||
@ -656,6 +659,9 @@ done_cache_entry(struct cache_entry *cached)
|
||||
delete_entry_content(cached);
|
||||
|
||||
if (cached->box_item) done_listbox_item(&cache_browser, cached->box_item);
|
||||
#ifdef CONFIG_SCRIPTING_SPIDERMONKEY
|
||||
if (cached->jsobject) smjs_detach_cache_entry_object(cached);
|
||||
#endif
|
||||
|
||||
if (cached->uri) done_uri(cached->uri);
|
||||
if (cached->proxy_uri) done_uri(cached->proxy_uri);
|
||||
|
3
src/cache/cache.h
vendored
3
src/cache/cache.h
vendored
@ -50,6 +50,9 @@ struct cache_entry {
|
||||
off_t data_size; /* The actual size of all fragments */
|
||||
|
||||
struct listbox_item *box_item; /* Dialog data for cache manager */
|
||||
#ifdef CONFIG_SCRIPTING_SPIDERMONKEY
|
||||
struct JSObject *jsobject; /* Instance of cache_entry_class */
|
||||
#endif
|
||||
|
||||
timeval_T max_age; /* Expiration time */
|
||||
|
||||
|
@ -83,6 +83,7 @@ render_dom_document(struct cache_entry *cached, struct document *document,
|
||||
{
|
||||
unsigned char *head = empty_string_or_(cached->head);
|
||||
struct dom_renderer renderer;
|
||||
struct dom_config config;
|
||||
struct conv_table *convert_table;
|
||||
struct sgml_parser *parser;
|
||||
enum sgml_parser_type parser_type;
|
||||
@ -121,7 +122,7 @@ render_dom_document(struct cache_entry *cached, struct document *document,
|
||||
} else if (renderer.doctype == SGML_DOCTYPE_RSS) {
|
||||
add_dom_stack_context(&parser->stack, &renderer,
|
||||
&dom_rss_renderer_context_info);
|
||||
add_dom_config_normalizer(&parser->stack, RSS_CONFIG_FLAGS);
|
||||
add_dom_config_normalizer(&parser->stack, &config, RSS_CONFIG_FLAGS);
|
||||
}
|
||||
|
||||
/* FIXME: When rendering this way we don't really care about the code.
|
||||
|
@ -224,7 +224,6 @@ dom_normalize_node_end(struct dom_stack *stack, struct dom_node *node, void *dat
|
||||
break;
|
||||
|
||||
case DOM_NODE_DOCUMENT:
|
||||
mem_free(config);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -285,20 +284,15 @@ static struct dom_stack_context_info dom_config_normalizer_context = {
|
||||
};
|
||||
|
||||
struct dom_config *
|
||||
add_dom_config_normalizer(struct dom_stack *stack, enum dom_config_flag flags)
|
||||
add_dom_config_normalizer(struct dom_stack *stack, struct dom_config *config,
|
||||
enum dom_config_flag flags)
|
||||
{
|
||||
struct dom_config *config;
|
||||
|
||||
config = mem_calloc(1, sizeof(*config));
|
||||
if (!config) return NULL;
|
||||
|
||||
memset(config, 0, sizeof(*config));
|
||||
config->flags = flags;
|
||||
|
||||
if (add_dom_stack_context(stack, config, &dom_config_normalizer_context))
|
||||
return config;
|
||||
|
||||
mem_free(config);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,8 @@ struct dom_config {
|
||||
};
|
||||
|
||||
struct dom_config *
|
||||
add_dom_config_normalizer(struct dom_stack *stack, enum dom_config_flag flags);
|
||||
add_dom_config_normalizer(struct dom_stack *stack, struct dom_config *config,
|
||||
enum dom_config_flag flags);
|
||||
|
||||
enum dom_config_flag
|
||||
parse_dom_config(unsigned char *flaglist, unsigned char separator);
|
||||
|
@ -252,6 +252,7 @@ main(int argc, char *argv[])
|
||||
enum sgml_parser_type type = SGML_PARSER_STREAM;
|
||||
enum dom_code code = 0;
|
||||
enum dom_config_flag normalize_flags = 0;
|
||||
struct dom_config config;
|
||||
int normalize = 0;
|
||||
int dump = 0;
|
||||
int complete = 1;
|
||||
@ -310,7 +311,7 @@ main(int argc, char *argv[])
|
||||
|
||||
parser->error_func = sgml_error_function;
|
||||
if (normalize)
|
||||
add_dom_config_normalizer(&parser->stack, normalize_flags);
|
||||
add_dom_config_normalizer(&parser->stack, &config, normalize_flags);
|
||||
else if (!dump)
|
||||
add_dom_stack_context(&parser->stack, NULL, &sgml_parser_test_context_info);
|
||||
|
||||
|
@ -184,32 +184,32 @@ spidermonkey_get_interpreter(struct ecmascript_interpreter *interpreter)
|
||||
}
|
||||
JS_InitStandardClasses(ctx, window_obj);
|
||||
JS_DefineProperties(ctx, window_obj, (JSPropertySpec *) window_props);
|
||||
JS_DefineFunctions(ctx, window_obj, (JSFunctionSpec *) window_funcs);
|
||||
spidermonkey_DefineFunctions(ctx, window_obj, window_funcs);
|
||||
JS_SetPrivate(ctx, window_obj, interpreter->vs); /* to @window_class */
|
||||
|
||||
document_obj = JS_InitClass(ctx, window_obj, NULL,
|
||||
(JSClass *) &document_class, NULL, 0,
|
||||
(JSPropertySpec *) document_props,
|
||||
(JSFunctionSpec *) document_funcs,
|
||||
NULL, NULL);
|
||||
document_obj = spidermonkey_InitClass(ctx, window_obj, NULL,
|
||||
(JSClass *) &document_class, NULL, 0,
|
||||
(JSPropertySpec *) document_props,
|
||||
document_funcs,
|
||||
NULL, NULL);
|
||||
|
||||
forms_obj = JS_InitClass(ctx, document_obj, NULL,
|
||||
(JSClass *) &forms_class, NULL, 0,
|
||||
(JSPropertySpec *) forms_props,
|
||||
(JSFunctionSpec *) forms_funcs,
|
||||
NULL, NULL);
|
||||
forms_obj = spidermonkey_InitClass(ctx, document_obj, NULL,
|
||||
(JSClass *) &forms_class, NULL, 0,
|
||||
(JSPropertySpec *) forms_props,
|
||||
forms_funcs,
|
||||
NULL, NULL);
|
||||
|
||||
history_obj = JS_InitClass(ctx, window_obj, NULL,
|
||||
(JSClass *) &history_class, NULL, 0,
|
||||
(JSPropertySpec *) NULL,
|
||||
(JSFunctionSpec *) history_funcs,
|
||||
NULL, NULL);
|
||||
history_obj = spidermonkey_InitClass(ctx, window_obj, NULL,
|
||||
(JSClass *) &history_class, NULL, 0,
|
||||
(JSPropertySpec *) NULL,
|
||||
history_funcs,
|
||||
NULL, NULL);
|
||||
|
||||
location_obj = JS_InitClass(ctx, window_obj, NULL,
|
||||
(JSClass *) &location_class, NULL, 0,
|
||||
(JSPropertySpec *) location_props,
|
||||
(JSFunctionSpec *) location_funcs,
|
||||
NULL, NULL);
|
||||
location_obj = spidermonkey_InitClass(ctx, window_obj, NULL,
|
||||
(JSClass *) &location_class, NULL, 0,
|
||||
(JSPropertySpec *) location_props,
|
||||
location_funcs,
|
||||
NULL, NULL);
|
||||
|
||||
menubar_obj = JS_InitClass(ctx, window_obj, NULL,
|
||||
(JSClass *) &menubar_class, NULL, 0,
|
||||
|
@ -2,6 +2,6 @@ top_builddir=../../..
|
||||
include $(top_builddir)/Makefile.config
|
||||
INCLUDES += $(SPIDERMONKEY_CFLAGS)
|
||||
|
||||
OBJS = document.o form.o location.o navigator.o unibar.o window.o
|
||||
OBJS = document.o form.o location.o navigator.o unibar.o util.o window.o
|
||||
|
||||
include $(top_srcdir)/Makefile.lib
|
||||
|
@ -245,7 +245,7 @@ document_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
static JSBool document_write(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
static JSBool document_writeln(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
const JSFunctionSpec document_funcs[] = {
|
||||
const spidermonkeyFunctionSpec document_funcs[] = {
|
||||
{ "write", document_write, 1 },
|
||||
{ "writeln", document_writeln, 1 },
|
||||
{ NULL }
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "ecmascript/spidermonkey/util.h"
|
||||
|
||||
extern const JSClass document_class;
|
||||
extern const JSFunctionSpec document_funcs[];
|
||||
extern const spidermonkeyFunctionSpec document_funcs[];
|
||||
extern const JSPropertySpec document_props[];
|
||||
|
||||
#endif
|
||||
|
@ -133,7 +133,7 @@ static JSBool input_click(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv
|
||||
static JSBool input_focus(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
static JSBool input_select(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
static const JSFunctionSpec input_funcs[] = {
|
||||
static const spidermonkeyFunctionSpec input_funcs[] = {
|
||||
{ "blur", input_blur, 0 },
|
||||
{ "click", input_click, 0 },
|
||||
{ "focus", input_focus, 0 },
|
||||
@ -567,7 +567,7 @@ get_input_object(JSContext *ctx, JSObject *jsform, long number)
|
||||
JSObject *jsinput = JS_NewObject(ctx, (JSClass *) &input_class, NULL, jsform);
|
||||
|
||||
JS_DefineProperties(ctx, jsinput, (JSPropertySpec *) input_props);
|
||||
JS_DefineFunctions(ctx, jsinput, (JSFunctionSpec *) input_funcs);
|
||||
spidermonkey_DefineFunctions(ctx, jsinput, input_funcs);
|
||||
JS_SetReservedSlot(ctx, jsinput, JSRS_INPUT_FSINDEX, INT_TO_JSVAL(number));
|
||||
return jsinput;;
|
||||
}
|
||||
@ -616,7 +616,7 @@ static const JSClass form_elements_class = {
|
||||
static JSBool form_elements_item(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
static JSBool form_elements_namedItem(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
static const JSFunctionSpec form_elements_funcs[] = {
|
||||
static const spidermonkeyFunctionSpec form_elements_funcs[] = {
|
||||
{ "item", form_elements_item, 1 },
|
||||
{ "namedItem", form_elements_namedItem, 1 },
|
||||
{ NULL }
|
||||
@ -855,7 +855,7 @@ static const JSPropertySpec form_props[] = {
|
||||
static JSBool form_reset(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
static JSBool form_submit(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
static const JSFunctionSpec form_funcs[] = {
|
||||
static const spidermonkeyFunctionSpec form_funcs[] = {
|
||||
{ "reset", form_reset, 0 },
|
||||
{ "submit", form_submit, 0 },
|
||||
{ NULL }
|
||||
@ -933,7 +933,8 @@ form_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
JSObject *jsform_elems = JS_NewObject(ctx, (JSClass *) &form_elements_class, NULL, obj);
|
||||
|
||||
JS_DefineProperties(ctx, jsform_elems, (JSPropertySpec *) form_elements_props);
|
||||
JS_DefineFunctions(ctx, jsform_elems, (JSFunctionSpec *) form_elements_funcs);
|
||||
spidermonkey_DefineFunctions(ctx, jsform_elems,
|
||||
form_elements_funcs);
|
||||
object_to_jsval(ctx, vp, jsform_elems);
|
||||
/* SM will cache this property value for us so we create this
|
||||
* just once per form. */
|
||||
@ -1162,7 +1163,7 @@ get_form_object(JSContext *ctx, JSObject *jsdoc, struct form_view *fv)
|
||||
JSObject *jsform = JS_NewObject(ctx, (JSClass *) &form_class, NULL, jsdoc);
|
||||
|
||||
JS_DefineProperties(ctx, jsform, (JSPropertySpec *) form_props);
|
||||
JS_DefineFunctions(ctx, jsform, (JSFunctionSpec *) form_funcs);
|
||||
spidermonkey_DefineFunctions(ctx, jsform, form_funcs);
|
||||
JS_SetPrivate(ctx, jsform, fv); /* to @form_class */
|
||||
fv->ecmascript_obj = jsform;
|
||||
return fv->ecmascript_obj;
|
||||
@ -1181,7 +1182,7 @@ const JSClass forms_class = {
|
||||
static JSBool forms_item(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
static JSBool forms_namedItem(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
const JSFunctionSpec forms_funcs[] = {
|
||||
const spidermonkeyFunctionSpec forms_funcs[] = {
|
||||
{ "item", forms_item, 1 },
|
||||
{ "namedItem", forms_namedItem, 1 },
|
||||
{ NULL }
|
||||
|
@ -7,7 +7,7 @@
|
||||
struct form_view;
|
||||
|
||||
extern const JSClass forms_class;
|
||||
extern const JSFunctionSpec forms_funcs[];
|
||||
extern const spidermonkeyFunctionSpec forms_funcs[];
|
||||
extern const JSPropertySpec forms_props[];
|
||||
|
||||
JSObject *get_form_object(JSContext *ctx, JSObject *jsdoc, struct form_view *fv);
|
||||
|
@ -57,7 +57,7 @@ const JSClass history_class = {
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
};
|
||||
|
||||
const JSFunctionSpec history_funcs[] = {
|
||||
const spidermonkeyFunctionSpec history_funcs[] = {
|
||||
{ "back", history_back, 0 },
|
||||
{ "forward", history_forward, 0 },
|
||||
{ "go", history_go, 1 },
|
||||
@ -224,7 +224,7 @@ location_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
|
||||
static JSBool location_toString(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
const JSFunctionSpec location_funcs[] = {
|
||||
const spidermonkeyFunctionSpec location_funcs[] = {
|
||||
{ "toString", location_toString, 0 },
|
||||
{ "toLocaleString", location_toString, 0 },
|
||||
{ NULL }
|
||||
|
@ -7,10 +7,10 @@
|
||||
struct document_view;
|
||||
|
||||
extern const JSClass history_class;
|
||||
extern const JSFunctionSpec history_funcs[];
|
||||
extern const spidermonkeyFunctionSpec history_funcs[];
|
||||
|
||||
extern const JSClass location_class;
|
||||
extern const JSFunctionSpec location_funcs[];
|
||||
extern const spidermonkeyFunctionSpec location_funcs[];
|
||||
extern const JSPropertySpec location_props[];
|
||||
|
||||
void location_goto(struct document_view *doc_view, unsigned char *url);
|
||||
|
60
src/ecmascript/spidermonkey/util.c
Normal file
60
src/ecmascript/spidermonkey/util.c
Normal file
@ -0,0 +1,60 @@
|
||||
/* Better compatibility across versions of SpiderMonkey. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "elinks.h"
|
||||
|
||||
#include "ecmascript/spidermonkey/util.h"
|
||||
|
||||
/** An ELinks-specific replacement for JS_DefineFunctions().
|
||||
*
|
||||
* @relates spidermonkeyFunctionSpec */
|
||||
JSBool
|
||||
spidermonkey_DefineFunctions(JSContext *cx, JSObject *obj,
|
||||
const spidermonkeyFunctionSpec *fs)
|
||||
{
|
||||
for (; fs->name; fs++) {
|
||||
if (!JS_DefineFunction(cx, obj, fs->name, fs->call,
|
||||
fs->nargs, 0))
|
||||
return JS_FALSE;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/** An ELinks-specific replacement for JS_InitClass().
|
||||
*
|
||||
* @relates spidermonkeyFunctionSpec */
|
||||
JSObject *
|
||||
spidermonkey_InitClass(JSContext *cx, JSObject *obj,
|
||||
JSObject *parent_proto, JSClass *clasp,
|
||||
JSNative constructor, uintN nargs,
|
||||
JSPropertySpec *ps,
|
||||
const spidermonkeyFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps,
|
||||
const spidermonkeyFunctionSpec *static_fs)
|
||||
{
|
||||
JSObject *proto = JS_InitClass(cx, obj, parent_proto, clasp,
|
||||
constructor, nargs,
|
||||
ps, NULL, static_ps, NULL);
|
||||
|
||||
if (proto == NULL)
|
||||
return NULL;
|
||||
|
||||
if (fs) {
|
||||
if (!spidermonkey_DefineFunctions(cx, proto, fs))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (static_fs) {
|
||||
JSObject *cons_obj = JS_GetConstructor(cx, proto);
|
||||
|
||||
if (cons_obj == NULL)
|
||||
return NULL;
|
||||
if (!spidermonkey_DefineFunctions(cx, cons_obj, static_fs))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return proto;
|
||||
}
|
@ -99,4 +99,29 @@ jsval_to_string(JSContext *ctx, jsval *vp)
|
||||
return empty_string_or_(JS_GetStringBytes(JS_ValueToString(ctx, val)));
|
||||
}
|
||||
|
||||
/** An ELinks-specific replacement for JSFunctionSpec.
|
||||
*
|
||||
* Bug 1016: In SpiderMonkey 1.7 bundled with XULRunner 1.8, jsapi.h
|
||||
* defines JSFunctionSpec in different ways depending on whether
|
||||
* MOZILLA_1_8_BRANCH is defined, and there is no obvious way for
|
||||
* ELinks to check whether MOZILLA_1_8_BRANCH was defined when the
|
||||
* library was built. Avoid the unstable JSFunctionSpec definitions
|
||||
* and use this ELinks-specific structure instead. */
|
||||
typedef struct spidermonkeyFunctionSpec {
|
||||
const char *name;
|
||||
JSNative call;
|
||||
uint8 nargs;
|
||||
/* ELinks does not use "flags" and "extra" so omit them here. */
|
||||
} spidermonkeyFunctionSpec;
|
||||
|
||||
JSBool spidermonkey_DefineFunctions(JSContext *cx, JSObject *obj,
|
||||
const spidermonkeyFunctionSpec *fs);
|
||||
JSObject *spidermonkey_InitClass(JSContext *cx, JSObject *obj,
|
||||
JSObject *parent_proto, JSClass *clasp,
|
||||
JSNative constructor, uintN nargs,
|
||||
JSPropertySpec *ps,
|
||||
const spidermonkeyFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps,
|
||||
const spidermonkeyFunctionSpec *static_fs);
|
||||
|
||||
#endif
|
||||
|
@ -302,7 +302,7 @@ static JSBool window_alert(JSContext *ctx, JSObject *obj, uintN argc, jsval *arg
|
||||
static JSBool window_open(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
static JSBool window_setTimeout(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
const JSFunctionSpec window_funcs[] = {
|
||||
const spidermonkeyFunctionSpec window_funcs[] = {
|
||||
{ "alert", window_alert, 1 },
|
||||
{ "open", window_open, 3 },
|
||||
{ "setTimeout", window_setTimeout, 2 },
|
||||
|
@ -6,6 +6,6 @@
|
||||
|
||||
extern const JSClass window_class;
|
||||
extern const JSPropertySpec window_props[];
|
||||
extern const JSFunctionSpec window_funcs[];
|
||||
extern const spidermonkeyFunctionSpec window_funcs[];
|
||||
|
||||
#endif
|
||||
|
@ -311,13 +311,6 @@ terminate_all_subsystems(void)
|
||||
void
|
||||
shrink_memory(int whole)
|
||||
{
|
||||
#ifdef CONFIG_SCRIPTING
|
||||
/* The SMJS pre-format-html hook constructs an SMJS object for
|
||||
* each cache entry. Give all scripting modules a cue to garbage
|
||||
* collect any such objects so that the entries can be freed. */
|
||||
if (whole)
|
||||
trigger_event_name("flush-caches");
|
||||
#endif
|
||||
shrink_dns_cache(whole);
|
||||
shrink_format_cache(whole);
|
||||
garbage_collection(whole);
|
||||
|
@ -1493,7 +1493,7 @@ http_got_header(struct socket *socket, struct read_buffer *rb)
|
||||
#endif
|
||||
unsigned char *d;
|
||||
struct uri *uri = conn->proxied_uri; /* Set to the real uri */
|
||||
struct http_version version;
|
||||
struct http_version version = { 0, 9 };
|
||||
enum connection_state state = (conn->state != S_PROC ? S_GETH : S_PROC);
|
||||
int a, h = 200;
|
||||
int cf;
|
||||
@ -1522,6 +1522,9 @@ again:
|
||||
read_from_socket(conn->socket, rb, state, http_got_header);
|
||||
return;
|
||||
}
|
||||
/* a == -2 from get_header means HTTP/0.9. In that case, skip
|
||||
* the get_http_code call; @h and @version have already been
|
||||
* initialized with the right values. */
|
||||
if (a == -2) a = 0;
|
||||
if ((a && get_http_code(rb, &h, &version))
|
||||
|| h == 101) {
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "protocol/uri.h"
|
||||
#include "scripting/smjs/cache_object.h"
|
||||
#include "scripting/smjs/core.h"
|
||||
#include "scripting/smjs/smjs.h"
|
||||
#include "util/error.h"
|
||||
#include "util/memory.h"
|
||||
|
||||
@ -42,6 +43,7 @@ static JSBool
|
||||
cache_entry_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
{
|
||||
struct cache_entry *cached;
|
||||
JSBool ret;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
@ -51,15 +53,22 @@ cache_entry_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
|
||||
cached = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &cache_entry_class, NULL);
|
||||
if (!cached) return JS_FALSE; /* already detached */
|
||||
|
||||
if (!cache_entry_is_valid(cached)) return JS_FALSE;
|
||||
assert(cache_entry_is_valid(cached));
|
||||
if_assert_failed return JS_FALSE;
|
||||
|
||||
/* Get a strong reference to the cache entry to prevent it
|
||||
* from being deleted if some function called below decides to
|
||||
* collect garbage. After this, all code paths must
|
||||
* eventually unlock the object. */
|
||||
object_lock(cached);
|
||||
|
||||
undef_to_jsval(ctx, vp);
|
||||
|
||||
if (!JSVAL_IS_INT(id))
|
||||
return JS_FALSE;
|
||||
|
||||
switch (JSVAL_TO_INT(id)) {
|
||||
ret = JS_FALSE;
|
||||
else switch (JSVAL_TO_INT(id)) {
|
||||
case CACHE_ENTRY_CONTENT: {
|
||||
struct fragment *fragment = get_cache_fragment(cached);
|
||||
|
||||
@ -69,27 +78,32 @@ cache_entry_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
fragment->data,
|
||||
fragment->length));
|
||||
|
||||
return JS_TRUE;
|
||||
ret = JS_TRUE;
|
||||
break;
|
||||
}
|
||||
case CACHE_ENTRY_TYPE:
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx,
|
||||
cached->content_type));
|
||||
|
||||
return JS_TRUE;
|
||||
ret = JS_TRUE;
|
||||
break;
|
||||
case CACHE_ENTRY_HEAD:
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx,
|
||||
cached->head));
|
||||
|
||||
return JS_TRUE;
|
||||
ret = JS_TRUE;
|
||||
break;
|
||||
case CACHE_ENTRY_LENGTH:
|
||||
*vp = INT_TO_JSVAL(cached->length);
|
||||
|
||||
return JS_TRUE;
|
||||
ret = JS_TRUE;
|
||||
break;
|
||||
case CACHE_ENTRY_URI:
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx,
|
||||
struri(cached->uri)));
|
||||
|
||||
return JS_TRUE;
|
||||
ret = JS_TRUE;
|
||||
break;
|
||||
default:
|
||||
/* Unrecognized integer property ID; someone is using
|
||||
* the object as an array. SMJS builtin classes (e.g.
|
||||
@ -97,8 +111,12 @@ cache_entry_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
* and leave *@vp unchanged. Do the same here.
|
||||
* (Actually not quite the same, as we already used
|
||||
* @undef_to_jsval.) */
|
||||
return JS_TRUE;
|
||||
ret = JS_TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
object_unlock(cached);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* @cache_entry_class.setProperty */
|
||||
@ -106,6 +124,7 @@ static JSBool
|
||||
cache_entry_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
{
|
||||
struct cache_entry *cached;
|
||||
JSBool ret;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
@ -115,13 +134,20 @@ cache_entry_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
|
||||
cached = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &cache_entry_class, NULL);
|
||||
if (!cached) return JS_FALSE; /* already detached */
|
||||
|
||||
if (!cache_entry_is_valid(cached)) return JS_FALSE;
|
||||
assert(cache_entry_is_valid(cached));
|
||||
if_assert_failed return JS_FALSE;
|
||||
|
||||
/* Get a strong reference to the cache entry to prevent it
|
||||
* from being deleted if some function called below decides to
|
||||
* collect garbage. After this, all code paths must
|
||||
* eventually unlock the object. */
|
||||
object_lock(cached);
|
||||
|
||||
if (!JSVAL_IS_INT(id))
|
||||
return JS_FALSE;
|
||||
|
||||
switch (JSVAL_TO_INT(id)) {
|
||||
ret = JS_FALSE;
|
||||
else switch (JSVAL_TO_INT(id)) {
|
||||
case CACHE_ENTRY_CONTENT: {
|
||||
JSString *jsstr = JS_ValueToString(smjs_ctx, *vp);
|
||||
unsigned char *str = JS_GetStringBytes(jsstr);
|
||||
@ -130,7 +156,8 @@ cache_entry_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
add_fragment(cached, 0, str, len);
|
||||
normalize_cache_entry(cached, len);
|
||||
|
||||
return JS_TRUE;
|
||||
ret = JS_TRUE;
|
||||
break;
|
||||
}
|
||||
case CACHE_ENTRY_TYPE: {
|
||||
JSString *jsstr = JS_ValueToString(smjs_ctx, *vp);
|
||||
@ -138,7 +165,8 @@ cache_entry_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
|
||||
mem_free_set(&cached->content_type, stracpy(str));
|
||||
|
||||
return JS_TRUE;
|
||||
ret = JS_TRUE;
|
||||
break;
|
||||
}
|
||||
case CACHE_ENTRY_HEAD: {
|
||||
JSString *jsstr = JS_ValueToString(smjs_ctx, *vp);
|
||||
@ -146,18 +174,25 @@ cache_entry_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
|
||||
mem_free_set(&cached->head, stracpy(str));
|
||||
|
||||
return JS_TRUE;
|
||||
ret = JS_TRUE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* Unrecognized integer property ID; someone is using
|
||||
* the object as an array. SMJS builtin classes (e.g.
|
||||
* js_RegExpClass) just return JS_TRUE in this case.
|
||||
* Do the same here. */
|
||||
return JS_TRUE;
|
||||
ret = JS_TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
object_unlock(cached);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* @cache_entry_class.finalize */
|
||||
/** Pointed to by cache_entry_class.finalize. SpiderMonkey
|
||||
* automatically finalizes all objects before it frees the JSRuntime,
|
||||
* so cache_entry.jsobject won't be left dangling. */
|
||||
static void
|
||||
cache_entry_finalize(JSContext *ctx, JSObject *obj)
|
||||
{
|
||||
@ -169,25 +204,37 @@ cache_entry_finalize(JSContext *ctx, JSObject *obj)
|
||||
cached = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &cache_entry_class, NULL);
|
||||
|
||||
if (!cached) return;
|
||||
if (!cached) return; /* already detached */
|
||||
|
||||
object_unlock(cached);
|
||||
JS_SetPrivate(ctx, obj, NULL); /* perhaps not necessary */
|
||||
assert(cached->jsobject == obj);
|
||||
if_assert_failed return;
|
||||
cached->jsobject = NULL;
|
||||
}
|
||||
|
||||
static const JSClass cache_entry_class = {
|
||||
"cache_entry",
|
||||
JSCLASS_HAS_PRIVATE, /* struct cache_entry * */
|
||||
JSCLASS_HAS_PRIVATE, /* struct cache_entry *; a weak reference */
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
cache_entry_get_property, cache_entry_set_property,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, cache_entry_finalize
|
||||
};
|
||||
|
||||
/** Return an SMJS object through which scripts can access @a cached.
|
||||
* If there already is such an object, return that; otherwise create a
|
||||
* new one. The SMJS object holds only a weak reference to @a cached;
|
||||
* so if the caller wants to guarantee that @a cached exists at least
|
||||
* until a script returns, it should use lock_object() and
|
||||
* unlock_object(). */
|
||||
JSObject *
|
||||
smjs_get_cache_entry_object(struct cache_entry *cached)
|
||||
{
|
||||
JSObject *cache_entry_object;
|
||||
|
||||
if (cached->jsobject) return cached->jsobject;
|
||||
|
||||
assert(smjs_ctx);
|
||||
if_assert_failed return NULL;
|
||||
|
||||
cache_entry_object = JS_NewObject(smjs_ctx,
|
||||
(JSClass *) &cache_entry_class,
|
||||
@ -195,14 +242,39 @@ smjs_get_cache_entry_object(struct cache_entry *cached)
|
||||
|
||||
if (!cache_entry_object) return NULL;
|
||||
|
||||
if (JS_FALSE == JS_SetPrivate(smjs_ctx, cache_entry_object, cached)) /* to @cache_entry_class */
|
||||
return NULL;
|
||||
|
||||
object_lock(cached);
|
||||
|
||||
if (JS_FALSE == JS_DefineProperties(smjs_ctx, cache_entry_object,
|
||||
(JSPropertySpec *) cache_entry_props))
|
||||
return NULL;
|
||||
|
||||
/* Do this last, so that if any previous step fails, we can
|
||||
* just forget the object and its finalizer won't attempt to
|
||||
* access @cached. */
|
||||
if (JS_FALSE == JS_SetPrivate(smjs_ctx, cache_entry_object, cached)) /* to @cache_entry_class */
|
||||
return NULL;
|
||||
|
||||
cached->jsobject = cache_entry_object;
|
||||
return cache_entry_object;
|
||||
}
|
||||
|
||||
/** Ensure that no JSObject contains the pointer @a cached. This is
|
||||
* called when the reference count of the cache entry *@a cached is
|
||||
* already 0 and it is about to be freed. If a JSObject was
|
||||
* previously attached to the cache entry, the object will remain in
|
||||
* memory but it will no longer be able to access the cache entry. */
|
||||
void
|
||||
smjs_detach_cache_entry_object(struct cache_entry *cached)
|
||||
{
|
||||
assert(smjs_ctx);
|
||||
assert(cached);
|
||||
if_assert_failed return;
|
||||
|
||||
if (!cached->jsobject) return;
|
||||
|
||||
assert(JS_GetInstancePrivate(smjs_ctx, cached->jsobject,
|
||||
(JSClass *) &cache_entry_class, NULL)
|
||||
== cached);
|
||||
if_assert_failed {}
|
||||
|
||||
JS_SetPrivate(smjs_ctx, cached->jsobject, NULL);
|
||||
cached->jsobject = NULL;
|
||||
}
|
||||
|
@ -154,6 +154,9 @@ cleanup_smjs(struct module *module)
|
||||
{
|
||||
if (!smjs_ctx) return;
|
||||
|
||||
/* These calls also finalize all JSObjects that have been
|
||||
* allocated in the JSRuntime, so cache_entry_finalize gets
|
||||
* called and resets each cache_entry.jsobject = NULL. */
|
||||
JS_DestroyContext(smjs_ctx);
|
||||
JS_DestroyRuntime(smjs_rt);
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ elinks_set_location(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* @elinks_funcs{"alert"} */
|
||||
/* function "alert" in the object returned by smjs_get_elinks_object() */
|
||||
static JSBool
|
||||
elinks_alert(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
@ -90,7 +90,7 @@ elinks_alert(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* @elinks_funcs{"execute"} */
|
||||
/* function "execute" in the object returned by smjs_get_elinks_object() */
|
||||
static JSBool
|
||||
elinks_execute(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
@ -117,12 +117,6 @@ static const JSClass elinks_class = {
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
};
|
||||
|
||||
static const JSFunctionSpec elinks_funcs[] = {
|
||||
{ "alert", elinks_alert, 1 },
|
||||
{ "execute", elinks_execute, 1 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static JSObject *
|
||||
smjs_get_elinks_object(void)
|
||||
{
|
||||
@ -133,7 +127,22 @@ smjs_get_elinks_object(void)
|
||||
|
||||
jsobj = JS_InitClass(smjs_ctx, smjs_global_object, NULL,
|
||||
(JSClass *) &elinks_class, NULL, 0, NULL,
|
||||
(JSFunctionSpec *) elinks_funcs, NULL, NULL);
|
||||
(JSFunctionSpec *) NULL, NULL, NULL);
|
||||
|
||||
/* Bug 1016: In SpiderMonkey 1.7 bundled with XULRunner 1.8,
|
||||
* jsapi.h defines JSFunctionSpec in different ways depending
|
||||
* on whether MOZILLA_1_8_BRANCH is defined, and there is no
|
||||
* obvious way for ELinks to check whether MOZILLA_1_8_BRANCH
|
||||
* was defined when the library was built. Avoid the unstable
|
||||
* JSFunctionSpec definitions and instead use JS_DefineFunction
|
||||
* directly.
|
||||
*
|
||||
* In elinks/src/ecmascript/spidermonkey/, there is an
|
||||
* ELinks-specific replacement for JSFunctionSpec; however, to
|
||||
* keep the modules independent, elinks/src/scripting/smjs/
|
||||
* does not use that. */
|
||||
JS_DefineFunction(smjs_ctx, jsobj, "alert", elinks_alert, 1, 0);
|
||||
JS_DefineFunction(smjs_ctx, jsobj, "execute", elinks_execute, 1, 0);
|
||||
|
||||
JS_DefineProperty(smjs_ctx, jsobj, "location", JSVAL_NULL,
|
||||
elinks_get_location, elinks_set_location,
|
||||
|
@ -89,26 +89,10 @@ end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static enum evhook_status
|
||||
script_hook_flush_caches(va_list ap, void *data)
|
||||
{
|
||||
/* script_hook_pre_format_html() calls smjs_get_cache_entry_object()
|
||||
* for each struct cache_entry. The resulting SMJS objects hold
|
||||
* references to the structs, and these references prevent ELinks
|
||||
* from freeing the cache entries. (The resource info dialog shows
|
||||
* that the entries are "in use".) SMJS does not immediately collect
|
||||
* these objects as garbage. If we're really trying to flush the
|
||||
* caches then ask SMJS to run a check. */
|
||||
if (smjs_ctx)
|
||||
JS_GC(smjs_ctx);
|
||||
return EVENT_HOOK_STATUS_NEXT;
|
||||
}
|
||||
|
||||
struct event_hook_info smjs_scripting_hooks[] = {
|
||||
{ "goto-url", 0, script_hook_url, "goto_url_hook" },
|
||||
{ "follow-url", 0, script_hook_url, "follow_url_hook" },
|
||||
{ "pre-format-html", 0, script_hook_pre_format_html, NULL },
|
||||
{ "flush-caches", 0, script_hook_flush_caches, NULL },
|
||||
|
||||
NULL_EVENT_HOOK_INFO,
|
||||
};
|
||||
|
@ -37,7 +37,7 @@ keymap_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
|
||||
action_str = get_action_name_from_keystroke((enum keymap_id) *data,
|
||||
keystroke_str);
|
||||
if (!action_str) goto ret_null;
|
||||
if (!action_str || !strcmp(action_str, "none")) goto ret_null;
|
||||
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(ctx, action_str));
|
||||
|
||||
@ -106,6 +106,12 @@ keymap_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
|
||||
return JS_TRUE;
|
||||
|
||||
} else if (JSVAL_IS_NULL(*vp)) { /* before JSVAL_IS_OBJECT */
|
||||
if (bind_do(keymap_str, keystroke_str, "none", 0))
|
||||
return JS_FALSE;
|
||||
|
||||
return JS_TRUE;
|
||||
|
||||
} else if (JSVAL_IS_OBJECT(*vp)) {
|
||||
unsigned char *err = NULL;
|
||||
int event_id;
|
||||
|
@ -32,6 +32,13 @@ smjs_loading_callback(struct download *download, void *data)
|
||||
|
||||
if (!download->cached) goto end;
|
||||
|
||||
/* download->cached->object.refcount is typically 0 here
|
||||
* because no struct document uses the cache entry. Because
|
||||
* the connection is no longer using the cache entry either,
|
||||
* it can be garbage collected. Don't let that happen while
|
||||
* the script is using it. */
|
||||
object_lock(download->cached);
|
||||
|
||||
assert(hop->callback);
|
||||
|
||||
smjs_ses = hop->ses;
|
||||
@ -44,6 +51,8 @@ smjs_loading_callback(struct download *download, void *data)
|
||||
JS_CallFunction(smjs_ctx, NULL, hop->callback, 1, args, &rval);
|
||||
|
||||
end:
|
||||
if (download->cached)
|
||||
object_unlock(download->cached);
|
||||
mem_free(download->data);
|
||||
mem_free(download);
|
||||
|
||||
|
@ -2,7 +2,14 @@
|
||||
#define EL__SCRIPTING_SMJS_SMJS_H
|
||||
|
||||
struct module;
|
||||
struct cache_entry;
|
||||
|
||||
extern struct module smjs_scripting_module;
|
||||
|
||||
/* TODO: Use trigger_event() for this, so that the caching code need
|
||||
* not directly call the SMJS scripting module? That would require
|
||||
* changes in struct cache_object though, to let a dynamic number of
|
||||
* scripting modules have pointers from there to their objects. */
|
||||
void smjs_detach_cache_entry_object(struct cache_entry *cached);
|
||||
|
||||
#endif
|
||||
|
@ -513,6 +513,17 @@ maybe_pre_format_html(struct cache_entry *cached, struct session *ses)
|
||||
if (!cached || cached->preformatted)
|
||||
return;
|
||||
|
||||
/* The script called from here may indirectly call
|
||||
* garbage_collection(). If the refcount of the cache entry
|
||||
* were 0, it could then be freed, and the
|
||||
* cached->preformatted assignment at the end of this function
|
||||
* would crash. Normally, the document has a reference to the
|
||||
* cache entry, and that suffices. If the following assertion
|
||||
* ever fails, object_lock(cached) and object_unlock(cached)
|
||||
* must be added to this function. */
|
||||
assert(cached->object.refcount > 0);
|
||||
if_assert_failed return;
|
||||
|
||||
fragment = get_cache_fragment(cached);
|
||||
if (!fragment) return;
|
||||
|
||||
|
@ -910,7 +910,7 @@ call_onsubmit_and_submit(struct session *ses, struct document_view *doc_view,
|
||||
* explicitly tell the ECMAScript code which of them was
|
||||
* pressed. W3C DOM Level 3 doesn't seem to include such a
|
||||
* feature. */
|
||||
if (fc->form->onsubmit) {
|
||||
if (fc->type != FC_RESET && fc->form->onsubmit) {
|
||||
struct string code;
|
||||
|
||||
if (init_string(&code)) {
|
||||
@ -958,7 +958,8 @@ goto_current_link(struct session *ses, struct document_view *doc_view, int do_re
|
||||
if (link_is_form(link)) {
|
||||
struct form_control *fc = link->data.form_control;
|
||||
|
||||
if (!call_onsubmit_and_submit(ses, doc_view, fc, do_reload))
|
||||
if (fc->type != FC_BUTTON
|
||||
&& !call_onsubmit_and_submit(ses, doc_view, fc, do_reload))
|
||||
return NULL;
|
||||
else
|
||||
return link;
|
||||
|
Loading…
Reference in New Issue
Block a user