First attempt to try to use abstracted AutoCompleter driver
authorMichael M Slusarz <slusarz@curecanti.org>
Thu, 29 Oct 2009 02:23:39 +0000 (20:23 -0600)
committerMichael M Slusarz <slusarz@curecanti.org>
Thu, 29 Oct 2009 02:26:16 +0000 (20:26 -0600)
Mike R. - probably will want to look at the kronolith/ansel drivers,
since I am not very familiar with the prettyautocompleter code. Probably
won't work out of the box but will need some additional tweaking.

ansel/lib/Ajax/Imple/LocationAutoCompleter.php
imp/lib/Ajax/Imple/ContactAutoCompleter.php
kronolith/lib/Ajax/Imple/ContactAutoCompleter.php
kronolith/lib/Ajax/Imple/TagAutoCompleter.php

index 52a18b6..659fe5c 100644 (file)
  * @author Michael J. Rubinsky <mrubinsk@horde.org>
  * @package Ansel
  */
-class Ansel_Ajax_Imple_LocationAutoCompleter extends Horde_Ajax_Imple_Base
+class Ansel_Ajax_Imple_LocationAutoCompleter extends Horde_Ajax_Imple_AutoCompleter
 {
-    public function __construct($params)
+    protected function _attach($js_params)
     {
-        if (!empty($params['triggerId'])) {
-            if (empty($params['resultsId'])) {
-                $params['resultsId'] = $params['triggerId'] . '_results';
-            }
-        }
-
-        parent::__construct($params);
-    }
-
-    public function attach()
-    {
-        Horde::addScriptFile('autocomplete.js', 'horde');
-        Horde::addScriptFile('effects.js', 'horde');
+        $js_params['indicator'] = $this->_params['triggerId'] . '_loading_img"';
+        $js_params['onSelect'] = 1;
+        $js_params['onShow'] = 1;
+        $js_params['tokens'] = '';
 
-        $url = $this->_getUrl('LocationAutoCompleter', 'ansel', array('input' => $this->_params['triggerId']));
+        $ret = array(
+            'func_replace' => array(
+                '"onSelect":1' => '"onSelect":function (v) { ' . $this->_params['map'] . '.ll = Ansel.ajax.locationAutoCompleter.geocache[v]; }',
+                '"onShow":1' => '"onType":function (e) { if !e.size() ' . $this->_params['map'] . '.ll = null; }'
+            ),
+            'params' => $js_params,
+            'var' => "Ansel.ajax['locationAutoCompleter']"
+        );
 
         /* Use ajax? */
         if (!isset($_SESSION['ansel']['ajax_locationac'])) {
             $results = $GLOBALS['ansel_storage']->searchLocations();
-            if (is_a($results, 'PEAR_Error')) {
+            if ($results instanceof PEAR_Error) {
                 Horde::logMessage($results, __FILE__, __LINE__, PEAR_LOG_ERR);
             } else {
                 // @TODO: This should be a config param?
-                if (count($results) > 50) {
-                    $_SESSION['ansel']['ajax_locationac'] = true;
-                } else {
-                    $_SESSION['ansel']['ajax_locationac'] = false;
-                }
+                $_SESSION['ansel']['ajax_locationac'] = (count($results) > 50);
             }
         }
 
-        $params = array(
-            '"' . $this->_params['triggerId'] . '"',
-            '"' . $this->_params['resultsId'] . '"'
-        );
-
-        $js_params = array(
-            'tokens: []',
-            'indicator: "' . $this->_params['triggerId'] . '_loading_img"',
-            'afterUpdateElement: function(e, v) {' . $this->_params['map'] . '.ll = Ansel.ajax.locationAutoCompleter.geocache[v.collectTextNodesIgnoreClass(\'informal\')];}',
-            'afterUpdateChoices: function(c, l) {if (!c.size()) {' . $this->_params['map'] . '.ll = null;}}'
-        );
-        $js = array();
-        if ($_SESSION['ansel']['ajax_locationac']) {
-            $params[] = '"' . $url . '"';
-            $params[] = '{' . implode(',', $js_params) . '}';
-            $js[] = 'Ansel.ajax[\'locationAutoCompleter\'] = new Ajax.Autocompleter(' . implode(',', $params) . ');';
+        if (!empty($_SESSION['ansel']['ajax_locationac'])) {
+            $ret['ajax'] => 'LocationAutoCompleter';
         } else {
+            $ret['browser'] => 'LocationAutoCompleter';
             if (empty($results)) {
                 $results = $GLOBALS['ansel_storage']->searchLocations();
             }
-            $jsparams[] = 'ignoreCase: true';
-            $params[] = Horde_Serialize::serialize($results, Horde_Serialize::JSON, Horde_Nls::getCharset());
-            $params[] = '{' . implode(',', $js_params) . '}';
-            $js[] = 'Ansel.ajax[\'locationAutoCompleter\'] = new Autocompleter.Local(' . implode(',', $params) . ');';
+            $ret['list'] = Horde_Serialize::serialize($results, Horde_Serialize::JSON);
         }
 
-        Horde::addInlineScript($js, 'dom');
+        return $ret;
     }
 
     public function handle($args)
index 6792752..ef523cc 100644 (file)
  * @author  Michael Slusarz <slusarz@horde.org>
  * @package IMP
  */
-class IMP_Ajax_Imple_ContactAutoCompleter extends Horde_Ajax_Imple_Base
+class IMP_Ajax_Imple_ContactAutoCompleter extends Horde_Ajax_Imple_AutoCompleter
 {
     /**
-     * The URL to use in attach().
-     *
-     * @var string
-     */
-    protected $_url;
-
-    /**
      * Has the address book been output to the browser?
      *
      * @var boolean
@@ -27,43 +20,25 @@ class IMP_Ajax_Imple_ContactAutoCompleter extends Horde_Ajax_Imple_Base
     static protected $_listOutput = false;
 
     /**
-     * Constructor.
-     *
-     * @param array $params  Configuration parameters.
-     * <pre>
-     * 'triggerId' => TODO (optional)
-     * </pre>
-     */
-    public function __construct($params)
-    {
-        if (empty($params['triggerId'])) {
-            $params['triggerId'] = $this->_randomid();
-        }
-
-        parent::__construct($params);
-    }
-
-    /**
      * Attach the object to a javascript event.
      */
-    public function attach()
+    protected function _attach($js_params)
     {
-        Horde::addScriptFile('effects.js', 'horde');
-        Horde::addScriptFile('autocomplete.js', 'horde');
-        Horde::addScriptFile('KeyNavList.js', 'horde');
-        Horde::addScriptFile('liquidmetal.js', 'horde');
+        $js_params['indicator'] = $this->_params['triggerId'] . '_loading_img';
+        $js_params['onSelect'] = 1;
+        $js_params['onType'] = 1;
 
-        $params = array(
-            '"' . $this->_params['triggerId'] . '"'
+        $ret = array(
+            'func_replace' => array(
+                '"onSelect":1' => '"onSelect":function (v) { if (!v.endsWith(";")) { v += ","; } return v + " "; }',
+                '"onType":1' => '"onType":function (e) { return e.include("<") ? "" : e; }'
+            ),
+            'params' => $js_params
         );
 
-        $js_params = array(
-            'indicator' => $this->_params['triggerId'] . '_loading_img',
-            'onSelect' => 1,
-            'onType' => 1,
-            'tokens' => array(',', ';')
-        );
-        $ac_browser = empty($GLOBALS['conf']['compose']['ac_browser']) ? 0 : $GLOBALS['conf']['compose']['ac_browser'];
+        $ac_browser = empty($GLOBALS['conf']['compose']['ac_browser'])
+            ? 0
+            : $GLOBALS['conf']['compose']['ac_browser'];
 
         if ($ac_browser && !isset($_SESSION['imp']['cache']['ac_ajax'])) {
             $success = $use_ajax = true;
@@ -84,36 +59,21 @@ class IMP_Ajax_Imple_ContactAutoCompleter extends Horde_Ajax_Imple_Base
         }
 
         if (!$ac_browser || $_SESSION['imp']['cache']['ac_ajax']) {
-            $func = 'Ajax.Autocompleter';
-            if (empty($this->_url)) {
-                $this->_url = $this->_getUrl('ContactAutoCompleter', 'imp', array('input' => $this->_params['triggerId']));
-            }
-            $params[] = '"' . $this->_url . '"';
-
-            $js_params['minChars'] = intval($GLOBALS['conf']['compose']['ac_threshold'] ? $GLOBALS['conf']['compose']['ac_threshold'] : 1);
+            $ret['ajax'] = 'ContactAutoCompleter';
+            $ret['params']['minChars'] = intval($GLOBALS['conf']['compose']['ac_threshold'] ? $GLOBALS['conf']['compose']['ac_threshold'] : 1);
         } else {
             if (!self::$_listOutput) {
                 if (!isset($addrlist)) {
                     $addrlist = IMP_Compose::getAddressList();
                 }
-                Horde::addInlineScript('if (!IMP) { var IMP = {}; } IMP.ac_list = '. Horde_Serialize::serialize(array_map('htmlspecialchars', $addrlist), Horde_Serialize::JSON, Horde_Nls::getCharset()));
+                Horde::addInlineScript('if (!window.IMP) window.IMP = {}; IMP.ac_list = '. Horde_Serialize::serialize($addrlist, Horde_Serialize::JSON, Horde_Nls::getCharset()));
                 self::$_listOutput = true;
             }
 
-            $func = 'Autocompleter.Local';
-            $params[] = 'IMP.ac_list';
-            $js_params['partialSearch'] = 1;
-            $js_params['fullSearch'] = 1;
-            $js_params['score'] = 1;
+            $ret['browser'] = 'IMP.ac_list';
         }
 
-        // There is no support for storing functions in JSON.  Have to
-        // hack around this a bit.
-        $js_params = Horde_Serialize::serialize($js_params, Horde_Serialize::JSON);
-        $js_params = str_replace('"onSelect":1', '"onSelect":function (v) { if (!v.endsWith(";")) { v += ","; } return v + " "; }', $js_params);
-        $js_params = str_replace('"onType":1', '"onType":function (e) { return e.include("<") ? "" : e; }', $js_params);
-
-        Horde::addInlineScript($this->_params['triggerId'] . '1 = new ' . $func . '(' . implode(',', $params) . ',' . $js_params . ')', 'dom');
+        return $ret;
     }
 
     /**
index 44cd5d5..3f99c6a 100644 (file)
  * @author  Michael Slusarz <slusarz@horde.org>
  * @package Kronolith
  */
-class Kronolith_Ajax_Imple_ContactAutoCompleter extends Horde_Ajax_Imple_Base
+class Kronolith_Ajax_Imple_ContactAutoCompleter extends Horde_Ajax_Imple_AutoCompleter
 {
     /**
-     * Constructor.
-     *
-     * @param array $params  Configuration parameters.
-     * <pre>
-     * 'triggerId' => TODO (optional)
-     * 'resultsId' => TODO (optional)
-     * </pre>
-     */
-    public function __construct($params)
-    {
-        if (empty($params['triggerId'])) {
-            $params['triggerId'] = $this->_randomid();
-        }
-        if (empty($params['resultsId'])) {
-            $params['resultsId'] = $params['triggerId'] . '_results';
-        }
-
-        parent::__construct($params);
-    }
-
-    /**
      * Attach the Imple object to a javascript event.
+     *
+     * @param array $js_params  See Horde_Ajax_Imple_AutoCompleter::_attach().
+     *
+     * @return array  See Horde_Ajax_Imple_AutoCompleter::_attach().
      */
-    public function attach()
+    protected function _attach($js_params)
     {
-        Horde::addScriptFile('effects.js', 'horde');
-        Horde::addScriptFile('autocomplete.js', 'horde');
-
-        $params = array(
-            '"' . $this->_params['triggerId'] . '"',
-            '"' . $this->_params['resultsId'] . '"',
-            '"' . $this->_getUrl('ContactAutoCompleter', 'kronolith', array('input' => $this->_params['triggerId'])) . '"'
+        $js_params['indicator'] = $this->_params['triggerId'] . '_loading_img"',
+
+        return array(
+            'ajax' => 'ContactAutoCompleter',
+            'func_replace' => array(
+                '"onSelect":1' => '"onSelect":function (v) { if (!v.endsWith(";")) { v += ","; } return v + " "; }',
+                '"onType":1' => '"onType":function (e) { return e.include("<") ? "" : e; }'
+            ),
+            'params' => $js_params
         );
-
-        $js_params = array(
-            'tokens: [",", ";"]',
-            'indicator: "' . $this->_params['triggerId'] . '_loading_img"',
-            'afterUpdateElement: function(f, t) { if (!f.value.endsWith(";")) { f.value += ","; } f.value += " "; }'
-        );
-
-        $params[] = '{' . implode(',', $js_params) . '}';
-
-        Horde::addInlineScript('new Ajax.Autocompleter(' . implode(',', $params) . ')', 'dom');
     }
 
     /**
@@ -73,35 +48,25 @@ class Kronolith_Ajax_Imple_ContactAutoCompleter extends Horde_Ajax_Imple_Base
             return array();
         }
 
-        return array_map('htmlspecialchars', $this->_expandAddresses($input));
+        return $this->_expandAddresses($input);
     }
 
     /**
      * Uses the Registry to expand names and return error information for
-     * any address that is either not valid or fails to expand. This function
-     * will not search if the address string is empty.
+     * any address that is either not valid or fails to expand.
      *
      * @param string $addrString  The name(s) or address(es) to expand.
      *
      * @return array  All matching addresses.
      */
-    protected function _expandAddresses($addrString)
+    protected function _getAddressList($addrString = '')
     {
-        return preg_match('|[^\s]|', $addrString)
-            ? $this->getAddressList(reset(array_filter(array_map('trim', Horde_Mime_Address::explode($addrString, ',;')))))
-            : '';
-    }
+        if (!preg_match('|[^\s]|', $addrString)) {
+            return array();
+        }
+
+        $search = reset(array_filter(array_map('trim', Horde_Mime_Address::explode($addrString, ',;'))));
 
-    /**
-     * Uses the Registry to expand names and return error information for
-     * any address that is either not valid or fails to expand.
-     *
-     * @param string $search  The term to search by.
-     *
-     * @return array  All matching addresses.
-     */
-    static public function getAddressList($search = '')
-    {
         $src = explode("\t", $GLOBALS['prefs']->getValue('search_sources'));
         if ((count($src) == 1) && empty($src[0])) {
             $src = array();
index 3a87d7e..bc92c4d 100644 (file)
@@ -8,86 +8,32 @@
  * @author  Michael Slusarz <slusarz@horde.org>
  * @package Kronolith
  */
-class Kronolith_Ajax_Imple_TagAutoCompleter extends Horde_Ajax_Imple_Base
+class Kronolith_Ajax_Imple_TagAutoCompleter extends Horde_Ajax_Imple_AutoCompleter
 {
     /**
-     * Constructor.
-     *
-     * @param array $params  Configuration parameters.
-     * <pre>
-     * 'triggerId' => TODO (optional)
-     * 'resultsId' => TODO (optional)
-     * </pre>
-     */
-    public function __construct($params)
-    {
-        if (!count($params)) {
-            return;
-        }
-        if (empty($params['resultsId'])) {
-            $params['resultsId'] = $params['triggerId'] . '_results';
-        }
-
-        parent::__construct($params);
-    }
-
-    /**
      * Attach the Imple object to a javascript event.
      * If the 'pretty' parameter is empty then we want a
      * traditional autocompleter, otherwise we get a spiffy pretty one.
      *
+     * @param array $js_params  See Horde_Ajax_Imple_AutoCompleter::_attach().
+     *
+     * @return array  See Horde_Ajax_Imple_AutoCompleter::_attach().
      */
-    public function attach()
+    protected function _attach($js_params)
     {
-        Horde::addScriptFile('effects.js', 'horde');
-        Horde::addScriptFile('autocomplete.js', 'horde');
-
-        $registry = Horde_Registry::singleton();
-
-        if ($pretty = !empty($this->_params['pretty'])) {
-            Horde::addScriptFile('prettyautocomplete.js', 'horde');
-            $this->_params['uri'] = $this->_getUrl('TagAutoCompleter', 'kronolith');
-        } else {
-            $this->_params['uri'] = $this->_getUrl('TagAutoCompleter', 'kronolith', array('input' => $this->_params['triggerId']));
-        }
+        $js_params['indicator'] = $this->_params['triggerId'] . '_loading_img"';
 
-        if (!$pretty) {
-            $params = array(
-                '"' . $this->_params['triggerId'] . '"',
-                '"' . $this->_params['resultsId'] . '"',
-                '"' . $this->_params['uri'] . '"'
-            );
-        }
-
-        $js_params = array(
-            'tokens: [","]',
-            'indicator: "' . $this->_params['triggerId'] . '_loading_img"'
+        $ret = array(
+            'params' => $js_params
         );
 
-        // The pretty version needs to set this callback itself...
-        if (!$pretty && !empty($this->_params['updateElement'])) {
-            $js_params[] = 'updateElement: ' . $this->_params['updateElement'];
-        }
-
-        $params[] = '{' . implode(',', $js_params) . '}';
-
-        if ($pretty) {
-            $js_vars = array('boxClass' => 'hordeACBox kronolithLongField',
-                             'uri' => $this->_params['uri'],
-                             'trigger' => $this->_params['triggerId'],
-                             'URI_IMG_HORDE' => $registry->getImageDir('horde'),
-                             'params' => $params);
-
-            if (!empty($this->_params['existing'])) {
-                $js_vars['existing'] = $this->_params['existing'];
-            }
-
-            $script = array('new PrettyAutocompleter(' . Horde_Serialize::serialize($js_vars, Horde_Serialize::JSON, Horde_Nls::getCharset()) . ')');
+        if (empty($this->_params['pretty'])) {
+            $ret['ajax'] = 'TagAutoCompleter';
         } else {
-            $script = array('new Ajax.Autocompleter(' . implode(',', $params) . ')');
+            $ret['pretty'] = 'TagAutoCompleter';
         }
 
-        Horde::addInlineScript($script, 'dom');
+        return $ret;
     }
 
     /**
@@ -104,22 +50,9 @@ class Kronolith_Ajax_Imple_TagAutoCompleter extends Horde_Ajax_Imple_Base
             !($input = Horde_Util::getFormData($args['input']))) {
             return array();
         }
-        return array_map('htmlspecialchars', $this->getTagList($input));
-    }
 
-    /**
-     * Get a list of existing, used tags that match the search term.
-     *
-     * @param string $search  The term to search by.
-     *
-     * @return array  All matching tags.
-     */
-    public function getTagList($search = '')
-    {
         $tagger = Kronolith::getTagger();
-        $tags = $tagger->listTags($search);
-
-        return array_values($tags);
+        return array_values($tagger->listTags($search));
     }
 
 }