twitter.js: bind return to fallthrough
[conkeror.git] / modules / text.js
blobfb980c96efdf5d3c3ed2d8c4a2306b29a8332096
1 /**
2  * (C) Copyright 2004-2007 Shawn Betts
3  * (C) Copyright 2007-2010 John J. Foerch
4  * (C) Copyright 2007-2008 Jeremy Maitin-Shepard
5  *
6  * Use, modification, and distribution are subject to the terms specified in the
7  * COPYING file.
8 **/
10 in_module(null);
12 /**
13  * Given a callback func and an interactive context I, call func, passing
14  * either a focused field, or the minibuffer's input element if the
15  * minibuffer is active. Afterward, call `scroll_selection_into_view' on
16  * the field. See `paste_x_primary_selection' and `open_line' for
17  * examples.
18  */
19 function call_on_focused_field (I, func, clear_mark) {
20     var m = I.window.minibuffer;
21     var s = m.current_state;
22     if (m._input_mode_enabled) {
23         m._restore_normal_state();
24         var e = m.input_element;
25     } else
26         var e = I.buffer.focused_element;
27     func(e);
28     if (clear_mark) {
29         if (m._input_mode_enabled)
30             s.mark_active = false;
31         else
32             I.buffer.mark_active = false;
33     }
34     scroll_selection_into_view(e);
38 /**
39  * Replace the current region with modifier(selection). Deactivates region
40  * and sets point to the end of the inserted text.  The modifier can
41  * control the exact placement of point by returning an array
42  * [replacement, point_offset] instead of just a string.
43  */
44 function modify_region (field, modifier) {
45     if (field.getAttribute("contenteditable") == 'true') {
46         // richedit
47         var doc = field.ownerDocument;
48         var win = doc.defaultView;
49         var sel = win.getSelection();
50         let replacement = modifier(win.getSelection().toString());
51         let point = null;
52         if (array_p(replacement)) {
53             point = replacement[1];
54             replacement = replacement[0];
55         } else
56             point = replacement.length;
57         doc.execCommand("insertHTML", false,
58                         html_escape(replacement)
59                             .replace(/\n/g, '<br>')
60                             .replace(/  /g, ' &nbsp;'));
61         if (point != replacement.length) {
62             sel.extend(sel.focusNode, point);
63             sel.collapse(sel.focusNode, point);
64         }
65     } else {
66         // normal text field
67         let replacement =
68             modifier(field.value.substring(field.selectionStart, field.selectionEnd));
69         let point = field.selectionStart;
70         if (array_p(replacement)) {
71             point += replacement[1];
72             replacement = replacement[0];
73         } else
74             point += replacement.length;
75         field.value =
76             field.value.substr(0, field.selectionStart) + replacement +
77             field.value.substr(field.selectionEnd);
78         field.setSelectionRange(point, point);
79     }
83 /**
84  * Takes an interactive context and a function to call with the word
85  * at point as its sole argument, and which returns a modified word.
86  */
87 //XXX: this should be implemented in terms of modify_region,
88 //     in order to work in richedit fields.
89 function modify_word_at_point (field, func) {
90     // Skip any whitespaces at point and move point to the right place.
91     var point = field.selectionStart;
92     var rest = field.value.substring(point);
94     // Skip any whitespaces.
95     for (var i = 0, rlen = rest.length; i < rlen; i++) {
96         if (" \n".indexOf(rest.charAt(i)) == -1) {
97             point += i;
98             break;
99         }
100     }
102     // Find the next whitespace, as it is the end of the word.  If no next
103     // whitespace is found, we're at the end of input.  TODO: Add "\n" support.
104     var goal = field.value.indexOf(" ", point);
105     if (goal == -1)
106         goal = field.value.length;
108     // Change the value of the text field.
109     var input = field.value;
110     field.value =
111         input.substring(0, point) +
112         func(input.substring(point, goal)) +
113         input.substring(goal);
115     // Move point.
116     field.selectionStart = goal;
117     field.selectionEnd = goal;
120 provide("text");