2 * (C) Copyright 2007-2008 Jeremy Maitin-Shepard
3 * (C) Copyright 2008-2009 John J. Foerch
5 * Use, modification, and distribution are subject to the terms specified in the
10 * block-content-focus-change-mode tries very hard to prevent
11 * rude websites from changing the element focus via javascript.
14 define_variable("block_content_focus_change_duration", 20,
15 "Duration (in milliseconds) during which an element is "+
16 "allowed to gain focus following a mouse click or key press, "+
17 "if `block_content_focus_change_mode' is enabled.");;
19 function block_content_focus_change_track_input () {
21 browser
.block_content_focus_change_timestamp
= Date
.now();
24 function block_content_focus_change_reset (buffer
) {
25 buffer
.browser
.block_content_focus_change_timestamp
= null;
28 function block_content_focus_change_test (buffer
, event
) {
29 return !(event
.target
instanceof Ci
.nsIDOMHTMLAnchorElement
) &&
30 (buffer
.browser
.block_content_focus_change_timestamp
== null ||
31 (Date
.now() - buffer
.browser
.block_content_focus_change_timestamp
)
32 > block_content_focus_change_duration
);
35 function block_content_focus_change_buffer_setup (buffer
) {
36 if (! (buffer
instanceof content_buffer
) || buffer
.dead
)
38 block_content_focus_change_reset(buffer
);
39 buffer
.focusblocker
= block_content_focus_change_test
;
40 buffer
.browser
.addEventListener("mousedown",
41 block_content_focus_change_track_input
,
43 buffer
.browser
.addEventListener("keypress",
44 block_content_focus_change_track_input
,
48 function block_content_focus_change_buffer_teardown (buffer
) {
49 if (! (buffer
instanceof content_buffer
) || buffer
.dead
)
51 delete buffer
.browser
.block_content_focus_change_timestamp
;
52 buffer
.focusblocker
= null;
53 buffer
.browser
.removeEventListener("mousedown",
54 block_content_focus_change_track_input
,
56 buffer
.browser
.removeEventListener("keypress",
57 block_content_focus_change_track_input
,
61 let (foo
= browser_set_element_focus
) {
62 define_global_mode("block_content_focus_change_mode",
63 function () { // enable
64 for_each_buffer(function (buffer
) {
65 block_content_focus_change_buffer_setup(buffer
);
67 add_hook("create_buffer_hook",
68 block_content_focus_change_buffer_setup
);
69 add_hook("content_buffer_started_loading_hook",
70 block_content_focus_change_reset
);
71 add_hook("content_buffer_location_change_hook",
72 block_content_focus_change_reset
);
73 // this is a really sick hack, but still preferable to
74 // considered alternatives.
75 conkeror
.browser_set_element_focus
=
76 function (buffer
, elem
, prevent_scroll
) {
77 buffer
.browser
.block_content_focus_change_timestamp
= Date
.now();
78 foo
.call(this, buffer
, elem
, prevent_scroll
);
81 function () { // disable
82 for_each_buffer(function (buffer
) {
83 block_content_focus_change_buffer_teardown(buffer
);
85 remove_hook("create_buffer_hook",
86 block_content_focus_change_buffer_setup
);
87 remove_hook("content_buffer_started_loading_hook",
88 block_content_focus_change_reset
);
89 remove_hook("content_buffer_location_change_hook",
90 block_content_focus_change_reset
);
91 conkeror
.browser_set_element_focus
= foo
;
95 block_content_focus_change_mode(true);
97 provide("block-content-focus-change");