From 8284ff5d3edd560e8e0c89e823701f9b3e50df20 Mon Sep 17 00:00:00 2001 From: Andy MacKinlay Date: Tue, 30 Sep 2014 17:29:25 +1000 Subject: [PATCH 1/2] added support for keyboard shortcuts for boolean attributes --- client/src/annotator_ui.js | 15 +++++++++++++++ server/src/document.py | 15 +++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/client/src/annotator_ui.js b/client/src/annotator_ui.js index 43d5bbb49..384e6e6bc 100644 --- a/client/src/annotator_ui.js +++ b/client/src/annotator_ui.js @@ -1917,6 +1917,21 @@ var AnnotatorUI = (function($, window, undefined) { $('').appendTo($span); } else if (attr.bool) { var escapedName = Util.escapeQuotes(attr.name); + if (attr.hotkey) { + spanKeymap[attr.hotkey] = attrId; + var replace = true; + escapedName = escapedName.replace(new RegExp("(&[^;]*?)?(" + attr.hotkey + ")", 'gi'), + function(all, entity, letter) { + if (replace && !entity) { + replace = false; + var hotkey = attr.hotkey.toLowerCase() == letter + ? attr.hotkey.toLowerCase() + : attr.hotkey.toUpperCase(); + return '[' + Util.escapeHTML(hotkey) + ']'; + } + return all; + }); + } var $input = $(''); diff --git a/server/src/document.py b/server/src/document.py index 199fbdc03..76bc0aff9 100644 --- a/server/src/document.py +++ b/server/src/document.py @@ -223,7 +223,7 @@ def _fill_relation_configuration(nodes, project_conf, hotkey_by_type): # TODO: this may not be a good spot for this -def _fill_attribute_configuration(nodes, project_conf): +def _fill_attribute_configuration(nodes, project_conf, hotkey_by_type): items = [] for node in nodes: if node == SEPARATOR_STR: @@ -235,6 +235,10 @@ def _fill_attribute_configuration(nodes, project_conf): item['type'] = _type item['unused'] = node.unused item['labels'] = project_conf.get_labels_by_type(_type) + try: + item['hotkey'] = hotkey_by_type[_type] + except KeyError: + pass attr_drawing_conf = project_conf.get_drawing_config_by_type(_type) if attr_drawing_conf is None: @@ -372,14 +376,17 @@ def get_base_types(directory): def get_attribute_types(directory): project_conf = ProjectConfiguration(directory) + keymap = project_conf.get_kb_shortcuts() + hotkey_by_type = dict((v, k) for k, v in keymap.iteritems()) + entity_attribute_hierarchy = project_conf.get_entity_attribute_type_hierarchy() - entity_attribute_types = _fill_attribute_configuration(entity_attribute_hierarchy, project_conf) + entity_attribute_types = _fill_attribute_configuration(entity_attribute_hierarchy, project_conf, hotkey_by_type) relation_attribute_hierarchy = project_conf.get_relation_attribute_type_hierarchy() - relation_attribute_types = _fill_attribute_configuration(relation_attribute_hierarchy, project_conf) + relation_attribute_types = _fill_attribute_configuration(relation_attribute_hierarchy, project_conf, hotkey_by_type) event_attribute_hierarchy = project_conf.get_event_attribute_type_hierarchy() - event_attribute_types = _fill_attribute_configuration(event_attribute_hierarchy, project_conf) + event_attribute_types = _fill_attribute_configuration(event_attribute_hierarchy, project_conf, hotkey_by_type) return entity_attribute_types, relation_attribute_types, event_attribute_types From 6ef486164c742538a93b258e633ddbf8a59421c6 Mon Sep 17 00:00:00 2001 From: Andy MacKinlay Date: Wed, 1 Oct 2014 10:35:04 +1000 Subject: [PATCH 2/2] re #1111 - can now select autocomplete cells using a shortcut key for the attribute name --- client/src/annotator_ui.js | 47 ++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/client/src/annotator_ui.js b/client/src/annotator_ui.js index 384e6e6bc..478bd1ffd 100644 --- a/client/src/annotator_ui.js +++ b/client/src/annotator_ui.js @@ -165,9 +165,18 @@ var AnnotatorUI = (function($, window, undefined) { var binding = keymap[prefix + code]; if (!binding) binding = keymap[prefix + String.fromCharCode(code)]; if (binding) { + var isAutocomplete = function(htmlNode) { + return htmlNode.nodeName === 'input' && typeof htmlNode.autocomplete !== 'undefined'; + }; var boundInput = $('#' + binding)[0]; if (boundInput && !boundInput.disabled) { - boundInput.click(); + if (boundInput.nodeName === 'select' && isAutocomplete(boundInput.nextSibling)) { + // special case for autocomplete cells for multi-valued attributes + // (this is maybe a slightly fragile way to go about this) + boundInput.nextSibling.focus(); + } else { + boundInput.click(); + } evt.preventDefault(); return false; } @@ -1909,6 +1918,22 @@ var AnnotatorUI = (function($, window, undefined) { addSpanTypesToDivInner($scroller, types); }; var addAttributeTypesToDiv = function($top, types, category) { + + var highlightHotkey = function(origName, hotkey, prefix, suffix) { + var replace = true; + return origName.replace(new RegExp("(&[^;]*?)?(" + hotkey + ")", 'gi'), + function(all, entity, letter) { + if (replace && !entity) { + replace = false; + var hotkeyMatch = hotkey.toLowerCase() == letter + ? hotkey.toLowerCase() + : hotkey.toUpperCase(); + return prefix + Util.escapeHTML(hotkeyMatch) + suffix; + } + return all; + }); + } + $.each(types, function(attrNo, attr) { var escapedType = Util.escapeQuotes(attr.type); var attrId = category+'_attr_'+escapedType; @@ -1919,18 +1944,7 @@ var AnnotatorUI = (function($, window, undefined) { var escapedName = Util.escapeQuotes(attr.name); if (attr.hotkey) { spanKeymap[attr.hotkey] = attrId; - var replace = true; - escapedName = escapedName.replace(new RegExp("(&[^;]*?)?(" + attr.hotkey + ")", 'gi'), - function(all, entity, letter) { - if (replace && !entity) { - replace = false; - var hotkey = attr.hotkey.toLowerCase() == letter - ? attr.hotkey.toLowerCase() - : attr.hotkey.toUpperCase(); - return '[' + Util.escapeHTML(hotkey) + ']'; - } - return all; - }); + escapedName = highlightHotkey(escapedName, attr.hotkey, '[', ']'); } var $input = $(''); - $span.text(attr.name); + var name = attr.name; + if (attr.hotkey) { + spanKeymap[attr.hotkey] = attrId; + name = highlightHotkey(name, attr.hotkey, '', ''); + } + $span.html(name); $span.append(': '); var $select = $('