summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/textanalysis.js37
-rw-r--r--src/textanalysis.ui.js99
-rw-r--r--src/view/completer.js167
-rw-r--r--src/view/node_info.js4
4 files changed, 209 insertions, 98 deletions
diff --git a/src/textanalysis.js b/src/textanalysis.js
index 98ca8aea..f2d5f555 100644
--- a/src/textanalysis.js
+++ b/src/textanalysis.js
@@ -9,7 +9,8 @@ var typeStack = [];
var lastnode;
-var sugg = {}; // suggestions for autocompletion of node names
+var sugg = {}, // suggestions for autocompletion of node names
+ suggestions_options = new Bacon.Bus(); // TODO: Property: same as bus, but with initial value
var ANALYSIS_NODE_START = 'ANALYSIS_NODE_START';
var ANALYSIS_NODE = 'ANALYSIS_NODE'
@@ -24,36 +25,7 @@ function autoSuggestAddName(name)
{
/* note that name can contain spaces - this is ok. We might want to limit this though? */
sugg[name] = 1;
-}
-
-function unquoted(name)
-{
- var start = 0,
- end = name.length;
-
- if (name.length >= 1) {
- if (name.charAt(0) == '"') {
- start = 1;
- if (name.length > 1 && name.charAt(name.length - 1) == '"') {
- end = name.length - 1;
- }
- }
- return name.substring(start, end);
- }
- return name;
-}
-
-function autocompleteCallback(request, response_callback)
-{
- var ret = [];
- if (request.term === "" || request.term) {
- for (var name in sugg) {
- if (name.toLowerCase().indexOf(unquoted(request.term.toLowerCase())) === 0) {
- ret.push(name);
- }
- }
- }
- response_callback(ret);
+ suggestions_options.push(sugg);
}
/* up_to_two_renames:
@@ -502,9 +474,8 @@ function init(graph)
return {
init:init,
- autocompleteCallback:autocompleteCallback,
textAnalyser:textAnalyser,
- autoSuggestAddName:autoSuggestAddName,
+ suggestions_options: suggestions_options,
ANALYSIS_NODE_START:ANALYSIS_NODE_START,
ANALYSIS_NODE: ANALYSIS_NODE,
ANALYSIS_LINK:ANALYSIS_LINK,
diff --git a/src/textanalysis.ui.js b/src/textanalysis.ui.js
index b7863271..0b2a9bc3 100644
--- a/src/textanalysis.ui.js
+++ b/src/textanalysis.ui.js
@@ -1,12 +1,12 @@
"use strict"
-define(['jquery', 'Bacon', 'consts', 'rz_bus', 'autocomplete', 'rz_core', 'textanalysis'],
-function($, Bacon, consts, rz_bus, autocomplete, rz_core, textanalysis) {
+define(['jquery', 'Bacon', 'consts', 'rz_bus', 'rz_core', 'textanalysis', 'view/completer'],
+function($, Bacon, consts, rz_bus, rz_core, textanalysis, completer) {
var text = "", // Last text of sentence
element_name = '#textanalyser',
element = $(element_name),
- suggestionChange,
+ element_raw = element[0],
plus_button = $('.add-button'),
description = consts.description;
@@ -37,6 +37,8 @@ var typeselection = function TypeSelectionDialog() {
return typeselection;
}();
+var analysisCompleter = completer(element, $('.suggestion'));
+
function analyzeSentence(sentence, finalize)
{
var ret = textanalysis.textAnalyser(sentence, finalize);
@@ -55,9 +57,7 @@ function analyzeSentence(sentence, finalize)
if (finalize || sentence.length == 0) {
typeselection.hide();
- $('span.ui-helper-hidden-accessible').hide();
- } else {
- $('span.ui-helper-hidden-accessible').show();
+ analysisCompleter.hide();
}
}
@@ -106,21 +106,7 @@ return {
return;
}
- element.autocompleteTrigger({
- triggerStart: '#',
- triggerEnd: '',
- source: textanalysis.autocompleteCallback,
- response: function(element, ui) {
- ui.content.forEach(function (x) {
- if (x.value.search(' ') != -1) {
- x.value = '"' + x.value + '"';
- }
- });
- },
- open: function() {
- $('.ui-autocomplete').css('width', '10px');
- },
- });
+ analysisCompleter.options.plug(textanalysis.suggestions_options);
var document_keydown = new Bacon.Bus();
rz_bus.ui_key.plug(document_keydown);
@@ -129,6 +115,12 @@ return {
var ret = undefined;
switch (e.keyCode) {
+ case 13:
+ if (!analysisCompleter.handleEnter()) {
+ submitNewSentence();
+ }
+ ret = false;
+ break;
case 9: //TAB
if (textanalysis.lastnode()) {
e.preventDefault();
@@ -136,32 +128,37 @@ return {
ret = false;
}
break;
- case 37: //UP
- $('html, body').scrollLeft(0);
- break;
- case 39: //DOWN
- $('html, body').scrollLeft(0);
+ case 38: //UP
+ case 40: //DOWN
+ ret = false;
break;
+ }
+ document_keydown.push({where: consts.KEYSTROKE_WHERE_TEXTANALYSIS, keys: [e.keyCode]});
+ return ret;
+ });
+ element.keyup(function(e) {
+ var ret = undefined;
+ switch (e.keyCode) {
case 38: //UP
- suggestionChange = true;
+ analysisCompleter.prev_option();
+ ret = false;
break;
case 40: //DOWN
- suggestionChange = true;
+ analysisCompleter.next_option();
+ ret = false;
break;
+ default:
+ analysisCompleter.oninput(element_raw.value, element_raw.selectionStart);
+ analysisCompleter.show();
}
- document_keydown.push({where: consts.KEYSTROKE_WHERE_DOCUMENT, keys: [e.keyCode]});
return ret;
});
- function maybeSubmitNewSentence() {
- if(!suggestionChange) {
- text = element.val();
- element.val("");
- analyzeSentence(text, true);
- text = "";
- } else {
- suggestionChange = false;
- }
+ function submitNewSentence() {
+ text = element.val();
+ element.val("");
+ analyzeSentence(text, true);
+ text = "";
}
// Click is required to prevent the default action - this is a form so that's a post,
@@ -171,34 +168,10 @@ return {
// http://stackoverflow.com/questions/15786891/browser-sometimes-ignores-a-jquery-click-event-during-a-css3-transform
plus_button.bind("click mousedown", function(e) {
console.dir(e);
- maybeSubmitNewSentence();
+ submitNewSentence();
e.preventDefault();
});
- var element_keydown = new Bacon.Bus();
- rz_bus.ui_key.plug(element_keydown);
- element.keydown(function(e) {
- var ret = undefined;
- switch (e.which) {
- case 13:
- maybeSubmitNewSentence();
- ret = false;
- break;
- case 37: //RIGHT
- $('body').scrollLeft(0);
- e.stopPropagation();
- ret = false;
- break;
- case 39: //LEFT
- $('body').scrollLeft(0);
- e.stopPropagation();
- ret = false;
- break;
- }
- element_keydown.push({where: consts.KEYSTROKE_WHERE_TEXTANALYSIS, keys:[e.which]});
- return ret;
- });
-
var input = new Bacon.Bus();
rz_bus.ui_input.plug(input);
if ('oninput' in document.documentElement) {
diff --git a/src/view/completer.js b/src/view/completer.js
new file mode 100644
index 00000000..ce848eff
--- /dev/null
+++ b/src/view/completer.js
@@ -0,0 +1,167 @@
+define(
+['jquery', 'Bacon'],
+function($, Bacon) {
+
+function unquoted(name)
+{
+ var start = 0,
+ end = name.length;
+
+ if (name.length >= 1) {
+ if (name.charAt(0) == '"') {
+ start = 1;
+ if (name.length > 1 && name.charAt(name.length - 1) == '"') {
+ end = name.length - 1;
+ }
+ }
+ return name.substring(start, end);
+ }
+ return name;
+}
+
+function setCaret(e, num)
+{
+ e.selectionStart = e.selectionEnd = num;
+}
+
+var completer = (function (input_element, dropdown) {
+ var triggerStart = '#',
+ triggerEnd = '',
+ dropdown_raw = dropdown[0],
+ options_bus = new Bacon.Bus(),
+ options = [],
+ selected_index = -1,
+ input_element_raw = input_element[0],
+ completion_start = 0,
+ completion_end = 0;
+
+ // turn off the browser's autocomplete
+ input_element.attr('autocomplete', 'off');
+
+ //$('.ui-autocomplete').css('width', '10px');
+ options_bus.onValue(function update_options(new_options) {
+ options = new_options;
+ });
+
+ function completions(text)
+ {
+ var ret = [],
+ noquotes = unquoted(text);
+
+ for (var name in options) {
+ if (name.toLowerCase().indexOf(noquotes) === 0) {
+ ret.push(name);
+ }
+ }
+ return ret;
+ }
+
+ function oninput(text, cursor) {
+ // #this is a #
+ // ^
+ //
+ // #this is a #t
+ // ^
+ //
+ // #this and #that then #he
+ // ^
+ console.log(text);
+ console.log(cursor);
+ var hash = text.slice(0, cursor).lastIndexOf('#');
+ // TODO check if current completion has been invalidated
+ _invalidateSelection();
+ dropdown_raw.innerHTML = ""; // remove all elements
+ if (hash == -1) {
+ return;
+ }
+ var space = text.slice(hash).indexOf(' ');
+ space = space == -1 ? text.length : space;
+ if (space < cursor) {
+ return;
+ }
+ // [hash] [cursor] [space/end]
+ completions(text.slice(hash + 1, space)).forEach(function(name) {
+ dropdown.append($('<div>' + name + '</div>'));
+ dropdown.children().each(function (index, elem) {
+ elem.onclick = function() { _applySuggestion(index); };
+ input_element.focus();
+ });
+ });
+ completion_start = hash + 1;
+ completion_end = space;
+ }
+
+ function _invalidateSelection() {
+ update_highlighting(-1);
+ }
+
+ function move_option(change, default_value) {
+ var next,
+ n = dropdown.children().length;
+
+ if (n == 0) {
+ return;
+ }
+ if (selected_index == -1) {
+ next = default_value;
+ } else {
+ next = (selected_index + change) % n;
+ }
+ update_highlighting(next);
+ }
+ function next_option() {
+ move_option(1, 0);
+ }
+ function prev_option() {
+ move_option(-1, dropdown.children().length);
+ }
+ function _get_option(index) {
+ return dropdown.children()[index].innerHTML;
+ }
+ function _choice(i) {
+ return dropdown.children().eq(i);
+ }
+ function update_highlighting(new_index) {
+ if (selected_index != -1) {
+ _choice(selected_index).removeClass('selected');
+ }
+ if (new_index != -1) {
+ _choice(new_index).addClass('selected');
+ }
+ selected_index = new_index;
+ }
+ function _applySuggestion(index) {
+ var cur = input_element.val(),
+ start = cur.slice(0, completion_start) + _get_option(index) + ' ';
+ input_element.val(start + cur.slice(completion_end));
+ setCaret(input_element, start.length);
+ oninput('', 0);
+ }
+ function handleEnter() {
+ if (selected_index == -1) {
+ return false;
+ }
+ _applySuggestion(selected_index);
+ return true;
+ }
+
+ return {
+ options: options_bus,
+ hide: function() {
+ console.log('hide');
+ dropdown.hide();
+ },
+ show: function() {
+ console.log('show');
+ dropdown.show();
+ },
+ oninput: oninput,
+ next_option: next_option,
+ prev_option: prev_option,
+ handleEnter: handleEnter,
+ };
+});
+
+return completer;
+
+});
diff --git a/src/view/node_info.js b/src/view/node_info.js
index f798b387..55d7ac72 100644
--- a/src/view/node_info.js
+++ b/src/view/node_info.js
@@ -1,5 +1,5 @@
-define(['jquery', 'view/helpers', 'view/internal'],
-function($, view_helpers, internal) {
+define(['jquery', 'datepicker', 'view/helpers', 'view/internal'],
+function($, _unused_datepicker, view_helpers, internal) {
function show(d) {
var editURL = '';