new module to enable editing and deleting of bookmarks
[conkeror/arlinius.git] / modules / text.js
blob93d10ede8e45242893a7963d7567bbb8e0cc04f5
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 /**
11  * Given a callback func and an interactive context I, call func, passing
12  * either a focused field, or the minibuffer's input element if the
13  * minibuffer is active. Afterward, call `scroll_selection_into_view' on
14  * the field. See `paste_x_primary_selection' and `open_line' for
15  * examples.
16  */
17 function call_on_focused_field (I, func, clear_mark) {
18     var m = I.window.minibuffer;
19     var s = m.current_state;
20     var e = null;
21     var frame;
22     if (m._input_mode_enabled) {
23         m._restore_normal_state();
24         e = m.input_element;
25     } else if ((e = I.buffer.focused_element)) {
26         if (e.getAttribute("contenteditable") == 'true')
27             e = e.ownerDocument;
28     } else if ((frame = I.buffer.focused_frame) &&
29                frame.document.designMode &&
30                frame.document.designMode == "on") {
31         e = frame.document;
32     }
33     func(e);
34     if (clear_mark) {
35         if (m._input_mode_enabled)
36             s.mark_active = false;
37         else
38             I.buffer.mark_active = false;
39     }
40     scroll_selection_into_view(e);
44 /**
45  * Replace the current region with modifier(selection). Deactivates region
46  * and sets point to the end of the inserted text.  The modifier can
47  * control the exact placement of point by returning an array
48  * [replacement, point_offset] instead of just a string.
49  */
50 function modify_region (field, modifier) {
51     if (field instanceof Ci.nsIDOMDocument) {
52         // richedit
53         var win = field.defaultView;
54         var sel = win.getSelection();
55         let replacement = modifier(win.getSelection().toString());
56         let point = null;
57         if (array_p(replacement)) {
58             point = replacement[1];
59             replacement = replacement[0];
60         } else
61             point = replacement.length;
62         field.execCommand("insertHTML", false,
63                         html_escape(replacement)
64                             .replace(/\n/g, '<br>')
65                             .replace(/  /g, ' &nbsp;'));
66         if (point != replacement.length) {
67             sel.extend(sel.focusNode, point);
68             sel.collapse(sel.focusNode, point);
69         }
70     } else {
71         // normal text field
72         let replacement =
73             modifier(field.value.substring(field.selectionStart, field.selectionEnd));
74         let point = field.selectionStart;
75         if (array_p(replacement)) {
76             point += replacement[1];
77             replacement = replacement[0];
78         } else
79             point += replacement.length;
80         field.value =
81             field.value.substr(0, field.selectionStart) + replacement +
82             field.value.substr(field.selectionEnd);
83         field.setSelectionRange(point, point);
84     }
88 /**
89  * Takes an interactive context and a function to call with the word
90  * at point as its sole argument, and which returns a modified word.
91  */
92 //XXX: this should be implemented in terms of modify_region,
93 //     in order to work in richedit fields.
94 function modify_word_at_point (field, func) {
95     // Skip any whitespaces at point and move point to the right place.
96     var point = field.selectionStart;
97     var rest = field.value.substring(point);
99     // Skip any whitespaces.
100     for (var i = 0, rlen = rest.length; i < rlen; i++) {
101         if (" \n".indexOf(rest.charAt(i)) == -1) {
102             point += i;
103             break;
104         }
105     }
107     // Find the next whitespace, as it is the end of the word.  If no next
108     // whitespace is found, we're at the end of input.  TODO: Add "\n" support.
109     var goal = field.value.indexOf(" ", point);
110     if (goal == -1)
111         goal = field.value.length;
113     // Change the value of the text field.
114     var input = field.value;
115     field.value =
116         input.substring(0, point) +
117         func(input.substring(point, goal)) +
118         input.substring(goal);
120     // Move point.
121     field.selectionStart = goal;
122     field.selectionEnd = goal;
125 provide("text");