2 * (C) Copyright 2004-2007 Shawn Betts
3 * (C) Copyright 2007-2010 John J. Foerch
4 * (C) Copyright 2007-2008 Jeremy Maitin-Shepard
6 * Use, modification, and distribution are subject to the terms specified in the
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
19 function call_on_focused_field (I, func, clear_mark) {
20 var m = I.window.minibuffer;
21 var s = m.current_state;
24 if (m._input_mode_enabled) {
25 m._restore_normal_state();
27 } else if (I.buffer.focused_element) {
28 e = I.buffer.focused_element;
29 } else if ((frame = I.buffer.focused_frame) &&
30 frame.document.designMode &&
31 frame.document.designMode == "on") {
36 if (m._input_mode_enabled)
37 s.mark_active = false;
39 I.buffer.mark_active = false;
41 scroll_selection_into_view(e);
46 * Replace the current region with modifier(selection). Deactivates region
47 * and sets point to the end of the inserted text. The modifier can
48 * control the exact placement of point by returning an array
49 * [replacement, point_offset] instead of just a string.
51 function modify_region (field, modifier) {
52 if (field instanceof Ci.nsIDOMDocument ||
53 (field.getAttribute("contenteditable") == 'true'))
56 var doc = (field instanceof Ci.nsIDOMDocument ?
59 var win = doc.defaultView;
60 var sel = win.getSelection();
61 let replacement = modifier(win.getSelection().toString());
63 if (array_p(replacement)) {
64 point = replacement[1];
65 replacement = replacement[0];
67 point = replacement.length;
68 doc.execCommand("insertHTML", false,
69 html_escape(replacement)
70 .replace(/\n/g, '<br>')
71 .replace(/ /g, ' '));
72 if (point != replacement.length) {
73 sel.extend(sel.focusNode, point);
74 sel.collapse(sel.focusNode, point);
79 modifier(field.value.substring(field.selectionStart, field.selectionEnd));
80 let point = field.selectionStart;
81 if (array_p(replacement)) {
82 point += replacement[1];
83 replacement = replacement[0];
85 point += replacement.length;
87 field.value.substr(0, field.selectionStart) + replacement +
88 field.value.substr(field.selectionEnd);
89 field.setSelectionRange(point, point);
95 * Takes an interactive context and a function to call with the word
96 * at point as its sole argument, and which returns a modified word.
98 //XXX: this should be implemented in terms of modify_region,
99 // in order to work in richedit fields.
100 function modify_word_at_point (field, func) {
101 // Skip any whitespaces at point and move point to the right place.
102 var point = field.selectionStart;
103 var rest = field.value.substring(point);
105 // Skip any whitespaces.
106 for (var i = 0, rlen = rest.length; i < rlen; i++) {
107 if (" \n".indexOf(rest.charAt(i)) == -1) {
113 // Find the next whitespace, as it is the end of the word. If no next
114 // whitespace is found, we're at the end of input. TODO: Add "\n" support.
115 var goal = field.value.indexOf(" ", point);
117 goal = field.value.length;
119 // Change the value of the text field.
120 var input = field.value;
122 input.substring(0, point) +
123 func(input.substring(point, goal)) +
124 input.substring(goal);
127 field.selectionStart = goal;
128 field.selectionEnd = goal;