Skip to content

Commit

Permalink
Worst fear realized: we DO need to implement a RFC822-like parser for…
Browse files Browse the repository at this point in the history
… autocomplete

Essentially, we need to be able to distinguish between commas in quotes,
commas in group definitions, and commas meant to delineate between
addresses. So implement a basic parser for these elements.

Fixes replies for addresses like: "Foo, Bar" <foo@example.com>
  • Loading branch information
slusarz committed Oct 11, 2013
1 parent f63c1ae commit 33dfbe8
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 12 deletions.
46 changes: 46 additions & 0 deletions imp/js/compose-base.js
Expand Up @@ -79,6 +79,52 @@ var ImpComposeBase = {
elt = $(elt);
elt.focus();
$(document).fire('AutoComplete:focus', elt);
},

autocompleteValue: function(ob, val)
{
var pos = 0,
chr, in_group, in_quote, tmp;

chr = val.charAt(pos);
while (chr !== "") {
var orig_pos = pos;
++pos;

if (!orig_pos || (val.charAt(orig_pos - 1) != '\\')) {
switch (chr) {
case ',':
if (!orig_pos) {
val = val.substr(1);
} else if (!in_group && !in_quote) {
ob.addNewItem(val.substr(0, orig_pos));
val = val.substr(orig_pos + 2);
pos = 0;
}
break;

case '"':
in_quote = !in_quote;
break;

case ':':
if (!in_quote) {
in_group = true;
}
break;

case ';':
if (!in_quote) {
in_group = false;
}
break;
}
}

chr = val.charAt(pos);
}

return val;
}

};
28 changes: 18 additions & 10 deletions imp/js/prettyautocomplete.js
Expand Up @@ -24,7 +24,7 @@ var IMP_PrettyAutocompleter = Class.create({

initialize: function(elt, params)
{
var active, p_clone;
var ac, active, p_clone;

this.p = Object.extend({
// Outer div/fake input box and CSS class
Expand All @@ -44,6 +44,7 @@ var IMP_PrettyAutocompleter = Class.create({
filterCallback: this.filterChoices.bind(this),
onAdd: Prototype.K,
onRemove: Prototype.K,
processValueCallback: this.processValueCallback.bind(this),
requireSelection: false
}, params || {});

Expand Down Expand Up @@ -90,8 +91,12 @@ var IMP_PrettyAutocompleter = Class.create({
p_clone = Object.toJSON(this.p).evalJSON();
p_clone.onSelect = this.updateElement.bind(this);
p_clone.paramName = this.elt.readAttribute('name');
p_clone.tokens = [];

new Ajax.Autocompleter(this.input, this.p.uri, p_clone);
ac = new Ajax.Autocompleter(this.input, this.p.uri, p_clone);
ac.getToken = function() {
return $F(this.input);
}.bind(this);

this.reset();

Expand Down Expand Up @@ -133,23 +138,26 @@ var IMP_PrettyAutocompleter = Class.create({

processValue: function(val)
{
var chr, pos = 0, tmp;

if (this.p.requireSelection) {
return val;
}

val = val.strip();
return this.p.processValueCallback(this, val.replace(/^\s+/, ''));
},

processValueCallback: function(ob, val)
{
var chr, pos = 0;

chr = val.charAt(pos);
while (chr !== "") {
if (this.p.tokens.indexOf(chr) === -1) {
if (ob.p.tokens.indexOf(chr) === -1) {
++pos;
} else {
if (!pos) {
val = val.substr(1);
} else if (val.charAt(pos - 1) != '\\') {
this.addNewItem(val.substr(0, pos));
} else {
ob.addNewItem(val.substr(0, pos));
val = val.substr(pos + 2);
pos = 0;
}
Expand All @@ -158,7 +166,7 @@ var IMP_PrettyAutocompleter = Class.create({
chr = val.charAt(pos);
}

return val;
return val.replace(/^\s+/, '');
},

// Used as the updateElement callback.
Expand Down Expand Up @@ -299,7 +307,7 @@ var IMP_PrettyAutocompleter = Class.create({
var input = $F(this.input);

if (input != this.lastinput) {
this.input.setValue(this.processValue(input).strip());
this.input.setValue(this.processValue(input));
this.lastinput = $F(this.input);
this.resize();
}
Expand Down
9 changes: 7 additions & 2 deletions imp/lib/Ajax/Imple/AutoCompleter/Pretty.php
Expand Up @@ -33,6 +33,8 @@ class IMP_Ajax_Imple_AutoCompleter_Pretty
*/
public function __construct(array $params = array())
{
global $page_output;

parent::__construct(array_merge(
array(
'boxClass' => 'hordeACBox impACBox',
Expand All @@ -41,6 +43,7 @@ public function __construct(array $params = array())
'displayFilter' => 'new Function("t", "return t.sub(/<[^>]*>$/, \"\").strip().escapeHTML()")',
'growingInputClass' => 'hordeACTrigger impACTrigger',
'listClass' => 'hordeACList impACList',
'processValueCallback' => 'ImpComposeBase.autocompleteValue.bind(ImpComposeBase)',
'removeClass' => 'hordeACItemRemove impACItemRemove',
'triggerContainer' => strval(new Horde_Support_Randomid())
), $params)
Expand All @@ -50,10 +53,12 @@ public function __construct(array $params = array())
'displayFilter',
'filterCallback',
'onAdd',
'onRemove'
'onRemove',
'processValueCallback'
));

$GLOBALS['page_output']->addScriptFile('prettyautocomplete.js');
$page_output->addScriptFile('compose-base.js');
$page_output->addScriptFile('prettyautocomplete.js');
}

/**
Expand Down

0 comments on commit 33dfbe8

Please sign in to comment.