configure_backup/conkeror/modules/text.js

126 lines
4.1 KiB
JavaScript

/**
* (C) Copyright 2004-2007 Shawn Betts
* (C) Copyright 2007-2010 John J. Foerch
* (C) Copyright 2007-2008 Jeremy Maitin-Shepard
*
* Use, modification, and distribution are subject to the terms specified in the
* COPYING file.
**/
/**
* Given a callback func and an interactive context I, call func, passing
* either a focused field, or the minibuffer's input element if the
* minibuffer is active. Afterward, call `scroll_selection_into_view' on
* the field. See `paste_x_primary_selection' and `open_line' for
* examples.
*/
function call_on_focused_field (I, func, clear_mark) {
var m = I.window.minibuffer;
var s = m.current_state;
var e = null;
var frame;
if (m._input_mode_enabled) {
m._restore_normal_state();
e = m.input_element;
} else if ((e = I.buffer.focused_element)) {
if (e.getAttribute("contenteditable") == 'true')
e = e.ownerDocument;
} else if ((frame = I.buffer.focused_frame) &&
frame.document.designMode &&
frame.document.designMode == "on") {
e = frame.document;
}
func(e);
if (clear_mark) {
if (m._input_mode_enabled)
s.mark_active = false;
else
I.buffer.mark_active = false;
}
scroll_selection_into_view(e);
}
/**
* Replace the current region with modifier(selection). Deactivates region
* and sets point to the end of the inserted text. The modifier can
* control the exact placement of point by returning an array
* [replacement, point_offset] instead of just a string.
*/
function modify_region (field, modifier) {
if (field instanceof Ci.nsIDOMDocument) {
// richedit
var win = field.defaultView;
var sel = win.getSelection();
let replacement = modifier(win.getSelection().toString());
let point = null;
if (array_p(replacement)) {
point = replacement[1];
replacement = replacement[0];
} else
point = replacement.length;
field.execCommand("insertHTML", false,
html_escape(replacement)
.replace(/\n/g, '<br>')
.replace(/ /g, ' &nbsp;'));
if (point != replacement.length) {
sel.extend(sel.focusNode, point);
sel.collapse(sel.focusNode, point);
}
} else {
// normal text field
let replacement =
modifier(field.value.substring(field.selectionStart, field.selectionEnd));
let point = field.selectionStart;
if (array_p(replacement)) {
point += replacement[1];
replacement = replacement[0];
} else
point += replacement.length;
field.value =
field.value.substr(0, field.selectionStart) + replacement +
field.value.substr(field.selectionEnd);
field.setSelectionRange(point, point);
}
}
/**
* Takes an interactive context and a function to call with the word
* at point as its sole argument, and which returns a modified word.
*/
//XXX: this should be implemented in terms of modify_region,
// in order to work in richedit fields.
function modify_word_at_point (field, func) {
// Skip any whitespaces at point and move point to the right place.
var point = field.selectionStart;
var rest = field.value.substring(point);
// Skip any whitespaces.
for (var i = 0, rlen = rest.length; i < rlen; i++) {
if (" \n".indexOf(rest.charAt(i)) == -1) {
point += i;
break;
}
}
// Find the next whitespace, as it is the end of the word. If no next
// whitespace is found, we're at the end of input. TODO: Add "\n" support.
var goal = field.value.indexOf(" ", point);
if (goal == -1)
goal = field.value.length;
// Change the value of the text field.
var input = field.value;
field.value =
input.substring(0, point) +
func(input.substring(point, goal)) +
input.substring(goal);
// Move point.
field.selectionStart = goal;
field.selectionEnd = goal;
}
provide("text");