From 012a3968759930c704e656223dc11f82267fa399 Mon Sep 17 00:00:00 2001 From: Sire Date: Thu, 10 Oct 2013 15:50:26 +0200 Subject: [PATCH] Removed autocomplete code which was already unplugged some times ago. --- docs/complete_protocol.txt | 158 ----------- docs/howto-filters.html | 2 +- docs/integrators-guide.html | 10 +- editor/editor.xhtml | 2 - editor/editornoframe.xhtml | 2 - scripts/ant.properties | 4 +- src/devices/autocomplete.js | 531 ------------------------------------ src/devices/popup.js | 2 +- src/filters/autocomplete.js | 69 ----- 9 files changed, 7 insertions(+), 773 deletions(-) delete mode 100755 docs/complete_protocol.txt delete mode 100644 src/devices/autocomplete.js delete mode 100644 src/filters/autocomplete.js diff --git a/docs/complete_protocol.txt b/docs/complete_protocol.txt deleted file mode 100755 index a813ce1..0000000 --- a/docs/complete_protocol.txt +++ /dev/null @@ -1,158 +0,0 @@ -============================================= -= Protocole pour le filtre autocomplete = -============================================= - - Auteur: Antoine Yersin - Date: 31/5/2010 - - -Ce document présente les principaux points clés du protocole à mettre en place pour le filtre autocomplete. - - -Messages du client ------------------- - -Ce protocole défini les messages échangés depuis le client vers le serveur. - -Le client doit envoyer les informations suivantes : - - a) URI de la ressource - b) requête pour la complétion - c) (optionnel) limite pour le nombre de résultats - - -Ces informations sont discutées ci-dessous: - -a) URI de la ressource -Le but est d'identifier quelle ressource interroger pour obtenir une liste de suggestions. Voici les options disponibles : - - - accès par service. Un service identifié par une URL est invoqué avec des paramètres. Nous nous intéressons ici à l'identification de la ressource. - - un identifiant simple (texte). Un mapping id <-> ressource/requête est codé en dur dans le serveur. - ex : http://www.madeinlocal.com/autocomplete?resource="Artists"&... - - URI de la ressource ajoutée à l'URL du service. - ex : http://www.madeinlocal.com/autocomplete/Artists?... - - URI d'une ressource (XPath) passé en paramètre - ex : http://www.madeinlocal.com/autocomplete?path="/data/Events/Event/Artists/Artist/artist_name"&... - - accès par ressource - - requête de type REST - ex : http://www.madeinlocal.com/data/artists.json?match="Micha"&... - -Dans le cas d'un premier développement, le plus simple est d'avoir des requêtes pré-enregistrées dans le serveur. Ces requêtes sont accédées comme des ressources et prennent les paramètres passés par le massage GET. Le schéma proposé est celui de le seconde proposition (http://www.madeinlocal.com/autocomplete/Artists?...). Il permet de rajouter facilement un nouveau champ auto-complétable en enregistrant une nouvelle requête. - -b) requête pour la complétion -Le but est d'avoir un critère pour extraire les résultats de la complétion. Voici les options disponibles : - - - un string interprété comme une requête "begin with" - - un string interprété comme une requête "contains" - - un string "REGEXP-like". Par exemple "Mic" pour contains et "^Mic" pour begin with - -L'autre aspect concerne la canonisation de ces données (majuscules/minuscules, accents, espaces...). Le but est de retourner un maximum de résultats pertinents par rapport à l'entrée de l'utilisateur. Les solutions suivantes peuvent être explorées. - - - Ignore case. (tout convertir en minuscule) - - Supprimer les accents éèê -> e - - Normaliser les espaces. Pas de leading/trailing spaces, les espaces multiples et les caractères \n\t.. sont convertis en espaces simples. - - Supprimer la ponctuation. (attention dans les cas où la ponctuation peut être pertinente) - -Une question demeure quant à savoir si cette canonisation se fait au niveau du client ou du serveur. Une réponse possible serait les deux. Au niveau du client afin d'assurer une syntaxe correcte de l'URL et au niveau du serveur pour avoir un sanitize des éléments de la requête (sécurité, évitement d'attaques par injection) - -c) limite -Une limite pour n'obtenir que n résultats au maximum - - -Messages du serveur -------------------- - -Le serveur doit renvoyer les résultats avec les informations suivantes : - - d) une liste de résultats. Chaque résultat contient les informations suivantes : - d1) une valeur (string) qui est celle entrée dans le champ comme résultat de la complétion - d2) (optionnel) un bout de HTML pour de l'affichage riche - d3) (non-applicable ici) des méta-informations (liens wikipedia, segmentation) - e) une valeur booléenne hasMore qui indique si il existe plus de résultats que ceux envoyé pour cette requête (pertinent en cas de c) limite) - - -Ces informations sont discutées ci-dessous: - -d) Structure d'un résultat - -d1) value -La valeur que prendra le champ lorsque cette suggestion d'auto-complétion est sélectionnée. - -d2) display -Un bout de code HTML qui peut être inséré dans une balise
  • afin d'obtenir un affichage riche. Dans le cas où cette valeur n'est pas fournie, une valeur par défaut basée sur le champ d1-valeur est construite. - -d3) meta-inf -Un objet JSON fournissant des informations supplémentaires. Celles-ci pourrait par exemple fournir un moyen de segmenter une liste de résultats, donner accès à des informations supplémentaires comme un lien vers un page wikipédia, etc. Ce point ne sera pas exploré plus avant car il rentre en compétition avec l'avantage visé par la fonctionnalité "pre-fill". - - -proposition de syntaxe des messages ------------------------------------ - -L'envoi d'une requête au serveur se fait via un message HTTP GET. Deux possibilités s'offrent pour encoder cette requête: - - - GET http://url/to/autocomplete/service?resource="resource_URI"&query="fla"&limit=x - - GET http://url/to/autocomplete/service/resource_URI?query="fla"&limit=x - -Il est plus pertinent, dans le cas du choix de la solution proposée au point a), d'encoder l'URI de la ressource dans l'URL de la requête. Cela permet d'accéder à des requêtes pré-enregistrées comme à des ressources web standards. - -Le serveur peut renvoyer les résultats d'une requête dans les trois formats suivants : - - - texte plein - - JSON - - XML - -Le format texte plein est inadapté, car il faudrait créer un langage ad-hoc pour encoder le paramètre "hasMore" et l'encodage du HTML de présentation (d2) serait compliqué. XML pourrait faire l'affaire, mais nécessite un parsage plus compliqué dans le client et contient un overhead important. - -La solution recommandée est donc JSON, selon la structure suivante (corps de la réponse pour une query="Mic"): - -{results: [{value: "Mica", display: "Mica"}, {value: "Michael Jackson, display: "..."}, {value: "Mickey 3D, display: "..."}, ...], hasMore: true/false} - - -Traitement des requêtes au niveau serveur ------------------------------------------ - -Ici sont discutés deux éléments concernant le traitement d'une requête par le serveur. - - Sélection d'un sous-ensemble de résultats - ......................................... - -Ce cas intervient quand le nombre de résultats d'une requêtes dépasse la le paramètre "limit". Il faut à ce moment sélectionner un sous-ensemble de résultats à envoyer au client. Voici une liste des stratégies de sélection : - - - Sélectionner les n premiers résultats - - Aléatoire - - Alphabétique (ou autre critère statique) - - Traitement statistique ("popularité", nombre de sélection) - - En fonctions de l'historique (les + récemment sélectionnés) - - En fonction du profil de l'utilisateur (goûts). Possibilité d'inférer des données. - - En fonction du contexte de la vitrine (connu du serveur. par ex. tags de l'événement). Possibilité d'inférer des données. - - En fonction du contexte de l'édition du template en cours. Possibilité d'inférer des données. Nécessite du développement client-side probablement lourd. - -Pour une première approche, seules les trois premières approches nous semblent envisageables afin de limiter les coûts de développements. - - Tri/ordonnancement de la liste des résultats - ............................................ - -Cet ordre sera repris pour l'affichage de la liste des suggestions. La stratégie peut être la même que pour la sélection d'un sous-ensemble de résultats. - - Autentification et sécurité - ........................... - -Le serveur doit aussi gérer les aspects sécuritaires du service d'auto-complétion. Ce service ne doit pas permettre de récupérer des données qui ne sont pas destinées à être largement publiée. De plus, un contrôle d'accès est nécessaire afin d'éviter des attaques DoS par "flood". Un système de session tel que probablement déjà en place sur madeinlocal.com semble suffisant à ce propos. - -Résumé des propositions ------------------------ - -Message envoyé par le client : - GET http://www.madeinlocal.com/autocomplete/Artists?query="Mic"&limit=200 - -Réponse du serveur : - mime-type: text/json - {results: [ - {value: "Mica", display: "Mica"}, - {value: "Michael Jackson, display: "Mica"}, - {value: "Mickey 3D, display: "Mica"}, - ... - ], - hasMore: true/false} - - Note : le champ display : 'inner html' est facultatif pour une première implémentation diff --git a/docs/howto-filters.html b/docs/howto-filters.html index f8f52a3..0b02870 100644 --- a/docs/howto-filters.html +++ b/docs/howto-filters.html @@ -47,7 +47,7 @@ - category A : filters with no side effect on the edited content, such filters will generally look for some specific data inside the content model and forward it to other components; such filters may build and maintain a toc, generate collaboration events outside of the application, etc. (e.g. the 'event' filter that generates a custom DOM event for some specific life cycle methods call) -- category B : some filters that change the user text entry but not the handle nor the target content model; such filters may do some small typographical corrections such as capitalizing some words, expanding some abbreviations, proposing some contextual input aids while typing, etc. (e.g. the 'autocomplete' filter) +- category B : some filters that change the user text entry but not the handle nor the target content model; such filters may do some small typographical corrections such as capitalizing some words, expanding some abbreviations, proposing some contextual input aids while typing, etc. (e.g. to implement autocomplete) - category C : some filters that change the handle and/or the target content model; such filter can improve the presentation of the edited content (e.g. displaying a video player if the input is a video URL), they can also allow to edit sub-content model using special rules to interpret the input (e.g. the 'wiki' filter in 'wiki.js', the 'date' filter that dynamically replaces the input device of a 'text' editor with a datepicker device to select a date) diff --git a/docs/integrators-guide.html b/docs/integrators-guide.html index a411603..bea8c88 100644 --- a/docs/integrators-guide.html +++ b/docs/integrators-guide.html @@ -13,7 +13,7 @@ ---------------- AXEL integrator's FAQ -------------------- ---------------------------------------------------------------- -Last update: 2013-05-01 by S.Sire +Last update: 2013-10-10 by S.Sire This document gives some advices for integrating AXEL into your application. It is presented as a FAQ. You are welcome to share your experience to improve @@ -293,9 +293,6 @@ requires a server that implements a corresponding communication protocol -autocomplete.js: communication layer for the 'autocomplete' filter -(UNSUPPORTED) requires a server that implements the autocomplete protocol - You need the files in "src/filters" according to the filters you use in your template. The only exception is "documentid.js" which can be required to use the 'photo' primitive editor. For your information: @@ -304,6 +301,8 @@ documentid.js: 'documentid' filter to be used with 'photo' plugin +event.js: 'event' filter to generate 'axel-update' events + wiki.js: 'wiki' filter of the 'text' primitive editor image.js: image inclusion by URL filter of the 'text' primitive editor @@ -315,9 +314,6 @@ 'video' plugin debug.js: 'debug' filter for each of the primitive editors - -autocomplete.js: 'autocomplete' filter for 'text' editor -(UNSUPPORTED) (depends on autocomplete.js and popup.js device)
    diff --git a/editor/editor.xhtml b/editor/editor.xhtml
    index 2affa65..8c0a4d8 100755
    --- a/editor/editor.xhtml
    +++ b/editor/editor.xhtml
    @@ -60,7 +60,6 @@
         
         
         
    -    
         
     
         
    @@ -77,7 +76,6 @@
         
         
         
    -    
         
         
         
    diff --git a/editor/editornoframe.xhtml b/editor/editornoframe.xhtml
    index 3a28918..bd58539 100755
    --- a/editor/editornoframe.xhtml
    +++ b/editor/editornoframe.xhtml
    @@ -59,7 +59,6 @@
       
       
       
    -  
       
     
       
    @@ -76,7 +75,6 @@
       
       
       
    -  
       
       
       
    diff --git a/scripts/ant.properties b/scripts/ant.properties
    index 39c8d80..7d6aaf7 100644
    --- a/scripts/ant.properties
    +++ b/scripts/ant.properties
    @@ -10,7 +10,7 @@ editor.lib.files = generator.js repeat.js choice.js keyboard.js tabgroupmgr.js x
     # devices
     devices.src.dir = ../src/devices
     devices.lib.files = text.js popup.js lens.js upload.js trackermenu.js
    -# autocomplete.js
    +#
     
     # plugins
     plugins.src.dir = ../src/plugins
    @@ -19,7 +19,7 @@ plugins.lib.files = select.js text.js content.js photo.js file.js link.js video.
     # filters
     filters.src.dir = ../src/filters
     filters.lib.files = event.js optional.js image.js wiki.js date.js style.js video.js
    -# autocomplete.js common.js debug.js documentid.js layout.js  
    +# common.js debug.js documentid.js layout.js  
     
     # css
     css.src.dir = ../stylesheets
    diff --git a/src/devices/autocomplete.js b/src/devices/autocomplete.js
    deleted file mode 100644
    index 85950b1..0000000
    --- a/src/devices/autocomplete.js
    +++ /dev/null
    @@ -1,531 +0,0 @@
    -/* ***** BEGIN LICENSE BLOCK *****
    - *
    - * @COPYRIGHT@
    - *
    - * This file is part of the Adaptable XML Editing Library (AXEL), version @VERSION@ 
    - *
    - * @LICENSE@
    - *
    - * Web site : http://media.epfl.ch/Templates/
    - * 
    - * Author(s) : Antoine Yersin
    - * 
    - * ***** END LICENSE BLOCK ***** */
    -
    -/**
    - * 

    - * The SuggestDevice class implements the well known auto-complete feature. It - * is used through the SuggestFilter, which is called by giving the filter=suggest - * parameter to an xt:use element. - *

    - * - * @class SuggestDevice - */ -xtiger.editor.AutocompleteDevice = (function AutocompleteDevice () { - - /* private instance */ - var _instance; - - /** - *

    - * The actual implementation class holding the autocompletion code. It's - * kept separated from the AutocompleteDevice class in order to allow a - * possible evolution where several managers can be used at once. - *

    - * - * @class AutocompleteDeviceInstance - * @name AutocompleteDeviceInstance - */ - var _AutocompleteDeviceInstance = function (aDocument) { - - /* default parameters */ - var _DEFAULT_PARAMS = { - 'limit': 200, - 'delay': 200, - 'display_max': 10, - 'suggestclass': 'ac_suggest', - 'matchclass': 'ac_match', - 'baselayout': '%suggest%' - } - - /* A reference document */ - this._document = aDocument; - - /* The device currently holding the manager. If null, the manager is unused */ - this._currentDevice; - - /* The current input field where the autocomplete is performed */ - this._currentField; - - /* timer for the state machine */ - this._timer; - - /* the current matching string */ - this._currentMatch; - - /* - * The suggestion cache - * - * The cache has the following structure (to be updated) : - * - * { - * a: {suggests: [result set], hasMore: true}, - * bc : {suggests: [result set], hasMore: false} - * } - */ - this._cache; - - /* URL of a service answering to auto-completion requests */ - this._serviceURL; - - /* A non-ambiguous identifier for the resource to query */ - this._resourceURI; - - /* the view device. Here a popup menu */ - this._viewer; - - /* a Hash containing all pending requests, sorted by their matching string */ - this._pendingRequests; - - /* The active parameters between a grab and a release of the device */ - this._sessionParams = _DEFAULT_PARAMS; - } - - /** @memberOf AutocompleteDeviceInstance */ - _AutocompleteDeviceInstance.prototype = { - - /** - *

    - * Create a viewer instance to handle the display and the selection - * of suggests. - *

    - */ - _createViewer: function () { - var _devKey = 'popupdevice'; - this._popupdevice = xtiger.session(this._document).load(_devKey); - if (! this._popupdevice) { - this._popupdevice = new xtiger.editor.PopupDevice(this._document); - xtiger.session(this._document).save(_devKey, this._popupdevice); - } - }, - - /** - *

    - * Format a suggest string into an HTML snippet. The snippet is - * supposed to be inserted into a - * <li> as innerHTML. - *

    - * - *

    - * This function is intent to provide a default layout in the - * absence of a "display" field in the suggest revieved by the - * server. This default layout is either fetched in the device's - * parameters list or is given as function's parameter. - *

    - * - * @param {String} - * aSuggest. The suggestion string to format - * @param {String} - * aMatch - * @param {String} - * aBaseLayout - */ - _formatSuggest: function (aSuggest, aMatch, aBaseLayout) { - var _suggest = aSuggest; - if (aMatch && typeof(aMatch) == 'String' && aMatch != '') { - try { - var _matcher = new RegExp(aMatch, 'i'); - _suggest = _suggest.replace(_matcher, function (m) { - return '' + m + ''; - }); - } catch (_err) { - xtiger.cross.log('warning', 'AutocompleteDevice: wrong syntax in matcher ' + aMatch); - } - } - return _suggest; - }, - - /** - *

    - * Display the results given as parameter. If the results list is - * empty, the functions hides the viewer. - *

    - * - * @param {[String]} - * aResultsList a list of suggests to display - */ - _showResults: function (aResultsList) { - if (aResultsList && aResultsList.length > 0) - this._popupdevice.startEditing(this._currentModel, aResultsList, this._currentMatch, this._currentField); - }, - - /** - *

    - * This function defines the communication protocol for the sending - * of request to the server. - *

    - * - * @param {String} - * aMatch The matching string - * @param {Integer|String} - * aLimit The limit of results to be received by the - * server - * @return {XHRHTTPObject} A XHR object ready to be sent, but - * without any callback yet - * - * @private - */ - _prepareRequest: function (aMatch, aLimit) { - var _xhr = xtiger.cross.getXHRObject(); - var _url = this._serviceURL + '/' + this._resourceURI; - _url += '?query=' + aMatch; - if (this._sessionParams['lang']) - _url += '&lang=' + this._sessionParams['lang'] - if (aLimit && aLimit > 0) - _url += '&limit=' + aLimit; - _xhr.open('GET', _url, true); // request are always async - return _xhr; - }, - - /** - *

    - * Launches a fetching process of suggests on the server. Prepares a - * request and sends it. Registers the callback for the reception of - * the answer. The callback is given the "match" patameter with a - * closure for the suggests' cache management. - *

    - * - * @param {String} - * aMatch The matching string. - */ - _fetchSuggests: function (aMatch) { - - // TODO implement policy for getting results from server or for pruning of the cache - - var _xhr = this._prepareRequest(aMatch, this._sessionParams['limit']); - var _this = this; - _xhr.onreadystatechange = function () { - if (_xhr.readyState == 4) { - if (_xhr.status == 200) { - _this._onRequestReceived(aMatch, _xhr); - } - else { - xtiger.cross.log('warning', 'Suggest device: request failed for query ' + aMatch + ' with status ' + _xhr.status); - } - } - } - try { - _xhr.send(null); - } catch (e) { - xtiger.cross.log('warning', 'Exception while contacting autocomplete service : ' + e.name); - } - }, - - /** - *

    - * Updates the session's cache. The cache is organized by matching - * keys. That means that some redundancies are possible between - * subset of results. Some results stored in "a" for instance, if - * "a" is an incomplete set of result, may be found again in "ab" - * for instance. - *

    - * - * @param {String} - * aMatch The matching string that yield this results - * list from the server - * @param {[Result]} - * aResultsList The list of results that were obtained - * from the serveur for the given matching string. - * @param {Boolean} - * hasMore If true, that means that the results list is - * incomplete for the given key - * - * @todo Optimization : avoid cache redundancy between subset of - * results - */ - _updateCache: function (aMatch, aResultsList, hasMore) { - if (this._cache[aMatch]) { // an entry of this key already exist - if (this._cache[aMatch].hasMore && !hasMore) // only overwrite if the result set is more complete - this._cache[aMatch] = {'suggests': aResultsList, 'hasMore': false}; - } - else { - this._cache[aMatch] = {'suggests': aResultsList, 'hasMore': hasMore}; - } - }, - - /** - *

    - * This function extracts suggests from the cache, given a match - * string. If no entry exists for the given match, it searches for a - * superset ("ab" instead of "abc") and prunes the results. - *

    - * - * @param {String} - * aMatch The matching string used to extract results - * @param {Integer} - * aMax A maximum number of results to extract. No real - * sorting policy is implemented yet - * @return {[String]} A list of suggests, in their string form. - */ - _extractFromCache: function (aMatch, aMax) { - var _res; - var _match = aMatch; - - while (!_res && _match.length > 0) { - if (this._cache[_match]) - _res = xtiger.util.array_map(this._cache[_match]['suggests'], function (e) {return e.value} ); - if (!_res) - _match = _match.slice(0, -1); - } - - if (!_res) // No results - return null; - - if (_match != aMatch) { - var _r = new RegExp('^' + aMatch, 'i'); - _res = xtiger.util.array_filter(_res, function (s) {return _r.test(s)}); - } - // limit the returned suggests - if (aMax && typeof(aMax) == 'number' && aMax > 0 && aMax < _res.length) - _res = _res.slice(0, aMax - 1); - - return _res; - }, - - /** - *

    - * This function scans the cache to determine if it contains a - * complete set of suggests for the given match. It works in the - * following fashion: - *

    - * - *

    - * First, it looks if the cache contains an entry for the given - * match. If it has one, it returns true if the hasMore property is - * false, false otherwise. - *

    - * - *

    - * If the cache has no entry for the given match, it reduces the match - * by pruning its last character, then it retries the previous step. It - * iterates until the matching string is found in the cache's entries or - * equals to "". - *

    - * - *

    - * This function test the full matching string for the following reason: - * If the cache has an entry for the match, but the entry is marked with - * the hasMore tag, there is no guarantee that asking again the server - * with this match will return the same list of suggests. It actually - * depends of the limit policy sets up on the server. - *

    - * - * @param {string} - * aMatch The matching string - * @return {boolean} True if the cache contains a fill set of - * suggests for the given match. False otherwise. - */ - _hasFullMatch: function (aMatch) { - var _testMatch = aMatch; - while (_testMatch.length > 0) { - if (this._cache[_testMatch]) - return !this._cache[_testMatch].hasMore; - _testMatch = _testMatch.slice(0, -1); // prune the last char - } - return false; - }, - - /** - *

    - * This function manage the state machine of the device. the - * device's state is mainly defined with the current string the - * suggests should match. - *

    - */ - _updateState: function () { - this._currentMatch = this._currentField.value; - - // Kill pending timeout, if any - if (this._timer) - clearTimeout(this._timer); - - if (this._hasFullMatch(this._currentMatch)) { - this._showResults(this._extractFromCache(this._currentMatch, this._sessionParams['display_max'])); - } - else { - if (this._currentMatch != '' && this._currentMatch.length >= this._sessionParams['kick_limit']) - this._timer = setTimeout('xtiger.editor.AutocompleteDevice.getInstance().onTimeout()', this._sessionParams['delay']); // FIXME this shameful quirk - } - }, - - /** - *

    - * Handler for the reception of request's answer. The role is to - * parse the answer's body and to update the suggests list - * accordingly. - *

    - * - * @param aMatch - * @param {XHRHTTPObject} aRequest - * @return - */ - _onRequestReceived: function (aMatch, aRequest) { - xtiger.cross.log('debug', 'Suggest for ' + aMatch + ': ' + aRequest.responseText); - try{ - var _parsedResults = eval('('+ aRequest.responseText + ')'); - this._updateCache(aMatch, _parsedResults.results, _parsedResults.hasMore); - this._showResults(this._extractFromCache(aMatch, this._sessionParams['display_max'])); - } - catch (err) { - xtiger.cross.log('warning', 'AutocompleteDevice: ' + err.message); - } - }, - - /** - *

    - * Event handler for timeout events. As those event are called in - * the window's scope, they are called from outside this class. This - * is an issue and must be avoided in cases where several suggest - * devices are working at the same time. - *

    - * - * @todo change the timeout event management - */ - onTimeout: function () { - this._fetchSuggests(this._currentMatch); - }, - - /** - *

    - * Checks that a model declares the mandatory parameters for the autocomplete - * device to autocomplete it (i.e. it must declare an 'autocomplete_URL' and - * and an 'autocomplete_resource' parameters). Prints a warning in case - * of failure. - *

    - * - * @param {aModel} - * The model to be checked - * @return {AutocompleteDeviceInstance | false} - * Returns itself in case of sucess so that this call can be cascaded, - * false otherwise. - */ - validateParameters: function (aModel) { - var _url = aModel.getParam('autocomplete_URL'); - var _rsrc = aModel.getParam('autocomplete_resource'); - _url || xtiger.cross.log('warning', - 'missing "autocomplete_URL" parameter on autocomplete filter'); - _rsrc || xtiger.cross.log('warning', - 'missing "autocomplete_resource" parameter on autocomplete filter'); - return (_url && _rsrc) ? this : false; - }, - - /** - *

    - * Grabs the manager with a device and a field where to perform the - * auto-complete. - *

    - * - *

    - * If this manager is already grabbed by another device, it is - * released. That means that the cache is emptied beforehand and all - * the current auto-completion suggests lost. - *

    - * - *

    - * The current device's model is accessed in order to find the suggest's - * filter parameters. - *

    - * - * @param {Model} - * aDevice The device currently grabbing the auto- - * complete manager. It must support the following - * filtering features (delegation's hooks) : grab(), - * release() and onKeyUp(). Moreover, it must be grabbed - * by a editor's model with the can()/execute() - * delegation functions implemented. - * @param {DOMInputField} - * An HTML field with a read-write "value" accessor - */ - grab: function (aDevice, aInputField) { - - if (this._currentDevice) /* guard against concurrent usage of the device */ - this.release(); - - this._currentDevice = aDevice; - this._currentField = aInputField; - - if (!this._popupdevice) - this._createViewer(); - - /* fetching parameters for this session */ - this._currentModel = aDevice.getCurrentModel(); - this._serviceURL = this._currentModel.getParam('autocomplete_URL'); - this._resourceURI = this._currentModel.getParam('autocomplete_resource'); - this._sessionParams['limit'] = this._currentModel.getParam('autocomplete_limit'); - this._sessionParams['kick_limit'] = this._currentModel.getParam('autocomplete_kick') || 2; - this._sessionParams['lang'] = this._currentModel.getParam('autocomplete_lang'); - - this._currentMatch = this._currentField.value; - - this._cache = {}; // Initialize the cache - }, - - /** - *

    - * Releases the manager. Releasing means the clearing of the cache - * and the reset of all state's variable. If there are pending requests, - * they are discarded. - *

    - */ - release: function () { - - this._currentDevice = null; - this._currentField = null; - this._currentModel = null; - - /* abort all pending requests */ - for (var _m in this._pendingRequests) { - this._pendingRequests[_m].abort(); - } - this._pendingRequests = {}; - - this._cache = null; - }, - - /** - *

    - * This function acts as a handler for keyboard events on the input field. - * As it may receive other keyboard events, it filters them by only - * considering events that modifies the field's content. - *

    - */ - onKeyUp: function (ev) { - if (!this._currentDevice) - return; - - if (this._currentField.value != this._currentMatch) - this._updateState(); - } - } - - return { - /** - *

    - * Gets the manager's instance. - *

    - * - *

    - * The current implementation only allows a single device to be used at - * once. However, this architecture is intent to allow the management of - * a pool of devices, acting independantly. - *

    - * - * @return {AutocompleteDeviceInstance} - */ - getInstance: function getInstance (aDocument) { - if (!_instance) - _instance = new _AutocompleteDeviceInstance(aDocument); - return _instance; - } - } -})(); \ No newline at end of file diff --git a/src/devices/popup.js b/src/devices/popup.js index eb77060..8d3f475 100755 --- a/src/devices/popup.js +++ b/src/devices/popup.js @@ -94,7 +94,7 @@ xtiger.editor.PopupDevice.prototype = { * If isCancel is true the model is not updated nor set. */ stopEditing : function (willEditAgain, isCancel) { - // Safety guard in case of consecutive stops (may arise in case of chaned device, such as with the autocomplete) + // Safety guard in case of consecutive stops (may arise in case of chained devices) if (!this._currentModel) return; diff --git a/src/filters/autocomplete.js b/src/filters/autocomplete.js deleted file mode 100644 index 1168083..0000000 --- a/src/filters/autocomplete.js +++ /dev/null @@ -1,69 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * - * @COPYRIGHT@ - * - * This file is part of the Adaptable XML Editing Library (AXEL), version @VERSION@ - * - * @LICENSE@ - * - * Web site : http://media.epfl.ch/Templates/ - * - * Author(s) : Antoine Yersin, Stéphane Sire - * - * ***** END LICENSE BLOCK ***** */ - - -/*****************************************************************************\ -| | -| AXEL 'autocomplete' filter | -| | -| Acts as a front-end for the AutocompleteDevice | -| | -|*****************************************************************************| -| Prerequisites: uses 'autocomplete' device | -| | -\*****************************************************************************/ -(function ( $axel ) { - - var _AutocompleteFilter = { - - // Stores an instance of an autocomplete device - onInit : function ( aDefaultData, anOptionAttr, aRepeater ) { - this.__autocomplete__onInit(aDefaultData, anOptionAttr, aRepeater); - this._autocompleteDevice = - xtiger.editor.AutocompleteDevice.getInstance(this.getDocument()).validateParameters(this); - }, - - methods : { - - update : function update ( aData ) { - this.__autocomplete__update(aData); - // prevents the usual device to update against a completion, otherwise it may overwrites the completion - this._device.cancelEditing(); - if (this._autocompleteDevice) { - this._autocompleteDevice.release(); - } - }, - - startEditing : function startEditing (aEvent) { - this.__autocomplete__startEditing(aEvent); - if (this._autocompleteDevice) { - this._autocompleteDevice.grab(this._device, this._device.getHandle()); - } - }, - - // Relays keyup from the text device to the autocomplete device - onkeyup : function onkeyup () { - if (this._autocompleteDevice) { - this._autocompleteDevice.onKeyUp(); - } - } - } - }; - - $axel.filter.register( - 'autocomplete', - { chain : ['onInit', 'update', 'startEditing'] }, - null, - _AutocompleteFilter); -}($axel));