1 /* The SpiderMonkey location and history objects implementation. */
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
= {
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 },
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
;
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 */
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
;
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
;
101 struct location
*loc
;
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
) {
112 go_history(ses
, loc
);
116 index
+= index
> 0 ? -1 : 1;
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
= {
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
},
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
))
149 undef_to_jsval(ctx
, vp
);
151 switch (JSVAL_TO_INT(id
)) {
153 astring_to_jsval(ctx
, vp
, get_uri_string(vs
->uri
, URI_ORIGINAL
));
156 INTERNAL("Invalid ID %d in location_get_property().", JSVAL_TO_INT(id
));
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
))
173 switch (JSVAL_TO_INT(id
)) {
175 location_goto(doc_view
, jsval_to_string(ctx
, vp
));
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 },
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
;
204 delayed_goto(void *data
)
206 struct delayed_goto
*deg
= data
;
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
,
220 location_goto(struct document_view
*doc_view
, unsigned char *url
)
222 unsigned char *new_abs_url
;
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));
232 new_uri
= get_uri(new_abs_url
, 0);
233 mem_free(new_abs_url
);
236 deg
= mem_calloc(1, sizeof(*deg
));
241 assert(doc_view
->vs
);
242 deg
->vs
= doc_view
->vs
;
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
);