Removed *.html and fixed typos
[elinks.git] / src / ecmascript / spidermonkey / location.c
blobc963a3ffb0aa61d867f0dc5a66a41a5675a30115
1 /* The SpiderMonkey location and history objects implementation. */
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
11 #include "elinks.h"
13 #include "ecmascript/spidermonkey/util.h"
15 #include "bfu/dialog.h"
16 #include "cache/cache.h"
17 #include "cookies/cookies.h"
18 #include "dialogs/menu.h"
19 #include "dialogs/status.h"
20 #include "document/html/frames.h"
21 #include "document/document.h"
22 #include "document/forms.h"
23 #include "document/view.h"
24 #include "ecmascript/ecmascript.h"
25 #include "ecmascript/spidermonkey/location.h"
26 #include "intl/gettext/libintl.h"
27 #include "main/select.h"
28 #include "osdep/newwin.h"
29 #include "osdep/sysname.h"
30 #include "protocol/http/http.h"
31 #include "protocol/uri.h"
32 #include "session/history.h"
33 #include "session/location.h"
34 #include "session/session.h"
35 #include "session/task.h"
36 #include "terminal/tab.h"
37 #include "terminal/terminal.h"
38 #include "util/conv.h"
39 #include "util/memory.h"
40 #include "util/string.h"
41 #include "viewer/text/draw.h"
42 #include "viewer/text/form.h"
43 #include "viewer/text/link.h"
44 #include "viewer/text/vs.h"
47 static JSBool history_back(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
48 static JSBool history_forward(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
49 static JSBool history_go(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
51 const JSClass history_class = {
52 "history",
53 JSCLASS_HAS_PRIVATE,
54 JS_PropertyStub, JS_PropertyStub,
55 JS_PropertyStub, JS_PropertyStub,
56 JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
59 const JSFunctionSpec history_funcs[] = {
60 { "back", history_back, 0 },
61 { "forward", history_forward, 0 },
62 { "go", history_go, 1 },
63 { NULL }
66 static JSBool
67 history_back(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
69 struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx);
70 struct document_view *doc_view = interpreter->vs->doc_view;
71 struct session *ses = doc_view->session;
73 go_back(ses);
75 /* history_back() must return 0 for onClick to cause displaying previous page
76 * and return non zero for <a href="javascript:history.back()"> to prevent
77 * "calculating" new link. Returned value 2 is changed to 0 in function
78 * spidermonkey_eval_boolback */
79 return 2;
82 static JSBool
83 history_forward(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
85 struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx);
86 struct document_view *doc_view = interpreter->vs->doc_view;
87 struct session *ses = doc_view->session;
89 go_unback(ses);
91 return 2;
94 static JSBool
95 history_go(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
97 struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx);
98 struct document_view *doc_view = interpreter->vs->doc_view;
99 struct session *ses = doc_view->session;
100 int index;
101 struct location *loc;
103 if (argc != 1)
104 return JS_TRUE;
106 index = atol(jsval_to_string(ctx, &argv[0]));
108 for (loc = cur_loc(ses);
109 loc != (struct location *) &ses->history.history;
110 loc = index > 0 ? loc->next : loc->prev) {
111 if (!index) {
112 go_history(ses, loc);
113 break;
116 index += index > 0 ? -1 : 1;
119 return 2;
123 static JSBool location_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp);
124 static JSBool location_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp);
126 const JSClass location_class = {
127 "location",
128 JSCLASS_HAS_PRIVATE,
129 JS_PropertyStub, JS_PropertyStub,
130 location_get_property, location_set_property,
131 JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
134 enum location_prop { JSP_LOC_HREF };
135 const JSPropertySpec location_props[] = {
136 { "href", JSP_LOC_HREF, JSPROP_ENUMERATE },
137 { NULL }
140 static JSBool
141 location_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
143 JSObject *parent = JS_GetParent(ctx, obj);
144 struct view_state *vs = JS_GetPrivate(ctx, parent);
146 if (!JSVAL_IS_INT(id))
147 return JS_TRUE;
149 undef_to_jsval(ctx, vp);
151 switch (JSVAL_TO_INT(id)) {
152 case JSP_LOC_HREF:
153 astring_to_jsval(ctx, vp, get_uri_string(vs->uri, URI_ORIGINAL));
154 break;
155 default:
156 INTERNAL("Invalid ID %d in location_get_property().", JSVAL_TO_INT(id));
157 break;
160 return JS_TRUE;
163 static JSBool
164 location_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
166 JSObject *parent = JS_GetParent(ctx, obj);
167 struct view_state *vs = JS_GetPrivate(ctx, parent);
168 struct document_view *doc_view = vs->doc_view;
170 if (!JSVAL_IS_INT(id))
171 return JS_TRUE;
173 switch (JSVAL_TO_INT(id)) {
174 case JSP_LOC_HREF:
175 location_goto(doc_view, jsval_to_string(ctx, vp));
176 break;
179 return JS_TRUE;
182 static JSBool location_toString(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
184 const JSFunctionSpec location_funcs[] = {
185 { "toString", location_toString, 0 },
186 { "toLocaleString", location_toString, 0 },
187 { NULL }
190 static JSBool
191 location_toString(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
193 return JS_GetProperty(ctx, obj, "href", rval);
196 struct delayed_goto {
197 /* It might look more convenient to pass doc_view around but it could
198 * disappear during wild dances inside of frames or so. */
199 struct view_state *vs;
200 struct uri *uri;
203 static void
204 delayed_goto(void *data)
206 struct delayed_goto *deg = data;
208 assert(deg);
209 if (deg->vs->doc_view
210 && deg->vs->doc_view == deg->vs->doc_view->session->doc_view) {
211 goto_uri_frame(deg->vs->doc_view->session, deg->uri,
212 deg->vs->doc_view->name,
213 CACHE_MODE_NORMAL);
215 done_uri(deg->uri);
216 mem_free(deg);
219 void
220 location_goto(struct document_view *doc_view, unsigned char *url)
222 unsigned char *new_abs_url;
223 struct uri *new_uri;
224 struct delayed_goto *deg;
226 /* Workaround for bug 611. Does not crash, but may lead to infinite loop.*/
227 if (!doc_view) return;
228 new_abs_url = join_urls(doc_view->document->uri,
229 trim_chars(url, ' ', 0));
230 if (!new_abs_url)
231 return;
232 new_uri = get_uri(new_abs_url, 0);
233 mem_free(new_abs_url);
234 if (!new_uri)
235 return;
236 deg = mem_calloc(1, sizeof(*deg));
237 if (!deg) {
238 done_uri(new_uri);
239 return;
241 assert(doc_view->vs);
242 deg->vs = doc_view->vs;
243 deg->uri = new_uri;
244 /* It does not seem to be very safe inside of frames to
245 * call goto_uri() right away. */
246 register_bottom_half(delayed_goto, deg);