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");