Mon 21 Jul 22:43:21 CEST 2025
This commit is contained in:
parent
943446368d
commit
a7e1b34c57
172
js/web/input.js
Normal file
172
js/web/input.js
Normal file
|
@ -0,0 +1,172 @@
|
|||
/* ------------------------------------------------------------------------*
|
||||
* Copyright 2013-2014 Arne F. Claassen
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------*/
|
||||
|
||||
var Josh = Josh || {};
|
||||
(function (root, $, _) {
|
||||
$.fn.josh_caretTo = function (index) {
|
||||
return this.queue(function (next) {
|
||||
if (this.createTextRange) {
|
||||
var range = this.createTextRange();
|
||||
range.move("character", index);
|
||||
range.select();
|
||||
} else if (this.selectionStart !== null) {
|
||||
this.setSelectionRange(index, index);
|
||||
}
|
||||
next();
|
||||
});
|
||||
};
|
||||
$.fn.josh_caretPosition = function () {
|
||||
var el = this.get(0);
|
||||
if (el.createTextRange) {
|
||||
var range = el.createTextRange();
|
||||
range.moveStart('character', -el.value.length);
|
||||
return range.text.length;
|
||||
} else if (el.selectionStart !== null) {
|
||||
return el.selectionStart;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
var history = Josh.History();
|
||||
var killring = new Josh.KillRing();
|
||||
|
||||
Josh.Input = function (config) {
|
||||
config = config || {};
|
||||
|
||||
// instance fields
|
||||
var _console = config.console || (Josh.Debug && root.console ? root.console : {
|
||||
log: function () {
|
||||
}
|
||||
});
|
||||
|
||||
var _id = "#" + config.id;
|
||||
var _blinktime = config.blinktime || 500;
|
||||
var _active = false;
|
||||
var _cursor_visible = false;
|
||||
var _isInput = false;
|
||||
var _history = config.history || history;
|
||||
var _killring = config.killring || killring;
|
||||
var _text;
|
||||
var self = {
|
||||
templates: {
|
||||
span: _.template('<span class="input"><span class="left"/><span class="cursor"/><span class="right"/></span>')
|
||||
},
|
||||
history: _history,
|
||||
killring: _killring
|
||||
};
|
||||
|
||||
$(document).ready(function () {
|
||||
var $input = $(_id);
|
||||
var el = $input.get(0);
|
||||
var readline = new Josh.ReadLine({
|
||||
history: _history,
|
||||
killring: _killring,
|
||||
console: _console
|
||||
});
|
||||
self.readline = readline;
|
||||
readline.attach(el);
|
||||
var activate = null;
|
||||
_isInput = $input.is('input');
|
||||
if (_isInput) {
|
||||
|
||||
_console.log(_id + ' is an input');
|
||||
|
||||
function renderInput(line) {
|
||||
var text = line ? line.text : '';
|
||||
_text = text;
|
||||
$input.val(text);
|
||||
$input.josh_caretTo(line.cursor);
|
||||
}
|
||||
readline.onChange(renderInput);
|
||||
$input.click(function() {
|
||||
var line = readline.getLine();
|
||||
line.cursor = $input.josh_caretPosition();
|
||||
readline.setLine(line);
|
||||
});
|
||||
|
||||
activate = function() {
|
||||
// Note: have to re-render with a setTimeout, because on focus, but after the onfocus event is processed,
|
||||
// the input will select all, invalidating our render
|
||||
setTimeout(function() {
|
||||
renderInput(readline.getLine());
|
||||
}, 0);
|
||||
};
|
||||
} else {
|
||||
_console.log(_id + ' is a non-input element');
|
||||
$input.html(self.templates.span());
|
||||
if(typeof $input.attr('tabindex') === 'undefined') {
|
||||
$input.attr('tabindex',0);
|
||||
}
|
||||
var $left = $input.find('.left');
|
||||
var $right = $input.find('.right');
|
||||
var $cursor = $input.find('.cursor');
|
||||
|
||||
function renderSpan(line) {
|
||||
var text = line.text || '';
|
||||
_text = text;
|
||||
var cursorIdx = line.cursor || 0;
|
||||
var left = _.escape(text.substr(0, cursorIdx)).replace(/ /g, ' ');
|
||||
var cursor = text.substr(cursorIdx, 1);
|
||||
var right = _.escape(text.substr(cursorIdx + 1)).replace(/ /g, ' ');
|
||||
$left.html(left);
|
||||
if (!cursor) {
|
||||
$cursor.html(' ').css('textDecoration', 'underline');
|
||||
} else {
|
||||
$cursor.text(cursor).css('textDecoration', 'underline');
|
||||
}
|
||||
$right.html(right);
|
||||
}
|
||||
|
||||
function blinkCursor() {
|
||||
if (!_active) {
|
||||
return;
|
||||
}
|
||||
root.setTimeout(function () {
|
||||
if (!_active) {
|
||||
return;
|
||||
}
|
||||
_cursor_visible = !_cursor_visible;
|
||||
if (_cursor_visible) {
|
||||
$cursor.css('textDecoration', 'underline');
|
||||
} else {
|
||||
$cursor.css('textDecoration', '');
|
||||
}
|
||||
blinkCursor();
|
||||
}, _blinktime);
|
||||
}
|
||||
|
||||
activate = function () {
|
||||
blinkCursor();
|
||||
}
|
||||
readline.onChange(renderSpan);
|
||||
}
|
||||
readline.unbind({keyCode: Josh.Keys.Special.Tab});
|
||||
readline.unbind({'char': 'R', ctrlKey: true});
|
||||
readline.onActivate(function () {
|
||||
_active = true;
|
||||
activate();
|
||||
});
|
||||
readline.onDeactivate(function () {
|
||||
_active = false;
|
||||
if (_text) {
|
||||
_history.accept(_text);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
return self;
|
||||
}
|
||||
})(this, $, _);
|
Loading…
Reference in New Issue
Block a user