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.
16 define_variable("block_content_focus_change_duration", 20,
17 "Duration (in milliseconds) during which an element is "+
18 "allowed to gain focus following a mouse click or key press, "+
19 "if `block_content_focus_change_mode' is enabled.");;
21 function block_content_focus_change_track_input () {
23 browser.block_content_focus_change_timestamp = Date.now();
26 function block_content_focus_change_reset (buffer) {
27 buffer.browser.block_content_focus_change_timestamp = null;
30 function block_content_focus_change_test (buffer, event) {
31 return !(event.target instanceof Ci.nsIDOMHTMLAnchorElement) &&
32 (buffer.browser.block_content_focus_change_timestamp == null ||
33 (Date.now() - buffer.browser.block_content_focus_change_timestamp)
34 > block_content_focus_change_duration);
37 function block_content_focus_change_buffer_setup (buffer) {
38 if (! (buffer instanceof content_buffer) || buffer.dead)
40 block_content_focus_change_reset(buffer);
41 buffer.focusblocker = block_content_focus_change_test;
42 buffer.browser.addEventListener("mousedown",
43 block_content_focus_change_track_input,
45 buffer.browser.addEventListener("keypress",
46 block_content_focus_change_track_input,
50 function block_content_focus_change_buffer_teardown (buffer) {
51 if (! (buffer instanceof content_buffer) || buffer.dead)
53 delete buffer.browser.block_content_focus_change_timestamp;
54 buffer.focusblocker = null;
55 buffer.browser.removeEventListener("mousedown",
56 block_content_focus_change_track_input,
58 buffer.browser.removeEventListener("keypress",
59 block_content_focus_change_track_input,
63 let (foo = browser_set_element_focus) {
64 define_global_mode("block_content_focus_change_mode",
65 function () { // enable
66 for_each_buffer(function (buffer) {
67 block_content_focus_change_buffer_setup(buffer);
69 add_hook("create_buffer_hook",
70 block_content_focus_change_buffer_setup);
71 add_hook("content_buffer_started_loading_hook",
72 block_content_focus_change_reset);
73 add_hook("content_buffer_location_change_hook",
74 block_content_focus_change_reset);
75 // this is a really sick hack, but still preferable to
76 // considered alternatives.
77 conkeror.browser_set_element_focus =
78 function (buffer, elem, prevent_scroll) {
79 buffer.browser.block_content_focus_change_timestamp = Date.now();
80 foo.call(this, buffer, elem, prevent_scroll);
83 function () { // disable
84 for_each_buffer(function (buffer) {
85 block_content_focus_change_buffer_teardown(buffer);
87 remove_hook("create_buffer_hook",
88 block_content_focus_change_buffer_setup);
89 remove_hook("content_buffer_started_loading_hook",
90 block_content_focus_change_reset);
91 remove_hook("content_buffer_location_change_hook",
92 block_content_focus_change_reset);
93 conkeror.browser_set_element_focus = foo;
97 block_content_focus_change_mode(true);
99 provide("block-content-focus-change");