ami/src/ami.js/inputbox.js

179 lines
5.7 KiB
JavaScript

#include utility.js
#include watcher.js
var AmiInputBox = function(parent) {
var watchers = new AmiWatcherCollection,
input = $e({
tag: 'textarea',
attrs: {
cols: '2',
id: 'message',
autofocus: 'autofocus',
maxlength: '0',
},
}),
container = $e({
attrs: { id: 'inputFieldContainer' },
child: input,
});
parent.appendChild(container);
watchers.define(['tab', 'enter', 'paste', 'length']);
var getValue = function() { return input.value; };
var getStartPos = function() { return input.selectionStart; };
var setStartPos = function(pos) { input.selectionStart = pos; };
var getEndPos = function() { return input.selectionEnd; };
var setEndPos = function(pos) { input.selectionEnd = pos; };
var reportLength = function() {
watchers.call('length', pub, [input.value.length]);
};
var setValue = function(text) {
input.value = (text || '').toString();
reportLength();
};
var clear = function() {
input.value = '';
reportLength();
};
var pub = {
getValue: getValue,
setValue: setValue,
clear: clear,
getStartPos: getStartPos,
setStartPos: setStartPos,
getEndPos: getEndPos,
setEndPos: setEndPos,
isEmpty: function() { input.value.length < 1; },
focus: function() { input.focus(); },
enter: function(ev) {
watchers.call('enter', pub, [ev]);
},
watch: function(name, watcher) {
watchers.watch(name, watcher);
},
unwatch: function(name, watcher) {
watchers.unwatch(name, watcher);
},
setMaxLength: function(length) {
input.maxLength = length;
},
getWordAtCursor: function() {
var text = getValue(),
start = input.selectionStart,
position = start,
word = '';
while(position >= 0 && text.charAt(position - 1) !== ' ' && text.charAt(position - 1) !== "\n") {
--position;
word = text.charAt(position) + word;
}
return { start: start, word: word };
},
insert: function(text) {
text = (text || '').toString();
var value = getValue(),
start = getStartPos(),
end = getEndPos();
setValue(value.substring(0, start) + text + value.substring(end));
setStartPos(start + text.length);
setEndPos(start + text.length);
},
insertAt: function(location, text, strip) {
if(location < 0)
throw 'invalid location';
text = (text || '').toString();
strip = parseInt(strip);
var value = getValue(),
start = value.substring(0, location),
end = value.substring(location);
if(strip < 0)
start = start.slice(0, strip);
else if(strip > 0)
end = end.slice(strip);
setValue(start + text + end);
var cursor = start.length + text.length;
setStartPos(cursor);
setEndPos(cursor);
},
insertAround: function(before, after) {
before = (before || '').toString();
after = (after || '').toString();
var value = getValue(),
start = getStartPos(),
end = getEndPos();
setValue(value.substring(0, start) + before + value.substring(start, end) + after + value.substring(end));
setStartPos(start + before.length);
setEndPos(end + before.length);
},
setClassName: function(className, enabled) {
input.classList[enabled ? 'add' : 'remove'](className);
},
setStyleValue: function(name, value, enabled, single) {
if(enabled) {
if(single) {
input.style[name] = value;
} else {
var existingStyle = input.style[name];
if(existingStyle) {
var split = existingStyle.split(' ');
if(split.indexOf(value) < 0)
input.style[name] += ' ' + value;
} else
input.style[name] = value;
}
} else {
if(single) {
input.style[name] = null;
} else {
var existingStyle = input.style[name];
if(existingStyle) {
var split = existingStyle.split(' ');
if(split.length === 1) {
if(split[0] === value)
input.style[name] = null;
} else if(split.length > 1) {
$ari(split, value);
input.style[name] = split.join(' ');
}
}
}
}
},
};
input.addEventListener('keydown', function(ev) {
var key = 'key' in ev ? ev.key : ('which' in ev ? ev.which : ev.keyCode);
if((key === 'Enter' || key === 13) && !ev.shiftKey && !ev.ctrlKey) {
watchers.call('enter', pub, [ev]);
return;
}
if((key === 'Tab' || key === 9) && !ev.shiftKey && !ev.ctrlKey) {
watchers.call('tab', pub, [ev]);
return;
}
});
input.addEventListener('input', function() {
reportLength();
});
input.addEventListener('paste', function(ev) {
watchers.call('paste', pub, [ev]);
});
return pub;
};