aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG2
-rw-r--r--Zotlabs/Lib/Enotify.php4
-rw-r--r--Zotlabs/Module/Acl.php31
-rw-r--r--Zotlabs/Module/Network.php13
-rw-r--r--Zotlabs/Storage/Directory.php6
-rwxr-xr-xboot.php2
-rw-r--r--doc/fr/about/project.bb174
-rw-r--r--include/attach.php130
-rw-r--r--include/bbcode.php8
-rwxr-xr-xinclude/oembed.php6
-rw-r--r--include/text.php18
-rw-r--r--include/zid.php6
-rw-r--r--library/jquery-textcomplete/jquery.textcomplete.js1488
-rw-r--r--library/jquery-textcomplete/jquery.textcomplete.min.js3
-rw-r--r--library/jquery-textcomplete/jquery.textcomplete.min.map1
-rw-r--r--library/textcomplete/textcomplete.js2409
-rw-r--r--library/textcomplete/textcomplete.js.map1
-rw-r--r--library/textcomplete/textcomplete.min.js2
-rw-r--r--library/textcomplete/textcomplete.min.js.map1
-rw-r--r--view/es-es/hmessages.po186
-rw-r--r--view/js/autocomplete.js128
-rw-r--r--view/php/theme_init.php3
-rw-r--r--view/theme/redbasic/schema/dark.css4
-rwxr-xr-xview/tpl/jot-header.tpl23
-rwxr-xr-xview/tpl/jot.tpl4
25 files changed, 2944 insertions, 1709 deletions
diff --git a/CHANGELOG b/CHANGELOG
index e7ffb00a7..472dad3e6 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -21,7 +21,7 @@ Hubzilla 3.4 (????-??-??)
- Implement auto-save posts and comments in browser using localStorage
- Display directory server in siteinfo.json
- Bring back the dnt policy document
- - Implement OAuth2
+ - Implement OAuth2/OpenIDConnect server
- Add basic structure for additional features documentation
- Community tag refactor
- Obscurify chats
diff --git a/Zotlabs/Lib/Enotify.php b/Zotlabs/Lib/Enotify.php
index 05ea67ea5..cfb0bd344 100644
--- a/Zotlabs/Lib/Enotify.php
+++ b/Zotlabs/Lib/Enotify.php
@@ -747,8 +747,8 @@ class Enotify {
// generate a mime boundary
$mimeBoundary = rand(0, 9) . "-"
- .rand(10000000000, 9999999999) . "-"
- .rand(10000000000, 9999999999) . "=:"
+ .rand(100000000, 999999999) . "-"
+ .rand(100000000, 999999999) . "=:"
.rand(10000, 99999);
// generate a multipart/alternative message header
diff --git a/Zotlabs/Module/Acl.php b/Zotlabs/Module/Acl.php
index 35594ae9f..2678aeb7a 100644
--- a/Zotlabs/Module/Acl.php
+++ b/Zotlabs/Module/Acl.php
@@ -268,15 +268,15 @@ class Acl extends \Zotlabs\Web\Controller {
});
}
}
- if(intval(get_config('system','taganyone')) || intval(get_pconfig(local_channel(),'system','taganyone'))) {
- if((count($r) < 100) && $type == 'c') {
- $r2 = q("SELECT substr(xchan_hash,1,18) as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self
- FROM xchan
- WHERE xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc"
- );
- if($r2)
- $r = array_merge($r,$r2);
- }
+ if((count($r) < 100) && $type == 'c') {
+ $r2 = q("SELECT substr(xchan_hash,1,18) as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self
+ FROM xchan
+ WHERE xchan_deleted = 0 and not xchan_network in ('rss','anon','unknown') $sql_extra2 order by $order_extra2 xchan_name asc"
+ );
+ if($r2) {
+ $r = array_merge($r,$r2);
+ $r = unique_multidim_array($r,'hash');
+ }
}
}
elseif($type == 'm') {
@@ -337,22 +337,21 @@ class Acl extends \Zotlabs\Web\Controller {
if($r) {
foreach($r as $g) {
- if(($g['network'] === 'rss') && ($type != 'a'))
+ if(in_array($g['network'],['rss','anon','unknown']) && ($type != 'a'))
continue;
$g['hash'] = urlencode($g['hash']);
if(! $g['nick']) {
- $t = explode(' ',strtolower($g['name']));
- $g['nick'] = $t[0] . '@';
+ $g['nick'] = $g['url'];
}
- if(in_array($g['hash'],$permitted) && in_array($type, [ 'c', 'f' ]) && (! $noforums)) {
+ if(in_array($g['hash'],$permitted) && $type === 'f' && (! $noforums)) {
$contacts[] = array(
"type" => "c",
"photo" => "images/twopeople.png",
- "name" => $g['name'] . (($type === 'f') ? '' : '+'),
- "id" => urlencode($g['id']) . (($type === 'f') ? '' : '+'),
+ "name" => $g['name'],
+ "id" => urlencode($g['id']),
"xid" => $g['hash'],
"link" => (($g['nick']) ? $g['nick'] : $g['url']),
"nick" => substr($g['nick'],0,strpos($g['nick'],'@')),
@@ -369,7 +368,7 @@ class Acl extends \Zotlabs\Web\Controller {
"id" => urlencode($g['id']),
"xid" => $g['hash'],
"link" => (($g['nick']) ? $g['nick'] : $g['url']),
- "nick" => (($g['nick']) ? substr($g['nick'],0,strpos($g['nick'],'@')) : $g['nick']),
+ "nick" => ((strpos($g['nick'],'@')) ? substr($g['nick'],0,strpos($g['nick'],'@')) : $g['nick']),
"self" => (intval($g['abook_self']) ? 'abook-self' : ''),
"taggable" => '',
"label" => '',
diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php
index 8d017207b..e97ebf1d0 100644
--- a/Zotlabs/Module/Network.php
+++ b/Zotlabs/Module/Network.php
@@ -218,15 +218,13 @@ class Network extends \Zotlabs\Web\Controller {
$contact_str = '';
$contacts = group_get_members($group);
if($contacts) {
- foreach($contacts as $c) {
- if($contact_str)
- $contact_str .= ',';
- $contact_str .= "'" . $c['xchan'] . "'";
- }
+ $contact_str = ids_to_querystr($contacts,'xchan',true);
}
else {
- $contact_str = ' 0 ';
- info( t('Privacy group is empty'));
+ $contact_str = " '0' ";
+ if(! $update) {
+ info( t('Privacy group is empty'));
+ }
}
$item_thread_top = '';
$sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND (( author_xchan IN ( $contact_str ) OR owner_xchan in ( $contact_str )) or allow_gid like '" . protect_sprintf('%<' . dbesc($group_hash) . '>%') . "' ) and id = parent $item_normal ) ";
@@ -480,7 +478,6 @@ class Network extends \Zotlabs\Web\Controller {
$ordering = "commented";
if($load) {
-
// Fetch a page full of parent items for this page
$r = q("SELECT item.parent AS item_id FROM item
left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids )
diff --git a/Zotlabs/Storage/Directory.php b/Zotlabs/Storage/Directory.php
index a2ae0fee8..d063eed40 100644
--- a/Zotlabs/Storage/Directory.php
+++ b/Zotlabs/Storage/Directory.php
@@ -389,8 +389,12 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota, DAV\IMo
);
if ($r) {
+
+ // When initiated from DAV, set the 'force' flag on attach_mkdir(). This will cause the operation to report success even if the
+ // folder already exists.
+
require_once('include/attach.php');
- $result = attach_mkdir($r[0], $this->auth->observer, array('filename' => $name, 'folder' => $this->folder_hash));
+ $result = attach_mkdir($r[0], $this->auth->observer, array('filename' => $name, 'folder' => $this->folder_hash, 'force' => true));
if($result['success']) {
$sync = attach_export_data($r[0],$result['data']['hash']);
diff --git a/boot.php b/boot.php
index d79f14617..5cf6cedeb 100755
--- a/boot.php
+++ b/boot.php
@@ -50,7 +50,7 @@ require_once('include/attach.php');
require_once('include/bbcode.php');
define ( 'PLATFORM_NAME', 'hubzilla' );
-define ( 'STD_VERSION', '3.5.1' );
+define ( 'STD_VERSION', '3.5.2' );
define ( 'ZOT_REVISION', '6.0a' );
diff --git a/doc/fr/about/project.bb b/doc/fr/about/project.bb
new file mode 100644
index 000000000..e9bf11cb4
--- /dev/null
+++ b/doc/fr/about/project.bb
@@ -0,0 +1,174 @@
+[h3]La gouvernance de $Projectname [/h3]
+La gouvernance est liée à la gestion d'un projet et plus particulièrement à la résolution des conflits.
+
+[h4]Gouvernance communautaire[/h4]
+Le projet est maintenu et les décisions sont prises par la "communauté". La structure de gouvernance continue d'évoluer. Jusqu'à ce que la structure soit finalisée, les décisions sont prises dans l'ordre suivant :
+
+[ol]
+[*] Consensus paresseux
+Si une proposition de projet est soumise à l'un des forums de gouvernance communautaire et qu'il n'y a pas d'objections sérieuses dans un délai "raisonnable" à partir de la date de la proposition (nous accordons généralement 2 à 3 jours pour que toutes les parties intéressées puissent intervenir), aucun vote n'est nécessaire et la proposition sera considérée comme approuvée. Certaines préoccupations peuvent être soulevées à ce moment-là, mais si elles sont abordées au cours de la discussion et des solutions de rechange fournies, elles seront quand même considérées comme approuvées.
+
+
+[*] Veto
+Les promoteurs principaux ayant un historique important d'engagements de projet peuvent opposer leur veto à toute décision. La décision ne peut être prise tant que le veto n'a pas été levé ou qu'une autre proposition n'a pas été présentée.
+
+
+[*] Vote de la communauté
+Une décision qui n'a pas de mandat clair ou de consensus clair, mais qui ne fait pas l'objet d'un veto, peut être soumise au vote de la communauté. Actuellement, il s'agit d'un simple vote populaire dans l'un des forums communautaires applicables. À ce moment-là, c'est le vote populaire qui décide du résultat. Cela pourrait changer à l'avenir si la communauté adopte un modèle de gouvernance de "conseil". Ce document sera mis à jour à ce moment-là avec les règles de gouvernance mises à jour.
+[/ol]
+
+Le vote communautaire n'offre pas toujours un résultat agréable et peut générer des factions polarisées au sein de la communauté (d'où la raison pour laquelle d'autres modèles sont à l'étude). Si la proposition est rejetée, il y a encore plusieurs choses qui peuvent être faites et la proposition peut être soumise à nouveau avec des paramètres légèrement différents (conversion vers un module complémentaire, conversion vers un module optionnel qui est désactivé par défaut, etc. Si l'intérêt pour le dispositif est élevé et que le vote est "serré", cela peut générer beaucoup de mauvais sentiments parmi les électeurs perdants. Lors de ces votes serrés, il est [b]fortement recommandé[/b] que l'auteur de la proposition prenne des mesures pour répondre à toute préoccupation soulevée et la soumettre de nouveau.
+
+[h3]Politique de confidentialité[/h3]
+
+Q : Qui peut voir mon contenu ?
+
+R : Par défaut, N'IMPORTE QUELLE personne sur Internet, à MOINS que vous le restreigniez. $Projectname vous permet de choisir le niveau de confidentialité que vous désirez. Le contenu restreint ne sera PAS visible pour les "réseaux d'espionnage" et les annonceurs. Il sera protégé contre les écoutes de l'extérieur - au mieux de nos capacités. Les administrateurs de Hub ayant suffisamment de compétences et de patience PEUVENT être en mesure d'écouter certaines communications privées, mais ils doivent déployer des trésors d'efforts pour le faire. Des modes de confidentialité existent au sein de $Projectname qui résistent même à l'écoute par des administrateurs de hub qualifiés et déterminés.
+
+Q : Mon contenu peut-il être censuré ?
+
+R : $Projectname (le réseau) NE PEUT PAS censurer votre contenu. Les administrateurs de serveur et de hub sont soumis aux lois locales et PEUVENT supprimer le contenu répréhensible de leur site/hub. N'importe qui PEUT devenir un administrateur de hub, y compris vous ; et donc publier du contenu qui pourrait autrement être censuré. Vous POUVEZ toujours être soumis aux lois locales.
+
+[h3]Définitions[/h3]
+
+[h4]$Projectname[/h4]
+Autrement appelé "le réseau", $Projectname est une collection d'ordinateurs/serveurs individuels (aka [b]hubs[/b]) qui se connectent ensemble pour former un plus grand réseau coopératif.
+
+[h4]Hub[/h4]
+Un ordinateur individuel ou un serveur connecté à $Projectname. Ces services sont fournis par un [b]administrateur de hub[/b] et peuvent être publics ou privés, payants ou gratuits.
+
+[h4]Administrateur de hub[/h4]
+Gérant du système d'un hub individuel.
+
+[h3]Politiques[/h3]
+
+[h4]Information publique[/h4]
+
+Toute information ou tout ce que vous affichez dans $Projectname PEUT être public ou visible par quiconque sur Internet. Dans la mesure du possible, $Projectname vous permet de protéger le contenu et de restreindre qui peut le consulter.
+
+La photo de votre profil, le nom de votre canal et l'emplacement (URL ou adresse réseau) de votre canal sont visibles par tous sur Internet et les contrôles de confidentialité n'affecteront pas l'affichage de ces éléments.
+
+Vous POUVEZ fournir en plus d'autres informations de profil. Toute information que vous fournissez dans votre profil "par défaut" ou [b]profil public[/b] PEUT être transmise à d'autres hubs dans $Projectname et peut également être affichée dans le répertoire des canaux. Vous pouvez limiter l'affichage de ces informations de profil. Il peut être limité aux seuls membres de votre hub, ou seulement aux connexions (amis), ou à d'autres groupes limités de visionneurs comme vous le souhaitez. Si vous souhaitez que votre profil soit restreint, vous devez définir le paramètre de confidentialité approprié ou simplement NE PAS fournir d'informations supplémentaires.
+
+[h4]Contenu[/h4]
+
+Le contenu que vous fournissez (messages de statut, photos, fichiers, etc.) vous appartient. Par défaut, $Projectname publie le contenu ouvertement et visible par tout le monde sur Internet (PUBLIC). Vous POUVEZ contrôler cela dans les paramètres de votre canal et restreindre les permissions par défaut ou vous POUVEZ restreindre la visibilité de n'importe quel élément publié séparément (PRIVÉ). Les développeurs de noms de projet s'assureront que le contenu restreint est visible SEULEMENT pour ceux qui figurent dans la liste des restrictions - au mieux de leurs capacités.
+
+Les contenus (en particulier les messages de statut) que vous partagez avec d'autres réseaux ou que vous avez rendus visibles à quiconque sur Internet (PUBLIC) ne peuvent pas être facilement repris une fois qu'ils ont été publiés. Il PEUT être partagé avec d'autres réseaux et rendu disponible par le biais de flux RSS/Atom. Il peut aussi être syndiqué sur d'autres sites $Projectname. Il PEUT apparaître sur d'autres réseaux et sites Web et être visible dans les recherches sur Internet. Si vous ne souhaitez pas ce comportement par défaut, veuillez ajuster les paramètres de votre canal et restreindre le nombre de personnes qui peuvent voir votre contenu.
+
+[h4]Commentaires et posts du Forum[/h4]
+
+Les commentaires sur les posts qui ont été créés par d'autres et les posts qui sont désignés comme posts du forum vous appartiennent en tant que créateur/auteur, mais la distribution de ces posts n'est pas sous votre contrôle direct, et vous renoncez à certains droits sur ces items. Ces messages/commentaires PEUVENT être redistribués à d'autres, et PEUVENT être visibles pour n'importe qui sur Internet. Dans le cas de commentaires, le créateur du "premier message" dans le fil de discussion (conversation) auquel vous répondez contrôle la distribution de tous les commentaires et réponses à ce message. Ils "possèdent" et ont donc certains droits sur l'ensemble de la conversation (y compris tous les commentaires qu'elle contient). Vous pouvez toujours modifier ou supprimer le commentaire, mais le propriétaire de la conversation a également le droit de modifier, supprimer, redistribuer et sauvegarder/restaurer tout ou partie du contenu de la conversation.
+
+[h4]Les informations privées[/h4]
+
+Les développeurs de $Projectname s'assureront que tout contenu que vous fournissez et qui est désigné comme PRIVÉ seront protégés contre les écoutes - au mieux de leurs capacités. Le contenu des canaux privés PEUT être vu dans la base de données de chaque administrateur de hub impliqué, mais les messages privés sont masqués dans la base de données. Cette dernière signifie qu'il est très difficile, mais PAS impossible que ce contenu soit vu par un administrateur de hub. Le contenu du canal privé et les messages privés sont également éliminés des notifications par courriel. Le cryptage de bout en bout est fourni en option et ceci NE PEUT PAS être vu, même par un administrateur déterminé.
+
+[h3]Confidentialité de l'identité[/h3]
+
+La confidentialité de votre identité est un autre aspect. Parce que vous avez une identité décentralisée dans $Projectname, votre vie privée s'étend au-delà de votre hub d'origine. Si vous voulez avoir le contrôle total de votre vie privée et de la sécurité, vous devriez faire fonctionner votre propre concentrateur sur un serveur dédié. Pour beaucoup de gens, c'est compliqué et cela peut mettre à l'épreuve leurs capacités techniques. Énumérons donc quelques précautions que vous pouvez prendre pour assurer votre vie privée autant que possible.
+
+Une identité décentralisée a beaucoup d'avantages et vous donne beaucoup de fonctionnalités intéressantes, mais vous devez être conscient du fait que votre identité est connue par d'autres hubs dans le réseau $Projectname. L'un de ces avantages est que d'autres canaux peuvent vous servir du contenu personnalisé et vous permettre de voir des choses privées (comme des photos privées que d'autres souhaitent partager avec vous). Pour cette raison, ces canaux ont besoin de savoir qui vous êtes. Mais nous comprenons que parfois, ces autres canaux en savent plus de vous que vous ne le souhaiteriez. Par exemple, le plug-in Visage qui peut indiquer au propriétaire d'un canal la dernière fois que vous avez visité son profil. Vous pouvez facilement OPT-OUT de ce bas niveau et nous pensons, le suivi inoffensif.
+
+Vous pouvez activer [url=http://donottrack.us/]Ne pas suivre (DNT)[/url] dans votre navigateur Web. Nous respectons cette nouvelle proposition de politique de confidentialité. Tous les navigateurs modernes supportent le DNT. Vous le trouverez dans les paramètres de confidentialité de vos navigateurs ou bien vous pouvez consulter le manuel du navigateur Web. Cela n'affectera pas la fonctionnalité de $Projectname. Ce réglage est probablement suffisant pour la plupart des gens.
+
+Vous pouvez [url=settings]désactiver la publication[/url] de votre chaîne dans notre répertoire de chaînes. Si vous voulez que les gens trouvent votre canal, vous devriez leur donner l'adresse de votre canal directement. Nous pensons que c'est une bonne indication que vous préférez une vie privée supplémentaire et que vous activez automatiquement l'option "Ne pas suivre" si c'est le cas.
+
+Vous pouvez avoir un hub bloqué. Cela signifie que tous les canaux et le contenu de cette hub ne sont pas publics et ne sont pas visibles pour le monde extérieur. C'est quelque chose que seul votre administrateur de hub peut faire. Nous respectons également ce principe et activons automatiquement l'option "Ne pas suivre" si elle est définie.
+
+[h3]La Censure[/h3]
+
+$Projectname est un réseau mondial qui inclut toutes les religions et toutes les cultures. Cela n'implique pas que tous les membres du réseau ressentent la même chose que vous sur les questions litigieuses, et certaines personnes peuvent être FORTEMENT opposées au contenu que vous publiez. En général, si vous souhaitez publier quelque chose que vous savez ne pas être universellement acceptable, la meilleure approche est de limiter l'audience en utilisant les contrôles de confidentialité à un petit cercle d'amis.
+
+$Projectname en tant que fournisseur de réseau n'est pas en mesure de censurer le contenu. Cependant, les administrateurs du hub PEUVENT censurer tout contenu qui apparaît sur leur hub pour se conformer aux lois locales ou même au jugement personnel. Leur décision est finale. Si vous avez des problèmes avec un administrateur de hub, vous pouvez déplacer votre compte et vos messages sur un autre site qui correspond mieux à vos attentes. Veuillez vérifier (périodiquement) les[Conditions d'utilisation](help/TermsOfService) de votre hub pour connaître les règles ou directives. Si votre contenu se compose de matériel qui est illégal ou qui peut causer des problèmes, vous êtes FORTEMENT encouragé à héberger le vôtre (devenez un administrateur de hub). Vous pouvez toujours trouver que votre contenu est bloqué sur certains hubs, mais $Projectname en tant que réseau ne peut pas l'empêcher d'être posté.
+
+$Projectname RECOMMANDE que les administrateurs du concentrateur accordent un délai de grâce de 1 à 2 jours entre l'avertissement au titulaire du compte du contenu qui doit être supprimé et la suppression ou la désactivation physique du compte. Cela donnera au propriétaire du contenu la possibilité d'exporter les métadonnées de son canal et de les importer sur un autre site. Dans de rares cas, le contenu peut être de nature à justifier la résiliation immédiate du compte. Il s'agit d'une décision de hub, pas d'une décision de $Projectname.
+
+Si vous publiez régulièrement des contenus à caractère adulte ou offensant, nous vous encourageons fortement à marquer votre compte "NSFW" (Not Safe For Work). Ceci empêchera l'affichage de votre photo de profil dans le répertoire, sauf pour les visiteurs qui ont choisi de désactiver le "mode sans échec". Si votre photo de profil est trouvée par les administrateurs d'annuaire comme étant adulte ou offensante, l'administrateur d'annuaire PEUT marquer votre photo de profil comme NSFW. Il n'existe actuellement aucun mécanisme officiel pour contester ou renverser cette décision, c'est pourquoi vous DEVEZ marquer votre propre compte NSFW s'il est susceptible d'être inapproprié pour le grand public.
+
+[h3]Remerciements[/h3]
+
+Merci à tous ceux qui ont aidé et contribué au projet et à ses prédécesseurs au fil des ans.
+Il est possible que votre nom nous ait échappé, mais ce n'est pas intentionnel. Nous remercions également la collectivité et ses membres pour leur précieuse contribution et sans qui tout cet effort n'aurait pas de sens.
+
+Il convient également de reconnaître les contributions et les solutions aux problèmes qui sont apparus à la suite de des discussions entre les membres et les développeurs d'autres projets quelque peu liés et concurrents ; même si nous avons eu nos désaccords occasionnels.
+
+[list]
+[li]Mike Macgirvin[/li]
+[li]Fabio Comuni[/li]
+[li]Simon L'nu[/li]
+[li]marijus[/li]
+[li]Tobias Diekershoff[/li]
+[li]fabrixxm[/li]
+[li]tommy tomson[/li]
+[li]Simon[/li]
+[li]zottel[/li]
+[li]Christian Vogeley[/li]
+[li]jeroenpraat[/li]
+[li]Michael Vogel[/li]
+[li]erik[/li]
+[li]Zach Prezkuta[/li]
+[li]Paolo T[/li]
+[li]Michael Meer[/li]
+[li]Michael[/li]
+[li]Abinoam P. Marques Jr[/li]
+[li]Tobias Hößl[/li]
+[li]Alexander Kampmann[/li]
+[li]Olaf Conradi[/li]
+[li]Paolo Tacconi[/li]
+[li]tobiasd[/li]
+[li]Devlon Duthie[/li]
+[li]Zvi ben Yaakov (a.k.a rdc)[/li]
+[li]Alexandre Hannud Abdo[/li]
+[li]Olivier Migeot[/li]
+[li]Chris Case[/li]
+[li]Klaus Weidenbach[/li]
+[li]Michael Johnston[/li]
+[li]olivierm[/li]
+[li]Vasudev Kamath[/li]
+[li]pixelroot[/li]
+[li]Max Weller[/li]
+[li]duthied[/li]
+[li]Martin Schmitt[/li]
+[li]Sebastian Egbers[/li]
+[li]Erkan Yilmaz[/li]
+[li]sasiflo[/li]
+[li]Stefan Parviainen[/li]
+[li]Haakon Meland Eriksen[/li]
+[li]Oliver Hartmann (23n)[/li]
+[li]Erik Lundin[/li]
+[li]habeascodice[/li]
+[li]sirius[/li]
+[li]Charles[/li]
+[li]Tony Baldwin[/li]
+[li]Hauke Zuehl[/li]
+[li]Keith Fernie[/li]
+[li]Anne Walk[/li]
+[li]toclimb[/li]
+[li]Daniel Frank[/li]
+[li]Matthew Exon[/li]
+[li]Michal Supler[/li]
+[li]Tobias Luther[/li]
+[li]U-SOUND\mike[/li]
+[li]mrjive[/li]
+[li]nostupidzone[/li]
+[li]tonnerkiller[/li]
+[li]Antoine G[/li]
+[li]Christian Drechsler[/li]
+[li]Ludovic Grossard[/li]
+[li]RedmatrixCanada[/li]
+[li]Stanislav Lechev [0xAF][/li]
+[li]aweiher[/li]
+[li]bufalo1973[/li]
+[li]dsp1986[/li]
+[li]felixgilles[/li]
+[li]ike[/li]
+[li]maase2[/li]
+[li]mycocham[/li]
+[li]ndurchx[/li]
+[li]pafcu[/li]
+[li]Simó Albert i Beltran[/li]
+[li]Manuel Reva[/li]
+[li]Manuel Jiménez Friaza[/li]
+[li]Gustav Wall aka "neue medienordnung plus"[/li]
+[/list]
diff --git a/include/attach.php b/include/attach.php
index 363005029..27bf0218a 100644
--- a/include/attach.php
+++ b/include/attach.php
@@ -2286,33 +2286,22 @@ function attach_move($channel_id, $resource_id, $new_folder_hash) {
if(! ($c && $resource_id))
return false;
+
+ // find the resource to be moved
+
$r = q("select * from attach where hash = '%s' and uid = %d limit 1",
dbesc($resource_id),
intval($channel_id)
);
- if(! $r)
+ if(! $r) {
+ logger('resource_id not found');
return false;
+ }
$oldstorepath = dbunescbin($r[0]['content']);
- if($r[0]['is_dir']) {
- $move_success = true;
- $x = q("select hash from attach where folder = '%s' and uid = %d",
- dbesc($r[0]['hash']),
- intval($channel_id)
- );
- if($x) {
- foreach($x as $xv) {
- $rs = attach_move($channel_id,$xv['hash'],$r[0]['hash']);
- if(! $rs) {
- $move_success = false;
- break;
- }
- }
- }
- return $move_success;
- }
+ // find the resource we are moving to
if($new_folder_hash) {
$n = q("select * from attach where hash = '%s' and uid = %d and is_dir = 1 limit 1",
@@ -2326,6 +2315,10 @@ function attach_move($channel_id, $resource_id, $new_folder_hash) {
$newstorepath = dbunescbin($n[0]['content']) . '/' . $resource_id;
}
else {
+
+ // root directory
+
+ $newdirname = EMPTY_STR;
$newstorepath = 'store/' . $c['channel_address'] . '/' . $resource_id;
}
@@ -2335,56 +2328,61 @@ function attach_move($channel_id, $resource_id, $new_folder_hash) {
$filename = $r[0]['filename'];
- $s = q("select filename, id, hash, filesize from attach where filename = '%s' and folder = '%s' ",
- dbesc($filename),
- dbesc($new_folder_hash)
- );
+ // don't do duplicate check unless our parent folder has changed.
- if($s) {
- $overwrite = get_pconfig($channel_id,'system','overwrite_dup_files');
- if($overwrite) {
- /// @fixme
- return;
- }
- else {
- if(strpos($filename,'.') !== false) {
- $basename = substr($filename,0,strrpos($filename,'.'));
- $ext = substr($filename,strrpos($filename,'.'));
+ if($r[0]['folder'] !== $new_folder_hash) {
+
+ $s = q("select filename, id, hash, filesize from attach where filename = '%s' and folder = '%s' ",
+ dbesc($filename),
+ dbesc($new_folder_hash)
+ );
+
+ if($s) {
+ $overwrite = get_pconfig($channel_id,'system','overwrite_dup_files');
+ if($overwrite) {
+ /// @fixme
+ return;
}
else {
- $basename = $filename;
- $ext = '';
- }
+ if(strpos($filename,'.') !== false) {
+ $basename = substr($filename,0,strrpos($filename,'.'));
+ $ext = substr($filename,strrpos($filename,'.'));
+ }
+ else {
+ $basename = $filename;
+ $ext = '';
+ }
- $matches = false;
- if(preg_match('/(.*?)\([0-9]{1,}\)$/',$basename,$matches))
- $basename = $matches[1];
+ $matches = false;
+ if(preg_match('/(.*?)\([0-9]{1,}\)$/',$basename,$matches))
+ $basename = $matches[1];
- $v = q("select filename from attach where ( filename = '%s' OR filename like '%s' ) and folder = '%s' ",
- dbesc($basename . $ext),
- dbesc($basename . '(%)' . $ext),
- dbesc($new_folder_hash)
- );
+ $v = q("select filename from attach where ( filename = '%s' OR filename like '%s' ) and folder = '%s' ",
+ dbesc($basename . $ext),
+ dbesc($basename . '(%)' . $ext),
+ dbesc($new_folder_hash)
+ );
- if($v) {
- $x = 1;
+ if($v) {
+ $x = 1;
- do {
- $found = false;
- foreach($v as $vv) {
- if($vv['filename'] === $basename . '(' . $x . ')' . $ext) {
- $found = true;
- break;
+ do {
+ $found = false;
+ foreach($v as $vv) {
+ if($vv['filename'] === $basename . '(' . $x . ')' . $ext) {
+ $found = true;
+ break;
+ }
}
+ if($found)
+ $x++;
}
- if($found)
- $x++;
+ while($found);
+ $filename = $basename . '(' . $x . ')' . $ext;
}
- while($found);
- $filename = $basename . '(' . $x . ')' . $ext;
+ else
+ $filename = $basename . $ext;
}
- else
- $filename = $basename . $ext;
}
}
@@ -2423,6 +2421,24 @@ function attach_move($channel_id, $resource_id, $new_folder_hash) {
);
}
+ if($r[0]['is_dir']) {
+ $move_success = true;
+ $x = q("select hash from attach where folder = '%s' and uid = %d",
+ dbesc($r[0]['hash']),
+ intval($channel_id)
+ );
+ if($x) {
+ foreach($x as $xv) {
+ $rs = attach_move($channel_id,$xv['hash'],$r[0]['hash']);
+ if(! $rs) {
+ $move_success = false;
+ break;
+ }
+ }
+ }
+ return $move_success;
+ }
+
return true;
}
diff --git a/include/bbcode.php b/include/bbcode.php
index 340fe6b25..345b5b025 100644
--- a/include/bbcode.php
+++ b/include/bbcode.php
@@ -85,12 +85,14 @@ function tryoembed($match) {
function nakedoembed($match) {
$url = ((count($match) == 2) ? $match[1] : $match[2]);
- $o = oembed_fetch_url($url);
+ $strip_url = strip_escaped_zids($url);
+
+ $o = oembed_fetch_url($strip_url);
if ($o['type'] == 'error')
- return $match[0];
+ return str_replace($url,$strip_url,$match[0]);
- return '[embed]' . $url . '[/embed]';
+ return '[embed]' . $strip_url . '[/embed]';
}
function tryzrlaudio($match) {
diff --git a/include/oembed.php b/include/oembed.php
index eee53b6c1..e677087a2 100755
--- a/include/oembed.php
+++ b/include/oembed.php
@@ -234,9 +234,11 @@ function oembed_fetch_url($embedurl){
if(preg_match('#\<iframe(.*?)src\=[\'\"](.*?)[\'\"]#',$j['html'],$matches)) {
$x = z_fetch_url($matches[2]);
- $j['html'] = $x['body'];
+ $orig = $j['html'] = $x['body'];
}
-
+
+ logger('frame src: ' . $j['html'], LOGGER_DATA);
+
$j['html'] = purify_html($j['html'],$allow_position);
if($j['html'] != $orig) {
logger('oembed html was purified. original: ' . $orig . ' purified: ' . $j['html'], LOGGER_DEBUG, LOG_INFO);
diff --git a/include/text.php b/include/text.php
index 60f6ff383..24f8e1623 100644
--- a/include/text.php
+++ b/include/text.php
@@ -2213,6 +2213,7 @@ function ids_to_querystr($arr,$idx = 'id',$quote = false) {
* @param $arr array
* @param $elm array key to extract from sub-array
* @param $delim string default ','
+ * @param $each filter function to apply to each element before evaluation, default is 'trim'.
* @returns string
*/
@@ -3306,6 +3307,7 @@ function cleanup_bbcode($body) {
* First protect any url inside certain bbcode tags so we don't double link it.
*/
+
$body = preg_replace_callback('/\[code(.*?)\[\/(code)\]/ism','\red_escape_codeblock',$body);
$body = preg_replace_callback('/\[url(.*?)\[\/(url)\]/ism','\red_escape_codeblock',$body);
$body = preg_replace_callback('/\[zrl(.*?)\[\/(zrl)\]/ism','\red_escape_codeblock',$body);
@@ -3335,7 +3337,6 @@ function cleanup_bbcode($body) {
$body = scale_external_images($body,false);
-
return $body;
}
@@ -3402,3 +3403,18 @@ function unpunify($s) {
}
+
+function unique_multidim_array($array, $key) {
+ $temp_array = array();
+ $i = 0;
+ $key_array = array();
+
+ foreach($array as $val) {
+ if (!in_array($val[$key], $key_array)) {
+ $key_array[$i] = $val[$key];
+ $temp_array[$i] = $val;
+ }
+ $i++;
+ }
+ return $temp_array;
+} \ No newline at end of file
diff --git a/include/zid.php b/include/zid.php
index 5275c6d5a..fe06948ba 100644
--- a/include/zid.php
+++ b/include/zid.php
@@ -60,7 +60,7 @@ function zid($s, $address = '') {
$url_match = true;
if ($mine && $myaddr && (! $url_match))
- $zurl = $s . (($num_slashes >= 3) ? '' : '/') . $achar . 'zid=' . urlencode($myaddr);
+ $zurl = $s . (($num_slashes >= 3) ? '' : '/') . (($achar === '?') ? '?f=&' : '&') . 'zid=' . urlencode($myaddr);
else
$zurl = $s;
@@ -103,6 +103,10 @@ function strip_zats($s) {
return preg_replace('/[\?&]zat=(.*?)(&|$)/ism','$2',$s);
}
+function strip_escaped_zids($s) {
+ $x = preg_replace('/&amp\;zid=(.*?)(&|$)/ism','$2',$s);
+ return strip_query_param($x,'f');
+}
function clean_query_string($s = '') {
diff --git a/library/jquery-textcomplete/jquery.textcomplete.js b/library/jquery-textcomplete/jquery.textcomplete.js
deleted file mode 100644
index 0dd9fd827..000000000
--- a/library/jquery-textcomplete/jquery.textcomplete.js
+++ /dev/null
@@ -1,1488 +0,0 @@
-(function (factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['jquery'], factory);
- } else if (typeof module === "object" && module.exports) {
- var $ = require('jquery');
- module.exports = factory($);
- } else {
- // Browser globals
- factory(jQuery);
- }
-}(function (jQuery) {
-
-/*!
- * jQuery.textcomplete
- *
- * Repository: https://github.com/yuku-t/jquery-textcomplete
- * License: MIT (https://github.com/yuku-t/jquery-textcomplete/blob/master/LICENSE)
- * Author: Yuku Takahashi
- */
-
-if (typeof jQuery === 'undefined') {
- throw new Error('jQuery.textcomplete requires jQuery');
-}
-
-+function ($) {
- 'use strict';
-
- var warn = function (message) {
- if (console.warn) { console.warn(message); }
- };
-
- var id = 1;
-
- $.fn.textcomplete = function (strategies, option) {
- var args = Array.prototype.slice.call(arguments);
- return this.each(function () {
- var self = this;
- var $this = $(this);
- var completer = $this.data('textComplete');
- if (!completer) {
- option || (option = {});
- option._oid = id++; // unique object id
- completer = new $.fn.textcomplete.Completer(this, option);
- $this.data('textComplete', completer);
- }
- if (typeof strategies === 'string') {
- if (!completer) return;
- args.shift()
- completer[strategies].apply(completer, args);
- if (strategies === 'destroy') {
- $this.removeData('textComplete');
- }
- } else {
- // For backward compatibility.
- // TODO: Remove at v0.4
- $.each(strategies, function (obj) {
- $.each(['header', 'footer', 'placement', 'maxCount'], function (name) {
- if (obj[name]) {
- completer.option[name] = obj[name];
- warn(name + 'as a strategy param is deprecated. Use option.');
- delete obj[name];
- }
- });
- });
- completer.register($.fn.textcomplete.Strategy.parse(strategies, {
- el: self,
- $el: $this
- }));
- }
- });
- };
-
-}(jQuery);
-
-+function ($) {
- 'use strict';
-
- // Exclusive execution control utility.
- //
- // func - The function to be locked. It is executed with a function named
- // `free` as the first argument. Once it is called, additional
- // execution are ignored until the free is invoked. Then the last
- // ignored execution will be replayed immediately.
- //
- // Examples
- //
- // var lockedFunc = lock(function (free) {
- // setTimeout(function { free(); }, 1000); // It will be free in 1 sec.
- // console.log('Hello, world');
- // });
- // lockedFunc(); // => 'Hello, world'
- // lockedFunc(); // none
- // lockedFunc(); // none
- // // 1 sec past then
- // // => 'Hello, world'
- // lockedFunc(); // => 'Hello, world'
- // lockedFunc(); // none
- //
- // Returns a wrapped function.
- var lock = function (func) {
- var locked, queuedArgsToReplay;
-
- return function () {
- // Convert arguments into a real array.
- var args = Array.prototype.slice.call(arguments);
- if (locked) {
- // Keep a copy of this argument list to replay later.
- // OK to overwrite a previous value because we only replay
- // the last one.
- queuedArgsToReplay = args;
- return;
- }
- locked = true;
- var self = this;
- args.unshift(function replayOrFree() {
- if (queuedArgsToReplay) {
- // Other request(s) arrived while we were locked.
- // Now that the lock is becoming available, replay
- // the latest such request, then call back here to
- // unlock (or replay another request that arrived
- // while this one was in flight).
- var replayArgs = queuedArgsToReplay;
- queuedArgsToReplay = undefined;
- replayArgs.unshift(replayOrFree);
- func.apply(self, replayArgs);
- } else {
- locked = false;
- }
- });
- func.apply(this, args);
- };
- };
-
- var isString = function (obj) {
- return Object.prototype.toString.call(obj) === '[object String]';
- };
-
- var uniqueId = 0;
-
- function Completer(element, option) {
- this.$el = $(element);
- this.id = 'textcomplete' + uniqueId++;
- this.strategies = [];
- this.views = [];
- this.option = $.extend({}, Completer.defaults, option);
-
- if (!this.$el.is('input[type=text]') && !this.$el.is('input[type=search]') && !this.$el.is('textarea') && !element.isContentEditable && element.contentEditable != 'true') {
- throw new Error('textcomplete must be called on a Textarea or a ContentEditable.');
- }
-
- // use ownerDocument to fix iframe / IE issues
- if (element === element.ownerDocument.activeElement) {
- // element has already been focused. Initialize view objects immediately.
- this.initialize()
- } else {
- // Initialize view objects lazily.
- var self = this;
- this.$el.one('focus.' + this.id, function () { self.initialize(); });
-
- // Special handling for CKEditor: lazy init on instance load
- if ((!this.option.adapter || this.option.adapter == 'CKEditor') && typeof CKEDITOR != 'undefined' && (this.$el.is('textarea'))) {
- CKEDITOR.on("instanceReady", function(event) {
- event.editor.once("focus", function(event2) {
- // replace the element with the Iframe element and flag it as CKEditor
- self.$el = $(event.editor.editable().$);
- if (!self.option.adapter) {
- self.option.adapter = $.fn.textcomplete['CKEditor'];
- self.option.ckeditor_instance = event.editor;
- }
- self.initialize();
- });
- });
- }
- }
- }
-
- Completer.defaults = {
- appendTo: 'body',
- className: '', // deprecated option
- dropdownClassName: 'dropdown-menu textcomplete-dropdown',
- maxCount: 10,
- zIndex: '100',
- rightEdgeOffset: 30
- };
-
- $.extend(Completer.prototype, {
- // Public properties
- // -----------------
-
- id: null,
- option: null,
- strategies: null,
- adapter: null,
- dropdown: null,
- $el: null,
- $iframe: null,
-
- // Public methods
- // --------------
-
- initialize: function () {
- var element = this.$el.get(0);
-
- // check if we are in an iframe
- // we need to alter positioning logic if using an iframe
- if (this.$el.prop('ownerDocument') !== document && window.frames.length) {
- for (var iframeIndex = 0; iframeIndex < window.frames.length; iframeIndex++) {
- if (this.$el.prop('ownerDocument') === window.frames[iframeIndex].document) {
- this.$iframe = $(window.frames[iframeIndex].frameElement);
- break;
- }
- }
- }
-
-
- // Initialize view objects.
- this.dropdown = new $.fn.textcomplete.Dropdown(element, this, this.option);
- var Adapter, viewName;
- if (this.option.adapter) {
- Adapter = this.option.adapter;
- } else {
- if (this.$el.is('textarea') || this.$el.is('input[type=text]') || this.$el.is('input[type=search]')) {
- viewName = typeof element.selectionEnd === 'number' ? 'Textarea' : 'IETextarea';
- } else {
- viewName = 'ContentEditable';
- }
- Adapter = $.fn.textcomplete[viewName];
- }
- this.adapter = new Adapter(element, this, this.option);
- },
-
- destroy: function () {
- this.$el.off('.' + this.id);
- if (this.adapter) {
- this.adapter.destroy();
- }
- if (this.dropdown) {
- this.dropdown.destroy();
- }
- this.$el = this.adapter = this.dropdown = null;
- },
-
- deactivate: function () {
- if (this.dropdown) {
- this.dropdown.deactivate();
- }
- },
-
- // Invoke textcomplete.
- trigger: function (text, skipUnchangedTerm) {
- if (!this.dropdown) { this.initialize(); }
- text != null || (text = this.adapter.getTextFromHeadToCaret());
- var searchQuery = this._extractSearchQuery(text);
- if (searchQuery.length) {
- var term = searchQuery[1];
- // Ignore shift-key, ctrl-key and so on.
- if (skipUnchangedTerm && this._term === term && term !== "") { return; }
- this._term = term;
- this._search.apply(this, searchQuery);
- } else {
- this._term = null;
- this.dropdown.deactivate();
- }
- },
-
- fire: function (eventName) {
- var args = Array.prototype.slice.call(arguments, 1);
- this.$el.trigger(eventName, args);
- return this;
- },
-
- register: function (strategies) {
- Array.prototype.push.apply(this.strategies, strategies);
- },
-
- // Insert the value into adapter view. It is called when the dropdown is clicked
- // or selected.
- //
- // value - The selected element of the array callbacked from search func.
- // strategy - The Strategy object.
- // e - Click or keydown event object.
- select: function (value, strategy, e) {
- this._term = null;
- this.adapter.select(value, strategy, e);
- this.fire('change').fire('textComplete:select', value, strategy);
- this.adapter.focus();
- },
-
- // Private properties
- // ------------------
-
- _clearAtNext: true,
- _term: null,
-
- // Private methods
- // ---------------
-
- // Parse the given text and extract the first matching strategy.
- //
- // Returns an array including the strategy, the query term and the match
- // object if the text matches an strategy; otherwise returns an empty array.
- _extractSearchQuery: function (text) {
- for (var i = 0; i < this.strategies.length; i++) {
- var strategy = this.strategies[i];
- var context = strategy.context(text);
- if (context || context === '') {
- var matchRegexp = $.isFunction(strategy.match) ? strategy.match(text) : strategy.match;
- if (isString(context)) { text = context; }
- var match = text.match(matchRegexp);
- if (match) { return [strategy, match[strategy.index], match]; }
- }
- }
- return []
- },
-
- // Call the search method of selected strategy..
- _search: lock(function (free, strategy, term, match) {
- var self = this;
- strategy.search(term, function (data, stillSearching) {
- if (!self.dropdown.shown) {
- self.dropdown.activate();
- }
- if (self._clearAtNext) {
- // The first callback in the current lock.
- self.dropdown.clear();
- self._clearAtNext = false;
- }
- self.dropdown.setPosition(self.adapter.getCaretPosition());
- self.dropdown.render(self._zip(data, strategy, term));
- if (!stillSearching) {
- // The last callback in the current lock.
- free();
- self._clearAtNext = true; // Call dropdown.clear at the next time.
- }
- }, match);
- }),
-
- // Build a parameter for Dropdown#render.
- //
- // Examples
- //
- // this._zip(['a', 'b'], 's');
- // //=> [{ value: 'a', strategy: 's' }, { value: 'b', strategy: 's' }]
- _zip: function (data, strategy, term) {
- return $.map(data, function (value) {
- return { value: value, strategy: strategy, term: term };
- });
- }
- });
-
- $.fn.textcomplete.Completer = Completer;
-}(jQuery);
-
-+function ($) {
- 'use strict';
-
- var $window = $(window);
-
- var include = function (zippedData, datum) {
- var i, elem;
- var idProperty = datum.strategy.idProperty
- for (i = 0; i < zippedData.length; i++) {
- elem = zippedData[i];
- if (elem.strategy !== datum.strategy) continue;
- if (idProperty) {
- if (elem.value[idProperty] === datum.value[idProperty]) return true;
- } else {
- if (elem.value === datum.value) return true;
- }
- }
- return false;
- };
-
- var dropdownViews = {};
- $(document).on('click', function (e) {
- var id = e.originalEvent && e.originalEvent.keepTextCompleteDropdown;
- $.each(dropdownViews, function (key, view) {
- if (key !== id) { view.deactivate(); }
- });
- });
-
- var commands = {
- SKIP_DEFAULT: 0,
- KEY_UP: 1,
- KEY_DOWN: 2,
- KEY_ENTER: 3,
- KEY_PAGEUP: 4,
- KEY_PAGEDOWN: 5,
- KEY_ESCAPE: 6
- };
-
- // Dropdown view
- // =============
-
- // Construct Dropdown object.
- //
- // element - Textarea or contenteditable element.
- function Dropdown(element, completer, option) {
- this.$el = Dropdown.createElement(option);
- this.completer = completer;
- this.id = completer.id + 'dropdown';
- this._data = []; // zipped data.
- this.$inputEl = $(element);
- this.option = option;
-
- // Override setPosition method.
- if (option.listPosition) { this.setPosition = option.listPosition; }
- if (option.height) { this.$el.height(option.height); }
- var self = this;
- $.each(['maxCount', 'placement', 'footer', 'header', 'noResultsMessage', 'className'], function (_i, name) {
- if (option[name] != null) { self[name] = option[name]; }
- });
- this._bindEvents(element);
- dropdownViews[this.id] = this;
- }
-
- $.extend(Dropdown, {
- // Class methods
- // -------------
-
- createElement: function (option) {
- var $parent = option.appendTo;
- if (!($parent instanceof $)) { $parent = $($parent); }
- var $el = $('<ul></ul>')
- .addClass(option.dropdownClassName)
- .attr('id', 'textcomplete-dropdown-' + option._oid)
- .css({
- display: 'none',
- left: 0,
- position: 'absolute',
- zIndex: option.zIndex
- })
- .appendTo($parent);
- return $el;
- }
- });
-
- $.extend(Dropdown.prototype, {
- // Public properties
- // -----------------
-
- $el: null, // jQuery object of ul.dropdown-menu element.
- $inputEl: null, // jQuery object of target textarea.
- completer: null,
- footer: null,
- header: null,
- id: null,
- maxCount: null,
- placement: '',
- shown: false,
- data: [], // Shown zipped data.
- className: '',
-
- // Public methods
- // --------------
-
- destroy: function () {
- // Don't remove $el because it may be shared by several textcompletes.
- this.deactivate();
-
- this.$el.off('.' + this.id);
- this.$inputEl.off('.' + this.id);
- this.clear();
- this.$el.remove();
- this.$el = this.$inputEl = this.completer = null;
- delete dropdownViews[this.id]
- },
-
- render: function (zippedData) {
- var contentsHtml = this._buildContents(zippedData);
- var unzippedData = $.map(zippedData, function (d) { return d.value; });
- if (zippedData.length) {
- var strategy = zippedData[0].strategy;
- if (strategy.id) {
- this.$el.attr('data-strategy', strategy.id);
- } else {
- this.$el.removeAttr('data-strategy');
- }
- this._renderHeader(unzippedData);
- this._renderFooter(unzippedData);
- if (contentsHtml) {
- this._renderContents(contentsHtml);
- this._fitToBottom();
- this._fitToRight();
- this._activateIndexedItem();
- }
- this._setScroll();
- } else if (this.noResultsMessage) {
- this._renderNoResultsMessage(unzippedData);
- } else if (this.shown) {
- this.deactivate();
- }
- },
-
- setPosition: function (pos) {
- // Make the dropdown fixed if the input is also fixed
- // This can't be done during init, as textcomplete may be used on multiple elements on the same page
- // Because the same dropdown is reused behind the scenes, we need to recheck every time the dropdown is showed
- var position = 'absolute';
- // Check if input or one of its parents has positioning we need to care about
- this.$inputEl.add(this.$inputEl.parents()).each(function() {
- if($(this).css('position') === 'absolute') // The element has absolute positioning, so it's all OK
- return false;
- if($(this).css('position') === 'fixed') {
- pos.top -= $window.scrollTop();
- pos.left -= $window.scrollLeft();
- position = 'fixed';
- return false;
- }
- });
- this.$el.css(this._applyPlacement(pos));
- this.$el.css({ position: position }); // Update positioning
-
- return this;
- },
-
- clear: function () {
- this.$el.html('');
- this.data = [];
- this._index = 0;
- this._$header = this._$footer = this._$noResultsMessage = null;
- },
-
- activate: function () {
- if (!this.shown) {
- this.clear();
- this.$el.show();
- if (this.className) { this.$el.addClass(this.className); }
- this.completer.fire('textComplete:show');
- this.shown = true;
- }
- return this;
- },
-
- deactivate: function () {
- if (this.shown) {
- this.$el.hide();
- if (this.className) { this.$el.removeClass(this.className); }
- this.completer.fire('textComplete:hide');
- this.shown = false;
- }
- return this;
- },
-
- isUp: function (e) {
- return e.keyCode === 38 || (e.ctrlKey && e.keyCode === 80); // UP, Ctrl-P
- },
-
- isDown: function (e) {
- return e.keyCode === 40 || (e.ctrlKey && e.keyCode === 78); // DOWN, Ctrl-N
- },
-
- isEnter: function (e) {
- var modifiers = e.ctrlKey || e.altKey || e.metaKey || e.shiftKey;
- return !modifiers && (e.keyCode === 13 || e.keyCode === 9 || (this.option.completeOnSpace === true && e.keyCode === 32)) // ENTER, TAB
- },
-
- isPageup: function (e) {
- return e.keyCode === 33; // PAGEUP
- },
-
- isPagedown: function (e) {
- return e.keyCode === 34; // PAGEDOWN
- },
-
- isEscape: function (e) {
- return e.keyCode === 27; // ESCAPE
- },
-
- // Private properties
- // ------------------
-
- _data: null, // Currently shown zipped data.
- _index: null,
- _$header: null,
- _$noResultsMessage: null,
- _$footer: null,
-
- // Private methods
- // ---------------
-
- _bindEvents: function () {
- this.$el.on('mousedown.' + this.id, '.textcomplete-item', $.proxy(this._onClick, this));
- this.$el.on('touchstart.' + this.id, '.textcomplete-item', $.proxy(this._onClick, this));
- this.$el.on('mouseover.' + this.id, '.textcomplete-item', $.proxy(this._onMouseover, this));
- this.$inputEl.on('keydown.' + this.id, $.proxy(this._onKeydown, this));
- },
-
- _onClick: function (e) {
- var $el = $(e.target);
- e.preventDefault();
- e.originalEvent.keepTextCompleteDropdown = this.id;
- if (!$el.hasClass('textcomplete-item')) {
- $el = $el.closest('.textcomplete-item');
- }
- var datum = this.data[parseInt($el.data('index'), 10)];
- this.completer.select(datum.value, datum.strategy, e);
- var self = this;
- // Deactive at next tick to allow other event handlers to know whether
- // the dropdown has been shown or not.
- setTimeout(function () {
- self.deactivate();
- if (e.type === 'touchstart') {
- self.$inputEl.focus();
- }
- }, 0);
- },
-
- // Activate hovered item.
- _onMouseover: function (e) {
- var $el = $(e.target);
- e.preventDefault();
- if (!$el.hasClass('textcomplete-item')) {
- $el = $el.closest('.textcomplete-item');
- }
- this._index = parseInt($el.data('index'), 10);
- this._activateIndexedItem();
- },
-
- _onKeydown: function (e) {
- if (!this.shown) { return; }
-
- var command;
-
- if ($.isFunction(this.option.onKeydown)) {
- command = this.option.onKeydown(e, commands);
- }
-
- if (command == null) {
- command = this._defaultKeydown(e);
- }
-
- switch (command) {
- case commands.KEY_UP:
- e.preventDefault();
- this._up();
- break;
- case commands.KEY_DOWN:
- e.preventDefault();
- this._down();
- break;
- case commands.KEY_ENTER:
- e.preventDefault();
- this._enter(e);
- break;
- case commands.KEY_PAGEUP:
- e.preventDefault();
- this._pageup();
- break;
- case commands.KEY_PAGEDOWN:
- e.preventDefault();
- this._pagedown();
- break;
- case commands.KEY_ESCAPE:
- e.preventDefault();
- this.deactivate();
- break;
- }
- },
-
- _defaultKeydown: function (e) {
- if (this.isUp(e)) {
- return commands.KEY_UP;
- } else if (this.isDown(e)) {
- return commands.KEY_DOWN;
- } else if (this.isEnter(e)) {
- return commands.KEY_ENTER;
- } else if (this.isPageup(e)) {
- return commands.KEY_PAGEUP;
- } else if (this.isPagedown(e)) {
- return commands.KEY_PAGEDOWN;
- } else if (this.isEscape(e)) {
- return commands.KEY_ESCAPE;
- }
- },
-
- _up: function () {
- if (this._index === 0) {
- this._index = this.data.length - 1;
- } else {
- this._index -= 1;
- }
- this._activateIndexedItem();
- this._setScroll();
- },
-
- _down: function () {
- if (this._index === this.data.length - 1) {
- this._index = 0;
- } else {
- this._index += 1;
- }
- this._activateIndexedItem();
- this._setScroll();
- },
-
- _enter: function (e) {
- var datum = this.data[parseInt(this._getActiveElement().data('index'), 10)];
- this.completer.select(datum.value, datum.strategy, e);
- this.deactivate();
- },
-
- _pageup: function () {
- var target = 0;
- var threshold = this._getActiveElement().position().top - this.$el.innerHeight();
- this.$el.children().each(function (i) {
- if ($(this).position().top + $(this).outerHeight() > threshold) {
- target = i;
- return false;
- }
- });
- this._index = target;
- this._activateIndexedItem();
- this._setScroll();
- },
-
- _pagedown: function () {
- var target = this.data.length - 1;
- var threshold = this._getActiveElement().position().top + this.$el.innerHeight();
- this.$el.children().each(function (i) {
- if ($(this).position().top > threshold) {
- target = i;
- return false
- }
- });
- this._index = target;
- this._activateIndexedItem();
- this._setScroll();
- },
-
- _activateIndexedItem: function () {
- this.$el.find('.textcomplete-item.active').removeClass('active');
- this._getActiveElement().addClass('active');
- },
-
- _getActiveElement: function () {
- return this.$el.children('.textcomplete-item:nth(' + this._index + ')');
- },
-
- _setScroll: function () {
- var $activeEl = this._getActiveElement();
- var itemTop = $activeEl.position().top;
- var itemHeight = $activeEl.outerHeight();
- var visibleHeight = this.$el.innerHeight();
- var visibleTop = this.$el.scrollTop();
- if (this._index === 0 || this._index == this.data.length - 1 || itemTop < 0) {
- this.$el.scrollTop(itemTop + visibleTop);
- } else if (itemTop + itemHeight > visibleHeight) {
- this.$el.scrollTop(itemTop + itemHeight + visibleTop - visibleHeight);
- }
- },
-
- _buildContents: function (zippedData) {
- var datum, i, index;
- var html = '';
- for (i = 0; i < zippedData.length; i++) {
- if (this.data.length === this.maxCount) break;
- datum = zippedData[i];
- if (include(this.data, datum)) { continue; }
- index = this.data.length;
- this.data.push(datum);
- html += '<li class="textcomplete-item" data-index="' + index + '"><a>';
- html += datum.strategy.template(datum.value, datum.term);
- html += '</a></li>';
- }
- return html;
- },
-
- _renderHeader: function (unzippedData) {
- if (this.header) {
- if (!this._$header) {
- this._$header = $('<li class="textcomplete-header"></li>').prependTo(this.$el);
- }
- var html = $.isFunction(this.header) ? this.header(unzippedData) : this.header;
- this._$header.html(html);
- }
- },
-
- _renderFooter: function (unzippedData) {
- if (this.footer) {
- if (!this._$footer) {
- this._$footer = $('<li class="textcomplete-footer"></li>').appendTo(this.$el);
- }
- var html = $.isFunction(this.footer) ? this.footer(unzippedData) : this.footer;
- this._$footer.html(html);
- }
- },
-
- _renderNoResultsMessage: function (unzippedData) {
- if (this.noResultsMessage) {
- if (!this._$noResultsMessage) {
- this._$noResultsMessage = $('<li class="textcomplete-no-results-message"></li>').appendTo(this.$el);
- }
- var html = $.isFunction(this.noResultsMessage) ? this.noResultsMessage(unzippedData) : this.noResultsMessage;
- this._$noResultsMessage.html(html);
- }
- },
-
- _renderContents: function (html) {
- if (this._$footer) {
- this._$footer.before(html);
- } else {
- this.$el.append(html);
- }
- },
-
- _fitToBottom: function() {
- var windowScrollBottom = $window.scrollTop() + $window.height();
- var height = this.$el.height();
- if ((this.$el.position().top + height) > windowScrollBottom) {
- // only do this if we are not in an iframe
- if (!this.completer.$iframe) {
- this.$el.offset({top: windowScrollBottom - height});
- }
- }
- },
-
- _fitToRight: function() {
- // We don't know how wide our content is until the browser positions us, and at that point it clips us
- // to the document width so we don't know if we would have overrun it. As a heuristic to avoid that clipping
- // (which makes our elements wrap onto the next line and corrupt the next item), if we're close to the right
- // edge, move left. We don't know how far to move left, so just keep nudging a bit.
- var tolerance = this.option.rightEdgeOffset; // pixels. Make wider than vertical scrollbar because we might not be able to use that space.
- var lastOffset = this.$el.offset().left, offset;
- var width = this.$el.width();
- var maxLeft = $window.width() - tolerance;
- while (lastOffset + width > maxLeft) {
- this.$el.offset({left: lastOffset - tolerance});
- offset = this.$el.offset().left;
- if (offset >= lastOffset) { break; }
- lastOffset = offset;
- }
- },
-
- _applyPlacement: function (position) {
- // If the 'placement' option set to 'top', move the position above the element.
- if (this.placement.indexOf('top') !== -1) {
- // Overwrite the position object to set the 'bottom' property instead of the top.
- position = {
- top: 'auto',
- bottom: this.$el.parent().height() - position.top + position.lineHeight,
- left: position.left
- };
- } else {
- position.bottom = 'auto';
- delete position.lineHeight;
- }
- if (this.placement.indexOf('absleft') !== -1) {
- position.left = 0;
- } else if (this.placement.indexOf('absright') !== -1) {
- position.right = 0;
- position.left = 'auto';
- }
- return position;
- }
- });
-
- $.fn.textcomplete.Dropdown = Dropdown;
- $.extend($.fn.textcomplete, commands);
-}(jQuery);
-
-+function ($) {
- 'use strict';
-
- // Memoize a search function.
- var memoize = function (func) {
- var memo = {};
- return function (term, callback) {
- if (memo[term]) {
- callback(memo[term]);
- } else {
- func.call(this, term, function (data) {
- memo[term] = (memo[term] || []).concat(data);
- callback.apply(null, arguments);
- });
- }
- };
- };
-
- function Strategy(options) {
- $.extend(this, options);
- if (this.cache) { this.search = memoize(this.search); }
- }
-
- Strategy.parse = function (strategiesArray, params) {
- return $.map(strategiesArray, function (strategy) {
- var strategyObj = new Strategy(strategy);
- strategyObj.el = params.el;
- strategyObj.$el = params.$el;
- return strategyObj;
- });
- };
-
- $.extend(Strategy.prototype, {
- // Public properties
- // -----------------
-
- // Required
- match: null,
- replace: null,
- search: null,
-
- // Optional
- id: null,
- cache: false,
- context: function () { return true; },
- index: 2,
- template: function (obj) { return obj; },
- idProperty: null
- });
-
- $.fn.textcomplete.Strategy = Strategy;
-
-}(jQuery);
-
-+function ($) {
- 'use strict';
-
- var now = Date.now || function () { return new Date().getTime(); };
-
- // Returns a function, that, as long as it continues to be invoked, will not
- // be triggered. The function will be called after it stops being called for
- // `wait` msec.
- //
- // This utility function was originally implemented at Underscore.js.
- var debounce = function (func, wait) {
- var timeout, args, context, timestamp, result;
- var later = function () {
- var last = now() - timestamp;
- if (last < wait) {
- timeout = setTimeout(later, wait - last);
- } else {
- timeout = null;
- result = func.apply(context, args);
- context = args = null;
- }
- };
-
- return function () {
- context = this;
- args = arguments;
- timestamp = now();
- if (!timeout) {
- timeout = setTimeout(later, wait);
- }
- return result;
- };
- };
-
- function Adapter () {}
-
- $.extend(Adapter.prototype, {
- // Public properties
- // -----------------
-
- id: null, // Identity.
- completer: null, // Completer object which creates it.
- el: null, // Textarea element.
- $el: null, // jQuery object of the textarea.
- option: null,
-
- // Public methods
- // --------------
-
- initialize: function (element, completer, option) {
- this.el = element;
- this.$el = $(element);
- this.id = completer.id + this.constructor.name;
- this.completer = completer;
- this.option = option;
-
- if (this.option.debounce) {
- this._onKeyup = debounce(this._onKeyup, this.option.debounce);
- }
-
- this._bindEvents();
- },
-
- destroy: function () {
- this.$el.off('.' + this.id); // Remove all event handlers.
- this.$el = this.el = this.completer = null;
- },
-
- // Update the element with the given value and strategy.
- //
- // value - The selected object. It is one of the item of the array
- // which was callbacked from the search function.
- // strategy - The Strategy associated with the selected value.
- select: function (/* value, strategy */) {
- throw new Error('Not implemented');
- },
-
- // Returns the caret's relative coordinates from body's left top corner.
- getCaretPosition: function () {
- var position = this._getCaretRelativePosition();
- var offset = this.$el.offset();
-
- // Calculate the left top corner of `this.option.appendTo` element.
- var $parent = this.option.appendTo;
- if ($parent) {
- if (!($parent instanceof $)) { $parent = $($parent); }
- var parentOffset = $parent.offsetParent().offset();
- offset.top -= parentOffset.top;
- offset.left -= parentOffset.left;
- }
-
- position.top += offset.top;
- position.left += offset.left;
- return position;
- },
-
- // Focus on the element.
- focus: function () {
- this.$el.focus();
- },
-
- // Private methods
- // ---------------
-
- _bindEvents: function () {
- this.$el.on('keyup.' + this.id, $.proxy(this._onKeyup, this));
- },
-
- _onKeyup: function (e) {
- if (this._skipSearch(e)) { return; }
- this.completer.trigger(this.getTextFromHeadToCaret(), true);
- },
-
- // Suppress searching if it returns true.
- _skipSearch: function (clickEvent) {
- switch (clickEvent.keyCode) {
- case 9: // TAB
- case 13: // ENTER
- case 16: // SHIFT
- case 17: // CTRL
- case 18: // ALT
- case 33: // PAGEUP
- case 34: // PAGEDOWN
- case 40: // DOWN
- case 38: // UP
- case 27: // ESC
- return true;
- }
- if (clickEvent.ctrlKey) switch (clickEvent.keyCode) {
- case 78: // Ctrl-N
- case 80: // Ctrl-P
- return true;
- }
- }
- });
-
- $.fn.textcomplete.Adapter = Adapter;
-}(jQuery);
-
-+function ($) {
- 'use strict';
-
- // Textarea adapter
- // ================
- //
- // Managing a textarea. It doesn't know a Dropdown.
- function Textarea(element, completer, option) {
- this.initialize(element, completer, option);
- }
-
- $.extend(Textarea.prototype, $.fn.textcomplete.Adapter.prototype, {
- // Public methods
- // --------------
-
- // Update the textarea with the given value and strategy.
- select: function (value, strategy, e) {
- var pre = this.getTextFromHeadToCaret();
- var post = this.el.value.substring(this.el.selectionEnd);
- var newSubstr = strategy.replace(value, e);
- var regExp;
- if (typeof newSubstr !== 'undefined') {
- if ($.isArray(newSubstr)) {
- post = newSubstr[1] + post;
- newSubstr = newSubstr[0];
- }
- regExp = $.isFunction(strategy.match) ? strategy.match(pre) : strategy.match;
- pre = pre.replace(regExp, newSubstr);
- this.$el.val(pre + post);
- this.el.selectionStart = this.el.selectionEnd = pre.length;
- }
- },
-
- getTextFromHeadToCaret: function () {
- return this.el.value.substring(0, this.el.selectionEnd);
- },
-
- // Private methods
- // ---------------
-
- _getCaretRelativePosition: function () {
- var p = $.fn.textcomplete.getCaretCoordinates(this.el, this.el.selectionStart);
- return {
- top: p.top + this._calculateLineHeight() - this.$el.scrollTop(),
- left: p.left - this.$el.scrollLeft(),
- lineHeight: this._calculateLineHeight()
- };
- },
-
- _calculateLineHeight: function () {
- var lineHeight = parseInt(this.$el.css('line-height'), 10);
- if (isNaN(lineHeight)) {
- // http://stackoverflow.com/a/4515470/1297336
- var parentNode = this.el.parentNode;
- var temp = document.createElement(this.el.nodeName);
- var style = this.el.style;
- temp.setAttribute(
- 'style',
- 'margin:0px;padding:0px;font-family:' + style.fontFamily + ';font-size:' + style.fontSize
- );
- temp.innerHTML = 'test';
- parentNode.appendChild(temp);
- lineHeight = temp.clientHeight;
- parentNode.removeChild(temp);
- }
- return lineHeight;
- }
- });
-
- $.fn.textcomplete.Textarea = Textarea;
-}(jQuery);
-
-+function ($) {
- 'use strict';
-
- var sentinelChar = '吶';
-
- function IETextarea(element, completer, option) {
- this.initialize(element, completer, option);
- $('<span>' + sentinelChar + '</span>').css({
- position: 'absolute',
- top: -9999,
- left: -9999
- }).insertBefore(element);
- }
-
- $.extend(IETextarea.prototype, $.fn.textcomplete.Textarea.prototype, {
- // Public methods
- // --------------
-
- select: function (value, strategy, e) {
- var pre = this.getTextFromHeadToCaret();
- var post = this.el.value.substring(pre.length);
- var newSubstr = strategy.replace(value, e);
- var regExp;
- if (typeof newSubstr !== 'undefined') {
- if ($.isArray(newSubstr)) {
- post = newSubstr[1] + post;
- newSubstr = newSubstr[0];
- }
- regExp = $.isFunction(strategy.match) ? strategy.match(pre) : strategy.match;
- pre = pre.replace(regExp, newSubstr);
- this.$el.val(pre + post);
- this.el.focus();
- var range = this.el.createTextRange();
- range.collapse(true);
- range.moveEnd('character', pre.length);
- range.moveStart('character', pre.length);
- range.select();
- }
- },
-
- getTextFromHeadToCaret: function () {
- this.el.focus();
- var range = document.selection.createRange();
- range.moveStart('character', -this.el.value.length);
- var arr = range.text.split(sentinelChar)
- return arr.length === 1 ? arr[0] : arr[1];
- }
- });
-
- $.fn.textcomplete.IETextarea = IETextarea;
-}(jQuery);
-
-// NOTE: TextComplete plugin has contenteditable support but it does not work
-// fine especially on old IEs.
-// Any pull requests are REALLY welcome.
-
-+function ($) {
- 'use strict';
-
- // ContentEditable adapter
- // =======================
- //
- // Adapter for contenteditable elements.
- function ContentEditable (element, completer, option) {
- this.initialize(element, completer, option);
- }
-
- $.extend(ContentEditable.prototype, $.fn.textcomplete.Adapter.prototype, {
- // Public methods
- // --------------
-
- // Update the content with the given value and strategy.
- // When an dropdown item is selected, it is executed.
- select: function (value, strategy, e) {
- var pre = this.getTextFromHeadToCaret();
- // use ownerDocument instead of window to support iframes
- var sel = this.el.ownerDocument.getSelection();
-
- var range = sel.getRangeAt(0);
- var selection = range.cloneRange();
- selection.selectNodeContents(range.startContainer);
- var content = selection.toString();
- var post = content.substring(range.startOffset);
- var newSubstr = strategy.replace(value, e);
- var regExp;
- if (typeof newSubstr !== 'undefined') {
- if ($.isArray(newSubstr)) {
- post = newSubstr[1] + post;
- newSubstr = newSubstr[0];
- }
- regExp = $.isFunction(strategy.match) ? strategy.match(pre) : strategy.match;
- pre = pre.replace(regExp, newSubstr)
- .replace(/ $/, "&nbsp"); // &nbsp necessary at least for CKeditor to not eat spaces
- range.selectNodeContents(range.startContainer);
- range.deleteContents();
-
- // create temporary elements
- var preWrapper = this.el.ownerDocument.createElement("div");
- preWrapper.innerHTML = pre;
- var postWrapper = this.el.ownerDocument.createElement("div");
- postWrapper.innerHTML = post;
-
- // create the fragment thats inserted
- var fragment = this.el.ownerDocument.createDocumentFragment();
- var childNode;
- var lastOfPre;
- while (childNode = preWrapper.firstChild) {
- lastOfPre = fragment.appendChild(childNode);
- }
- while (childNode = postWrapper.firstChild) {
- fragment.appendChild(childNode);
- }
-
- // insert the fragment & jump behind the last node in "pre"
- range.insertNode(fragment);
- range.setStartAfter(lastOfPre);
-
- range.collapse(true);
- sel.removeAllRanges();
- sel.addRange(range);
- }
- },
-
- // Private methods
- // ---------------
-
- // Returns the caret's relative position from the contenteditable's
- // left top corner.
- //
- // Examples
- //
- // this._getCaretRelativePosition()
- // //=> { top: 18, left: 200, lineHeight: 16 }
- //
- // Dropdown's position will be decided using the result.
- _getCaretRelativePosition: function () {
- var range = this.el.ownerDocument.getSelection().getRangeAt(0).cloneRange();
- var node = this.el.ownerDocument.createElement('span');
- range.insertNode(node);
- range.selectNodeContents(node);
- range.deleteContents();
- var $node = $(node);
- var position = $node.offset();
- position.left -= this.$el.offset().left;
- position.top += $node.height() - this.$el.offset().top;
- position.lineHeight = $node.height();
-
- // special positioning logic for iframes
- // this is typically used for contenteditables such as tinymce or ckeditor
- if (this.completer.$iframe) {
- var iframePosition = this.completer.$iframe.offset();
- position.top += iframePosition.top;
- position.left += iframePosition.left;
- //subtract scrollTop from element in iframe
- position.top -= this.$el.scrollTop();
- }
-
- $node.remove();
- return position;
- },
-
- // Returns the string between the first character and the caret.
- // Completer will be triggered with the result for start autocompleting.
- //
- // Example
- //
- // // Suppose the html is '<b>hello</b> wor|ld' and | is the caret.
- // this.getTextFromHeadToCaret()
- // // => ' wor' // not '<b>hello</b> wor'
- getTextFromHeadToCaret: function () {
- var range = this.el.ownerDocument.getSelection().getRangeAt(0);
- var selection = range.cloneRange();
- selection.selectNodeContents(range.startContainer);
- return selection.toString().substring(0, range.startOffset);
- }
- });
-
- $.fn.textcomplete.ContentEditable = ContentEditable;
-}(jQuery);
-
-// NOTE: TextComplete plugin has contenteditable support but it does not work
-// fine especially on old IEs.
-// Any pull requests are REALLY welcome.
-
-+function ($) {
- 'use strict';
-
- // CKEditor adapter
- // =======================
- //
- // Adapter for CKEditor, based on contenteditable elements.
- function CKEditor (element, completer, option) {
- this.initialize(element, completer, option);
- }
-
- $.extend(CKEditor.prototype, $.fn.textcomplete.ContentEditable.prototype, {
- _bindEvents: function () {
- var $this = this;
- this.option.ckeditor_instance.on('key', function(event) {
- var domEvent = event.data;
- $this._onKeyup(domEvent);
- if ($this.completer.dropdown.shown && $this._skipSearch(domEvent)) {
- return false;
- }
- }, null, null, 1); // 1 = Priority = Important!
- // we actually also need the native event, as the CKEditor one is happening to late
- this.$el.on('keyup.' + this.id, $.proxy(this._onKeyup, this));
- },
-});
-
- $.fn.textcomplete.CKEditor = CKEditor;
-}(jQuery);
-
-// The MIT License (MIT)
-//
-// Copyright (c) 2015 Jonathan Ong me@jongleberry.com
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
-// associated documentation files (the "Software"), to deal in the Software without restriction,
-// including without limitation the rights to use, copy, modify, merge, publish, distribute,
-// sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all copies or
-// substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
-// NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-// https://github.com/component/textarea-caret-position
-
-(function ($) {
-
-// The properties that we copy into a mirrored div.
-// Note that some browsers, such as Firefox,
-// do not concatenate properties, i.e. padding-top, bottom etc. -> padding,
-// so we have to do every single property specifically.
-var properties = [
- 'direction', // RTL support
- 'boxSizing',
- 'width', // on Chrome and IE, exclude the scrollbar, so the mirror div wraps exactly as the textarea does
- 'height',
- 'overflowX',
- 'overflowY', // copy the scrollbar for IE
-
- 'borderTopWidth',
- 'borderRightWidth',
- 'borderBottomWidth',
- 'borderLeftWidth',
- 'borderStyle',
-
- 'paddingTop',
- 'paddingRight',
- 'paddingBottom',
- 'paddingLeft',
-
- // https://developer.mozilla.org/en-US/docs/Web/CSS/font
- 'fontStyle',
- 'fontVariant',
- 'fontWeight',
- 'fontStretch',
- 'fontSize',
- 'fontSizeAdjust',
- 'lineHeight',
- 'fontFamily',
-
- 'textAlign',
- 'textTransform',
- 'textIndent',
- 'textDecoration', // might not make a difference, but better be safe
-
- 'letterSpacing',
- 'wordSpacing',
-
- 'tabSize',
- 'MozTabSize'
-
-];
-
-var isBrowser = (typeof window !== 'undefined');
-var isFirefox = (isBrowser && window.mozInnerScreenX != null);
-
-function getCaretCoordinates(element, position, options) {
- if(!isBrowser) {
- throw new Error('textarea-caret-position#getCaretCoordinates should only be called in a browser');
- }
-
- var debug = options && options.debug || false;
- if (debug) {
- var el = document.querySelector('#input-textarea-caret-position-mirror-div');
- if ( el ) { el.parentNode.removeChild(el); }
- }
-
- // mirrored div
- var div = document.createElement('div');
- div.id = 'input-textarea-caret-position-mirror-div';
- document.body.appendChild(div);
-
- var style = div.style;
- var computed = window.getComputedStyle? getComputedStyle(element) : element.currentStyle; // currentStyle for IE < 9
-
- // default textarea styles
- style.whiteSpace = 'pre-wrap';
- if (element.nodeName !== 'INPUT')
- style.wordWrap = 'break-word'; // only for textarea-s
-
- // position off-screen
- style.position = 'absolute'; // required to return coordinates properly
- if (!debug)
- style.visibility = 'hidden'; // not 'display: none' because we want rendering
-
- // transfer the element's properties to the div
- properties.forEach(function (prop) {
- style[prop] = computed[prop];
- });
-
- if (isFirefox) {
- // Firefox lies about the overflow property for textareas: https://bugzilla.mozilla.org/show_bug.cgi?id=984275
- if (element.scrollHeight > parseInt(computed.height))
- style.overflowY = 'scroll';
- } else {
- style.overflow = 'hidden'; // for Chrome to not render a scrollbar; IE keeps overflowY = 'scroll'
- }
-
- div.textContent = element.value.substring(0, position);
- // the second special handling for input type="text" vs textarea: spaces need to be replaced with non-breaking spaces - http://stackoverflow.com/a/13402035/1269037
- if (element.nodeName === 'INPUT')
- div.textContent = div.textContent.replace(/\s/g, '\u00a0');
-
- var span = document.createElement('span');
- // Wrapping must be replicated *exactly*, including when a long word gets
- // onto the next line, with whitespace at the end of the line before (#7).
- // The *only* reliable way to do that is to copy the *entire* rest of the
- // textarea's content into the <span> created at the caret position.
- // for inputs, just '.' would be enough, but why bother?
- span.textContent = element.value.substring(position) || '.'; // || because a completely empty faux span doesn't render at all
- div.appendChild(span);
-
- var coordinates = {
- top: span.offsetTop + parseInt(computed['borderTopWidth']),
- left: span.offsetLeft + parseInt(computed['borderLeftWidth'])
- };
-
- if (debug) {
- span.style.backgroundColor = '#aaa';
- } else {
- document.body.removeChild(div);
- }
-
- return coordinates;
-}
-
-$.fn.textcomplete.getCaretCoordinates = getCaretCoordinates;
-
-}(jQuery));
-
-return jQuery;
-}));
diff --git a/library/jquery-textcomplete/jquery.textcomplete.min.js b/library/jquery-textcomplete/jquery.textcomplete.min.js
deleted file mode 100644
index d8f67a804..000000000
--- a/library/jquery-textcomplete/jquery.textcomplete.min.js
+++ /dev/null
@@ -1,3 +0,0 @@
-/*! jquery-textcomplete - v1.8.0 - 2016-11-15 */
-!function(a){if("function"==typeof define&&define.amd)define(["jquery"],a);else if("object"==typeof module&&module.exports){var b=require("jquery");module.exports=a(b)}else a(jQuery)}(function(a){if("undefined"==typeof a)throw new Error("jQuery.textcomplete requires jQuery");return+function(a){"use strict";var b=function(a){console.warn&&console.warn(a)},c=1;a.fn.textcomplete=function(d,e){var f=Array.prototype.slice.call(arguments);return this.each(function(){var g=this,h=a(this),i=h.data("textComplete");if(i||(e||(e={}),e._oid=c++,i=new a.fn.textcomplete.Completer(this,e),h.data("textComplete",i)),"string"==typeof d){if(!i)return;f.shift(),i[d].apply(i,f),"destroy"===d&&h.removeData("textComplete")}else a.each(d,function(c){a.each(["header","footer","placement","maxCount"],function(a){c[a]&&(i.option[a]=c[a],b(a+"as a strategy param is deprecated. Use option."),delete c[a])})}),i.register(a.fn.textcomplete.Strategy.parse(d,{el:g,$el:h}))})}}(a),+function(a){"use strict";function b(c,d){if(this.$el=a(c),this.id="textcomplete"+e++,this.strategies=[],this.views=[],this.option=a.extend({},b.defaults,d),!(this.$el.is("input[type=text]")||this.$el.is("input[type=search]")||this.$el.is("textarea")||c.isContentEditable||"true"==c.contentEditable))throw new Error("textcomplete must be called on a Textarea or a ContentEditable.");if(c===c.ownerDocument.activeElement)this.initialize();else{var f=this;this.$el.one("focus."+this.id,function(){f.initialize()}),this.option.adapter&&"CKEditor"!=this.option.adapter||"undefined"==typeof CKEDITOR||!this.$el.is("textarea")||CKEDITOR.on("instanceReady",function(b){b.editor.once("focus",function(c){f.$el=a(b.editor.editable().$),f.option.adapter||(f.option.adapter=a.fn.textcomplete.CKEditor,f.option.ckeditor_instance=b.editor),f.initialize()})})}}var c=function(a){var b,c;return function(){var d=Array.prototype.slice.call(arguments);if(b)return void(c=d);b=!0;var e=this;d.unshift(function f(){if(c){var d=c;c=void 0,d.unshift(f),a.apply(e,d)}else b=!1}),a.apply(this,d)}},d=function(a){return"[object String]"===Object.prototype.toString.call(a)},e=0;b.defaults={appendTo:"body",className:"",dropdownClassName:"dropdown-menu textcomplete-dropdown",maxCount:10,zIndex:"100",rightEdgeOffset:30},a.extend(b.prototype,{id:null,option:null,strategies:null,adapter:null,dropdown:null,$el:null,$iframe:null,initialize:function(){var b=this.$el.get(0);if(this.$el.prop("ownerDocument")!==document&&window.frames.length)for(var c=0;c<window.frames.length;c++)if(this.$el.prop("ownerDocument")===window.frames[c].document){this.$iframe=a(window.frames[c].frameElement);break}this.dropdown=new a.fn.textcomplete.Dropdown(b,this,this.option);var d,e;this.option.adapter?d=this.option.adapter:(e=this.$el.is("textarea")||this.$el.is("input[type=text]")||this.$el.is("input[type=search]")?"number"==typeof b.selectionEnd?"Textarea":"IETextarea":"ContentEditable",d=a.fn.textcomplete[e]),this.adapter=new d(b,this,this.option)},destroy:function(){this.$el.off("."+this.id),this.adapter&&this.adapter.destroy(),this.dropdown&&this.dropdown.destroy(),this.$el=this.adapter=this.dropdown=null},deactivate:function(){this.dropdown&&this.dropdown.deactivate()},trigger:function(a,b){this.dropdown||this.initialize(),null!=a||(a=this.adapter.getTextFromHeadToCaret());var c=this._extractSearchQuery(a);if(c.length){var d=c[1];if(b&&this._term===d&&""!==d)return;this._term=d,this._search.apply(this,c)}else this._term=null,this.dropdown.deactivate()},fire:function(a){var b=Array.prototype.slice.call(arguments,1);return this.$el.trigger(a,b),this},register:function(a){Array.prototype.push.apply(this.strategies,a)},select:function(a,b,c){this._term=null,this.adapter.select(a,b,c),this.fire("change").fire("textComplete:select",a,b),this.adapter.focus()},_clearAtNext:!0,_term:null,_extractSearchQuery:function(b){for(var c=0;c<this.strategies.length;c++){var e=this.strategies[c],f=e.context(b);if(f||""===f){var g=a.isFunction(e.match)?e.match(b):e.match;d(f)&&(b=f);var h=b.match(g);if(h)return[e,h[e.index],h]}}return[]},_search:c(function(a,b,c,d){var e=this;b.search(c,function(d,f){e.dropdown.shown||e.dropdown.activate(),e._clearAtNext&&(e.dropdown.clear(),e._clearAtNext=!1),e.dropdown.setPosition(e.adapter.getCaretPosition()),e.dropdown.render(e._zip(d,b,c)),f||(a(),e._clearAtNext=!0)},d)}),_zip:function(b,c,d){return a.map(b,function(a){return{value:a,strategy:c,term:d}})}}),a.fn.textcomplete.Completer=b}(a),+function(a){"use strict";function b(c,d,f){this.$el=b.createElement(f),this.completer=d,this.id=d.id+"dropdown",this._data=[],this.$inputEl=a(c),this.option=f,f.listPosition&&(this.setPosition=f.listPosition),f.height&&this.$el.height(f.height);var g=this;a.each(["maxCount","placement","footer","header","noResultsMessage","className"],function(a,b){null!=f[b]&&(g[b]=f[b])}),this._bindEvents(c),e[this.id]=this}var c=a(window),d=function(a,b){var c,d,e=b.strategy.idProperty;for(c=0;c<a.length;c++)if(d=a[c],d.strategy===b.strategy)if(e){if(d.value[e]===b.value[e])return!0}else if(d.value===b.value)return!0;return!1},e={};a(document).on("click",function(b){var c=b.originalEvent&&b.originalEvent.keepTextCompleteDropdown;a.each(e,function(a,b){a!==c&&b.deactivate()})});var f={SKIP_DEFAULT:0,KEY_UP:1,KEY_DOWN:2,KEY_ENTER:3,KEY_PAGEUP:4,KEY_PAGEDOWN:5,KEY_ESCAPE:6};a.extend(b,{createElement:function(b){var c=b.appendTo;c instanceof a||(c=a(c));var d=a("<ul></ul>").addClass(b.dropdownClassName).attr("id","textcomplete-dropdown-"+b._oid).css({display:"none",left:0,position:"absolute",zIndex:b.zIndex}).appendTo(c);return d}}),a.extend(b.prototype,{$el:null,$inputEl:null,completer:null,footer:null,header:null,id:null,maxCount:null,placement:"",shown:!1,data:[],className:"",destroy:function(){this.deactivate(),this.$el.off("."+this.id),this.$inputEl.off("."+this.id),this.clear(),this.$el.remove(),this.$el=this.$inputEl=this.completer=null,delete e[this.id]},render:function(b){var c=this._buildContents(b),d=a.map(b,function(a){return a.value});if(b.length){var e=b[0].strategy;e.id?this.$el.attr("data-strategy",e.id):this.$el.removeAttr("data-strategy"),this._renderHeader(d),this._renderFooter(d),c&&(this._renderContents(c),this._fitToBottom(),this._fitToRight(),this._activateIndexedItem()),this._setScroll()}else this.noResultsMessage?this._renderNoResultsMessage(d):this.shown&&this.deactivate()},setPosition:function(b){var d="absolute";return this.$inputEl.add(this.$inputEl.parents()).each(function(){return"absolute"===a(this).css("position")?!1:"fixed"===a(this).css("position")?(b.top-=c.scrollTop(),b.left-=c.scrollLeft(),d="fixed",!1):void 0}),this.$el.css(this._applyPlacement(b)),this.$el.css({position:d}),this},clear:function(){this.$el.html(""),this.data=[],this._index=0,this._$header=this._$footer=this._$noResultsMessage=null},activate:function(){return this.shown||(this.clear(),this.$el.show(),this.className&&this.$el.addClass(this.className),this.completer.fire("textComplete:show"),this.shown=!0),this},deactivate:function(){return this.shown&&(this.$el.hide(),this.className&&this.$el.removeClass(this.className),this.completer.fire("textComplete:hide"),this.shown=!1),this},isUp:function(a){return 38===a.keyCode||a.ctrlKey&&80===a.keyCode},isDown:function(a){return 40===a.keyCode||a.ctrlKey&&78===a.keyCode},isEnter:function(a){var b=a.ctrlKey||a.altKey||a.metaKey||a.shiftKey;return!b&&(13===a.keyCode||9===a.keyCode||this.option.completeOnSpace===!0&&32===a.keyCode)},isPageup:function(a){return 33===a.keyCode},isPagedown:function(a){return 34===a.keyCode},isEscape:function(a){return 27===a.keyCode},_data:null,_index:null,_$header:null,_$noResultsMessage:null,_$footer:null,_bindEvents:function(){this.$el.on("mousedown."+this.id,".textcomplete-item",a.proxy(this._onClick,this)),this.$el.on("touchstart."+this.id,".textcomplete-item",a.proxy(this._onClick,this)),this.$el.on("mouseover."+this.id,".textcomplete-item",a.proxy(this._onMouseover,this)),this.$inputEl.on("keydown."+this.id,a.proxy(this._onKeydown,this))},_onClick:function(b){var c=a(b.target);b.preventDefault(),b.originalEvent.keepTextCompleteDropdown=this.id,c.hasClass("textcomplete-item")||(c=c.closest(".textcomplete-item"));var d=this.data[parseInt(c.data("index"),10)];this.completer.select(d.value,d.strategy,b);var e=this;setTimeout(function(){e.deactivate(),"touchstart"===b.type&&e.$inputEl.focus()},0)},_onMouseover:function(b){var c=a(b.target);b.preventDefault(),c.hasClass("textcomplete-item")||(c=c.closest(".textcomplete-item")),this._index=parseInt(c.data("index"),10),this._activateIndexedItem()},_onKeydown:function(b){if(this.shown){var c;switch(a.isFunction(this.option.onKeydown)&&(c=this.option.onKeydown(b,f)),null==c&&(c=this._defaultKeydown(b)),c){case f.KEY_UP:b.preventDefault(),this._up();break;case f.KEY_DOWN:b.preventDefault(),this._down();break;case f.KEY_ENTER:b.preventDefault(),this._enter(b);break;case f.KEY_PAGEUP:b.preventDefault(),this._pageup();break;case f.KEY_PAGEDOWN:b.preventDefault(),this._pagedown();break;case f.KEY_ESCAPE:b.preventDefault(),this.deactivate()}}},_defaultKeydown:function(a){return this.isUp(a)?f.KEY_UP:this.isDown(a)?f.KEY_DOWN:this.isEnter(a)?f.KEY_ENTER:this.isPageup(a)?f.KEY_PAGEUP:this.isPagedown(a)?f.KEY_PAGEDOWN:this.isEscape(a)?f.KEY_ESCAPE:void 0},_up:function(){0===this._index?this._index=this.data.length-1:this._index-=1,this._activateIndexedItem(),this._setScroll()},_down:function(){this._index===this.data.length-1?this._index=0:this._index+=1,this._activateIndexedItem(),this._setScroll()},_enter:function(a){var b=this.data[parseInt(this._getActiveElement().data("index"),10)];this.completer.select(b.value,b.strategy,a),this.deactivate()},_pageup:function(){var b=0,c=this._getActiveElement().position().top-this.$el.innerHeight();this.$el.children().each(function(d){return a(this).position().top+a(this).outerHeight()>c?(b=d,!1):void 0}),this._index=b,this._activateIndexedItem(),this._setScroll()},_pagedown:function(){var b=this.data.length-1,c=this._getActiveElement().position().top+this.$el.innerHeight();this.$el.children().each(function(d){return a(this).position().top>c?(b=d,!1):void 0}),this._index=b,this._activateIndexedItem(),this._setScroll()},_activateIndexedItem:function(){this.$el.find(".textcomplete-item.active").removeClass("active"),this._getActiveElement().addClass("active")},_getActiveElement:function(){return this.$el.children(".textcomplete-item:nth("+this._index+")")},_setScroll:function(){var a=this._getActiveElement(),b=a.position().top,c=a.outerHeight(),d=this.$el.innerHeight(),e=this.$el.scrollTop();0===this._index||this._index==this.data.length-1||0>b?this.$el.scrollTop(b+e):b+c>d&&this.$el.scrollTop(b+c+e-d)},_buildContents:function(a){var b,c,e,f="";for(c=0;c<a.length&&this.data.length!==this.maxCount;c++)b=a[c],d(this.data,b)||(e=this.data.length,this.data.push(b),f+='<li class="textcomplete-item" data-index="'+e+'"><a>',f+=b.strategy.template(b.value,b.term),f+="</a></li>");return f},_renderHeader:function(b){if(this.header){this._$header||(this._$header=a('<li class="textcomplete-header"></li>').prependTo(this.$el));var c=a.isFunction(this.header)?this.header(b):this.header;this._$header.html(c)}},_renderFooter:function(b){if(this.footer){this._$footer||(this._$footer=a('<li class="textcomplete-footer"></li>').appendTo(this.$el));var c=a.isFunction(this.footer)?this.footer(b):this.footer;this._$footer.html(c)}},_renderNoResultsMessage:function(b){if(this.noResultsMessage){this._$noResultsMessage||(this._$noResultsMessage=a('<li class="textcomplete-no-results-message"></li>').appendTo(this.$el));var c=a.isFunction(this.noResultsMessage)?this.noResultsMessage(b):this.noResultsMessage;this._$noResultsMessage.html(c)}},_renderContents:function(a){this._$footer?this._$footer.before(a):this.$el.append(a)},_fitToBottom:function(){var a=c.scrollTop()+c.height(),b=this.$el.height();this.$el.position().top+b>a&&(this.completer.$iframe||this.$el.offset({top:a-b}))},_fitToRight:function(){for(var a,b=this.option.rightEdgeOffset,d=this.$el.offset().left,e=this.$el.width(),f=c.width()-b;d+e>f&&(this.$el.offset({left:d-b}),a=this.$el.offset().left,!(a>=d));)d=a},_applyPlacement:function(a){return-1!==this.placement.indexOf("top")?a={top:"auto",bottom:this.$el.parent().height()-a.top+a.lineHeight,left:a.left}:(a.bottom="auto",delete a.lineHeight),-1!==this.placement.indexOf("absleft")?a.left=0:-1!==this.placement.indexOf("absright")&&(a.right=0,a.left="auto"),a}}),a.fn.textcomplete.Dropdown=b,a.extend(a.fn.textcomplete,f)}(a),+function(a){"use strict";function b(b){a.extend(this,b),this.cache&&(this.search=c(this.search))}var c=function(a){var b={};return function(c,d){b[c]?d(b[c]):a.call(this,c,function(a){b[c]=(b[c]||[]).concat(a),d.apply(null,arguments)})}};b.parse=function(c,d){return a.map(c,function(a){var c=new b(a);return c.el=d.el,c.$el=d.$el,c})},a.extend(b.prototype,{match:null,replace:null,search:null,id:null,cache:!1,context:function(){return!0},index:2,template:function(a){return a},idProperty:null}),a.fn.textcomplete.Strategy=b}(a),+function(a){"use strict";function b(){}var c=Date.now||function(){return(new Date).getTime()},d=function(a,b){var d,e,f,g,h,i=function(){var j=c()-g;b>j?d=setTimeout(i,b-j):(d=null,h=a.apply(f,e),f=e=null)};return function(){return f=this,e=arguments,g=c(),d||(d=setTimeout(i,b)),h}};a.extend(b.prototype,{id:null,completer:null,el:null,$el:null,option:null,initialize:function(b,c,e){this.el=b,this.$el=a(b),this.id=c.id+this.constructor.name,this.completer=c,this.option=e,this.option.debounce&&(this._onKeyup=d(this._onKeyup,this.option.debounce)),this._bindEvents()},destroy:function(){this.$el.off("."+this.id),this.$el=this.el=this.completer=null},select:function(){throw new Error("Not implemented")},getCaretPosition:function(){var b=this._getCaretRelativePosition(),c=this.$el.offset(),d=this.option.appendTo;if(d){d instanceof a||(d=a(d));var e=d.offsetParent().offset();c.top-=e.top,c.left-=e.left}return b.top+=c.top,b.left+=c.left,b},focus:function(){this.$el.focus()},_bindEvents:function(){this.$el.on("keyup."+this.id,a.proxy(this._onKeyup,this))},_onKeyup:function(a){this._skipSearch(a)||this.completer.trigger(this.getTextFromHeadToCaret(),!0)},_skipSearch:function(a){switch(a.keyCode){case 9:case 13:case 16:case 17:case 18:case 33:case 34:case 40:case 38:case 27:return!0}if(a.ctrlKey)switch(a.keyCode){case 78:case 80:return!0}}}),a.fn.textcomplete.Adapter=b}(a),+function(a){"use strict";function b(a,b,c){this.initialize(a,b,c)}a.extend(b.prototype,a.fn.textcomplete.Adapter.prototype,{select:function(b,c,d){var e,f=this.getTextFromHeadToCaret(),g=this.el.value.substring(this.el.selectionEnd),h=c.replace(b,d);"undefined"!=typeof h&&(a.isArray(h)&&(g=h[1]+g,h=h[0]),e=a.isFunction(c.match)?c.match(f):c.match,f=f.replace(e,h),this.$el.val(f+g),this.el.selectionStart=this.el.selectionEnd=f.length)},getTextFromHeadToCaret:function(){return this.el.value.substring(0,this.el.selectionEnd)},_getCaretRelativePosition:function(){var b=a.fn.textcomplete.getCaretCoordinates(this.el,this.el.selectionStart);return{top:b.top+this._calculateLineHeight()-this.$el.scrollTop(),left:b.left-this.$el.scrollLeft(),lineHeight:this._calculateLineHeight()}},_calculateLineHeight:function(){var a=parseInt(this.$el.css("line-height"),10);if(isNaN(a)){var b=this.el.parentNode,c=document.createElement(this.el.nodeName),d=this.el.style;c.setAttribute("style","margin:0px;padding:0px;font-family:"+d.fontFamily+";font-size:"+d.fontSize),c.innerHTML="test",b.appendChild(c),a=c.clientHeight,b.removeChild(c)}return a}}),a.fn.textcomplete.Textarea=b}(a),+function(a){"use strict";function b(b,d,e){this.initialize(b,d,e),a("<span>"+c+"</span>").css({position:"absolute",top:-9999,left:-9999}).insertBefore(b)}var c="吶";a.extend(b.prototype,a.fn.textcomplete.Textarea.prototype,{select:function(b,c,d){var e,f=this.getTextFromHeadToCaret(),g=this.el.value.substring(f.length),h=c.replace(b,d);if("undefined"!=typeof h){a.isArray(h)&&(g=h[1]+g,h=h[0]),e=a.isFunction(c.match)?c.match(f):c.match,f=f.replace(e,h),this.$el.val(f+g),this.el.focus();var i=this.el.createTextRange();i.collapse(!0),i.moveEnd("character",f.length),i.moveStart("character",f.length),i.select()}},getTextFromHeadToCaret:function(){this.el.focus();var a=document.selection.createRange();a.moveStart("character",-this.el.value.length);var b=a.text.split(c);return 1===b.length?b[0]:b[1]}}),a.fn.textcomplete.IETextarea=b}(a),+function(a){"use strict";function b(a,b,c){this.initialize(a,b,c)}a.extend(b.prototype,a.fn.textcomplete.Adapter.prototype,{select:function(b,c,d){var e=this.getTextFromHeadToCaret(),f=this.el.ownerDocument.getSelection(),g=f.getRangeAt(0),h=g.cloneRange();h.selectNodeContents(g.startContainer);var i,j=h.toString(),k=j.substring(g.startOffset),l=c.replace(b,d);if("undefined"!=typeof l){a.isArray(l)&&(k=l[1]+k,l=l[0]),i=a.isFunction(c.match)?c.match(e):c.match,e=e.replace(i,l).replace(/ $/,"&nbsp"),g.selectNodeContents(g.startContainer),g.deleteContents();var m=this.el.ownerDocument.createElement("div");m.innerHTML=e;var n=this.el.ownerDocument.createElement("div");n.innerHTML=k;for(var o,p,q=this.el.ownerDocument.createDocumentFragment();o=m.firstChild;)p=q.appendChild(o);for(;o=n.firstChild;)q.appendChild(o);g.insertNode(q),g.setStartAfter(p),g.collapse(!0),f.removeAllRanges(),f.addRange(g)}},_getCaretRelativePosition:function(){var b=this.el.ownerDocument.getSelection().getRangeAt(0).cloneRange(),c=this.el.ownerDocument.createElement("span");b.insertNode(c),b.selectNodeContents(c),b.deleteContents();var d=a(c),e=d.offset();if(e.left-=this.$el.offset().left,e.top+=d.height()-this.$el.offset().top,e.lineHeight=d.height(),this.completer.$iframe){var f=this.completer.$iframe.offset();e.top+=f.top,e.left+=f.left,e.top-=this.$el.scrollTop()}return d.remove(),e},getTextFromHeadToCaret:function(){var a=this.el.ownerDocument.getSelection().getRangeAt(0),b=a.cloneRange();return b.selectNodeContents(a.startContainer),b.toString().substring(0,a.startOffset)}}),a.fn.textcomplete.ContentEditable=b}(a),+function(a){"use strict";function b(a,b,c){this.initialize(a,b,c)}a.extend(b.prototype,a.fn.textcomplete.ContentEditable.prototype,{_bindEvents:function(){var b=this;this.option.ckeditor_instance.on("key",function(a){var c=a.data;return b._onKeyup(c),b.completer.dropdown.shown&&b._skipSearch(c)?!1:void 0},null,null,1),this.$el.on("keyup."+this.id,a.proxy(this._onKeyup,this))}}),a.fn.textcomplete.CKEditor=b}(a),function(a){function b(a,b,f){if(!d)throw new Error("textarea-caret-position#getCaretCoordinates should only be called in a browser");var g=f&&f.debug||!1;if(g){var h=document.querySelector("#input-textarea-caret-position-mirror-div");h&&h.parentNode.removeChild(h)}var i=document.createElement("div");i.id="input-textarea-caret-position-mirror-div",document.body.appendChild(i);var j=i.style,k=window.getComputedStyle?getComputedStyle(a):a.currentStyle;j.whiteSpace="pre-wrap","INPUT"!==a.nodeName&&(j.wordWrap="break-word"),j.position="absolute",g||(j.visibility="hidden"),c.forEach(function(a){j[a]=k[a]}),e?a.scrollHeight>parseInt(k.height)&&(j.overflowY="scroll"):j.overflow="hidden",i.textContent=a.value.substring(0,b),"INPUT"===a.nodeName&&(i.textContent=i.textContent.replace(/\s/g," "));var l=document.createElement("span");l.textContent=a.value.substring(b)||".",i.appendChild(l);var m={top:l.offsetTop+parseInt(k.borderTopWidth),left:l.offsetLeft+parseInt(k.borderLeftWidth)};return g?l.style.backgroundColor="#aaa":document.body.removeChild(i),m}var c=["direction","boxSizing","width","height","overflowX","overflowY","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","borderStyle","paddingTop","paddingRight","paddingBottom","paddingLeft","fontStyle","fontVariant","fontWeight","fontStretch","fontSize","fontSizeAdjust","lineHeight","fontFamily","textAlign","textTransform","textIndent","textDecoration","letterSpacing","wordSpacing","tabSize","MozTabSize"],d="undefined"!=typeof window,e=d&&null!=window.mozInnerScreenX;a.fn.textcomplete.getCaretCoordinates=b}(a),a});
-//# sourceMappingURL=dist/jquery.textcomplete.min.map \ No newline at end of file
diff --git a/library/jquery-textcomplete/jquery.textcomplete.min.map b/library/jquery-textcomplete/jquery.textcomplete.min.map
deleted file mode 100644
index 0e249c1c4..000000000
--- a/library/jquery-textcomplete/jquery.textcomplete.min.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"dist/jquery.textcomplete.min.js","sources":["dist/jquery.textcomplete.js"],"names":["factory","define","amd","module","exports","$","require","jQuery","Error","warn","message","console","id","fn","textcomplete","strategies","option","args","Array","prototype","slice","call","arguments","this","each","self","$this","completer","data","_oid","Completer","shift","apply","removeData","obj","name","register","Strategy","parse","el","$el","element","uniqueId","views","extend","defaults","is","isContentEditable","contentEditable","ownerDocument","activeElement","initialize","one","adapter","CKEDITOR","on","event","editor","once","event2","editable","ckeditor_instance","lock","func","locked","queuedArgsToReplay","unshift","replayOrFree","replayArgs","undefined","isString","Object","toString","appendTo","className","dropdownClassName","maxCount","zIndex","rightEdgeOffset","dropdown","$iframe","get","prop","document","window","frames","length","iframeIndex","frameElement","Dropdown","Adapter","viewName","selectionEnd","destroy","off","deactivate","trigger","text","skipUnchangedTerm","getTextFromHeadToCaret","searchQuery","_extractSearchQuery","term","_term","_search","fire","eventName","push","select","value","strategy","e","focus","_clearAtNext","i","context","matchRegexp","isFunction","match","index","free","search","stillSearching","shown","activate","clear","setPosition","getCaretPosition","render","_zip","map","createElement","_data","$inputEl","listPosition","height","_i","_bindEvents","dropdownViews","$window","include","zippedData","datum","elem","idProperty","originalEvent","keepTextCompleteDropdown","key","view","commands","SKIP_DEFAULT","KEY_UP","KEY_DOWN","KEY_ENTER","KEY_PAGEUP","KEY_PAGEDOWN","KEY_ESCAPE","$parent","addClass","attr","css","display","left","position","footer","header","placement","remove","contentsHtml","_buildContents","unzippedData","d","removeAttr","_renderHeader","_renderFooter","_renderContents","_fitToBottom","_fitToRight","_activateIndexedItem","_setScroll","noResultsMessage","_renderNoResultsMessage","pos","add","parents","top","scrollTop","scrollLeft","_applyPlacement","html","_index","_$header","_$footer","_$noResultsMessage","show","hide","removeClass","isUp","keyCode","ctrlKey","isDown","isEnter","modifiers","altKey","metaKey","shiftKey","completeOnSpace","isPageup","isPagedown","isEscape","proxy","_onClick","_onMouseover","_onKeydown","target","preventDefault","hasClass","closest","parseInt","setTimeout","type","command","onKeydown","_defaultKeydown","_up","_down","_enter","_pageup","_pagedown","_getActiveElement","threshold","innerHeight","children","outerHeight","find","$activeEl","itemTop","itemHeight","visibleHeight","visibleTop","template","prependTo","before","append","windowScrollBottom","offset","tolerance","lastOffset","width","maxLeft","indexOf","bottom","parent","lineHeight","right","options","cache","memoize","memo","callback","concat","strategiesArray","params","strategyObj","replace","now","Date","getTime","debounce","wait","timeout","timestamp","result","later","last","constructor","_onKeyup","_getCaretRelativePosition","parentOffset","offsetParent","_skipSearch","clickEvent","Textarea","regExp","pre","post","substring","newSubstr","isArray","val","selectionStart","p","getCaretCoordinates","_calculateLineHeight","isNaN","parentNode","temp","nodeName","style","setAttribute","fontFamily","fontSize","innerHTML","appendChild","clientHeight","removeChild","IETextarea","sentinelChar","insertBefore","range","createTextRange","collapse","moveEnd","moveStart","selection","createRange","arr","split","ContentEditable","sel","getSelection","getRangeAt","cloneRange","selectNodeContents","startContainer","content","startOffset","deleteContents","preWrapper","postWrapper","childNode","lastOfPre","fragment","createDocumentFragment","firstChild","insertNode","setStartAfter","removeAllRanges","addRange","node","$node","iframePosition","CKEditor","domEvent","isBrowser","debug","querySelector","div","body","computed","getComputedStyle","currentStyle","whiteSpace","wordWrap","visibility","properties","forEach","isFirefox","scrollHeight","overflowY","overflow","textContent","span","coordinates","offsetTop","offsetLeft","backgroundColor","mozInnerScreenX"],"mappings":"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"} \ No newline at end of file
diff --git a/library/textcomplete/textcomplete.js b/library/textcomplete/textcomplete.js
new file mode 100644
index 000000000..5134be691
--- /dev/null
+++ b/library/textcomplete/textcomplete.js
@@ -0,0 +1,2409 @@
+/******/ (function(modules) { // webpackBootstrap
+/******/ // The module cache
+/******/ var installedModules = {};
+/******/
+/******/ // The require function
+/******/ function __webpack_require__(moduleId) {
+/******/
+/******/ // Check if module is in cache
+/******/ if(installedModules[moduleId]) {
+/******/ return installedModules[moduleId].exports;
+/******/ }
+/******/ // Create a new module (and put it into the cache)
+/******/ var module = installedModules[moduleId] = {
+/******/ i: moduleId,
+/******/ l: false,
+/******/ exports: {}
+/******/ };
+/******/
+/******/ // Execute the module function
+/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ // Flag the module as loaded
+/******/ module.l = true;
+/******/
+/******/ // Return the exports of the module
+/******/ return module.exports;
+/******/ }
+/******/
+/******/
+/******/ // expose the modules object (__webpack_modules__)
+/******/ __webpack_require__.m = modules;
+/******/
+/******/ // expose the module cache
+/******/ __webpack_require__.c = installedModules;
+/******/
+/******/ // define getter function for harmony exports
+/******/ __webpack_require__.d = function(exports, name, getter) {
+/******/ if(!__webpack_require__.o(exports, name)) {
+/******/ Object.defineProperty(exports, name, {
+/******/ configurable: false,
+/******/ enumerable: true,
+/******/ get: getter
+/******/ });
+/******/ }
+/******/ };
+/******/
+/******/ // getDefaultExport function for compatibility with non-harmony modules
+/******/ __webpack_require__.n = function(module) {
+/******/ var getter = module && module.__esModule ?
+/******/ function getDefault() { return module['default']; } :
+/******/ function getModuleExports() { return module; };
+/******/ __webpack_require__.d(getter, 'a', getter);
+/******/ return getter;
+/******/ };
+/******/
+/******/ // Object.prototype.hasOwnProperty.call
+/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ // __webpack_public_path__
+/******/ __webpack_require__.p = "";
+/******/
+/******/ // Load entry module and return exports
+/******/ return __webpack_require__(__webpack_require__.s = 5);
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _strategy = __webpack_require__(2);
+
+var _strategy2 = _interopRequireDefault(_strategy);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+/**
+ * Encapsulate an result of each search results.
+ */
+var SearchResult = function () {
+
+ /**
+ * @param {object} data - An element of array callbacked by search function.
+ */
+ function SearchResult(data, term, strategy) {
+ _classCallCheck(this, SearchResult);
+
+ this.data = data;
+ this.term = term;
+ this.strategy = strategy;
+ }
+
+ _createClass(SearchResult, [{
+ key: "replace",
+ value: function replace(beforeCursor, afterCursor) {
+ var replacement = this.strategy.replace(this.data);
+ if (replacement !== null) {
+ if (Array.isArray(replacement)) {
+ afterCursor = replacement[1] + afterCursor;
+ replacement = replacement[0];
+ }
+ var match = this.strategy.matchText(beforeCursor);
+ if (match) {
+ replacement = replacement.replace(/\$&/g, match[0]).replace(/\$(\d)/g, function (_, p1) {
+ return match[parseInt(p1, 10)];
+ });
+ return [[beforeCursor.slice(0, match.index), replacement, beforeCursor.slice(match.index + match[0].length)].join(""), afterCursor];
+ }
+ }
+ }
+ }, {
+ key: "render",
+ value: function render() {
+ return this.strategy.template(this.data, this.term);
+ }
+ }]);
+
+ return SearchResult;
+}();
+
+exports.default = SearchResult;
+
+/***/ }),
+/* 1 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var has = Object.prototype.hasOwnProperty
+ , prefix = '~';
+
+/**
+ * Constructor to create a storage for our `EE` objects.
+ * An `Events` instance is a plain object whose properties are event names.
+ *
+ * @constructor
+ * @api private
+ */
+function Events() {}
+
+//
+// We try to not inherit from `Object.prototype`. In some engines creating an
+// instance in this way is faster than calling `Object.create(null)` directly.
+// If `Object.create(null)` is not supported we prefix the event names with a
+// character to make sure that the built-in object properties are not
+// overridden or used as an attack vector.
+//
+if (Object.create) {
+ Events.prototype = Object.create(null);
+
+ //
+ // This hack is needed because the `__proto__` property is still inherited in
+ // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
+ //
+ if (!new Events().__proto__) prefix = false;
+}
+
+/**
+ * Representation of a single event listener.
+ *
+ * @param {Function} fn The listener function.
+ * @param {Mixed} context The context to invoke the listener with.
+ * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
+ * @constructor
+ * @api private
+ */
+function EE(fn, context, once) {
+ this.fn = fn;
+ this.context = context;
+ this.once = once || false;
+}
+
+/**
+ * Minimal `EventEmitter` interface that is molded against the Node.js
+ * `EventEmitter` interface.
+ *
+ * @constructor
+ * @api public
+ */
+function EventEmitter() {
+ this._events = new Events();
+ this._eventsCount = 0;
+}
+
+/**
+ * Return an array listing the events for which the emitter has registered
+ * listeners.
+ *
+ * @returns {Array}
+ * @api public
+ */
+EventEmitter.prototype.eventNames = function eventNames() {
+ var names = []
+ , events
+ , name;
+
+ if (this._eventsCount === 0) return names;
+
+ for (name in (events = this._events)) {
+ if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
+ }
+
+ if (Object.getOwnPropertySymbols) {
+ return names.concat(Object.getOwnPropertySymbols(events));
+ }
+
+ return names;
+};
+
+/**
+ * Return the listeners registered for a given event.
+ *
+ * @param {String|Symbol} event The event name.
+ * @param {Boolean} exists Only check if there are listeners.
+ * @returns {Array|Boolean}
+ * @api public
+ */
+EventEmitter.prototype.listeners = function listeners(event, exists) {
+ var evt = prefix ? prefix + event : event
+ , available = this._events[evt];
+
+ if (exists) return !!available;
+ if (!available) return [];
+ if (available.fn) return [available.fn];
+
+ for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) {
+ ee[i] = available[i].fn;
+ }
+
+ return ee;
+};
+
+/**
+ * Calls each of the listeners registered for a given event.
+ *
+ * @param {String|Symbol} event The event name.
+ * @returns {Boolean} `true` if the event had listeners, else `false`.
+ * @api public
+ */
+EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
+ var evt = prefix ? prefix + event : event;
+
+ if (!this._events[evt]) return false;
+
+ var listeners = this._events[evt]
+ , len = arguments.length
+ , args
+ , i;
+
+ if (listeners.fn) {
+ if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
+
+ switch (len) {
+ case 1: return listeners.fn.call(listeners.context), true;
+ case 2: return listeners.fn.call(listeners.context, a1), true;
+ case 3: return listeners.fn.call(listeners.context, a1, a2), true;
+ case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
+ case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
+ case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
+ }
+
+ for (i = 1, args = new Array(len -1); i < len; i++) {
+ args[i - 1] = arguments[i];
+ }
+
+ listeners.fn.apply(listeners.context, args);
+ } else {
+ var length = listeners.length
+ , j;
+
+ for (i = 0; i < length; i++) {
+ if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
+
+ switch (len) {
+ case 1: listeners[i].fn.call(listeners[i].context); break;
+ case 2: listeners[i].fn.call(listeners[i].context, a1); break;
+ case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
+ case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
+ default:
+ if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
+ args[j - 1] = arguments[j];
+ }
+
+ listeners[i].fn.apply(listeners[i].context, args);
+ }
+ }
+ }
+
+ return true;
+};
+
+/**
+ * Add a listener for a given event.
+ *
+ * @param {String|Symbol} event The event name.
+ * @param {Function} fn The listener function.
+ * @param {Mixed} [context=this] The context to invoke the listener with.
+ * @returns {EventEmitter} `this`.
+ * @api public
+ */
+EventEmitter.prototype.on = function on(event, fn, context) {
+ var listener = new EE(fn, context || this)
+ , evt = prefix ? prefix + event : event;
+
+ if (!this._events[evt]) this._events[evt] = listener, this._eventsCount++;
+ else if (!this._events[evt].fn) this._events[evt].push(listener);
+ else this._events[evt] = [this._events[evt], listener];
+
+ return this;
+};
+
+/**
+ * Add a one-time listener for a given event.
+ *
+ * @param {String|Symbol} event The event name.
+ * @param {Function} fn The listener function.
+ * @param {Mixed} [context=this] The context to invoke the listener with.
+ * @returns {EventEmitter} `this`.
+ * @api public
+ */
+EventEmitter.prototype.once = function once(event, fn, context) {
+ var listener = new EE(fn, context || this, true)
+ , evt = prefix ? prefix + event : event;
+
+ if (!this._events[evt]) this._events[evt] = listener, this._eventsCount++;
+ else if (!this._events[evt].fn) this._events[evt].push(listener);
+ else this._events[evt] = [this._events[evt], listener];
+
+ return this;
+};
+
+/**
+ * Remove the listeners of a given event.
+ *
+ * @param {String|Symbol} event The event name.
+ * @param {Function} fn Only remove the listeners that match this function.
+ * @param {Mixed} context Only remove the listeners that have this context.
+ * @param {Boolean} once Only remove one-time listeners.
+ * @returns {EventEmitter} `this`.
+ * @api public
+ */
+EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
+ var evt = prefix ? prefix + event : event;
+
+ if (!this._events[evt]) return this;
+ if (!fn) {
+ if (--this._eventsCount === 0) this._events = new Events();
+ else delete this._events[evt];
+ return this;
+ }
+
+ var listeners = this._events[evt];
+
+ if (listeners.fn) {
+ if (
+ listeners.fn === fn
+ && (!once || listeners.once)
+ && (!context || listeners.context === context)
+ ) {
+ if (--this._eventsCount === 0) this._events = new Events();
+ else delete this._events[evt];
+ }
+ } else {
+ for (var i = 0, events = [], length = listeners.length; i < length; i++) {
+ if (
+ listeners[i].fn !== fn
+ || (once && !listeners[i].once)
+ || (context && listeners[i].context !== context)
+ ) {
+ events.push(listeners[i]);
+ }
+ }
+
+ //
+ // Reset the array, or remove it completely if we have no more listeners.
+ //
+ if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
+ else if (--this._eventsCount === 0) this._events = new Events();
+ else delete this._events[evt];
+ }
+
+ return this;
+};
+
+/**
+ * Remove all listeners, or those of the specified event.
+ *
+ * @param {String|Symbol} [event] The event name.
+ * @returns {EventEmitter} `this`.
+ * @api public
+ */
+EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
+ var evt;
+
+ if (event) {
+ evt = prefix ? prefix + event : event;
+ if (this._events[evt]) {
+ if (--this._eventsCount === 0) this._events = new Events();
+ else delete this._events[evt];
+ }
+ } else {
+ this._events = new Events();
+ this._eventsCount = 0;
+ }
+
+ return this;
+};
+
+//
+// Alias methods names because people roll like that.
+//
+EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
+EventEmitter.prototype.addListener = EventEmitter.prototype.on;
+
+//
+// This function doesn't apply anymore.
+//
+EventEmitter.prototype.setMaxListeners = function setMaxListeners() {
+ return this;
+};
+
+//
+// Expose the prefix.
+//
+EventEmitter.prefixed = prefix;
+
+//
+// Allow `EventEmitter` to be imported as module namespace.
+//
+EventEmitter.EventEmitter = EventEmitter;
+
+//
+// Expose the module.
+//
+if (true) {
+ module.exports = EventEmitter;
+}
+
+
+/***/ }),
+/* 2 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var DEFAULT_INDEX = 2;
+
+function DEFAULT_TEMPLATE(value) {
+ return value;
+}
+
+/**
+ * Properties for a strategy.
+ *
+ * @typedef
+ */
+
+/**
+ * Encapsulate a single strategy.
+ */
+var Strategy = function () {
+ function Strategy(props) {
+ _classCallCheck(this, Strategy);
+
+ this.props = props;
+ this.cache = props.cache ? {} : null;
+ }
+
+ /**
+ * @return {this}
+ */
+
+
+ _createClass(Strategy, [{
+ key: "destroy",
+ value: function destroy() {
+ this.cache = null;
+ return this;
+ }
+ }, {
+ key: "search",
+ value: function search(term, callback, match) {
+ if (this.cache) {
+ this.searchWithCache(term, callback, match);
+ } else {
+ this.props.search(term, callback, match);
+ }
+ }
+
+ /**
+ * @param {object} data - An element of array callbacked by search function.
+ */
+
+ }, {
+ key: "replace",
+ value: function replace(data) {
+ return this.props.replace(data);
+ }
+
+ /** @private */
+
+ }, {
+ key: "searchWithCache",
+ value: function searchWithCache(term, callback, match) {
+ var _this = this;
+
+ if (this.cache && this.cache[term]) {
+ callback(this.cache[term]);
+ } else {
+ this.props.search(term, function (results) {
+ if (_this.cache) {
+ _this.cache[term] = results;
+ }
+ callback(results);
+ }, match);
+ }
+ }
+
+ /** @private */
+
+ }, {
+ key: "matchText",
+ value: function matchText(text) {
+ if (typeof this.match === "function") {
+ return this.match(text);
+ } else {
+ return text.match(this.match);
+ }
+ }
+
+ /** @private */
+
+ }, {
+ key: "match",
+ get: function get() {
+ return this.props.match;
+ }
+
+ /** @private */
+
+ }, {
+ key: "index",
+ get: function get() {
+ return typeof this.props.index === "number" ? this.props.index : DEFAULT_INDEX;
+ }
+ }, {
+ key: "template",
+ get: function get() {
+ return this.props.template || DEFAULT_TEMPLATE;
+ }
+ }]);
+
+ return Strategy;
+}();
+
+exports.default = Strategy;
+
+/***/ }),
+/* 3 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.calculateElementOffset = calculateElementOffset;
+exports.getLineHeightPx = getLineHeightPx;
+exports.calculateLineHeightPx = calculateLineHeightPx;
+
+
+/**
+ * Create a custom event
+ *
+ * @private
+ */
+var createCustomEvent = exports.createCustomEvent = function () {
+ if (typeof window.CustomEvent === "function") {
+ return function (type, options) {
+ return new document.defaultView.CustomEvent(type, {
+ cancelable: options && options.cancelable || false,
+ detail: options && options.detail || undefined
+ });
+ };
+ } else {
+ // Custom event polyfill from
+ // https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#polyfill
+ return function (type, options) {
+ var event = document.createEvent("CustomEvent");
+ event.initCustomEvent(type,
+ /* bubbles */false, options && options.cancelable || false, options && options.detail || undefined);
+ return event;
+ };
+ }
+}
+
+/**
+ * Get the current coordinates of the `el` relative to the document.
+ *
+ * @private
+ */
+();function calculateElementOffset(el) {
+ var rect = el.getBoundingClientRect();
+ var _el$ownerDocument = el.ownerDocument,
+ defaultView = _el$ownerDocument.defaultView,
+ documentElement = _el$ownerDocument.documentElement;
+
+ var offset = {
+ top: rect.top + defaultView.pageYOffset,
+ left: rect.left + defaultView.pageXOffset
+ };
+ if (documentElement) {
+ offset.top -= documentElement.clientTop;
+ offset.left -= documentElement.clientLeft;
+ }
+ return offset;
+}
+
+var CHAR_CODE_ZERO = "0".charCodeAt(0);
+var CHAR_CODE_NINE = "9".charCodeAt(0);
+
+function isDigit(charCode) {
+ return charCode >= CHAR_CODE_ZERO && charCode <= CHAR_CODE_NINE;
+}
+
+/**
+ * Returns the line-height of the given node in pixels.
+ *
+ * @private
+ */
+function getLineHeightPx(node) {
+ var computedStyle = window.getComputedStyle(node
+
+ // If the char code starts with a digit, it is either a value in pixels,
+ // or unitless, as per:
+ // https://drafts.csswg.org/css2/visudet.html#propdef-line-height
+ // https://drafts.csswg.org/css2/cascade.html#computed-value
+ );if (isDigit(computedStyle.lineHeight.charCodeAt(0))) {
+ // In real browsers the value is *always* in pixels, even for unit-less
+ // line-heights. However, we still check as per the spec.
+ if (isDigit(computedStyle.lineHeight.charCodeAt(computedStyle.lineHeight.length - 1))) {
+ return parseFloat(computedStyle.lineHeight) * parseFloat(computedStyle.fontSize);
+ } else {
+ return parseFloat(computedStyle.lineHeight);
+ }
+ }
+
+ // Otherwise, the value is "normal".
+ // If the line-height is "normal", calculate by font-size
+ return calculateLineHeightPx(node.nodeName, computedStyle);
+}
+
+/**
+ * Returns calculated line-height of the given node in pixels.
+ *
+ * @private
+ */
+function calculateLineHeightPx(nodeName, computedStyle) {
+ var body = document.body;
+ if (!body) {
+ return 0;
+ }
+
+ var tempNode = document.createElement(nodeName);
+ tempNode.innerHTML = "&nbsp;";
+ tempNode.style.fontSize = computedStyle.fontSize;
+ tempNode.style.fontFamily = computedStyle.fontFamily;
+ tempNode.style.padding = "0";
+ body.appendChild(tempNode
+
+ // Make sure textarea has only 1 row
+ );if (tempNode instanceof HTMLTextAreaElement) {
+ ;tempNode.rows = 1;
+ }
+
+ // Assume the height of the element is the line-height
+ var height = tempNode.offsetHeight;
+ body.removeChild(tempNode);
+
+ return height;
+}
+
+/***/ }),
+/* 4 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _eventemitter = __webpack_require__(1);
+
+var _eventemitter2 = _interopRequireDefault(_eventemitter);
+
+var _utils = __webpack_require__(3);
+
+var _search_result = __webpack_require__(0);
+
+var _search_result2 = _interopRequireDefault(_search_result);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+/*eslint no-unused-vars: off*/
+
+/**
+ * Abstract class representing a editor target.
+ *
+ * Editor classes must implement `#applySearchResult`, `#getCursorOffset` and
+ * `#getBeforeCursor` methods.
+ *
+ * Editor classes must invoke `#emitMoveEvent`, `#emitEnterEvent`,
+ * `#emitChangeEvent` and `#emitEscEvent` at proper timing.
+ *
+ * @abstract
+ */
+
+
+/** @typedef */
+var Editor = function (_EventEmitter) {
+ _inherits(Editor, _EventEmitter);
+
+ function Editor() {
+ _classCallCheck(this, Editor);
+
+ return _possibleConstructorReturn(this, (Editor.__proto__ || Object.getPrototypeOf(Editor)).apply(this, arguments));
+ }
+
+ _createClass(Editor, [{
+ key: "destroy",
+
+ /**
+ * It is called when associated textcomplete object is destroyed.
+ *
+ * @return {this}
+ */
+ value: function destroy() {
+ return this;
+ }
+
+ /**
+ * It is called when a search result is selected by a user.
+ */
+
+ }, {
+ key: "applySearchResult",
+ value: function applySearchResult(_) {
+ throw new Error("Not implemented.");
+ }
+
+ /**
+ * The input cursor's absolute coordinates from the window's left
+ * top corner.
+ */
+
+ }, {
+ key: "getCursorOffset",
+ value: function getCursorOffset() {
+ throw new Error("Not implemented.");
+ }
+
+ /**
+ * Editor string value from head to cursor.
+ * Returns null if selection type is range not cursor.
+ */
+
+ }, {
+ key: "getBeforeCursor",
+ value: function getBeforeCursor() {
+ throw new Error("Not implemented.");
+ }
+
+ /**
+ * Emit a move event, which moves active dropdown element.
+ * Child class must call this method at proper timing with proper parameter.
+ *
+ * @see {@link Textarea} for live example.
+ */
+
+ }, {
+ key: "emitMoveEvent",
+ value: function emitMoveEvent(code) {
+ var moveEvent = (0, _utils.createCustomEvent)("move", {
+ cancelable: true,
+ detail: {
+ code: code
+ }
+ });
+ this.emit("move", moveEvent);
+ return moveEvent;
+ }
+
+ /**
+ * Emit a enter event, which selects current search result.
+ * Child class must call this method at proper timing.
+ *
+ * @see {@link Textarea} for live example.
+ */
+
+ }, {
+ key: "emitEnterEvent",
+ value: function emitEnterEvent() {
+ var enterEvent = (0, _utils.createCustomEvent)("enter", { cancelable: true });
+ this.emit("enter", enterEvent);
+ return enterEvent;
+ }
+
+ /**
+ * Emit a change event, which triggers auto completion.
+ * Child class must call this method at proper timing.
+ *
+ * @see {@link Textarea} for live example.
+ */
+
+ }, {
+ key: "emitChangeEvent",
+ value: function emitChangeEvent() {
+ var changeEvent = (0, _utils.createCustomEvent)("change", {
+ detail: {
+ beforeCursor: this.getBeforeCursor()
+ }
+ });
+ this.emit("change", changeEvent);
+ return changeEvent;
+ }
+
+ /**
+ * Emit a esc event, which hides dropdown element.
+ * Child class must call this method at proper timing.
+ *
+ * @see {@link Textarea} for live example.
+ */
+
+ }, {
+ key: "emitEscEvent",
+ value: function emitEscEvent() {
+ var escEvent = (0, _utils.createCustomEvent)("esc", { cancelable: true });
+ this.emit("esc", escEvent);
+ return escEvent;
+ }
+
+ /**
+ * Helper method for parsing KeyboardEvent.
+ *
+ * @see {@link Textarea} for live example.
+ */
+
+ }, {
+ key: "getCode",
+ value: function getCode(e) {
+ return e.keyCode === 9 ? "ENTER" // tab
+ : e.keyCode === 13 ? "ENTER" // enter
+ : e.keyCode === 27 ? "ESC" // esc
+ : e.keyCode === 38 ? "UP" // up
+ : e.keyCode === 40 ? "DOWN" // down
+ : e.keyCode === 78 && e.ctrlKey ? "DOWN" // ctrl-n
+ : e.keyCode === 80 && e.ctrlKey ? "UP" // ctrl-p
+ : "OTHER";
+ }
+ }]);
+
+ return Editor;
+}(_eventemitter2.default);
+
+exports.default = Editor;
+
+/***/ }),
+/* 5 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/* WEBPACK VAR INJECTION */(function(global) {
+
+var _textcomplete = __webpack_require__(7);
+
+var _textcomplete2 = _interopRequireDefault(_textcomplete);
+
+var _textarea = __webpack_require__(12);
+
+var _textarea2 = _interopRequireDefault(_textarea);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var editors = void 0;
+if (global.Textcomplete && global.Textcomplete.editors) {
+ editors = global.Textcomplete.editors;
+} else {
+ editors = {};
+}
+editors.Textarea = _textarea2.default;
+
+global.Textcomplete = _textcomplete2.default;
+global.Textcomplete.editors = editors;
+/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(6)))
+
+/***/ }),
+/* 6 */
+/***/ (function(module, exports) {
+
+var g;
+
+// This works in non-strict mode
+g = (function() {
+ return this;
+})();
+
+try {
+ // This works if eval is allowed (see CSP)
+ g = g || Function("return this")() || (1,eval)("this");
+} catch(e) {
+ // This works if the window reference is available
+ if(typeof window === "object")
+ g = window;
+}
+
+// g can still be undefined, but nothing to do about it...
+// We return undefined, instead of nothing here, so it's
+// easier to handle this case. if(!global) { ...}
+
+module.exports = g;
+
+
+/***/ }),
+/* 7 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _completer = __webpack_require__(8);
+
+var _completer2 = _interopRequireDefault(_completer);
+
+var _editor = __webpack_require__(4);
+
+var _editor2 = _interopRequireDefault(_editor);
+
+var _dropdown = __webpack_require__(10);
+
+var _dropdown2 = _interopRequireDefault(_dropdown);
+
+var _strategy = __webpack_require__(2);
+
+var _strategy2 = _interopRequireDefault(_strategy);
+
+var _search_result = __webpack_require__(0);
+
+var _search_result2 = _interopRequireDefault(_search_result);
+
+var _eventemitter = __webpack_require__(1);
+
+var _eventemitter2 = _interopRequireDefault(_eventemitter);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+var CALLBACK_METHODS = ["handleChange", "handleEnter", "handleEsc", "handleHit", "handleMove", "handleSelect"];
+
+/** @typedef */
+
+/**
+ * The core of textcomplete. It acts as a mediator.
+ */
+var Textcomplete = function (_EventEmitter) {
+ _inherits(Textcomplete, _EventEmitter);
+
+ /**
+ * @param {Editor} editor - Where the textcomplete works on.
+ */
+ function Textcomplete(editor) {
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+
+ _classCallCheck(this, Textcomplete);
+
+ var _this = _possibleConstructorReturn(this, (Textcomplete.__proto__ || Object.getPrototypeOf(Textcomplete)).call(this));
+
+ _this.completer = new _completer2.default();
+ _this.isQueryInFlight = false;
+ _this.nextPendingQuery = null;
+ _this.dropdown = new _dropdown2.default(options.dropdown || {});
+ _this.editor = editor;
+ _this.options = options;
+
+ CALLBACK_METHODS.forEach(function (method) {
+ ;_this[method] = _this[method].bind(_this);
+ });
+
+ _this.startListening();
+ return _this;
+ }
+
+ /**
+ * @return {this}
+ */
+
+
+ _createClass(Textcomplete, [{
+ key: "destroy",
+ value: function destroy() {
+ var destroyEditor = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
+
+ this.completer.destroy();
+ this.dropdown.destroy();
+ if (destroyEditor) {
+ this.editor.destroy();
+ }
+ this.stopListening();
+ return this;
+ }
+
+ /**
+ * @return {this}
+ */
+
+ }, {
+ key: "hide",
+ value: function hide() {
+ this.dropdown.deactivate();
+ return this;
+ }
+
+ /**
+ * @return {this}
+ * @example
+ * textcomplete.register([{
+ * match: /(^|\s)(\w+)$/,
+ * search: function (term, callback) {
+ * $.ajax({ ... })
+ * .done(callback)
+ * .fail([]);
+ * },
+ * replace: function (value) {
+ * return '$1' + value + ' ';
+ * }
+ * }]);
+ */
+
+ }, {
+ key: "register",
+ value: function register(strategyPropsArray) {
+ var _this2 = this;
+
+ strategyPropsArray.forEach(function (props) {
+ _this2.completer.registerStrategy(new _strategy2.default(props));
+ });
+ return this;
+ }
+
+ /**
+ * Start autocompleting.
+ *
+ * @param {string} text - Head to input cursor.
+ * @return {this}
+ */
+
+ }, {
+ key: "trigger",
+ value: function trigger(text) {
+ if (this.isQueryInFlight) {
+ this.nextPendingQuery = text;
+ } else {
+ this.isQueryInFlight = true;
+ this.nextPendingQuery = null;
+ this.completer.run(text);
+ }
+ return this;
+ }
+
+ /** @private */
+
+ }, {
+ key: "handleHit",
+ value: function handleHit(_ref) {
+ var searchResults = _ref.searchResults;
+
+ if (searchResults.length) {
+ this.dropdown.render(searchResults, this.editor.getCursorOffset());
+ } else {
+ this.dropdown.deactivate();
+ }
+ this.isQueryInFlight = false;
+ if (this.nextPendingQuery !== null) {
+ this.trigger(this.nextPendingQuery);
+ }
+ }
+
+ /** @private */
+
+ }, {
+ key: "handleMove",
+ value: function handleMove(e) {
+ e.detail.code === "UP" ? this.dropdown.up(e) : this.dropdown.down(e);
+ }
+
+ /** @private */
+
+ }, {
+ key: "handleEnter",
+ value: function handleEnter(e) {
+ var activeItem = this.dropdown.getActiveItem();
+ if (activeItem) {
+ this.dropdown.select(activeItem);
+ e.preventDefault();
+ } else {
+ this.dropdown.deactivate();
+ }
+ }
+
+ /** @private */
+
+ }, {
+ key: "handleEsc",
+ value: function handleEsc(e) {
+ if (this.dropdown.shown) {
+ this.dropdown.deactivate();
+ e.preventDefault();
+ }
+ }
+
+ /** @private */
+
+ }, {
+ key: "handleChange",
+ value: function handleChange(e) {
+ if (e.detail.beforeCursor != null) {
+ this.trigger(e.detail.beforeCursor);
+ } else {
+ this.dropdown.deactivate();
+ }
+ }
+
+ /** @private */
+
+ }, {
+ key: "handleSelect",
+ value: function handleSelect(selectEvent) {
+ this.emit("select", selectEvent);
+ if (!selectEvent.defaultPrevented) {
+ this.editor.applySearchResult(selectEvent.detail.searchResult);
+ }
+ }
+
+ /** @private */
+
+ }, {
+ key: "startListening",
+ value: function startListening() {
+ var _this3 = this;
+
+ this.editor.on("move", this.handleMove).on("enter", this.handleEnter).on("esc", this.handleEsc).on("change", this.handleChange);
+ this.dropdown.on("select", this.handleSelect);["show", "shown", "render", "rendered", "selected", "hidden", "hide"].forEach(function (eventName) {
+ _this3.dropdown.on(eventName, function () {
+ return _this3.emit(eventName);
+ });
+ });
+ this.completer.on("hit", this.handleHit);
+ }
+
+ /** @private */
+
+ }, {
+ key: "stopListening",
+ value: function stopListening() {
+ this.completer.removeAllListeners();
+ this.dropdown.removeAllListeners();
+ this.editor.removeListener("move", this.handleMove).removeListener("enter", this.handleEnter).removeListener("esc", this.handleEsc).removeListener("change", this.handleChange);
+ }
+ }]);
+
+ return Textcomplete;
+}(_eventemitter2.default);
+
+exports.default = Textcomplete;
+
+/***/ }),
+/* 8 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _eventemitter = __webpack_require__(1);
+
+var _eventemitter2 = _interopRequireDefault(_eventemitter);
+
+var _query = __webpack_require__(9);
+
+var _query2 = _interopRequireDefault(_query);
+
+var _search_result = __webpack_require__(0);
+
+var _search_result2 = _interopRequireDefault(_search_result);
+
+var _strategy = __webpack_require__(2);
+
+var _strategy2 = _interopRequireDefault(_strategy);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+var CALLBACK_METHODS = ["handleQueryResult"];
+
+/**
+ * Complete engine.
+ */
+
+var Completer = function (_EventEmitter) {
+ _inherits(Completer, _EventEmitter);
+
+ function Completer() {
+ _classCallCheck(this, Completer);
+
+ var _this = _possibleConstructorReturn(this, (Completer.__proto__ || Object.getPrototypeOf(Completer)).call(this));
+
+ _this.strategies = [];
+
+ CALLBACK_METHODS.forEach(function (method) {
+ ;_this[method] = _this[method].bind(_this);
+ });
+ return _this;
+ }
+
+ /**
+ * @return {this}
+ */
+
+
+ _createClass(Completer, [{
+ key: "destroy",
+ value: function destroy() {
+ this.strategies.forEach(function (strategy) {
+ return strategy.destroy();
+ });
+ return this;
+ }
+
+ /**
+ * Register a strategy to the completer.
+ *
+ * @return {this}
+ */
+
+ }, {
+ key: "registerStrategy",
+ value: function registerStrategy(strategy) {
+ this.strategies.push(strategy);
+ return this;
+ }
+
+ /**
+ * @param {string} text - Head to input cursor.
+ */
+
+ }, {
+ key: "run",
+ value: function run(text) {
+ var query = this.extractQuery(text);
+ if (query) {
+ query.execute(this.handleQueryResult);
+ } else {
+ this.handleQueryResult([]);
+ }
+ }
+
+ /**
+ * Find a query, which matches to the given text.
+ *
+ * @private
+ */
+
+ }, {
+ key: "extractQuery",
+ value: function extractQuery(text) {
+ for (var i = 0; i < this.strategies.length; i++) {
+ var query = _query2.default.build(this.strategies[i], text);
+ if (query) {
+ return query;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Callbacked by {@link Query#execute}.
+ *
+ * @private
+ */
+
+ }, {
+ key: "handleQueryResult",
+ value: function handleQueryResult(searchResults) {
+ this.emit("hit", { searchResults: searchResults });
+ }
+ }]);
+
+ return Completer;
+}(_eventemitter2.default);
+
+exports.default = Completer;
+
+/***/ }),
+/* 9 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _search_result = __webpack_require__(0);
+
+var _search_result2 = _interopRequireDefault(_search_result);
+
+var _strategy = __webpack_require__(2);
+
+var _strategy2 = _interopRequireDefault(_strategy);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+/**
+ * Encapsulate matching condition between a Strategy and current editor's value.
+ */
+var Query = function () {
+ _createClass(Query, null, [{
+ key: "build",
+
+
+ /**
+ * Build a Query object by the given string if this matches to the string.
+ *
+ * @param {string} text - Head to input cursor.
+ */
+ value: function build(strategy, text) {
+ if (typeof strategy.props.context === "function") {
+ var context = strategy.props.context(text);
+ if (typeof context === "string") {
+ text = context;
+ } else if (!context) {
+ return null;
+ }
+ }
+ var match = strategy.matchText(text);
+ return match ? new Query(strategy, match[strategy.index], match) : null;
+ }
+ }]);
+
+ function Query(strategy, term, match) {
+ _classCallCheck(this, Query);
+
+ this.strategy = strategy;
+ this.term = term;
+ this.match = match;
+ }
+
+ /**
+ * Invoke search strategy and callback the given function.
+ */
+
+
+ _createClass(Query, [{
+ key: "execute",
+ value: function execute(callback) {
+ var _this = this;
+
+ this.strategy.search(this.term, function (results) {
+ callback(results.map(function (result) {
+ return new _search_result2.default(result, _this.term, _this.strategy);
+ }));
+ }, this.match);
+ }
+ }]);
+
+ return Query;
+}();
+
+exports.default = Query;
+
+/***/ }),
+/* 10 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _eventemitter = __webpack_require__(1);
+
+var _eventemitter2 = _interopRequireDefault(_eventemitter);
+
+var _dropdown_item = __webpack_require__(11);
+
+var _dropdown_item2 = _interopRequireDefault(_dropdown_item);
+
+var _search_result = __webpack_require__(0);
+
+var _search_result2 = _interopRequireDefault(_search_result);
+
+var _utils = __webpack_require__(3);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+var DEFAULT_CLASS_NAME = "dropdown-menu textcomplete-dropdown";
+
+/** @typedef */
+
+/**
+ * Encapsulate a dropdown view.
+ *
+ * @prop {boolean} shown - Whether the #el is shown or not.
+ * @prop {DropdownItem[]} items - The array of rendered dropdown items.
+ */
+var Dropdown = function (_EventEmitter) {
+ _inherits(Dropdown, _EventEmitter);
+
+ _createClass(Dropdown, null, [{
+ key: "createElement",
+ value: function createElement() {
+ var el = document.createElement("ul");
+ var style = el.style;
+ style.display = "none";
+ style.position = "absolute";
+ style.zIndex = "10000";
+ var body = document.body;
+ if (body) {
+ body.appendChild(el);
+ }
+ return el;
+ }
+ }]);
+
+ function Dropdown(options) {
+ _classCallCheck(this, Dropdown);
+
+ var _this = _possibleConstructorReturn(this, (Dropdown.__proto__ || Object.getPrototypeOf(Dropdown)).call(this));
+
+ _this.shown = false;
+ _this.items = [];
+ _this.activeItem = null;
+ _this.footer = options.footer;
+ _this.header = options.header;
+ _this.maxCount = options.maxCount || 10;
+ _this.el.className = options.className || DEFAULT_CLASS_NAME;
+ _this.rotate = options.hasOwnProperty("rotate") ? options.rotate : true;
+ _this.placement = options.placement;
+ _this.itemOptions = options.item || {};
+ var style = options.style;
+ if (style) {
+ Object.keys(style).forEach(function (key) {
+ ;_this.el.style[key] = style[key];
+ });
+ }
+ return _this;
+ }
+
+ /**
+ * @return {this}
+ */
+
+
+ _createClass(Dropdown, [{
+ key: "destroy",
+ value: function destroy() {
+ var parentNode = this.el.parentNode;
+ if (parentNode) {
+ parentNode.removeChild(this.el);
+ }
+ this.clear()._el = null;
+ return this;
+ }
+ }, {
+ key: "render",
+
+
+ /**
+ * Render the given data as dropdown items.
+ *
+ * @return {this}
+ */
+ value: function render(searchResults, cursorOffset) {
+ var _this2 = this;
+
+ var renderEvent = (0, _utils.createCustomEvent)("render", { cancelable: true });
+ this.emit("render", renderEvent);
+ if (renderEvent.defaultPrevented) {
+ return this;
+ }
+ var rawResults = searchResults.map(function (searchResult) {
+ return searchResult.data;
+ });
+ var dropdownItems = searchResults.slice(0, this.maxCount || searchResults.length).map(function (searchResult) {
+ return new _dropdown_item2.default(searchResult, _this2.itemOptions);
+ });
+ this.clear().setStrategyId(searchResults[0]).renderEdge(rawResults, "header").append(dropdownItems).renderEdge(rawResults, "footer").show().setOffset(cursorOffset);
+ this.emit("rendered", (0, _utils.createCustomEvent)("rendered"));
+ return this;
+ }
+
+ /**
+ * Hide the dropdown then sweep out items.
+ *
+ * @return {this}
+ */
+
+ }, {
+ key: "deactivate",
+ value: function deactivate() {
+ return this.hide().clear();
+ }
+
+ /**
+ * @return {this}
+ */
+
+ }, {
+ key: "select",
+ value: function select(dropdownItem) {
+ var detail = { searchResult: dropdownItem.searchResult };
+ var selectEvent = (0, _utils.createCustomEvent)("select", {
+ cancelable: true,
+ detail: detail
+ });
+ this.emit("select", selectEvent);
+ if (selectEvent.defaultPrevented) {
+ return this;
+ }
+ this.deactivate();
+ this.emit("selected", (0, _utils.createCustomEvent)("selected", { detail: detail }));
+ return this;
+ }
+
+ /**
+ * @return {this}
+ */
+
+ }, {
+ key: "up",
+ value: function up(e) {
+ return this.shown ? this.moveActiveItem("prev", e) : this;
+ }
+
+ /**
+ * @return {this}
+ */
+
+ }, {
+ key: "down",
+ value: function down(e) {
+ return this.shown ? this.moveActiveItem("next", e) : this;
+ }
+
+ /**
+ * Retrieve the active item.
+ */
+
+ }, {
+ key: "getActiveItem",
+ value: function getActiveItem() {
+ return this.activeItem;
+ }
+
+ /**
+ * Add items to dropdown.
+ *
+ * @private
+ */
+
+ }, {
+ key: "append",
+ value: function append(items) {
+ var _this3 = this;
+
+ var fragment = document.createDocumentFragment();
+ items.forEach(function (item) {
+ _this3.items.push(item);
+ item.appended(_this3);
+ fragment.appendChild(item.el);
+ });
+ this.el.appendChild(fragment);
+ return this;
+ }
+
+ /** @private */
+
+ }, {
+ key: "setOffset",
+ value: function setOffset(cursorOffset) {
+ var doc = document.documentElement;
+ if (doc) {
+ var elementWidth = this.el.offsetWidth;
+ if (cursorOffset.left) {
+ var browserWidth = doc.clientWidth;
+ if (cursorOffset.left + elementWidth > browserWidth) {
+ cursorOffset.left = browserWidth - elementWidth;
+ }
+ this.el.style.left = cursorOffset.left + "px";
+ } else if (cursorOffset.right) {
+ if (cursorOffset.right - elementWidth < 0) {
+ cursorOffset.right = 0;
+ }
+ this.el.style.right = cursorOffset.right + "px";
+ }
+ if (this.isPlacementTop()) {
+ this.el.style.bottom = doc.clientHeight - cursorOffset.top + cursorOffset.lineHeight + "px";
+ } else {
+ this.el.style.top = cursorOffset.top + "px";
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Show the element.
+ *
+ * @private
+ */
+
+ }, {
+ key: "show",
+ value: function show() {
+ if (!this.shown) {
+ var showEvent = (0, _utils.createCustomEvent)("show", { cancelable: true });
+ this.emit("show", showEvent);
+ if (showEvent.defaultPrevented) {
+ return this;
+ }
+ this.el.style.display = "block";
+ this.shown = true;
+ this.emit("shown", (0, _utils.createCustomEvent)("shown"));
+ }
+ return this;
+ }
+
+ /**
+ * Hide the element.
+ *
+ * @private
+ */
+
+ }, {
+ key: "hide",
+ value: function hide() {
+ if (this.shown) {
+ var hideEvent = (0, _utils.createCustomEvent)("hide", { cancelable: true });
+ this.emit("hide", hideEvent);
+ if (hideEvent.defaultPrevented) {
+ return this;
+ }
+ this.el.style.display = "none";
+ this.shown = false;
+ this.emit("hidden", (0, _utils.createCustomEvent)("hidden"));
+ }
+ return this;
+ }
+
+ /**
+ * Clear search results.
+ *
+ * @private
+ */
+
+ }, {
+ key: "clear",
+ value: function clear() {
+ this.el.innerHTML = "";
+ this.items.forEach(function (item) {
+ return item.destroy();
+ });
+ this.items = [];
+ return this;
+ }
+
+ /** @private */
+
+ }, {
+ key: "moveActiveItem",
+ value: function moveActiveItem(direction, e) {
+ var nextActiveItem = direction === "next" ? this.activeItem ? this.activeItem.next : this.items[0] : this.activeItem ? this.activeItem.prev : this.items[this.items.length - 1];
+ if (nextActiveItem) {
+ nextActiveItem.activate();
+ e.preventDefault();
+ }
+ return this;
+ }
+
+ /** @private */
+
+ }, {
+ key: "setStrategyId",
+ value: function setStrategyId(searchResult) {
+ var strategyId = searchResult && searchResult.strategy.props.id;
+ if (strategyId) {
+ this.el.setAttribute("data-strategy", strategyId);
+ } else {
+ this.el.removeAttribute("data-strategy");
+ }
+ return this;
+ }
+
+ /**
+ * @private
+ * @param {object[]} rawResults - What callbacked by search function.
+ */
+
+ }, {
+ key: "renderEdge",
+ value: function renderEdge(rawResults, type) {
+ var source = (type === "header" ? this.header : this.footer) || "";
+ var content = typeof source === "function" ? source(rawResults) : source;
+ var li = document.createElement("li");
+ li.classList.add("textcomplete-" + type);
+ li.innerHTML = content;
+ this.el.appendChild(li);
+ return this;
+ }
+
+ /** @private */
+
+ }, {
+ key: "isPlacementTop",
+ value: function isPlacementTop() {
+ return this.placement === "top";
+ }
+ }, {
+ key: "el",
+ get: function get() {
+ if (!this._el) {
+ this._el = Dropdown.createElement();
+ }
+ return this._el;
+ }
+ }]);
+
+ return Dropdown;
+}(_eventemitter2.default);
+
+exports.default = Dropdown;
+
+/***/ }),
+/* 11 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.DEFAULT_CLASS_NAME = undefined;
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _search_result = __webpack_require__(0);
+
+var _search_result2 = _interopRequireDefault(_search_result);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var DEFAULT_CLASS_NAME = exports.DEFAULT_CLASS_NAME = "textcomplete-item";
+var CALLBACK_METHODS = ["onClick", "onMouseover"];
+
+/** @typedef */
+
+
+// Declare interface instead of importing Dropdown itself to prevent circular dependency.
+
+/**
+ * Encapsulate an item of dropdown.
+ */
+var DropdownItem = function () {
+ function DropdownItem(searchResult, options) {
+ var _this = this;
+
+ _classCallCheck(this, DropdownItem);
+
+ this.searchResult = searchResult;
+ this.active = false;
+ this.className = options.className || DEFAULT_CLASS_NAME;
+ this.activeClassName = this.className + " active";
+
+ CALLBACK_METHODS.forEach(function (method) {
+ ;_this[method] = _this[method].bind(_this);
+ });
+ }
+
+ _createClass(DropdownItem, [{
+ key: "destroy",
+
+
+ /**
+ * Try to free resources and perform other cleanup operations.
+ */
+ value: function destroy() {
+ this.el.removeEventListener("mousedown", this.onClick, false);
+ this.el.removeEventListener("mouseover", this.onMouseover, false);
+ this.el.removeEventListener("touchstart", this.onClick, false);
+ if (this.active) {
+ this.dropdown.activeItem = null;
+ }
+ // This element has already been removed by {@link Dropdown#clear}.
+ this._el = null;
+ }
+
+ /**
+ * Callbacked when it is appended to a dropdown.
+ *
+ * @see Dropdown#append
+ */
+
+ }, {
+ key: "appended",
+ value: function appended(dropdown) {
+ this.dropdown = dropdown;
+ this.siblings = dropdown.items;
+ this.index = this.siblings.length - 1;
+ }
+
+ /**
+ * Deactivate active item then activate itself.
+ *
+ * @return {this}
+ */
+
+ }, {
+ key: "activate",
+ value: function activate() {
+ if (!this.active) {
+ var _activeItem = this.dropdown.getActiveItem();
+ if (_activeItem) {
+ _activeItem.deactivate();
+ }
+ this.dropdown.activeItem = this;
+ this.active = true;
+ this.el.className = this.activeClassName;
+ }
+ return this;
+ }
+
+ /**
+ * Get the next sibling.
+ */
+
+ }, {
+ key: "deactivate",
+
+
+ /** @private */
+ value: function deactivate() {
+ if (this.active) {
+ this.active = false;
+ this.el.className = this.className;
+ this.dropdown.activeItem = null;
+ }
+ return this;
+ }
+
+ /** @private */
+
+ }, {
+ key: "onClick",
+ value: function onClick(e) {
+ e.preventDefault // Prevent blur event
+ ();this.dropdown.select(this);
+ }
+
+ /** @private */
+
+ }, {
+ key: "onMouseover",
+ value: function onMouseover() {
+ this.activate();
+ }
+ }, {
+ key: "el",
+ get: function get() {
+ if (this._el) {
+ return this._el;
+ }
+ var li = document.createElement("li");
+ li.className = this.active ? this.activeClassName : this.className;
+ var a = document.createElement("a");
+ a.innerHTML = this.searchResult.render();
+ li.appendChild(a);
+ this._el = li;
+ li.addEventListener("mousedown", this.onClick);
+ li.addEventListener("mouseover", this.onMouseover);
+ li.addEventListener("touchstart", this.onClick);
+ return li;
+ }
+ }, {
+ key: "next",
+ get: function get() {
+ var nextIndex = void 0;
+ if (this.index === this.siblings.length - 1) {
+ if (!this.dropdown.rotate) {
+ return null;
+ }
+ nextIndex = 0;
+ } else {
+ nextIndex = this.index + 1;
+ }
+ return this.siblings[nextIndex];
+ }
+
+ /**
+ * Get the previous sibling.
+ */
+
+ }, {
+ key: "prev",
+ get: function get() {
+ var nextIndex = void 0;
+ if (this.index === 0) {
+ if (!this.dropdown.rotate) {
+ return null;
+ }
+ nextIndex = this.siblings.length - 1;
+ } else {
+ nextIndex = this.index - 1;
+ }
+ return this.siblings[nextIndex];
+ }
+ }]);
+
+ return DropdownItem;
+}();
+
+exports.default = DropdownItem;
+
+/***/ }),
+/* 12 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
+
+var _update = __webpack_require__(13);
+
+var _update2 = _interopRequireDefault(_update);
+
+var _editor = __webpack_require__(4);
+
+var _editor2 = _interopRequireDefault(_editor);
+
+var _utils = __webpack_require__(3);
+
+var _search_result = __webpack_require__(0);
+
+var _search_result2 = _interopRequireDefault(_search_result);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+var getCaretCoordinates = __webpack_require__(14);
+
+var CALLBACK_METHODS = ["onInput", "onKeydown"];
+
+/**
+ * Encapsulate the target textarea element.
+ */
+
+var Textarea = function (_Editor) {
+ _inherits(Textarea, _Editor);
+
+ /**
+ * @param {HTMLTextAreaElement} el - Where the textcomplete works on.
+ */
+ function Textarea(el) {
+ _classCallCheck(this, Textarea);
+
+ var _this = _possibleConstructorReturn(this, (Textarea.__proto__ || Object.getPrototypeOf(Textarea)).call(this));
+
+ _this.el = el;
+
+ CALLBACK_METHODS.forEach(function (method) {
+ ;_this[method] = _this[method].bind(_this);
+ });
+
+ _this.startListening();
+ return _this;
+ }
+
+ /**
+ * @return {this}
+ */
+
+
+ _createClass(Textarea, [{
+ key: "destroy",
+ value: function destroy() {
+ _get(Textarea.prototype.__proto__ || Object.getPrototypeOf(Textarea.prototype), "destroy", this).call(this);
+ this.stopListening
+ // Release the element reference early to help garbage collection.
+ ();this.el = null;
+ return this;
+ }
+
+ /**
+ * Implementation for {@link Editor#applySearchResult}
+ */
+
+ }, {
+ key: "applySearchResult",
+ value: function applySearchResult(searchResult) {
+ var before = this.getBeforeCursor();
+ if (before != null) {
+ var replace = searchResult.replace(before, this.getAfterCursor());
+ this.el.focus // Clicking a dropdown item removes focus from the element.
+ ();if (Array.isArray(replace)) {
+ (0, _update2.default)(this.el, replace[0], replace[1]);
+ this.el.dispatchEvent(new Event("input"));
+ }
+ }
+ }
+
+ /**
+ * Implementation for {@link Editor#getCursorOffset}
+ */
+
+ }, {
+ key: "getCursorOffset",
+ value: function getCursorOffset() {
+ var elOffset = (0, _utils.calculateElementOffset)(this.el);
+ var elScroll = this.getElScroll();
+ var cursorPosition = this.getCursorPosition();
+ var lineHeight = (0, _utils.getLineHeightPx)(this.el);
+ var top = elOffset.top - elScroll.top + cursorPosition.top + lineHeight;
+ var left = elOffset.left - elScroll.left + cursorPosition.left;
+ if (this.el.dir !== "rtl") {
+ return { top: top, left: left, lineHeight: lineHeight };
+ } else {
+ var right = document.documentElement ? document.documentElement.clientWidth - left : 0;
+ return { top: top, right: right, lineHeight: lineHeight };
+ }
+ }
+
+ /**
+ * Implementation for {@link Editor#getBeforeCursor}
+ */
+
+ }, {
+ key: "getBeforeCursor",
+ value: function getBeforeCursor() {
+ return this.el.selectionStart !== this.el.selectionEnd ? null : this.el.value.substring(0, this.el.selectionEnd);
+ }
+
+ /** @private */
+
+ }, {
+ key: "getAfterCursor",
+ value: function getAfterCursor() {
+ return this.el.value.substring(this.el.selectionEnd);
+ }
+
+ /** @private */
+
+ }, {
+ key: "getElScroll",
+ value: function getElScroll() {
+ return { top: this.el.scrollTop, left: this.el.scrollLeft };
+ }
+
+ /**
+ * The input cursor's relative coordinates from the textarea's left
+ * top corner.
+ *
+ * @private
+ */
+
+ }, {
+ key: "getCursorPosition",
+ value: function getCursorPosition() {
+ return getCaretCoordinates(this.el, this.el.selectionEnd);
+ }
+
+ /** @private */
+
+ }, {
+ key: "onInput",
+ value: function onInput() {
+ this.emitChangeEvent();
+ }
+
+ /** @private */
+
+ }, {
+ key: "onKeydown",
+ value: function onKeydown(e) {
+ var code = this.getCode(e);
+ var event = void 0;
+ if (code === "UP" || code === "DOWN") {
+ event = this.emitMoveEvent(code);
+ } else if (code === "ENTER") {
+ event = this.emitEnterEvent();
+ } else if (code === "ESC") {
+ event = this.emitEscEvent();
+ }
+ if (event && event.defaultPrevented) {
+ e.preventDefault();
+ }
+ }
+
+ /** @private */
+
+ }, {
+ key: "startListening",
+ value: function startListening() {
+ this.el.addEventListener("input", this.onInput);
+ this.el.addEventListener("keydown", this.onKeydown);
+ }
+
+ /** @private */
+
+ }, {
+ key: "stopListening",
+ value: function stopListening() {
+ this.el.removeEventListener("input", this.onInput);
+ this.el.removeEventListener("keydown", this.onKeydown);
+ }
+ }]);
+
+ return Textarea;
+}(_editor2.default);
+
+exports.default = Textarea;
+
+/***/ }),
+/* 13 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+exports.default = function (el, headToCursor, cursorToTail) {
+ var curr = el.value,
+ // strA + strB1 + strC
+ next = headToCursor + (cursorToTail || ''),
+ // strA + strB2 + strC
+ activeElement = document.activeElement;
+
+ // Calculate length of strA and strC
+ var aLength = 0,
+ cLength = 0;
+ while (aLength < curr.length && aLength < next.length && curr[aLength] === next[aLength]) {
+ aLength++;
+ }
+ while (curr.length - cLength - 1 >= 0 && next.length - cLength - 1 >= 0 && curr[curr.length - cLength - 1] === next[next.length - cLength - 1]) {
+ cLength++;
+ }
+ aLength = Math.min(aLength, Math.min(curr.length, next.length) - cLength);
+
+ // Select strB1
+ el.setSelectionRange(aLength, curr.length - cLength);
+
+ // Get strB2
+ var strB2 = next.substring(aLength, next.length - cLength);
+
+ // Replace strB1 with strB2
+ el.focus();
+ if (!document.execCommand('insertText', false, strB2)) {
+ // Document.execCommand returns false if the command is not supported.
+ // Firefox and IE returns false in this case.
+ el.value = next;
+ el.dispatchEvent(createInputEvent());
+ }
+
+ // Move cursor to the end of headToCursor
+ el.setSelectionRange(headToCursor.length, headToCursor.length);
+
+ activeElement && activeElement.focus();
+ return el;
+};
+
+function createInputEvent() {
+ if (typeof Event !== "undefined") {
+ return new Event("input", { bubbles: true, cancelable: true });
+ } else {
+ var event = document.createEvent("Event");
+ event.initEvent("input", true, true);
+ return event;
+ }
+}
+
+/***/ }),
+/* 14 */
+/***/ (function(module, exports) {
+
+/* jshint browser: true */
+
+(function () {
+
+// The properties that we copy into a mirrored div.
+// Note that some browsers, such as Firefox,
+// do not concatenate properties, i.e. padding-top, bottom etc. -> padding,
+// so we have to do every single property specifically.
+var properties = [
+ 'direction', // RTL support
+ 'boxSizing',
+ 'width', // on Chrome and IE, exclude the scrollbar, so the mirror div wraps exactly as the textarea does
+ 'height',
+ 'overflowX',
+ 'overflowY', // copy the scrollbar for IE
+
+ 'borderTopWidth',
+ 'borderRightWidth',
+ 'borderBottomWidth',
+ 'borderLeftWidth',
+ 'borderStyle',
+
+ 'paddingTop',
+ 'paddingRight',
+ 'paddingBottom',
+ 'paddingLeft',
+
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/font
+ 'fontStyle',
+ 'fontVariant',
+ 'fontWeight',
+ 'fontStretch',
+ 'fontSize',
+ 'fontSizeAdjust',
+ 'lineHeight',
+ 'fontFamily',
+
+ 'textAlign',
+ 'textTransform',
+ 'textIndent',
+ 'textDecoration', // might not make a difference, but better be safe
+
+ 'letterSpacing',
+ 'wordSpacing',
+
+ 'tabSize',
+ 'MozTabSize'
+
+];
+
+var isBrowser = (typeof window !== 'undefined');
+var isFirefox = (isBrowser && window.mozInnerScreenX != null);
+
+function getCaretCoordinates(element, position, options) {
+ if(!isBrowser) {
+ throw new Error('textarea-caret-position#getCaretCoordinates should only be called in a browser');
+ }
+
+ var debug = options && options.debug || false;
+ if (debug) {
+ var el = document.querySelector('#input-textarea-caret-position-mirror-div');
+ if ( el ) { el.parentNode.removeChild(el); }
+ }
+
+ // mirrored div
+ var div = document.createElement('div');
+ div.id = 'input-textarea-caret-position-mirror-div';
+ document.body.appendChild(div);
+
+ var style = div.style;
+ var computed = window.getComputedStyle? getComputedStyle(element) : element.currentStyle; // currentStyle for IE < 9
+
+ // default textarea styles
+ style.whiteSpace = 'pre-wrap';
+ if (element.nodeName !== 'INPUT')
+ style.wordWrap = 'break-word'; // only for textarea-s
+
+ // position off-screen
+ style.position = 'absolute'; // required to return coordinates properly
+ if (!debug)
+ style.visibility = 'hidden'; // not 'display: none' because we want rendering
+
+ // transfer the element's properties to the div
+ properties.forEach(function (prop) {
+ style[prop] = computed[prop];
+ });
+
+ if (isFirefox) {
+ // Firefox lies about the overflow property for textareas: https://bugzilla.mozilla.org/show_bug.cgi?id=984275
+ if (element.scrollHeight > parseInt(computed.height))
+ style.overflowY = 'scroll';
+ } else {
+ style.overflow = 'hidden'; // for Chrome to not render a scrollbar; IE keeps overflowY = 'scroll'
+ }
+
+ div.textContent = element.value.substring(0, position);
+ // the second special handling for input type="text" vs textarea: spaces need to be replaced with non-breaking spaces - http://stackoverflow.com/a/13402035/1269037
+ if (element.nodeName === 'INPUT')
+ div.textContent = div.textContent.replace(/\s/g, '\u00a0');
+
+ var span = document.createElement('span');
+ // Wrapping must be replicated *exactly*, including when a long word gets
+ // onto the next line, with whitespace at the end of the line before (#7).
+ // The *only* reliable way to do that is to copy the *entire* rest of the
+ // textarea's content into the <span> created at the caret position.
+ // for inputs, just '.' would be enough, but why bother?
+ span.textContent = element.value.substring(position) || '.'; // || because a completely empty faux span doesn't render at all
+ div.appendChild(span);
+
+ var coordinates = {
+ top: span.offsetTop + parseInt(computed['borderTopWidth']),
+ left: span.offsetLeft + parseInt(computed['borderLeftWidth'])
+ };
+
+ if (debug) {
+ span.style.backgroundColor = '#aaa';
+ } else {
+ document.body.removeChild(div);
+ }
+
+ return coordinates;
+}
+
+if (typeof module != 'undefined' && typeof module.exports != 'undefined') {
+ module.exports = getCaretCoordinates;
+} else if(isBrowser){
+ window.getCaretCoordinates = getCaretCoordinates;
+}
+
+}());
+
+
+/***/ })
+/******/ ]);
+//# sourceMappingURL=textcomplete.js.map \ No newline at end of file
diff --git a/library/textcomplete/textcomplete.js.map b/library/textcomplete/textcomplete.js.map
new file mode 100644
index 000000000..42ed11883
--- /dev/null
+++ b/library/textcomplete/textcomplete.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["webpack:///webpack/bootstrap 0bc74e584933ddf1c7ac","webpack:///./src/search_result.js","webpack:///./node_modules/eventemitter3/index.js","webpack:///./src/strategy.js","webpack:///./src/utils.js","webpack:///./src/editor.js","webpack:///./src/main.js","webpack:///(webpack)/buildin/global.js","webpack:///./src/textcomplete.js","webpack:///./src/completer.js","webpack:///./src/query.js","webpack:///./src/dropdown.js","webpack:///./src/dropdown_item.js","webpack:///./src/textarea.js","webpack:///./node_modules/undate/lib/update.js","webpack:///./node_modules/textarea-caret/index.js"],"names":["SearchResult","data","term","strategy","beforeCursor","afterCursor","replacement","replace","Array","isArray","match","matchText","_","p1","parseInt","slice","index","length","join","template","DEFAULT_INDEX","DEFAULT_TEMPLATE","value","Strategy","props","cache","callback","searchWithCache","search","results","text","calculateElementOffset","getLineHeightPx","calculateLineHeightPx","createCustomEvent","window","CustomEvent","type","options","document","defaultView","cancelable","detail","undefined","event","createEvent","initCustomEvent","el","rect","getBoundingClientRect","ownerDocument","documentElement","offset","top","pageYOffset","left","pageXOffset","clientTop","clientLeft","CHAR_CODE_ZERO","charCodeAt","CHAR_CODE_NINE","isDigit","charCode","node","computedStyle","getComputedStyle","lineHeight","parseFloat","fontSize","nodeName","body","tempNode","createElement","innerHTML","style","fontFamily","padding","appendChild","HTMLTextAreaElement","rows","height","offsetHeight","removeChild","Editor","Error","code","moveEvent","emit","enterEvent","changeEvent","getBeforeCursor","escEvent","e","keyCode","ctrlKey","editors","global","Textcomplete","Textarea","CALLBACK_METHODS","editor","completer","isQueryInFlight","nextPendingQuery","dropdown","forEach","method","bind","startListening","destroyEditor","destroy","stopListening","deactivate","strategyPropsArray","registerStrategy","run","searchResults","render","getCursorOffset","trigger","up","down","activeItem","getActiveItem","select","preventDefault","shown","selectEvent","defaultPrevented","applySearchResult","searchResult","on","handleMove","handleEnter","handleEsc","handleChange","handleSelect","eventName","handleHit","removeAllListeners","removeListener","Completer","strategies","push","query","extractQuery","execute","handleQueryResult","i","build","Query","context","map","result","DEFAULT_CLASS_NAME","Dropdown","display","position","zIndex","items","footer","header","maxCount","className","rotate","hasOwnProperty","placement","itemOptions","item","Object","keys","key","parentNode","clear","_el","cursorOffset","renderEvent","rawResults","dropdownItems","setStrategyId","renderEdge","append","show","setOffset","hide","dropdownItem","moveActiveItem","fragment","createDocumentFragment","appended","doc","elementWidth","offsetWidth","browserWidth","clientWidth","right","isPlacementTop","bottom","clientHeight","showEvent","hideEvent","direction","nextActiveItem","next","prev","activate","strategyId","id","setAttribute","removeAttribute","source","content","li","classList","add","DropdownItem","active","activeClassName","removeEventListener","onClick","onMouseover","siblings","a","addEventListener","nextIndex","getCaretCoordinates","require","before","getAfterCursor","focus","dispatchEvent","Event","elOffset","elScroll","getElScroll","cursorPosition","getCursorPosition","dir","selectionStart","selectionEnd","substring","scrollTop","scrollLeft","emitChangeEvent","getCode","emitMoveEvent","emitEnterEvent","emitEscEvent","onInput","onKeydown"],"mappings":";AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;AC3DA;;;;;;;;AAEA;;;IAGqBA,Y;;AAKnB;;;AAGA,wBAAYC,IAAZ,EAA0BC,IAA1B,EAAwCC,QAAxC,EAA4D;AAAA;;AAC1D,SAAKF,IAAL,GAAYA,IAAZ;AACA,SAAKC,IAAL,GAAYA,IAAZ;AACA,SAAKC,QAAL,GAAgBA,QAAhB;AACD;;;;4BAEOC,Y,EAAsBC,W,EAAqB;AACjD,UAAIC,cAAc,KAAKH,QAAL,CAAcI,OAAd,CAAsB,KAAKN,IAA3B,CAAlB;AACA,UAAIK,gBAAgB,IAApB,EAA0B;AACxB,YAAIE,MAAMC,OAAN,CAAcH,WAAd,CAAJ,EAAgC;AAC9BD,wBAAcC,YAAY,CAAZ,IAAiBD,WAA/B;AACAC,wBAAcA,YAAY,CAAZ,CAAd;AACD;AACD,YAAMI,QAAQ,KAAKP,QAAL,CAAcQ,SAAd,CAAwBP,YAAxB,CAAd;AACA,YAAIM,KAAJ,EAAW;AACTJ,wBAAcA,YACXC,OADW,CACH,MADG,EACKG,MAAM,CAAN,CADL,EAEXH,OAFW,CAEH,SAFG,EAEQ,UAACK,CAAD,EAAIC,EAAJ;AAAA,mBAAWH,MAAMI,SAASD,EAAT,EAAa,EAAb,CAAN,CAAX;AAAA,WAFR,CAAd;AAGA,iBAAO,CACL,CACET,aAAaW,KAAb,CAAmB,CAAnB,EAAsBL,MAAMM,KAA5B,CADF,EAEEV,WAFF,EAGEF,aAAaW,KAAb,CAAmBL,MAAMM,KAAN,GAAcN,MAAM,CAAN,EAASO,MAA1C,CAHF,EAIEC,IAJF,CAIO,EAJP,CADK,EAMLb,WANK,CAAP;AAQD;AACF;AACF;;;6BAEgB;AACf,aAAO,KAAKF,QAAL,CAAcgB,QAAd,CAAuB,KAAKlB,IAA5B,EAAkC,KAAKC,IAAvC,CAAP;AACD;;;;;;kBAxCkBF,Y;;;;;;;ACPrB;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,SAAS;AACpB,WAAW,MAAM;AACjB,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,WAAW,cAAc;AACzB,WAAW,QAAQ;AACnB,aAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,0DAA0D,OAAO;AACjE;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,WAAW,cAAc;AACzB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,yCAAyC,SAAS;AAClD;AACA;;AAEA;AACA,GAAG;AACH;AACA;;AAEA,eAAe,YAAY;AAC3B;;AAEA;AACA,2DAA2D;AAC3D,+DAA+D;AAC/D,mEAAmE;AACnE,uEAAuE;AACvE;AACA,0DAA0D,SAAS;AACnE;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,WAAW,cAAc;AACzB,WAAW,SAAS;AACpB,WAAW,MAAM;AACjB,aAAa,aAAa;AAC1B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,WAAW,cAAc;AACzB,WAAW,SAAS;AACpB,WAAW,MAAM;AACjB,aAAa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","file":"textcomplete.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 5);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 0bc74e584933ddf1c7ac","// @flow\n\nimport Strategy from \"./strategy\"\n\n/**\n * Encapsulate an result of each search results.\n */\nexport default class SearchResult {\n data: Object\n term: string\n strategy: Strategy\n\n /**\n * @param {object} data - An element of array callbacked by search function.\n */\n constructor(data: Object, term: string, strategy: Strategy) {\n this.data = data\n this.term = term\n this.strategy = strategy\n }\n\n replace(beforeCursor: string, afterCursor: string) {\n let replacement = this.strategy.replace(this.data)\n if (replacement !== null) {\n if (Array.isArray(replacement)) {\n afterCursor = replacement[1] + afterCursor\n replacement = replacement[0]\n }\n const match = this.strategy.matchText(beforeCursor)\n if (match) {\n replacement = replacement\n .replace(/\\$&/g, match[0])\n .replace(/\\$(\\d)/g, (_, p1) => match[parseInt(p1, 10)])\n return [\n [\n beforeCursor.slice(0, match.index),\n replacement,\n beforeCursor.slice(match.index + match[0].length),\n ].join(\"\"),\n afterCursor,\n ]\n }\n }\n }\n\n render(): string {\n return this.strategy.template(this.data, this.term)\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/search_result.js","'use strict';\n\nvar has = Object.prototype.hasOwnProperty\n , prefix = '~';\n\n/**\n * Constructor to create a storage for our `EE` objects.\n * An `Events` instance is a plain object whose properties are event names.\n *\n * @constructor\n * @api private\n */\nfunction Events() {}\n\n//\n// We try to not inherit from `Object.prototype`. In some engines creating an\n// instance in this way is faster than calling `Object.create(null)` directly.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// character to make sure that the built-in object properties are not\n// overridden or used as an attack vector.\n//\nif (Object.create) {\n Events.prototype = Object.create(null);\n\n //\n // This hack is needed because the `__proto__` property is still inherited in\n // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.\n //\n if (!new Events().__proto__) prefix = false;\n}\n\n/**\n * Representation of a single event listener.\n *\n * @param {Function} fn The listener function.\n * @param {Mixed} context The context to invoke the listener with.\n * @param {Boolean} [once=false] Specify if the listener is a one-time listener.\n * @constructor\n * @api private\n */\nfunction EE(fn, context, once) {\n this.fn = fn;\n this.context = context;\n this.once = once || false;\n}\n\n/**\n * Minimal `EventEmitter` interface that is molded against the Node.js\n * `EventEmitter` interface.\n *\n * @constructor\n * @api public\n */\nfunction EventEmitter() {\n this._events = new Events();\n this._eventsCount = 0;\n}\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @api public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n var names = []\n , events\n , name;\n\n if (this._eventsCount === 0) return names;\n\n for (name in (events = this._events)) {\n if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n }\n\n if (Object.getOwnPropertySymbols) {\n return names.concat(Object.getOwnPropertySymbols(events));\n }\n\n return names;\n};\n\n/**\n * Return the listeners registered for a given event.\n *\n * @param {String|Symbol} event The event name.\n * @param {Boolean} exists Only check if there are listeners.\n * @returns {Array|Boolean}\n * @api public\n */\nEventEmitter.prototype.listeners = function listeners(event, exists) {\n var evt = prefix ? prefix + event : event\n , available = this._events[evt];\n\n if (exists) return !!available;\n if (!available) return [];\n if (available.fn) return [available.fn];\n\n for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) {\n ee[i] = available[i].fn;\n }\n\n return ee;\n};\n\n/**\n * Calls each of the listeners registered for a given event.\n *\n * @param {String|Symbol} event The event name.\n * @returns {Boolean} `true` if the event had listeners, else `false`.\n * @api public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return false;\n\n var listeners = this._events[evt]\n , len = arguments.length\n , args\n , i;\n\n if (listeners.fn) {\n if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n switch (len) {\n case 1: return listeners.fn.call(listeners.context), true;\n case 2: return listeners.fn.call(listeners.context, a1), true;\n case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n }\n\n for (i = 1, args = new Array(len -1); i < len; i++) {\n args[i - 1] = arguments[i];\n }\n\n listeners.fn.apply(listeners.context, args);\n } else {\n var length = listeners.length\n , j;\n\n for (i = 0; i < length; i++) {\n if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n switch (len) {\n case 1: listeners[i].fn.call(listeners[i].context); break;\n case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;\n default:\n if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n args[j - 1] = arguments[j];\n }\n\n listeners[i].fn.apply(listeners[i].context, args);\n }\n }\n }\n\n return true;\n};\n\n/**\n * Add a listener for a given event.\n *\n * @param {String|Symbol} event The event name.\n * @param {Function} fn The listener function.\n * @param {Mixed} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @api public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n var listener = new EE(fn, context || this)\n , evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) this._events[evt] = listener, this._eventsCount++;\n else if (!this._events[evt].fn) this._events[evt].push(listener);\n else this._events[evt] = [this._events[evt], listener];\n\n return this;\n};\n\n/**\n * Add a one-time listener for a given event.\n *\n * @param {String|Symbol} event The event name.\n * @param {Function} fn The listener function.\n * @param {Mixed} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @api public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n var listener = new EE(fn, context || this, true)\n , evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) this._events[evt] = listener, this._eventsCount++;\n else if (!this._events[evt].fn) this._events[evt].push(listener);\n else this._events[evt] = [this._events[evt], listener];\n\n return this;\n};\n\n/**\n * Remove the listeners of a given event.\n *\n * @param {String|Symbol} event The event name.\n * @param {Function} fn Only remove the listeners that match this function.\n * @param {Mixed} context Only remove the listeners that have this context.\n * @param {Boolean} once Only remove one-time listeners.\n * @returns {EventEmitter} `this`.\n * @api public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return this;\n if (!fn) {\n if (--this._eventsCount === 0) this._events = new Events();\n else delete this._events[evt];\n return this;\n }\n\n var listeners = this._events[evt];\n\n if (listeners.fn) {\n if (\n listeners.fn === fn\n && (!once || listeners.once)\n && (!context || listeners.context === context)\n ) {\n if (--this._eventsCount === 0) this._events = new Events();\n else delete this._events[evt];\n }\n } else {\n for (var i = 0, events = [], length = listeners.length; i < length; i++) {\n if (\n listeners[i].fn !== fn\n || (once && !listeners[i].once)\n || (context && listeners[i].context !== context)\n ) {\n events.push(listeners[i]);\n }\n }\n\n //\n // Reset the array, or remove it completely if we have no more listeners.\n //\n if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;\n else if (--this._eventsCount === 0) this._events = new Events();\n else delete this._events[evt];\n }\n\n return this;\n};\n\n/**\n * Remove all listeners, or those of the specified event.\n *\n * @param {String|Symbol} [event] The event name.\n * @returns {EventEmitter} `this`.\n * @api public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n var evt;\n\n if (event) {\n evt = prefix ? prefix + event : event;\n if (this._events[evt]) {\n if (--this._eventsCount === 0) this._events = new Events();\n else delete this._events[evt];\n }\n } else {\n this._events = new Events();\n this._eventsCount = 0;\n }\n\n return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// This function doesn't apply anymore.\n//\nEventEmitter.prototype.setMaxListeners = function setMaxListeners() {\n return this;\n};\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Allow `EventEmitter` to be imported as module namespace.\n//\nEventEmitter.EventEmitter = EventEmitter;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n module.exports = EventEmitter;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/eventemitter3/index.js\n// module id = 1\n// module chunks = 0","// @flow\n\ndeclare class MatchData extends Array<string> {\n index: number;\n}\n\nexport type { MatchData }\n\nconst DEFAULT_INDEX = 2\n\nfunction DEFAULT_TEMPLATE(value) {\n return value\n}\n\n/**\n * Properties for a strategy.\n *\n * @typedef\n */\nexport type StrategyProperties = {\n match: RegExp | (string => MatchData | null),\n search: Function,\n replace: any => string[] | string | null,\n cache?: boolean,\n context?: Function,\n template?: any => string,\n index?: number,\n id?: string,\n}\n\n/**\n * Encapsulate a single strategy.\n */\nexport default class Strategy {\n props: StrategyProperties\n cache: ?Object\n\n constructor(props: StrategyProperties) {\n this.props = props\n this.cache = props.cache ? {} : null\n }\n\n /**\n * @return {this}\n */\n destroy() {\n this.cache = null\n return this\n }\n\n search(term: string, callback: Function, match: MatchData): void {\n if (this.cache) {\n this.searchWithCache(term, callback, match)\n } else {\n this.props.search(term, callback, match)\n }\n }\n\n /**\n * @param {object} data - An element of array callbacked by search function.\n */\n replace(data: any) {\n return this.props.replace(data)\n }\n\n /** @private */\n searchWithCache(term: string, callback: Function, match: MatchData): void {\n if (this.cache && this.cache[term]) {\n callback(this.cache[term])\n } else {\n this.props.search(\n term,\n results => {\n if (this.cache) {\n this.cache[term] = results\n }\n callback(results)\n },\n match,\n )\n }\n }\n\n /** @private */\n matchText(text: string): MatchData | null {\n if (typeof this.match === \"function\") {\n return this.match(text)\n } else {\n return (text.match(this.match): any)\n }\n }\n\n /** @private */\n get match(): $PropertyType<StrategyProperties, \"match\"> {\n return this.props.match\n }\n\n /** @private */\n get index(): number {\n return typeof this.props.index === \"number\"\n ? this.props.index\n : DEFAULT_INDEX\n }\n\n get template(): (...any) => string {\n return this.props.template || DEFAULT_TEMPLATE\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/strategy.js","// @flow\n\n/**\n * Create a custom event\n *\n * @private\n */\nexport const createCustomEvent = (() => {\n if (typeof window.CustomEvent === \"function\") {\n return function(\n type: string,\n options: ?{ detail?: Object, cancelable?: boolean },\n ): CustomEvent {\n return new document.defaultView.CustomEvent(type, {\n cancelable: (options && options.cancelable) || false,\n detail: (options && options.detail) || undefined,\n })\n }\n } else {\n // Custom event polyfill from\n // https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#polyfill\n return function(\n type: string,\n options: ?{ detail?: Object, cancelable?: boolean },\n ): CustomEvent {\n const event = document.createEvent(\"CustomEvent\")\n event.initCustomEvent(\n type,\n /* bubbles */ false,\n (options && options.cancelable) || false,\n (options && options.detail) || undefined,\n )\n return event\n }\n }\n})()\n\n/**\n * Get the current coordinates of the `el` relative to the document.\n *\n * @private\n */\nexport function calculateElementOffset(\n el: HTMLElement,\n): { top: number, left: number } {\n const rect = el.getBoundingClientRect()\n const { defaultView, documentElement } = el.ownerDocument\n const offset = {\n top: rect.top + defaultView.pageYOffset,\n left: rect.left + defaultView.pageXOffset,\n }\n if (documentElement) {\n offset.top -= documentElement.clientTop\n offset.left -= documentElement.clientLeft\n }\n return offset\n}\n\nconst CHAR_CODE_ZERO = \"0\".charCodeAt(0)\nconst CHAR_CODE_NINE = \"9\".charCodeAt(0)\n\nfunction isDigit(charCode: number): boolean {\n return charCode >= CHAR_CODE_ZERO && charCode <= CHAR_CODE_NINE\n}\n\n/**\n * Returns the line-height of the given node in pixels.\n *\n * @private\n */\nexport function getLineHeightPx(node: HTMLElement): number {\n const computedStyle = window.getComputedStyle(node)\n\n // If the char code starts with a digit, it is either a value in pixels,\n // or unitless, as per:\n // https://drafts.csswg.org/css2/visudet.html#propdef-line-height\n // https://drafts.csswg.org/css2/cascade.html#computed-value\n if (isDigit(computedStyle.lineHeight.charCodeAt(0))) {\n // In real browsers the value is *always* in pixels, even for unit-less\n // line-heights. However, we still check as per the spec.\n if (\n isDigit(\n computedStyle.lineHeight.charCodeAt(\n computedStyle.lineHeight.length - 1,\n ),\n )\n ) {\n return (\n parseFloat(computedStyle.lineHeight) *\n parseFloat(computedStyle.fontSize)\n )\n } else {\n return parseFloat(computedStyle.lineHeight)\n }\n }\n\n // Otherwise, the value is \"normal\".\n // If the line-height is \"normal\", calculate by font-size\n return calculateLineHeightPx(node.nodeName, computedStyle)\n}\n\n/**\n * Returns calculated line-height of the given node in pixels.\n *\n * @private\n */\nexport function calculateLineHeightPx(\n nodeName: string,\n computedStyle: CSSStyleDeclaration,\n): number {\n const body = document.body\n if (!body) {\n return 0\n }\n\n const tempNode = document.createElement(nodeName)\n tempNode.innerHTML = \"&nbsp;\"\n tempNode.style.fontSize = computedStyle.fontSize\n tempNode.style.fontFamily = computedStyle.fontFamily\n tempNode.style.padding = \"0\"\n body.appendChild(tempNode)\n\n // Make sure textarea has only 1 row\n if (tempNode instanceof HTMLTextAreaElement) {\n ;(tempNode: HTMLTextAreaElement).rows = 1\n }\n\n // Assume the height of the element is the line-height\n const height = tempNode.offsetHeight\n body.removeChild(tempNode)\n\n return height\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/utils.js","// @flow\n/*eslint no-unused-vars: off*/\n\nimport EventEmitter from \"eventemitter3\"\n\nimport { createCustomEvent } from \"./utils\"\nimport SearchResult from \"./search_result\"\n\n/** @typedef */\nexport type CursorOffset = {\n lineHeight: number,\n top: number,\n left?: number,\n right?: number,\n}\n\ntype KeyCode = \"ESC\" | \"ENTER\" | \"UP\" | \"DOWN\" | \"OTHER\"\n\n/**\n * Abstract class representing a editor target.\n *\n * Editor classes must implement `#applySearchResult`, `#getCursorOffset` and\n * `#getBeforeCursor` methods.\n *\n * Editor classes must invoke `#emitMoveEvent`, `#emitEnterEvent`,\n * `#emitChangeEvent` and `#emitEscEvent` at proper timing.\n *\n * @abstract\n */\nexport default class Editor extends EventEmitter {\n /**\n * It is called when associated textcomplete object is destroyed.\n *\n * @return {this}\n */\n destroy() {\n return this\n }\n\n /**\n * It is called when a search result is selected by a user.\n */\n applySearchResult(_: SearchResult): void {\n throw new Error(\"Not implemented.\")\n }\n\n /**\n * The input cursor's absolute coordinates from the window's left\n * top corner.\n */\n getCursorOffset(): CursorOffset {\n throw new Error(\"Not implemented.\")\n }\n\n /**\n * Editor string value from head to cursor.\n * Returns null if selection type is range not cursor.\n */\n getBeforeCursor(): ?string {\n throw new Error(\"Not implemented.\")\n }\n\n /**\n * Emit a move event, which moves active dropdown element.\n * Child class must call this method at proper timing with proper parameter.\n *\n * @see {@link Textarea} for live example.\n */\n emitMoveEvent(code: \"UP\" | \"DOWN\"): CustomEvent {\n const moveEvent = createCustomEvent(\"move\", {\n cancelable: true,\n detail: {\n code: code,\n },\n })\n this.emit(\"move\", moveEvent)\n return moveEvent\n }\n\n /**\n * Emit a enter event, which selects current search result.\n * Child class must call this method at proper timing.\n *\n * @see {@link Textarea} for live example.\n */\n emitEnterEvent(): CustomEvent {\n const enterEvent = createCustomEvent(\"enter\", { cancelable: true })\n this.emit(\"enter\", enterEvent)\n return enterEvent\n }\n\n /**\n * Emit a change event, which triggers auto completion.\n * Child class must call this method at proper timing.\n *\n * @see {@link Textarea} for live example.\n */\n emitChangeEvent(): CustomEvent {\n const changeEvent = createCustomEvent(\"change\", {\n detail: {\n beforeCursor: this.getBeforeCursor(),\n },\n })\n this.emit(\"change\", changeEvent)\n return changeEvent\n }\n\n /**\n * Emit a esc event, which hides dropdown element.\n * Child class must call this method at proper timing.\n *\n * @see {@link Textarea} for live example.\n */\n emitEscEvent(): CustomEvent {\n const escEvent = createCustomEvent(\"esc\", { cancelable: true })\n this.emit(\"esc\", escEvent)\n return escEvent\n }\n\n /**\n * Helper method for parsing KeyboardEvent.\n *\n * @see {@link Textarea} for live example.\n */\n getCode(e: KeyboardEvent): KeyCode {\n return e.keyCode === 9\n ? \"ENTER\" // tab\n : e.keyCode === 13\n ? \"ENTER\" // enter\n : e.keyCode === 27\n ? \"ESC\" // esc\n : e.keyCode === 38\n ? \"UP\" // up\n : e.keyCode === 40\n ? \"DOWN\" // down\n : e.keyCode === 78 && e.ctrlKey\n ? \"DOWN\" // ctrl-n\n : e.keyCode === 80 && e.ctrlKey\n ? \"UP\" // ctrl-p\n : \"OTHER\"\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/editor.js","import Textcomplete from \"./textcomplete\"\nimport Textarea from \"./textarea\"\n\nlet editors\nif (global.Textcomplete && global.Textcomplete.editors) {\n editors = global.Textcomplete.editors\n} else {\n editors = {}\n}\neditors.Textarea = Textarea\n\nglobal.Textcomplete = Textcomplete\nglobal.Textcomplete.editors = editors\n\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","var g;\r\n\r\n// This works in non-strict mode\r\ng = (function() {\r\n\treturn this;\r\n})();\r\n\r\ntry {\r\n\t// This works if eval is allowed (see CSP)\r\n\tg = g || Function(\"return this\")() || (1,eval)(\"this\");\r\n} catch(e) {\r\n\t// This works if the window reference is available\r\n\tif(typeof window === \"object\")\r\n\t\tg = window;\r\n}\r\n\r\n// g can still be undefined, but nothing to do about it...\r\n// We return undefined, instead of nothing here, so it's\r\n// easier to handle this case. if(!global) { ...}\r\n\r\nmodule.exports = g;\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// (webpack)/buildin/global.js\n// module id = 6\n// module chunks = 0","// @flow\n\nimport Completer from \"./completer\"\nimport Editor from \"./editor\"\nimport Dropdown, { type DropdownOptions } from \"./dropdown\"\nimport Strategy, { type StrategyProperties } from \"./strategy\"\nimport SearchResult from \"./search_result\"\n\nimport EventEmitter from \"eventemitter3\"\n\nconst CALLBACK_METHODS = [\n \"handleChange\",\n \"handleEnter\",\n \"handleEsc\",\n \"handleHit\",\n \"handleMove\",\n \"handleSelect\",\n]\n\n/** @typedef */\ntype TextcompleteOptions = {\n dropdown?: DropdownOptions,\n}\n\n/**\n * The core of textcomplete. It acts as a mediator.\n */\nexport default class Textcomplete extends EventEmitter {\n dropdown: Dropdown\n editor: Editor\n options: TextcompleteOptions\n completer: Completer\n isQueryInFlight: boolean\n nextPendingQuery: string | null\n\n /**\n * @param {Editor} editor - Where the textcomplete works on.\n */\n constructor(editor: Editor, options: TextcompleteOptions = {}) {\n super()\n\n this.completer = new Completer()\n this.isQueryInFlight = false\n this.nextPendingQuery = null\n this.dropdown = new Dropdown(options.dropdown || {})\n this.editor = editor\n this.options = options\n\n CALLBACK_METHODS.forEach(method => {\n ;(this: any)[method] = (this: any)[method].bind(this)\n })\n\n this.startListening()\n }\n\n /**\n * @return {this}\n */\n destroy(destroyEditor: boolean = true) {\n this.completer.destroy()\n this.dropdown.destroy()\n if (destroyEditor) {\n this.editor.destroy()\n }\n this.stopListening()\n return this\n }\n\n /**\n * @return {this}\n */\n hide() {\n this.dropdown.deactivate()\n return this\n }\n\n /**\n * @return {this}\n * @example\n * textcomplete.register([{\n * match: /(^|\\s)(\\w+)$/,\n * search: function (term, callback) {\n * $.ajax({ ... })\n * .done(callback)\n * .fail([]);\n * },\n * replace: function (value) {\n * return '$1' + value + ' ';\n * }\n * }]);\n */\n register(strategyPropsArray: StrategyProperties[]) {\n strategyPropsArray.forEach(props => {\n this.completer.registerStrategy(new Strategy(props))\n })\n return this\n }\n\n /**\n * Start autocompleting.\n *\n * @param {string} text - Head to input cursor.\n * @return {this}\n */\n trigger(text: string) {\n if (this.isQueryInFlight) {\n this.nextPendingQuery = text\n } else {\n this.isQueryInFlight = true\n this.nextPendingQuery = null\n this.completer.run(text)\n }\n return this\n }\n\n /** @private */\n handleHit({ searchResults }: { searchResults: SearchResult[] }) {\n if (searchResults.length) {\n this.dropdown.render(searchResults, this.editor.getCursorOffset())\n } else {\n this.dropdown.deactivate()\n }\n this.isQueryInFlight = false\n if (this.nextPendingQuery !== null) {\n this.trigger(this.nextPendingQuery)\n }\n }\n\n /** @private */\n handleMove(e: CustomEvent) {\n e.detail.code === \"UP\" ? this.dropdown.up(e) : this.dropdown.down(e)\n }\n\n /** @private */\n handleEnter(e: CustomEvent) {\n const activeItem = this.dropdown.getActiveItem()\n if (activeItem) {\n this.dropdown.select(activeItem)\n e.preventDefault()\n } else {\n this.dropdown.deactivate()\n }\n }\n\n /** @private */\n handleEsc(e: CustomEvent) {\n if (this.dropdown.shown) {\n this.dropdown.deactivate()\n e.preventDefault()\n }\n }\n\n /** @private */\n handleChange(e: CustomEvent) {\n if (e.detail.beforeCursor != null) {\n this.trigger(e.detail.beforeCursor)\n } else {\n this.dropdown.deactivate()\n }\n }\n\n /** @private */\n handleSelect(selectEvent: CustomEvent) {\n this.emit(\"select\", selectEvent)\n if (!selectEvent.defaultPrevented) {\n this.editor.applySearchResult(selectEvent.detail.searchResult)\n }\n }\n\n /** @private */\n startListening() {\n this.editor\n .on(\"move\", this.handleMove)\n .on(\"enter\", this.handleEnter)\n .on(\"esc\", this.handleEsc)\n .on(\"change\", this.handleChange)\n this.dropdown.on(\"select\", this.handleSelect)\n ;[\n \"show\",\n \"shown\",\n \"render\",\n \"rendered\",\n \"selected\",\n \"hidden\",\n \"hide\",\n ].forEach(eventName => {\n this.dropdown.on(eventName, () => this.emit(eventName))\n })\n this.completer.on(\"hit\", this.handleHit)\n }\n\n /** @private */\n stopListening() {\n this.completer.removeAllListeners()\n this.dropdown.removeAllListeners()\n this.editor\n .removeListener(\"move\", this.handleMove)\n .removeListener(\"enter\", this.handleEnter)\n .removeListener(\"esc\", this.handleEsc)\n .removeListener(\"change\", this.handleChange)\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/textcomplete.js","// @flow\n\nimport EventEmitter from \"eventemitter3\"\n\nimport Query from \"./query\"\nimport SearchResult from \"./search_result\"\nimport Strategy from \"./strategy\"\n\nconst CALLBACK_METHODS = [\"handleQueryResult\"]\n\n/**\n * Complete engine.\n */\nexport default class Completer extends EventEmitter {\n strategies: Strategy[]\n\n constructor() {\n super()\n this.strategies = []\n\n CALLBACK_METHODS.forEach(method => {\n ;(this: any)[method] = (this: any)[method].bind(this)\n })\n }\n\n /**\n * @return {this}\n */\n destroy() {\n this.strategies.forEach(strategy => strategy.destroy())\n return this\n }\n\n /**\n * Register a strategy to the completer.\n *\n * @return {this}\n */\n registerStrategy(strategy: Strategy) {\n this.strategies.push(strategy)\n return this\n }\n\n /**\n * @param {string} text - Head to input cursor.\n */\n run(text: string): void {\n const query = this.extractQuery(text)\n if (query) {\n query.execute(this.handleQueryResult)\n } else {\n this.handleQueryResult([])\n }\n }\n\n /**\n * Find a query, which matches to the given text.\n *\n * @private\n */\n extractQuery(text: string) {\n for (let i = 0; i < this.strategies.length; i++) {\n const query = Query.build(this.strategies[i], text)\n if (query) {\n return query\n }\n }\n return null\n }\n\n /**\n * Callbacked by {@link Query#execute}.\n *\n * @private\n */\n handleQueryResult(searchResults: SearchResult[]) {\n this.emit(\"hit\", { searchResults })\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/completer.js","// @flow\n\nimport SearchResult from \"./search_result\"\nimport Strategy from \"./strategy\"\nimport type { MatchData } from \"./strategy\"\n\n/**\n * Encapsulate matching condition between a Strategy and current editor's value.\n */\nexport default class Query {\n strategy: Strategy\n term: string\n match: MatchData\n\n /**\n * Build a Query object by the given string if this matches to the string.\n *\n * @param {string} text - Head to input cursor.\n */\n static build(strategy: Strategy, text: string): ?Query {\n if (typeof strategy.props.context === \"function\") {\n const context = strategy.props.context(text)\n if (typeof context === \"string\") {\n text = context\n } else if (!context) {\n return null\n }\n }\n const match = strategy.matchText(text)\n return match ? new Query(strategy, match[strategy.index], match) : null\n }\n\n constructor(strategy: Strategy, term: string, match: MatchData) {\n this.strategy = strategy\n this.term = term\n this.match = match\n }\n\n /**\n * Invoke search strategy and callback the given function.\n */\n execute(callback: (SearchResult[]) => void) {\n this.strategy.search(\n this.term,\n results => {\n callback(\n results.map(result => {\n return new SearchResult(result, this.term, this.strategy)\n }),\n )\n },\n this.match,\n )\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/query.js","// @flow\nimport EventEmitter from \"eventemitter3\"\n\nimport DropdownItem, { type DropdownItemOptions } from \"./dropdown_item\"\nimport SearchResult from \"./search_result\"\nimport { createCustomEvent } from \"./utils\"\nimport type { CursorOffset } from \"./editor\"\n\nconst DEFAULT_CLASS_NAME = \"dropdown-menu textcomplete-dropdown\"\n\n/** @typedef */\nexport type DropdownOptions = {\n className?: string,\n footer?: any => string | string,\n header?: any => string | string,\n maxCount?: number,\n placement?: string,\n rotate?: boolean,\n style?: { [string]: string },\n item?: DropdownItemOptions,\n}\n\n/**\n * Encapsulate a dropdown view.\n *\n * @prop {boolean} shown - Whether the #el is shown or not.\n * @prop {DropdownItem[]} items - The array of rendered dropdown items.\n */\nexport default class Dropdown extends EventEmitter {\n shown: boolean\n items: DropdownItem[]\n activeItem: DropdownItem | null\n footer: $PropertyType<DropdownOptions, \"footer\">\n header: $PropertyType<DropdownOptions, \"header\">\n maxCount: $PropertyType<DropdownOptions, \"maxCount\">\n rotate: $PropertyType<DropdownOptions, \"rotate\">\n placement: $PropertyType<DropdownOptions, \"placement\">\n itemOptions: DropdownItemOptions\n _el: ?HTMLUListElement\n\n static createElement(): HTMLUListElement {\n const el = document.createElement(\"ul\")\n const style = el.style\n style.display = \"none\"\n style.position = \"absolute\"\n style.zIndex = \"10000\"\n const body = document.body\n if (body) {\n body.appendChild(el)\n }\n return el\n }\n\n constructor(options: DropdownOptions) {\n super()\n this.shown = false\n this.items = []\n this.activeItem = null\n this.footer = options.footer\n this.header = options.header\n this.maxCount = options.maxCount || 10\n this.el.className = options.className || DEFAULT_CLASS_NAME\n this.rotate = options.hasOwnProperty(\"rotate\") ? options.rotate : true\n this.placement = options.placement\n this.itemOptions = options.item || {}\n const style = options.style\n if (style) {\n Object.keys(style).forEach(key => {\n ;(this.el.style: any)[key] = style[key]\n })\n }\n }\n\n /**\n * @return {this}\n */\n destroy() {\n const parentNode = this.el.parentNode\n if (parentNode) {\n parentNode.removeChild(this.el)\n }\n this.clear()._el = null\n return this\n }\n\n get el(): HTMLUListElement {\n if (!this._el) {\n this._el = Dropdown.createElement()\n }\n return this._el\n }\n\n /**\n * Render the given data as dropdown items.\n *\n * @return {this}\n */\n render(searchResults: SearchResult[], cursorOffset: CursorOffset) {\n const renderEvent = createCustomEvent(\"render\", { cancelable: true })\n this.emit(\"render\", renderEvent)\n if (renderEvent.defaultPrevented) {\n return this\n }\n const rawResults = searchResults.map(searchResult => searchResult.data)\n const dropdownItems = searchResults\n .slice(0, this.maxCount || searchResults.length)\n .map(searchResult => new DropdownItem(searchResult, this.itemOptions))\n this.clear()\n .setStrategyId(searchResults[0])\n .renderEdge(rawResults, \"header\")\n .append(dropdownItems)\n .renderEdge(rawResults, \"footer\")\n .show()\n .setOffset(cursorOffset)\n this.emit(\"rendered\", createCustomEvent(\"rendered\"))\n return this\n }\n\n /**\n * Hide the dropdown then sweep out items.\n *\n * @return {this}\n */\n deactivate() {\n return this.hide().clear()\n }\n\n /**\n * @return {this}\n */\n select(dropdownItem: DropdownItem) {\n const detail = { searchResult: dropdownItem.searchResult }\n const selectEvent = createCustomEvent(\"select\", {\n cancelable: true,\n detail: detail,\n })\n this.emit(\"select\", selectEvent)\n if (selectEvent.defaultPrevented) {\n return this\n }\n this.deactivate()\n this.emit(\"selected\", createCustomEvent(\"selected\", { detail }))\n return this\n }\n\n /**\n * @return {this}\n */\n up(e: CustomEvent) {\n return this.shown ? this.moveActiveItem(\"prev\", e) : this\n }\n\n /**\n * @return {this}\n */\n down(e: CustomEvent) {\n return this.shown ? this.moveActiveItem(\"next\", e) : this\n }\n\n /**\n * Retrieve the active item.\n */\n getActiveItem(): DropdownItem | null {\n return this.activeItem\n }\n\n /**\n * Add items to dropdown.\n *\n * @private\n */\n append(items: DropdownItem[]) {\n const fragment = document.createDocumentFragment()\n items.forEach(item => {\n this.items.push(item)\n item.appended(this)\n fragment.appendChild(item.el)\n })\n this.el.appendChild(fragment)\n return this\n }\n\n /** @private */\n setOffset(cursorOffset: CursorOffset) {\n const doc = document.documentElement\n if (doc) {\n const elementWidth = this.el.offsetWidth\n if (cursorOffset.left) {\n const browserWidth = doc.clientWidth\n if (cursorOffset.left + elementWidth > browserWidth) {\n cursorOffset.left = browserWidth - elementWidth\n }\n this.el.style.left = `${cursorOffset.left}px`\n } else if (cursorOffset.right) {\n if (cursorOffset.right - elementWidth < 0) {\n cursorOffset.right = 0\n }\n this.el.style.right = `${cursorOffset.right}px`\n }\n if (this.isPlacementTop()) {\n this.el.style.bottom = `${doc.clientHeight -\n cursorOffset.top +\n cursorOffset.lineHeight}px`\n } else {\n this.el.style.top = `${cursorOffset.top}px`\n }\n }\n return this\n }\n\n /**\n * Show the element.\n *\n * @private\n */\n show() {\n if (!this.shown) {\n const showEvent = createCustomEvent(\"show\", { cancelable: true })\n this.emit(\"show\", showEvent)\n if (showEvent.defaultPrevented) {\n return this\n }\n this.el.style.display = \"block\"\n this.shown = true\n this.emit(\"shown\", createCustomEvent(\"shown\"))\n }\n return this\n }\n\n /**\n * Hide the element.\n *\n * @private\n */\n hide() {\n if (this.shown) {\n const hideEvent = createCustomEvent(\"hide\", { cancelable: true })\n this.emit(\"hide\", hideEvent)\n if (hideEvent.defaultPrevented) {\n return this\n }\n this.el.style.display = \"none\"\n this.shown = false\n this.emit(\"hidden\", createCustomEvent(\"hidden\"))\n }\n return this\n }\n\n /**\n * Clear search results.\n *\n * @private\n */\n clear() {\n this.el.innerHTML = \"\"\n this.items.forEach(item => item.destroy())\n this.items = []\n return this\n }\n\n /** @private */\n moveActiveItem(direction: \"next\" | \"prev\", e: CustomEvent) {\n const nextActiveItem =\n direction === \"next\"\n ? this.activeItem ? this.activeItem.next : this.items[0]\n : this.activeItem\n ? this.activeItem.prev\n : this.items[this.items.length - 1]\n if (nextActiveItem) {\n nextActiveItem.activate()\n e.preventDefault()\n }\n return this\n }\n\n /** @private */\n setStrategyId(searchResult: ?SearchResult) {\n const strategyId = searchResult && searchResult.strategy.props.id\n if (strategyId) {\n this.el.setAttribute(\"data-strategy\", strategyId)\n } else {\n this.el.removeAttribute(\"data-strategy\")\n }\n return this\n }\n\n /**\n * @private\n * @param {object[]} rawResults - What callbacked by search function.\n */\n renderEdge(rawResults: Object[], type: \"header\" | \"footer\") {\n const source = (type === \"header\" ? this.header : this.footer) || \"\"\n const content: any =\n typeof source === \"function\" ? source(rawResults) : source\n const li = document.createElement(\"li\")\n li.classList.add(`textcomplete-${type}`)\n li.innerHTML = content\n this.el.appendChild(li)\n return this\n }\n\n /** @private */\n isPlacementTop() {\n return this.placement === \"top\"\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/dropdown.js","// @flow\n\nimport SearchResult from \"./search_result\"\n\nexport const DEFAULT_CLASS_NAME = \"textcomplete-item\"\nconst CALLBACK_METHODS = [\"onClick\", \"onMouseover\"]\n\n/** @typedef */\nexport type DropdownItemOptions = {\n className?: string,\n}\n\n// Declare interface instead of importing Dropdown itself to prevent circular dependency.\ninterface Dropdown {\n activeItem: DropdownItem | null;\n items: DropdownItem[];\n rotate: ?Boolean;\n getActiveItem(): DropdownItem | null;\n select(DropdownItem): DropdownItem;\n}\n\n/**\n * Encapsulate an item of dropdown.\n */\nexport default class DropdownItem {\n searchResult: SearchResult\n active: boolean\n className: string\n activeClassName: string\n siblings: DropdownItem[]\n dropdown: Dropdown\n index: number\n _el: ?HTMLLIElement\n\n constructor(searchResult: SearchResult, options: DropdownItemOptions) {\n this.searchResult = searchResult\n this.active = false\n this.className = options.className || DEFAULT_CLASS_NAME\n this.activeClassName = `${this.className} active`\n\n CALLBACK_METHODS.forEach(method => {\n ;(this: any)[method] = (this: any)[method].bind(this)\n })\n }\n\n get el(): HTMLLIElement {\n if (this._el) {\n return this._el\n }\n const li = document.createElement(\"li\")\n li.className = this.active ? this.activeClassName : this.className\n const a = document.createElement(\"a\")\n a.innerHTML = this.searchResult.render()\n li.appendChild(a)\n this._el = li\n li.addEventListener(\"mousedown\", this.onClick)\n li.addEventListener(\"mouseover\", this.onMouseover)\n li.addEventListener(\"touchstart\", this.onClick)\n return li\n }\n\n /**\n * Try to free resources and perform other cleanup operations.\n */\n destroy() {\n this.el.removeEventListener(\"mousedown\", this.onClick, false)\n this.el.removeEventListener(\"mouseover\", this.onMouseover, false)\n this.el.removeEventListener(\"touchstart\", this.onClick, false)\n if (this.active) {\n this.dropdown.activeItem = null\n }\n // This element has already been removed by {@link Dropdown#clear}.\n this._el = null\n }\n\n /**\n * Callbacked when it is appended to a dropdown.\n *\n * @see Dropdown#append\n */\n appended(dropdown: Dropdown) {\n this.dropdown = dropdown\n this.siblings = dropdown.items\n this.index = this.siblings.length - 1\n }\n\n /**\n * Deactivate active item then activate itself.\n *\n * @return {this}\n */\n activate() {\n if (!this.active) {\n const activeItem = this.dropdown.getActiveItem()\n if (activeItem) {\n activeItem.deactivate()\n }\n this.dropdown.activeItem = this\n this.active = true\n this.el.className = this.activeClassName\n }\n return this\n }\n\n /**\n * Get the next sibling.\n */\n get next(): ?DropdownItem {\n let nextIndex\n if (this.index === this.siblings.length - 1) {\n if (!this.dropdown.rotate) {\n return null\n }\n nextIndex = 0\n } else {\n nextIndex = this.index + 1\n }\n return this.siblings[nextIndex]\n }\n\n /**\n * Get the previous sibling.\n */\n get prev(): ?DropdownItem {\n let nextIndex\n if (this.index === 0) {\n if (!this.dropdown.rotate) {\n return null\n }\n nextIndex = this.siblings.length - 1\n } else {\n nextIndex = this.index - 1\n }\n return this.siblings[nextIndex]\n }\n\n /** @private */\n deactivate() {\n if (this.active) {\n this.active = false\n this.el.className = this.className\n this.dropdown.activeItem = null\n }\n return this\n }\n\n /** @private */\n onClick(e: Event) {\n e.preventDefault() // Prevent blur event\n this.dropdown.select(this)\n }\n\n /** @private */\n onMouseover() {\n this.activate()\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/dropdown_item.js","// @flow\n\nimport update from \"undate/lib/update\"\n\nimport Editor from \"./editor\"\nimport { calculateElementOffset, getLineHeightPx } from \"./utils\"\nimport SearchResult from \"./search_result\"\n\nconst getCaretCoordinates = require(\"textarea-caret\")\n\nconst CALLBACK_METHODS = [\"onInput\", \"onKeydown\"]\n\n/**\n * Encapsulate the target textarea element.\n */\nexport default class Textarea extends Editor {\n el: HTMLTextAreaElement\n\n /**\n * @param {HTMLTextAreaElement} el - Where the textcomplete works on.\n */\n constructor(el: HTMLTextAreaElement) {\n super()\n this.el = el\n\n CALLBACK_METHODS.forEach(method => {\n ;(this: any)[method] = (this: any)[method].bind(this)\n })\n\n this.startListening()\n }\n\n /**\n * @return {this}\n */\n destroy() {\n super.destroy()\n this.stopListening()\n // Release the element reference early to help garbage collection.\n ;(this: any).el = null\n return this\n }\n\n /**\n * Implementation for {@link Editor#applySearchResult}\n */\n applySearchResult(searchResult: SearchResult) {\n const before = this.getBeforeCursor()\n if (before != null) {\n const replace = searchResult.replace(before, this.getAfterCursor())\n this.el.focus() // Clicking a dropdown item removes focus from the element.\n if (Array.isArray(replace)) {\n update(this.el, replace[0], replace[1])\n this.el.dispatchEvent(new Event(\"input\"))\n }\n }\n }\n\n /**\n * Implementation for {@link Editor#getCursorOffset}\n */\n getCursorOffset() {\n const elOffset = calculateElementOffset(this.el)\n const elScroll = this.getElScroll()\n const cursorPosition = this.getCursorPosition()\n const lineHeight = getLineHeightPx(this.el)\n const top = elOffset.top - elScroll.top + cursorPosition.top + lineHeight\n const left = elOffset.left - elScroll.left + cursorPosition.left\n if (this.el.dir !== \"rtl\") {\n return { top, left, lineHeight }\n } else {\n const right = document.documentElement\n ? document.documentElement.clientWidth - left\n : 0\n return { top, right, lineHeight }\n }\n }\n\n /**\n * Implementation for {@link Editor#getBeforeCursor}\n */\n getBeforeCursor() {\n return this.el.selectionStart !== this.el.selectionEnd\n ? null\n : this.el.value.substring(0, this.el.selectionEnd)\n }\n\n /** @private */\n getAfterCursor() {\n return this.el.value.substring(this.el.selectionEnd)\n }\n\n /** @private */\n getElScroll(): { top: number, left: number } {\n return { top: this.el.scrollTop, left: this.el.scrollLeft }\n }\n\n /**\n * The input cursor's relative coordinates from the textarea's left\n * top corner.\n *\n * @private\n */\n getCursorPosition(): { top: number, left: number } {\n return getCaretCoordinates(this.el, this.el.selectionEnd)\n }\n\n /** @private */\n onInput() {\n this.emitChangeEvent()\n }\n\n /** @private */\n onKeydown(e: KeyboardEvent) {\n const code = this.getCode(e)\n let event\n if (code === \"UP\" || code === \"DOWN\") {\n event = this.emitMoveEvent(code)\n } else if (code === \"ENTER\") {\n event = this.emitEnterEvent()\n } else if (code === \"ESC\") {\n event = this.emitEscEvent()\n }\n if (event && event.defaultPrevented) {\n e.preventDefault()\n }\n }\n\n /** @private */\n startListening() {\n this.el.addEventListener(\"input\", this.onInput)\n this.el.addEventListener(\"keydown\", this.onKeydown)\n }\n\n /** @private */\n stopListening() {\n this.el.removeEventListener(\"input\", this.onInput)\n this.el.removeEventListener(\"keydown\", this.onKeydown)\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/textarea.js","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nexports.default = function (el, headToCursor, cursorToTail) {\n var curr = el.value,\n // strA + strB1 + strC\n next = headToCursor + (cursorToTail || ''),\n // strA + strB2 + strC\n activeElement = document.activeElement;\n\n // Calculate length of strA and strC\n var aLength = 0,\n cLength = 0;\n while (aLength < curr.length && aLength < next.length && curr[aLength] === next[aLength]) {\n aLength++;\n }\n while (curr.length - cLength - 1 >= 0 && next.length - cLength - 1 >= 0 && curr[curr.length - cLength - 1] === next[next.length - cLength - 1]) {\n cLength++;\n }\n aLength = Math.min(aLength, Math.min(curr.length, next.length) - cLength);\n\n // Select strB1\n el.setSelectionRange(aLength, curr.length - cLength);\n\n // Get strB2\n var strB2 = next.substring(aLength, next.length - cLength);\n\n // Replace strB1 with strB2\n el.focus();\n if (!document.execCommand('insertText', false, strB2)) {\n // Document.execCommand returns false if the command is not supported.\n // Firefox and IE returns false in this case.\n el.value = next;\n el.dispatchEvent(createInputEvent());\n }\n\n // Move cursor to the end of headToCursor\n el.setSelectionRange(headToCursor.length, headToCursor.length);\n\n activeElement && activeElement.focus();\n return el;\n};\n\nfunction createInputEvent() {\n if (typeof Event !== \"undefined\") {\n return new Event(\"input\", { bubbles: true, cancelable: true });\n } else {\n var event = document.createEvent(\"Event\");\n event.initEvent(\"input\", true, true);\n return event;\n }\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/undate/lib/update.js\n// module id = 13\n// module chunks = 0","/* jshint browser: true */\n\n(function () {\n\n// The properties that we copy into a mirrored div.\n// Note that some browsers, such as Firefox,\n// do not concatenate properties, i.e. padding-top, bottom etc. -> padding,\n// so we have to do every single property specifically.\nvar properties = [\n 'direction', // RTL support\n 'boxSizing',\n 'width', // on Chrome and IE, exclude the scrollbar, so the mirror div wraps exactly as the textarea does\n 'height',\n 'overflowX',\n 'overflowY', // copy the scrollbar for IE\n\n 'borderTopWidth',\n 'borderRightWidth',\n 'borderBottomWidth',\n 'borderLeftWidth',\n 'borderStyle',\n\n 'paddingTop',\n 'paddingRight',\n 'paddingBottom',\n 'paddingLeft',\n\n // https://developer.mozilla.org/en-US/docs/Web/CSS/font\n 'fontStyle',\n 'fontVariant',\n 'fontWeight',\n 'fontStretch',\n 'fontSize',\n 'fontSizeAdjust',\n 'lineHeight',\n 'fontFamily',\n\n 'textAlign',\n 'textTransform',\n 'textIndent',\n 'textDecoration', // might not make a difference, but better be safe\n\n 'letterSpacing',\n 'wordSpacing',\n\n 'tabSize',\n 'MozTabSize'\n\n];\n\nvar isBrowser = (typeof window !== 'undefined');\nvar isFirefox = (isBrowser && window.mozInnerScreenX != null);\n\nfunction getCaretCoordinates(element, position, options) {\n if(!isBrowser) {\n throw new Error('textarea-caret-position#getCaretCoordinates should only be called in a browser');\n }\n\n var debug = options && options.debug || false;\n if (debug) {\n var el = document.querySelector('#input-textarea-caret-position-mirror-div');\n if ( el ) { el.parentNode.removeChild(el); }\n }\n\n // mirrored div\n var div = document.createElement('div');\n div.id = 'input-textarea-caret-position-mirror-div';\n document.body.appendChild(div);\n\n var style = div.style;\n var computed = window.getComputedStyle? getComputedStyle(element) : element.currentStyle; // currentStyle for IE < 9\n\n // default textarea styles\n style.whiteSpace = 'pre-wrap';\n if (element.nodeName !== 'INPUT')\n style.wordWrap = 'break-word'; // only for textarea-s\n\n // position off-screen\n style.position = 'absolute'; // required to return coordinates properly\n if (!debug)\n style.visibility = 'hidden'; // not 'display: none' because we want rendering\n\n // transfer the element's properties to the div\n properties.forEach(function (prop) {\n style[prop] = computed[prop];\n });\n\n if (isFirefox) {\n // Firefox lies about the overflow property for textareas: https://bugzilla.mozilla.org/show_bug.cgi?id=984275\n if (element.scrollHeight > parseInt(computed.height))\n style.overflowY = 'scroll';\n } else {\n style.overflow = 'hidden'; // for Chrome to not render a scrollbar; IE keeps overflowY = 'scroll'\n }\n\n div.textContent = element.value.substring(0, position);\n // the second special handling for input type=\"text\" vs textarea: spaces need to be replaced with non-breaking spaces - http://stackoverflow.com/a/13402035/1269037\n if (element.nodeName === 'INPUT')\n div.textContent = div.textContent.replace(/\\s/g, '\\u00a0');\n\n var span = document.createElement('span');\n // Wrapping must be replicated *exactly*, including when a long word gets\n // onto the next line, with whitespace at the end of the line before (#7).\n // The *only* reliable way to do that is to copy the *entire* rest of the\n // textarea's content into the <span> created at the caret position.\n // for inputs, just '.' would be enough, but why bother?\n span.textContent = element.value.substring(position) || '.'; // || because a completely empty faux span doesn't render at all\n div.appendChild(span);\n\n var coordinates = {\n top: span.offsetTop + parseInt(computed['borderTopWidth']),\n left: span.offsetLeft + parseInt(computed['borderLeftWidth'])\n };\n\n if (debug) {\n span.style.backgroundColor = '#aaa';\n } else {\n document.body.removeChild(div);\n }\n\n return coordinates;\n}\n\nif (typeof module != 'undefined' && typeof module.exports != 'undefined') {\n module.exports = getCaretCoordinates;\n} else if(isBrowser){\n window.getCaretCoordinates = getCaretCoordinates;\n}\n\n}());\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/textarea-caret/index.js\n// module id = 14\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file
diff --git a/library/textcomplete/textcomplete.min.js b/library/textcomplete/textcomplete.min.js
new file mode 100644
index 000000000..717a2c905
--- /dev/null
+++ b/library/textcomplete/textcomplete.min.js
@@ -0,0 +1,2 @@
+!function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=5)}([function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),o=n(2),s=(function(e){e&&e.__esModule}(o),function(){function e(t,n,i){r(this,e),this.data=t,this.term=n,this.strategy=i}return i(e,[{key:"replace",value:function(e,t){var n=this.strategy.replace(this.data);if(null!==n){Array.isArray(n)&&(t=n[1]+t,n=n[0]);var r=this.strategy.matchText(e);if(r)return n=n.replace(/\$&/g,r[0]).replace(/\$(\d)/g,function(e,t){return r[parseInt(t,10)]}),[[e.slice(0,r.index),n,e.slice(r.index+r[0].length)].join(""),t]}}},{key:"render",value:function(){return this.strategy.template(this.data,this.term)}}]),e}());t.default=s},function(e){"use strict";function t(){}function n(e,t,n){this.fn=e,this.context=t,this.once=n||!1}function r(){this._events=new t,this._eventsCount=0}var i=Object.prototype.hasOwnProperty,o="~";Object.create&&(t.prototype=Object.create(null),(new t).__proto__||(o=!1)),r.prototype.eventNames=function(){var e,t,n=[];if(0===this._eventsCount)return n;for(t in e=this._events)i.call(e,t)&&n.push(o?t.slice(1):t);return Object.getOwnPropertySymbols?n.concat(Object.getOwnPropertySymbols(e)):n},r.prototype.listeners=function(e,t){var n=o?o+e:e,r=this._events[n];if(t)return!!r;if(!r)return[];if(r.fn)return[r.fn];for(var i=0,s=r.length,a=new Array(s);i<s;i++)a[i]=r[i].fn;return a},r.prototype.emit=function(e,t,n,r,i,s){var a=o?o+e:e;if(!this._events[a])return!1;var u,l,c=this._events[a],h=arguments.length;if(c.fn){switch(c.once&&this.removeListener(e,c.fn,void 0,!0),h){case 1:return c.fn.call(c.context),!0;case 2:return c.fn.call(c.context,t),!0;case 3:return c.fn.call(c.context,t,n),!0;case 4:return c.fn.call(c.context,t,n,r),!0;case 5:return c.fn.call(c.context,t,n,r,i),!0;case 6:return c.fn.call(c.context,t,n,r,i,s),!0}for(l=1,u=new Array(h-1);l<h;l++)u[l-1]=arguments[l];c.fn.apply(c.context,u)}else{var f,d=c.length;for(l=0;l<d;l++)switch(c[l].once&&this.removeListener(e,c[l].fn,void 0,!0),h){case 1:c[l].fn.call(c[l].context);break;case 2:c[l].fn.call(c[l].context,t);break;case 3:c[l].fn.call(c[l].context,t,n);break;case 4:c[l].fn.call(c[l].context,t,n,r);break;default:if(!u)for(f=1,u=new Array(h-1);f<h;f++)u[f-1]=arguments[f];c[l].fn.apply(c[l].context,u)}}return!0},r.prototype.on=function(e,t,r){var i=new n(t,r||this),s=o?o+e:e;return this._events[s]?this._events[s].fn?this._events[s]=[this._events[s],i]:this._events[s].push(i):(this._events[s]=i,this._eventsCount++),this},r.prototype.once=function(e,t,r){var i=new n(t,r||this,!0),s=o?o+e:e;return this._events[s]?this._events[s].fn?this._events[s]=[this._events[s],i]:this._events[s].push(i):(this._events[s]=i,this._eventsCount++),this},r.prototype.removeListener=function(e,n,r,i){var s=o?o+e:e;if(!this._events[s])return this;if(!n)return 0==--this._eventsCount?this._events=new t:delete this._events[s],this;var a=this._events[s];if(a.fn)a.fn!==n||i&&!a.once||r&&a.context!==r||(0==--this._eventsCount?this._events=new t:delete this._events[s]);else{for(var u=0,l=[],c=a.length;u<c;u++)(a[u].fn!==n||i&&!a[u].once||r&&a[u].context!==r)&&l.push(a[u]);l.length?this._events[s]=1===l.length?l[0]:l:0==--this._eventsCount?this._events=new t:delete this._events[s]}return this},r.prototype.removeAllListeners=function(e){var n;return e?(n=o?o+e:e,this._events[n]&&(0==--this._eventsCount?this._events=new t:delete this._events[n])):(this._events=new t,this._eventsCount=0),this},r.prototype.off=r.prototype.removeListener,r.prototype.addListener=r.prototype.on,r.prototype.setMaxListeners=function(){return this},r.prefixed=o,r.EventEmitter=r,e.exports=r},function(e,t){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e){return e}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),o=function(){function e(t){n(this,e),this.props=t,this.cache=t.cache?{}:null}return i(e,[{key:"destroy",value:function(){return this.cache=null,this}},{key:"search",value:function(e,t,n){this.cache?this.searchWithCache(e,t,n):this.props.search(e,t,n)}},{key:"replace",value:function(e){return this.props.replace(e)}},{key:"searchWithCache",value:function(e,t,n){var r=this;this.cache&&this.cache[e]?t(this.cache[e]):this.props.search(e,function(n){r.cache&&(r.cache[e]=n),t(n)},n)}},{key:"matchText",value:function(e){return"function"==typeof this.match?this.match(e):e.match(this.match)}},{key:"match",get:function(){return this.props.match}},{key:"index",get:function(){return"number"==typeof this.props.index?this.props.index:2}},{key:"template",get:function(){return this.props.template||r}}]),e}();t.default=o},function(e,t){"use strict";function n(e){var t=e.getBoundingClientRect(),n=e.ownerDocument,r=n.defaultView,i=n.documentElement,o={top:t.top+r.pageYOffset,left:t.left+r.pageXOffset};return i&&(o.top-=i.clientTop,o.left-=i.clientLeft),o}function r(e){return e>=s&&e<=a}function i(e){var t=window.getComputedStyle(e);return r(t.lineHeight.charCodeAt(0))?r(t.lineHeight.charCodeAt(t.lineHeight.length-1))?parseFloat(t.lineHeight)*parseFloat(t.fontSize):parseFloat(t.lineHeight):o(e.nodeName,t)}function o(e,t){var n=document.body;if(!n)return 0;var r=document.createElement(e);r.innerHTML="&nbsp;",r.style.fontSize=t.fontSize,r.style.fontFamily=t.fontFamily,r.style.padding="0",n.appendChild(r),r instanceof HTMLTextAreaElement&&(r.rows=1);var i=r.offsetHeight;return n.removeChild(r),i}Object.defineProperty(t,"__esModule",{value:!0}),t.calculateElementOffset=n,t.getLineHeightPx=i,t.calculateLineHeightPx=o;var s=(t.createCustomEvent=function(){return"function"==typeof window.CustomEvent?function(e,t){return new document.defaultView.CustomEvent(e,{cancelable:t&&t.cancelable||!1,detail:t&&t.detail||void 0})}:function(e,t){var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,!1,t&&t.cancelable||!1,t&&t.detail||void 0),n}}(),"0".charCodeAt(0)),a="9".charCodeAt(0)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),u=n(1),l=r(u),c=n(3),h=n(0),f=(r(h),function(e){function t(){return i(this,t),o(this,(t.__proto__||Object.getPrototypeOf(t)).apply(this,arguments))}return s(t,e),a(t,[{key:"destroy",value:function(){return this}},{key:"applySearchResult",value:function(){throw new Error("Not implemented.")}},{key:"getCursorOffset",value:function(){throw new Error("Not implemented.")}},{key:"getBeforeCursor",value:function(){throw new Error("Not implemented.")}},{key:"emitMoveEvent",value:function(e){var t=(0,c.createCustomEvent)("move",{cancelable:!0,detail:{code:e}});return this.emit("move",t),t}},{key:"emitEnterEvent",value:function(){var e=(0,c.createCustomEvent)("enter",{cancelable:!0});return this.emit("enter",e),e}},{key:"emitChangeEvent",value:function(){var e=(0,c.createCustomEvent)("change",{detail:{beforeCursor:this.getBeforeCursor()}});return this.emit("change",e),e}},{key:"emitEscEvent",value:function(){var e=(0,c.createCustomEvent)("esc",{cancelable:!0});return this.emit("esc",e),e}},{key:"getCode",value:function(e){return 9===e.keyCode?"ENTER":13===e.keyCode?"ENTER":27===e.keyCode?"ESC":38===e.keyCode?"UP":40===e.keyCode?"DOWN":78===e.keyCode&&e.ctrlKey?"DOWN":80===e.keyCode&&e.ctrlKey?"UP":"OTHER"}}]),t}(l.default));t.default=f},function(e,t,n){"use strict";(function(e){function t(e){return e&&e.__esModule?e:{default:e}}var r=n(7),i=t(r),o=n(12),s=t(o),a=void 0;a=e.Textcomplete&&e.Textcomplete.editors?e.Textcomplete.editors:{},a.Textarea=s.default,e.Textcomplete=i.default,e.Textcomplete.editors=a}).call(t,n(6))},function(e){var t;t=function(){return this}();try{t=t||Function("return this")()||(0,eval)("this")}catch(e){"object"==typeof window&&(t=window)}e.exports=t},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),u=n(8),l=r(u),c=n(4),h=(r(c),n(10)),f=r(h),d=n(2),v=r(d),p=n(0),y=(r(p),n(1)),m=r(y),g=["handleChange","handleEnter","handleEsc","handleHit","handleMove","handleSelect"],b=function(e){function t(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};i(this,t);var r=o(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return r.completer=new l.default,r.isQueryInFlight=!1,r.nextPendingQuery=null,r.dropdown=new f.default(n.dropdown||{}),r.editor=e,r.options=n,g.forEach(function(e){r[e]=r[e].bind(r)}),r.startListening(),r}return s(t,e),a(t,[{key:"destroy",value:function(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];return this.completer.destroy(),this.dropdown.destroy(),e&&this.editor.destroy(),this.stopListening(),this}},{key:"hide",value:function(){return this.dropdown.deactivate(),this}},{key:"register",value:function(e){var t=this;return e.forEach(function(e){t.completer.registerStrategy(new v.default(e))}),this}},{key:"trigger",value:function(e){return this.isQueryInFlight?this.nextPendingQuery=e:(this.isQueryInFlight=!0,this.nextPendingQuery=null,this.completer.run(e)),this}},{key:"handleHit",value:function(e){var t=e.searchResults;t.length?this.dropdown.render(t,this.editor.getCursorOffset()):this.dropdown.deactivate(),this.isQueryInFlight=!1,null!==this.nextPendingQuery&&this.trigger(this.nextPendingQuery)}},{key:"handleMove",value:function(e){"UP"===e.detail.code?this.dropdown.up(e):this.dropdown.down(e)}},{key:"handleEnter",value:function(e){var t=this.dropdown.getActiveItem();t?(this.dropdown.select(t),e.preventDefault()):this.dropdown.deactivate()}},{key:"handleEsc",value:function(e){this.dropdown.shown&&(this.dropdown.deactivate(),e.preventDefault())}},{key:"handleChange",value:function(e){null!=e.detail.beforeCursor?this.trigger(e.detail.beforeCursor):this.dropdown.deactivate()}},{key:"handleSelect",value:function(e){this.emit("select",e),e.defaultPrevented||this.editor.applySearchResult(e.detail.searchResult)}},{key:"startListening",value:function(){var e=this;this.editor.on("move",this.handleMove).on("enter",this.handleEnter).on("esc",this.handleEsc).on("change",this.handleChange),this.dropdown.on("select",this.handleSelect),["show","shown","render","rendered","selected","hidden","hide"].forEach(function(t){e.dropdown.on(t,function(){return e.emit(t)})}),this.completer.on("hit",this.handleHit)}},{key:"stopListening",value:function(){this.completer.removeAllListeners(),this.dropdown.removeAllListeners(),this.editor.removeListener("move",this.handleMove).removeListener("enter",this.handleEnter).removeListener("esc",this.handleEsc).removeListener("change",this.handleChange)}}]),t}(m.default);t.default=b},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),u=n(1),l=r(u),c=n(9),h=r(c),f=n(0),d=(r(f),n(2)),v=(r(d),["handleQueryResult"]),p=function(e){function t(){i(this,t);var e=o(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return e.strategies=[],v.forEach(function(t){e[t]=e[t].bind(e)}),e}return s(t,e),a(t,[{key:"destroy",value:function(){return this.strategies.forEach(function(e){return e.destroy()}),this}},{key:"registerStrategy",value:function(e){return this.strategies.push(e),this}},{key:"run",value:function(e){var t=this.extractQuery(e);t?t.execute(this.handleQueryResult):this.handleQueryResult([])}},{key:"extractQuery",value:function(e){for(var t=0;t<this.strategies.length;t++){var n=h.default.build(this.strategies[t],e);if(n)return n}return null}},{key:"handleQueryResult",value:function(e){this.emit("hit",{searchResults:e})}}]),t}(l.default);t.default=p},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),s=n(0),a=r(s),u=n(2),l=(r(u),function(){function e(t,n,r){i(this,e),this.strategy=t,this.term=n,this.match=r}return o(e,null,[{key:"build",value:function(t,n){if("function"==typeof t.props.context){var r=t.props.context(n);if("string"==typeof r)n=r;else if(!r)return null}var i=t.matchText(n);return i?new e(t,i[t.index],i):null}}]),o(e,[{key:"execute",value:function(e){var t=this;this.strategy.search(this.term,function(n){e(n.map(function(e){return new a.default(e,t.term,t.strategy)}))},this.match)}}]),e}());t.default=l},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),u=n(1),l=r(u),c=n(11),h=r(c),f=n(0),d=(r(f),n(3)),v="dropdown-menu textcomplete-dropdown",p=function(e){function t(e){i(this,t);var n=o(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));n.shown=!1,n.items=[],n.activeItem=null,n.footer=e.footer,n.header=e.header,n.maxCount=e.maxCount||10,n.el.className=e.className||v,n.rotate=!e.hasOwnProperty("rotate")||e.rotate,n.placement=e.placement,n.itemOptions=e.item||{};var r=e.style;return r&&Object.keys(r).forEach(function(e){n.el.style[e]=r[e]}),n}return s(t,e),a(t,null,[{key:"createElement",value:function(){var e=document.createElement("ul"),t=e.style;t.display="none",t.position="absolute",t.zIndex="10000";var n=document.body;return n&&n.appendChild(e),e}}]),a(t,[{key:"destroy",value:function(){var e=this.el.parentNode;return e&&e.removeChild(this.el),this.clear()._el=null,this}},{key:"render",value:function(e,t){var n=this,r=(0,d.createCustomEvent)("render",{cancelable:!0});if(this.emit("render",r),r.defaultPrevented)return this;var i=e.map(function(e){return e.data}),o=e.slice(0,this.maxCount||e.length).map(function(e){return new h.default(e,n.itemOptions)});return this.clear().setStrategyId(e[0]).renderEdge(i,"header").append(o).renderEdge(i,"footer").show().setOffset(t),this.emit("rendered",(0,d.createCustomEvent)("rendered")),this}},{key:"deactivate",value:function(){return this.hide().clear()}},{key:"select",value:function(e){var t={searchResult:e.searchResult},n=(0,d.createCustomEvent)("select",{cancelable:!0,detail:t});return this.emit("select",n),n.defaultPrevented?this:(this.deactivate(),this.emit("selected",(0,d.createCustomEvent)("selected",{detail:t})),this)}},{key:"up",value:function(e){return this.shown?this.moveActiveItem("prev",e):this}},{key:"down",value:function(e){return this.shown?this.moveActiveItem("next",e):this}},{key:"getActiveItem",value:function(){return this.activeItem}},{key:"append",value:function(e){var t=this,n=document.createDocumentFragment();return e.forEach(function(e){t.items.push(e),e.appended(t),n.appendChild(e.el)}),this.el.appendChild(n),this}},{key:"setOffset",value:function(e){var t=document.documentElement;if(t){var n=this.el.offsetWidth;if(e.left){var r=t.clientWidth;e.left+n>r&&(e.left=r-n),this.el.style.left=e.left+"px"}else e.right&&(e.right-n<0&&(e.right=0),this.el.style.right=e.right+"px");this.isPlacementTop()?this.el.style.bottom=t.clientHeight-e.top+e.lineHeight+"px":this.el.style.top=e.top+"px"}return this}},{key:"show",value:function(){if(!this.shown){var e=(0,d.createCustomEvent)("show",{cancelable:!0});if(this.emit("show",e),e.defaultPrevented)return this;this.el.style.display="block",this.shown=!0,this.emit("shown",(0,d.createCustomEvent)("shown"))}return this}},{key:"hide",value:function(){if(this.shown){var e=(0,d.createCustomEvent)("hide",{cancelable:!0});if(this.emit("hide",e),e.defaultPrevented)return this;this.el.style.display="none",this.shown=!1,this.emit("hidden",(0,d.createCustomEvent)("hidden"))}return this}},{key:"clear",value:function(){return this.el.innerHTML="",this.items.forEach(function(e){return e.destroy()}),this.items=[],this}},{key:"moveActiveItem",value:function(e,t){var n="next"===e?this.activeItem?this.activeItem.next:this.items[0]:this.activeItem?this.activeItem.prev:this.items[this.items.length-1];return n&&(n.activate(),t.preventDefault()),this}},{key:"setStrategyId",value:function(e){var t=e&&e.strategy.props.id;return t?this.el.setAttribute("data-strategy",t):this.el.removeAttribute("data-strategy"),this}},{key:"renderEdge",value:function(e,t){var n=("header"===t?this.header:this.footer)||"",r="function"==typeof n?n(e):n,i=document.createElement("li");return i.classList.add("textcomplete-"+t),i.innerHTML=r,this.el.appendChild(i),this}},{key:"isPlacementTop",value:function(){return"top"===this.placement}},{key:"el",get:function(){return this._el||(this._el=t.createElement()),this._el}}]),t}(l.default);t.default=p},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0}),t.DEFAULT_CLASS_NAME=void 0;var i=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),o=n(0),s=(function(e){e&&e.__esModule}(o),t.DEFAULT_CLASS_NAME="textcomplete-item"),a=["onClick","onMouseover"],u=function(){function e(t,n){var i=this;r(this,e),this.searchResult=t,this.active=!1,this.className=n.className||s,this.activeClassName=this.className+" active",a.forEach(function(e){i[e]=i[e].bind(i)})}return i(e,[{key:"destroy",value:function(){this.el.removeEventListener("mousedown",this.onClick,!1),this.el.removeEventListener("mouseover",this.onMouseover,!1),this.el.removeEventListener("touchstart",this.onClick,!1),this.active&&(this.dropdown.activeItem=null),this._el=null}},{key:"appended",value:function(e){this.dropdown=e,this.siblings=e.items,this.index=this.siblings.length-1}},{key:"activate",value:function(){if(!this.active){var e=this.dropdown.getActiveItem();e&&e.deactivate(),this.dropdown.activeItem=this,this.active=!0,this.el.className=this.activeClassName}return this}},{key:"deactivate",value:function(){return this.active&&(this.active=!1,this.el.className=this.className,this.dropdown.activeItem=null),this}},{key:"onClick",value:function(e){e.preventDefault(),this.dropdown.select(this)}},{key:"onMouseover",value:function(){this.activate()}},{key:"el",get:function(){if(this._el)return this._el;var e=document.createElement("li");e.className=this.active?this.activeClassName:this.className;var t=document.createElement("a");return t.innerHTML=this.searchResult.render(),e.appendChild(t),this._el=e,e.addEventListener("mousedown",this.onClick),e.addEventListener("mouseover",this.onMouseover),e.addEventListener("touchstart",this.onClick),e}},{key:"next",get:function(){var e=void 0;if(this.index===this.siblings.length-1){if(!this.dropdown.rotate)return null;e=0}else e=this.index+1;return this.siblings[e]}},{key:"prev",get:function(){var e=void 0;if(0===this.index){if(!this.dropdown.rotate)return null;e=this.siblings.length-1}else e=this.index-1;return this.siblings[e]}}]),e}();t.default=u},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),u=function e(t,n,r){null===t&&(t=Function.prototype);var i=Object.getOwnPropertyDescriptor(t,n);if(void 0===i){var o=Object.getPrototypeOf(t);return null===o?void 0:e(o,n,r)}if("value"in i)return i.value;var s=i.get;if(void 0!==s)return s.call(r)},l=n(13),c=r(l),h=n(4),f=r(h),d=n(3),v=n(0),p=(r(v),n(14)),y=["onInput","onKeydown"],m=function(e){function t(e){i(this,t);var n=o(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return n.el=e,y.forEach(function(e){n[e]=n[e].bind(n)}),n.startListening(),n}return s(t,e),a(t,[{key:"destroy",value:function(){return u(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"destroy",this).call(this),this.stopListening(),this.el=null,this}},{key:"applySearchResult",value:function(e){var t=this.getBeforeCursor();if(null!=t){var n=e.replace(t,this.getAfterCursor());this.el.focus(),Array.isArray(n)&&((0,c.default)(this.el,n[0],n[1]),this.el.dispatchEvent(new Event("input")))}}},{key:"getCursorOffset",value:function(){var e=(0,d.calculateElementOffset)(this.el),t=this.getElScroll(),n=this.getCursorPosition(),r=(0,d.getLineHeightPx)(this.el),i=e.top-t.top+n.top+r,o=e.left-t.left+n.left;return"rtl"!==this.el.dir?{top:i,left:o,lineHeight:r}:{top:i,right:document.documentElement?document.documentElement.clientWidth-o:0,lineHeight:r}}},{key:"getBeforeCursor",value:function(){return this.el.selectionStart!==this.el.selectionEnd?null:this.el.value.substring(0,this.el.selectionEnd)}},{key:"getAfterCursor",value:function(){return this.el.value.substring(this.el.selectionEnd)}},{key:"getElScroll",value:function(){return{top:this.el.scrollTop,left:this.el.scrollLeft}}},{key:"getCursorPosition",value:function(){return p(this.el,this.el.selectionEnd)}},{key:"onInput",value:function(){this.emitChangeEvent()}},{key:"onKeydown",value:function(e){var t=this.getCode(e),n=void 0;"UP"===t||"DOWN"===t?n=this.emitMoveEvent(t):"ENTER"===t?n=this.emitEnterEvent():"ESC"===t&&(n=this.emitEscEvent()),n&&n.defaultPrevented&&e.preventDefault()}},{key:"startListening",value:function(){this.el.addEventListener("input",this.onInput),this.el.addEventListener("keydown",this.onKeydown)}},{key:"stopListening",value:function(){this.el.removeEventListener("input",this.onInput),this.el.removeEventListener("keydown",this.onKeydown)}}]),t}(f.default);t.default=m},function(e,t){"use strict";function n(){if("undefined"!=typeof Event)return new Event("input",{bubbles:!0,cancelable:!0});var e=document.createEvent("Event");return e.initEvent("input",!0,!0),e}Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t,r){for(var i=e.value,o=t+(r||""),s=document.activeElement,a=0,u=0;a<i.length&&a<o.length&&i[a]===o[a];)a++;for(;i.length-u-1>=0&&o.length-u-1>=0&&i[i.length-u-1]===o[o.length-u-1];)u++;a=Math.min(a,Math.min(i.length,o.length)-u),e.setSelectionRange(a,i.length-u);var l=o.substring(a,o.length-u);return e.focus(),document.execCommand("insertText",!1,l)||(e.value=o,e.dispatchEvent(n())),e.setSelectionRange(t.length,t.length),s&&s.focus(),e}},function(e){!function(){function t(e,t,o){if(!r)throw new Error("textarea-caret-position#getCaretCoordinates should only be called in a browser");var s=o&&o.debug||!1;if(s){var a=document.querySelector("#input-textarea-caret-position-mirror-div");a&&a.parentNode.removeChild(a)}var u=document.createElement("div");u.id="input-textarea-caret-position-mirror-div",document.body.appendChild(u);var l=u.style,c=window.getComputedStyle?getComputedStyle(e):e.currentStyle;l.whiteSpace="pre-wrap","INPUT"!==e.nodeName&&(l.wordWrap="break-word"),l.position="absolute",s||(l.visibility="hidden"),n.forEach(function(e){l[e]=c[e]}),i?e.scrollHeight>parseInt(c.height)&&(l.overflowY="scroll"):l.overflow="hidden",u.textContent=e.value.substring(0,t),"INPUT"===e.nodeName&&(u.textContent=u.textContent.replace(/\s/g," "));var h=document.createElement("span");h.textContent=e.value.substring(t)||".",u.appendChild(h);var f={top:h.offsetTop+parseInt(c.borderTopWidth),left:h.offsetLeft+parseInt(c.borderLeftWidth)};return s?h.style.backgroundColor="#aaa":document.body.removeChild(u),f}var n=["direction","boxSizing","width","height","overflowX","overflowY","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","borderStyle","paddingTop","paddingRight","paddingBottom","paddingLeft","fontStyle","fontVariant","fontWeight","fontStretch","fontSize","fontSizeAdjust","lineHeight","fontFamily","textAlign","textTransform","textIndent","textDecoration","letterSpacing","wordSpacing","tabSize","MozTabSize"],r="undefined"!=typeof window,i=r&&null!=window.mozInnerScreenX;void 0!==e&&void 0!==e.exports?e.exports=t:r&&(window.getCaretCoordinates=t)}()}]);
+//# sourceMappingURL=textcomplete.min.js.map \ No newline at end of file
diff --git a/library/textcomplete/textcomplete.min.js.map b/library/textcomplete/textcomplete.min.js.map
new file mode 100644
index 000000000..435675297
--- /dev/null
+++ b/library/textcomplete/textcomplete.min.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["webpack:///textcomplete.min.js","webpack:///webpack/bootstrap 5fdd342a07201b673919","webpack:///./src/search_result.js","webpack:///./node_modules/eventemitter3/index.js","webpack:///./src/strategy.js","webpack:///./src/utils.js","webpack:///./src/editor.js","webpack:///./src/main.js","webpack:///(webpack)/buildin/global.js","webpack:///./src/textcomplete.js","webpack:///./src/completer.js","webpack:///./src/query.js","webpack:///./src/dropdown.js","webpack:///./src/dropdown_item.js","webpack:///./src/textarea.js","webpack:///./node_modules/undate/lib/update.js","webpack:///./node_modules/textarea-caret/index.js"],"names":["modules","__webpack_require__","moduleId","installedModules","exports","module","i","l","call","m","c","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","n","__esModule","object","property","prototype","hasOwnProperty","p","s","_classCallCheck","instance","Constructor","TypeError","value","_createClass","defineProperties","target","props","length","descriptor","writable","key","protoProps","staticProps","_strategy","SearchResult","obj","data","term","strategy","this","beforeCursor","afterCursor","replacement","replace","Array","isArray","match","matchText","_","p1","parseInt","slice","index","join","template","default","Events","EE","fn","context","once","EventEmitter","_events","_eventsCount","has","prefix","create","__proto__","eventNames","events","names","push","getOwnPropertySymbols","concat","listeners","event","exists","evt","available","ee","emit","a1","a2","a3","a4","a5","args","len","arguments","removeListener","undefined","apply","j","on","listener","removeAllListeners","off","addListener","setMaxListeners","prefixed","DEFAULT_TEMPLATE","Strategy","cache","callback","searchWithCache","search","_this","results","text","calculateElementOffset","el","rect","getBoundingClientRect","_el$ownerDocument","ownerDocument","defaultView","documentElement","offset","top","pageYOffset","left","pageXOffset","clientTop","clientLeft","isDigit","charCode","CHAR_CODE_ZERO","CHAR_CODE_NINE","getLineHeightPx","node","computedStyle","window","getComputedStyle","lineHeight","charCodeAt","parseFloat","fontSize","calculateLineHeightPx","nodeName","body","document","tempNode","createElement","innerHTML","style","fontFamily","padding","appendChild","HTMLTextAreaElement","rows","height","offsetHeight","removeChild","createCustomEvent","CustomEvent","type","options","cancelable","detail","createEvent","initCustomEvent","_interopRequireDefault","_possibleConstructorReturn","self","ReferenceError","_inherits","subClass","superClass","constructor","setPrototypeOf","_eventemitter","_eventemitter2","_utils","_search_result","Editor","_EventEmitter","getPrototypeOf","Error","code","moveEvent","enterEvent","changeEvent","getBeforeCursor","escEvent","e","keyCode","ctrlKey","global","_textcomplete","_textcomplete2","_textarea","_textarea2","editors","Textcomplete","Textarea","g","Function","eval","_completer","_completer2","_editor","_dropdown","_dropdown2","_strategy2","CALLBACK_METHODS","editor","completer","isQueryInFlight","nextPendingQuery","dropdown","forEach","method","bind","startListening","destroyEditor","destroy","stopListening","deactivate","strategyPropsArray","_this2","registerStrategy","run","_ref","searchResults","render","getCursorOffset","trigger","up","down","activeItem","getActiveItem","select","preventDefault","shown","selectEvent","defaultPrevented","applySearchResult","searchResult","_this3","handleMove","handleEnter","handleEsc","handleChange","handleSelect","eventName","handleHit","_query","_query2","Completer","strategies","query","extractQuery","execute","handleQueryResult","build","_search_result2","Query","map","result","_dropdown_item","_dropdown_item2","DEFAULT_CLASS_NAME","Dropdown","items","footer","header","maxCount","className","rotate","placement","itemOptions","item","keys","display","position","zIndex","parentNode","clear","_el","cursorOffset","renderEvent","rawResults","dropdownItems","setStrategyId","renderEdge","append","show","setOffset","hide","dropdownItem","moveActiveItem","fragment","createDocumentFragment","appended","doc","elementWidth","offsetWidth","browserWidth","clientWidth","right","isPlacementTop","bottom","clientHeight","showEvent","hideEvent","direction","nextActiveItem","next","prev","activate","strategyId","id","setAttribute","removeAttribute","source","content","li","classList","add","DropdownItem","active","activeClassName","removeEventListener","onClick","onMouseover","siblings","a","addEventListener","nextIndex","_get","receiver","desc","getOwnPropertyDescriptor","parent","_update","_update2","_editor2","getCaretCoordinates","_Editor","before","getAfterCursor","focus","dispatchEvent","Event","elOffset","elScroll","getElScroll","cursorPosition","getCursorPosition","dir","selectionStart","selectionEnd","substring","scrollTop","scrollLeft","emitChangeEvent","getCode","emitMoveEvent","emitEnterEvent","emitEscEvent","onInput","onKeydown","createInputEvent","bubbles","initEvent","headToCursor","cursorToTail","curr","activeElement","aLength","cLength","Math","min","setSelectionRange","strB2","execCommand","element","isBrowser","debug","querySelector","div","computed","currentStyle","whiteSpace","wordWrap","visibility","properties","prop","isFirefox","scrollHeight","overflowY","overflow","textContent","span","coordinates","offsetTop","offsetLeft","backgroundColor","mozInnerScreenX"],"mappings":"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","file":"textcomplete.min.js","sourcesContent":["/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 5);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _strategy = __webpack_require__(2);\n\nvar _strategy2 = _interopRequireDefault(_strategy);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/**\n * Encapsulate an result of each search results.\n */\nvar SearchResult = function () {\n\n /**\n * @param {object} data - An element of array callbacked by search function.\n */\n function SearchResult(data, term, strategy) {\n _classCallCheck(this, SearchResult);\n\n this.data = data;\n this.term = term;\n this.strategy = strategy;\n }\n\n _createClass(SearchResult, [{\n key: \"replace\",\n value: function replace(beforeCursor, afterCursor) {\n var replacement = this.strategy.replace(this.data);\n if (replacement !== null) {\n if (Array.isArray(replacement)) {\n afterCursor = replacement[1] + afterCursor;\n replacement = replacement[0];\n }\n var match = this.strategy.matchText(beforeCursor);\n if (match) {\n replacement = replacement.replace(/\\$&/g, match[0]).replace(/\\$(\\d)/g, function (_, p1) {\n return match[parseInt(p1, 10)];\n });\n return [[beforeCursor.slice(0, match.index), replacement, beforeCursor.slice(match.index + match[0].length)].join(\"\"), afterCursor];\n }\n }\n }\n }, {\n key: \"render\",\n value: function render() {\n return this.strategy.template(this.data, this.term);\n }\n }]);\n\n return SearchResult;\n}();\n\nexports.default = SearchResult;\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar has = Object.prototype.hasOwnProperty\n , prefix = '~';\n\n/**\n * Constructor to create a storage for our `EE` objects.\n * An `Events` instance is a plain object whose properties are event names.\n *\n * @constructor\n * @api private\n */\nfunction Events() {}\n\n//\n// We try to not inherit from `Object.prototype`. In some engines creating an\n// instance in this way is faster than calling `Object.create(null)` directly.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// character to make sure that the built-in object properties are not\n// overridden or used as an attack vector.\n//\nif (Object.create) {\n Events.prototype = Object.create(null);\n\n //\n // This hack is needed because the `__proto__` property is still inherited in\n // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.\n //\n if (!new Events().__proto__) prefix = false;\n}\n\n/**\n * Representation of a single event listener.\n *\n * @param {Function} fn The listener function.\n * @param {Mixed} context The context to invoke the listener with.\n * @param {Boolean} [once=false] Specify if the listener is a one-time listener.\n * @constructor\n * @api private\n */\nfunction EE(fn, context, once) {\n this.fn = fn;\n this.context = context;\n this.once = once || false;\n}\n\n/**\n * Minimal `EventEmitter` interface that is molded against the Node.js\n * `EventEmitter` interface.\n *\n * @constructor\n * @api public\n */\nfunction EventEmitter() {\n this._events = new Events();\n this._eventsCount = 0;\n}\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @api public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n var names = []\n , events\n , name;\n\n if (this._eventsCount === 0) return names;\n\n for (name in (events = this._events)) {\n if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n }\n\n if (Object.getOwnPropertySymbols) {\n return names.concat(Object.getOwnPropertySymbols(events));\n }\n\n return names;\n};\n\n/**\n * Return the listeners registered for a given event.\n *\n * @param {String|Symbol} event The event name.\n * @param {Boolean} exists Only check if there are listeners.\n * @returns {Array|Boolean}\n * @api public\n */\nEventEmitter.prototype.listeners = function listeners(event, exists) {\n var evt = prefix ? prefix + event : event\n , available = this._events[evt];\n\n if (exists) return !!available;\n if (!available) return [];\n if (available.fn) return [available.fn];\n\n for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) {\n ee[i] = available[i].fn;\n }\n\n return ee;\n};\n\n/**\n * Calls each of the listeners registered for a given event.\n *\n * @param {String|Symbol} event The event name.\n * @returns {Boolean} `true` if the event had listeners, else `false`.\n * @api public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return false;\n\n var listeners = this._events[evt]\n , len = arguments.length\n , args\n , i;\n\n if (listeners.fn) {\n if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n switch (len) {\n case 1: return listeners.fn.call(listeners.context), true;\n case 2: return listeners.fn.call(listeners.context, a1), true;\n case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n }\n\n for (i = 1, args = new Array(len -1); i < len; i++) {\n args[i - 1] = arguments[i];\n }\n\n listeners.fn.apply(listeners.context, args);\n } else {\n var length = listeners.length\n , j;\n\n for (i = 0; i < length; i++) {\n if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n switch (len) {\n case 1: listeners[i].fn.call(listeners[i].context); break;\n case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;\n default:\n if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n args[j - 1] = arguments[j];\n }\n\n listeners[i].fn.apply(listeners[i].context, args);\n }\n }\n }\n\n return true;\n};\n\n/**\n * Add a listener for a given event.\n *\n * @param {String|Symbol} event The event name.\n * @param {Function} fn The listener function.\n * @param {Mixed} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @api public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n var listener = new EE(fn, context || this)\n , evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) this._events[evt] = listener, this._eventsCount++;\n else if (!this._events[evt].fn) this._events[evt].push(listener);\n else this._events[evt] = [this._events[evt], listener];\n\n return this;\n};\n\n/**\n * Add a one-time listener for a given event.\n *\n * @param {String|Symbol} event The event name.\n * @param {Function} fn The listener function.\n * @param {Mixed} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @api public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n var listener = new EE(fn, context || this, true)\n , evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) this._events[evt] = listener, this._eventsCount++;\n else if (!this._events[evt].fn) this._events[evt].push(listener);\n else this._events[evt] = [this._events[evt], listener];\n\n return this;\n};\n\n/**\n * Remove the listeners of a given event.\n *\n * @param {String|Symbol} event The event name.\n * @param {Function} fn Only remove the listeners that match this function.\n * @param {Mixed} context Only remove the listeners that have this context.\n * @param {Boolean} once Only remove one-time listeners.\n * @returns {EventEmitter} `this`.\n * @api public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return this;\n if (!fn) {\n if (--this._eventsCount === 0) this._events = new Events();\n else delete this._events[evt];\n return this;\n }\n\n var listeners = this._events[evt];\n\n if (listeners.fn) {\n if (\n listeners.fn === fn\n && (!once || listeners.once)\n && (!context || listeners.context === context)\n ) {\n if (--this._eventsCount === 0) this._events = new Events();\n else delete this._events[evt];\n }\n } else {\n for (var i = 0, events = [], length = listeners.length; i < length; i++) {\n if (\n listeners[i].fn !== fn\n || (once && !listeners[i].once)\n || (context && listeners[i].context !== context)\n ) {\n events.push(listeners[i]);\n }\n }\n\n //\n // Reset the array, or remove it completely if we have no more listeners.\n //\n if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;\n else if (--this._eventsCount === 0) this._events = new Events();\n else delete this._events[evt];\n }\n\n return this;\n};\n\n/**\n * Remove all listeners, or those of the specified event.\n *\n * @param {String|Symbol} [event] The event name.\n * @returns {EventEmitter} `this`.\n * @api public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n var evt;\n\n if (event) {\n evt = prefix ? prefix + event : event;\n if (this._events[evt]) {\n if (--this._eventsCount === 0) this._events = new Events();\n else delete this._events[evt];\n }\n } else {\n this._events = new Events();\n this._eventsCount = 0;\n }\n\n return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// This function doesn't apply anymore.\n//\nEventEmitter.prototype.setMaxListeners = function setMaxListeners() {\n return this;\n};\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Allow `EventEmitter` to be imported as module namespace.\n//\nEventEmitter.EventEmitter = EventEmitter;\n\n//\n// Expose the module.\n//\nif (true) {\n module.exports = EventEmitter;\n}\n\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar DEFAULT_INDEX = 2;\n\nfunction DEFAULT_TEMPLATE(value) {\n return value;\n}\n\n/**\n * Properties for a strategy.\n *\n * @typedef\n */\n\n/**\n * Encapsulate a single strategy.\n */\nvar Strategy = function () {\n function Strategy(props) {\n _classCallCheck(this, Strategy);\n\n this.props = props;\n this.cache = props.cache ? {} : null;\n }\n\n /**\n * @return {this}\n */\n\n\n _createClass(Strategy, [{\n key: \"destroy\",\n value: function destroy() {\n this.cache = null;\n return this;\n }\n }, {\n key: \"search\",\n value: function search(term, callback, match) {\n if (this.cache) {\n this.searchWithCache(term, callback, match);\n } else {\n this.props.search(term, callback, match);\n }\n }\n\n /**\n * @param {object} data - An element of array callbacked by search function.\n */\n\n }, {\n key: \"replace\",\n value: function replace(data) {\n return this.props.replace(data);\n }\n\n /** @private */\n\n }, {\n key: \"searchWithCache\",\n value: function searchWithCache(term, callback, match) {\n var _this = this;\n\n if (this.cache && this.cache[term]) {\n callback(this.cache[term]);\n } else {\n this.props.search(term, function (results) {\n if (_this.cache) {\n _this.cache[term] = results;\n }\n callback(results);\n }, match);\n }\n }\n\n /** @private */\n\n }, {\n key: \"matchText\",\n value: function matchText(text) {\n if (typeof this.match === \"function\") {\n return this.match(text);\n } else {\n return text.match(this.match);\n }\n }\n\n /** @private */\n\n }, {\n key: \"match\",\n get: function get() {\n return this.props.match;\n }\n\n /** @private */\n\n }, {\n key: \"index\",\n get: function get() {\n return typeof this.props.index === \"number\" ? this.props.index : DEFAULT_INDEX;\n }\n }, {\n key: \"template\",\n get: function get() {\n return this.props.template || DEFAULT_TEMPLATE;\n }\n }]);\n\n return Strategy;\n}();\n\nexports.default = Strategy;\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.calculateElementOffset = calculateElementOffset;\nexports.getLineHeightPx = getLineHeightPx;\nexports.calculateLineHeightPx = calculateLineHeightPx;\n\n\n/**\n * Create a custom event\n *\n * @private\n */\nvar createCustomEvent = exports.createCustomEvent = function () {\n if (typeof window.CustomEvent === \"function\") {\n return function (type, options) {\n return new document.defaultView.CustomEvent(type, {\n cancelable: options && options.cancelable || false,\n detail: options && options.detail || undefined\n });\n };\n } else {\n // Custom event polyfill from\n // https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#polyfill\n return function (type, options) {\n var event = document.createEvent(\"CustomEvent\");\n event.initCustomEvent(type,\n /* bubbles */false, options && options.cancelable || false, options && options.detail || undefined);\n return event;\n };\n }\n}\n\n/**\n * Get the current coordinates of the `el` relative to the document.\n *\n * @private\n */\n();function calculateElementOffset(el) {\n var rect = el.getBoundingClientRect();\n var _el$ownerDocument = el.ownerDocument,\n defaultView = _el$ownerDocument.defaultView,\n documentElement = _el$ownerDocument.documentElement;\n\n var offset = {\n top: rect.top + defaultView.pageYOffset,\n left: rect.left + defaultView.pageXOffset\n };\n if (documentElement) {\n offset.top -= documentElement.clientTop;\n offset.left -= documentElement.clientLeft;\n }\n return offset;\n}\n\nvar CHAR_CODE_ZERO = \"0\".charCodeAt(0);\nvar CHAR_CODE_NINE = \"9\".charCodeAt(0);\n\nfunction isDigit(charCode) {\n return charCode >= CHAR_CODE_ZERO && charCode <= CHAR_CODE_NINE;\n}\n\n/**\n * Returns the line-height of the given node in pixels.\n *\n * @private\n */\nfunction getLineHeightPx(node) {\n var computedStyle = window.getComputedStyle(node\n\n // If the char code starts with a digit, it is either a value in pixels,\n // or unitless, as per:\n // https://drafts.csswg.org/css2/visudet.html#propdef-line-height\n // https://drafts.csswg.org/css2/cascade.html#computed-value\n );if (isDigit(computedStyle.lineHeight.charCodeAt(0))) {\n // In real browsers the value is *always* in pixels, even for unit-less\n // line-heights. However, we still check as per the spec.\n if (isDigit(computedStyle.lineHeight.charCodeAt(computedStyle.lineHeight.length - 1))) {\n return parseFloat(computedStyle.lineHeight) * parseFloat(computedStyle.fontSize);\n } else {\n return parseFloat(computedStyle.lineHeight);\n }\n }\n\n // Otherwise, the value is \"normal\".\n // If the line-height is \"normal\", calculate by font-size\n return calculateLineHeightPx(node.nodeName, computedStyle);\n}\n\n/**\n * Returns calculated line-height of the given node in pixels.\n *\n * @private\n */\nfunction calculateLineHeightPx(nodeName, computedStyle) {\n var body = document.body;\n if (!body) {\n return 0;\n }\n\n var tempNode = document.createElement(nodeName);\n tempNode.innerHTML = \"&nbsp;\";\n tempNode.style.fontSize = computedStyle.fontSize;\n tempNode.style.fontFamily = computedStyle.fontFamily;\n tempNode.style.padding = \"0\";\n body.appendChild(tempNode\n\n // Make sure textarea has only 1 row\n );if (tempNode instanceof HTMLTextAreaElement) {\n ;tempNode.rows = 1;\n }\n\n // Assume the height of the element is the line-height\n var height = tempNode.offsetHeight;\n body.removeChild(tempNode);\n\n return height;\n}\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _eventemitter = __webpack_require__(1);\n\nvar _eventemitter2 = _interopRequireDefault(_eventemitter);\n\nvar _utils = __webpack_require__(3);\n\nvar _search_result = __webpack_require__(0);\n\nvar _search_result2 = _interopRequireDefault(_search_result);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n/*eslint no-unused-vars: off*/\n\n/**\n * Abstract class representing a editor target.\n *\n * Editor classes must implement `#applySearchResult`, `#getCursorOffset` and\n * `#getBeforeCursor` methods.\n *\n * Editor classes must invoke `#emitMoveEvent`, `#emitEnterEvent`,\n * `#emitChangeEvent` and `#emitEscEvent` at proper timing.\n *\n * @abstract\n */\n\n\n/** @typedef */\nvar Editor = function (_EventEmitter) {\n _inherits(Editor, _EventEmitter);\n\n function Editor() {\n _classCallCheck(this, Editor);\n\n return _possibleConstructorReturn(this, (Editor.__proto__ || Object.getPrototypeOf(Editor)).apply(this, arguments));\n }\n\n _createClass(Editor, [{\n key: \"destroy\",\n\n /**\n * It is called when associated textcomplete object is destroyed.\n *\n * @return {this}\n */\n value: function destroy() {\n return this;\n }\n\n /**\n * It is called when a search result is selected by a user.\n */\n\n }, {\n key: \"applySearchResult\",\n value: function applySearchResult(_) {\n throw new Error(\"Not implemented.\");\n }\n\n /**\n * The input cursor's absolute coordinates from the window's left\n * top corner.\n */\n\n }, {\n key: \"getCursorOffset\",\n value: function getCursorOffset() {\n throw new Error(\"Not implemented.\");\n }\n\n /**\n * Editor string value from head to cursor.\n * Returns null if selection type is range not cursor.\n */\n\n }, {\n key: \"getBeforeCursor\",\n value: function getBeforeCursor() {\n throw new Error(\"Not implemented.\");\n }\n\n /**\n * Emit a move event, which moves active dropdown element.\n * Child class must call this method at proper timing with proper parameter.\n *\n * @see {@link Textarea} for live example.\n */\n\n }, {\n key: \"emitMoveEvent\",\n value: function emitMoveEvent(code) {\n var moveEvent = (0, _utils.createCustomEvent)(\"move\", {\n cancelable: true,\n detail: {\n code: code\n }\n });\n this.emit(\"move\", moveEvent);\n return moveEvent;\n }\n\n /**\n * Emit a enter event, which selects current search result.\n * Child class must call this method at proper timing.\n *\n * @see {@link Textarea} for live example.\n */\n\n }, {\n key: \"emitEnterEvent\",\n value: function emitEnterEvent() {\n var enterEvent = (0, _utils.createCustomEvent)(\"enter\", { cancelable: true });\n this.emit(\"enter\", enterEvent);\n return enterEvent;\n }\n\n /**\n * Emit a change event, which triggers auto completion.\n * Child class must call this method at proper timing.\n *\n * @see {@link Textarea} for live example.\n */\n\n }, {\n key: \"emitChangeEvent\",\n value: function emitChangeEvent() {\n var changeEvent = (0, _utils.createCustomEvent)(\"change\", {\n detail: {\n beforeCursor: this.getBeforeCursor()\n }\n });\n this.emit(\"change\", changeEvent);\n return changeEvent;\n }\n\n /**\n * Emit a esc event, which hides dropdown element.\n * Child class must call this method at proper timing.\n *\n * @see {@link Textarea} for live example.\n */\n\n }, {\n key: \"emitEscEvent\",\n value: function emitEscEvent() {\n var escEvent = (0, _utils.createCustomEvent)(\"esc\", { cancelable: true });\n this.emit(\"esc\", escEvent);\n return escEvent;\n }\n\n /**\n * Helper method for parsing KeyboardEvent.\n *\n * @see {@link Textarea} for live example.\n */\n\n }, {\n key: \"getCode\",\n value: function getCode(e) {\n return e.keyCode === 9 ? \"ENTER\" // tab\n : e.keyCode === 13 ? \"ENTER\" // enter\n : e.keyCode === 27 ? \"ESC\" // esc\n : e.keyCode === 38 ? \"UP\" // up\n : e.keyCode === 40 ? \"DOWN\" // down\n : e.keyCode === 78 && e.ctrlKey ? \"DOWN\" // ctrl-n\n : e.keyCode === 80 && e.ctrlKey ? \"UP\" // ctrl-p\n : \"OTHER\";\n }\n }]);\n\n return Editor;\n}(_eventemitter2.default);\n\nexports.default = Editor;\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n/* WEBPACK VAR INJECTION */(function(global) {\n\nvar _textcomplete = __webpack_require__(7);\n\nvar _textcomplete2 = _interopRequireDefault(_textcomplete);\n\nvar _textarea = __webpack_require__(12);\n\nvar _textarea2 = _interopRequireDefault(_textarea);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar editors = void 0;\nif (global.Textcomplete && global.Textcomplete.editors) {\n editors = global.Textcomplete.editors;\n} else {\n editors = {};\n}\neditors.Textarea = _textarea2.default;\n\nglobal.Textcomplete = _textcomplete2.default;\nglobal.Textcomplete.editors = editors;\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(6)))\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports) {\n\nvar g;\r\n\r\n// This works in non-strict mode\r\ng = (function() {\r\n\treturn this;\r\n})();\r\n\r\ntry {\r\n\t// This works if eval is allowed (see CSP)\r\n\tg = g || Function(\"return this\")() || (1,eval)(\"this\");\r\n} catch(e) {\r\n\t// This works if the window reference is available\r\n\tif(typeof window === \"object\")\r\n\t\tg = window;\r\n}\r\n\r\n// g can still be undefined, but nothing to do about it...\r\n// We return undefined, instead of nothing here, so it's\r\n// easier to handle this case. if(!global) { ...}\r\n\r\nmodule.exports = g;\r\n\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _completer = __webpack_require__(8);\n\nvar _completer2 = _interopRequireDefault(_completer);\n\nvar _editor = __webpack_require__(4);\n\nvar _editor2 = _interopRequireDefault(_editor);\n\nvar _dropdown = __webpack_require__(10);\n\nvar _dropdown2 = _interopRequireDefault(_dropdown);\n\nvar _strategy = __webpack_require__(2);\n\nvar _strategy2 = _interopRequireDefault(_strategy);\n\nvar _search_result = __webpack_require__(0);\n\nvar _search_result2 = _interopRequireDefault(_search_result);\n\nvar _eventemitter = __webpack_require__(1);\n\nvar _eventemitter2 = _interopRequireDefault(_eventemitter);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar CALLBACK_METHODS = [\"handleChange\", \"handleEnter\", \"handleEsc\", \"handleHit\", \"handleMove\", \"handleSelect\"];\n\n/** @typedef */\n\n/**\n * The core of textcomplete. It acts as a mediator.\n */\nvar Textcomplete = function (_EventEmitter) {\n _inherits(Textcomplete, _EventEmitter);\n\n /**\n * @param {Editor} editor - Where the textcomplete works on.\n */\n function Textcomplete(editor) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n _classCallCheck(this, Textcomplete);\n\n var _this = _possibleConstructorReturn(this, (Textcomplete.__proto__ || Object.getPrototypeOf(Textcomplete)).call(this));\n\n _this.completer = new _completer2.default();\n _this.isQueryInFlight = false;\n _this.nextPendingQuery = null;\n _this.dropdown = new _dropdown2.default(options.dropdown || {});\n _this.editor = editor;\n _this.options = options;\n\n CALLBACK_METHODS.forEach(function (method) {\n ;_this[method] = _this[method].bind(_this);\n });\n\n _this.startListening();\n return _this;\n }\n\n /**\n * @return {this}\n */\n\n\n _createClass(Textcomplete, [{\n key: \"destroy\",\n value: function destroy() {\n var destroyEditor = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;\n\n this.completer.destroy();\n this.dropdown.destroy();\n if (destroyEditor) {\n this.editor.destroy();\n }\n this.stopListening();\n return this;\n }\n\n /**\n * @return {this}\n */\n\n }, {\n key: \"hide\",\n value: function hide() {\n this.dropdown.deactivate();\n return this;\n }\n\n /**\n * @return {this}\n * @example\n * textcomplete.register([{\n * match: /(^|\\s)(\\w+)$/,\n * search: function (term, callback) {\n * $.ajax({ ... })\n * .done(callback)\n * .fail([]);\n * },\n * replace: function (value) {\n * return '$1' + value + ' ';\n * }\n * }]);\n */\n\n }, {\n key: \"register\",\n value: function register(strategyPropsArray) {\n var _this2 = this;\n\n strategyPropsArray.forEach(function (props) {\n _this2.completer.registerStrategy(new _strategy2.default(props));\n });\n return this;\n }\n\n /**\n * Start autocompleting.\n *\n * @param {string} text - Head to input cursor.\n * @return {this}\n */\n\n }, {\n key: \"trigger\",\n value: function trigger(text) {\n if (this.isQueryInFlight) {\n this.nextPendingQuery = text;\n } else {\n this.isQueryInFlight = true;\n this.nextPendingQuery = null;\n this.completer.run(text);\n }\n return this;\n }\n\n /** @private */\n\n }, {\n key: \"handleHit\",\n value: function handleHit(_ref) {\n var searchResults = _ref.searchResults;\n\n if (searchResults.length) {\n this.dropdown.render(searchResults, this.editor.getCursorOffset());\n } else {\n this.dropdown.deactivate();\n }\n this.isQueryInFlight = false;\n if (this.nextPendingQuery !== null) {\n this.trigger(this.nextPendingQuery);\n }\n }\n\n /** @private */\n\n }, {\n key: \"handleMove\",\n value: function handleMove(e) {\n e.detail.code === \"UP\" ? this.dropdown.up(e) : this.dropdown.down(e);\n }\n\n /** @private */\n\n }, {\n key: \"handleEnter\",\n value: function handleEnter(e) {\n var activeItem = this.dropdown.getActiveItem();\n if (activeItem) {\n this.dropdown.select(activeItem);\n e.preventDefault();\n } else {\n this.dropdown.deactivate();\n }\n }\n\n /** @private */\n\n }, {\n key: \"handleEsc\",\n value: function handleEsc(e) {\n if (this.dropdown.shown) {\n this.dropdown.deactivate();\n e.preventDefault();\n }\n }\n\n /** @private */\n\n }, {\n key: \"handleChange\",\n value: function handleChange(e) {\n if (e.detail.beforeCursor != null) {\n this.trigger(e.detail.beforeCursor);\n } else {\n this.dropdown.deactivate();\n }\n }\n\n /** @private */\n\n }, {\n key: \"handleSelect\",\n value: function handleSelect(selectEvent) {\n this.emit(\"select\", selectEvent);\n if (!selectEvent.defaultPrevented) {\n this.editor.applySearchResult(selectEvent.detail.searchResult);\n }\n }\n\n /** @private */\n\n }, {\n key: \"startListening\",\n value: function startListening() {\n var _this3 = this;\n\n this.editor.on(\"move\", this.handleMove).on(\"enter\", this.handleEnter).on(\"esc\", this.handleEsc).on(\"change\", this.handleChange);\n this.dropdown.on(\"select\", this.handleSelect);[\"show\", \"shown\", \"render\", \"rendered\", \"selected\", \"hidden\", \"hide\"].forEach(function (eventName) {\n _this3.dropdown.on(eventName, function () {\n return _this3.emit(eventName);\n });\n });\n this.completer.on(\"hit\", this.handleHit);\n }\n\n /** @private */\n\n }, {\n key: \"stopListening\",\n value: function stopListening() {\n this.completer.removeAllListeners();\n this.dropdown.removeAllListeners();\n this.editor.removeListener(\"move\", this.handleMove).removeListener(\"enter\", this.handleEnter).removeListener(\"esc\", this.handleEsc).removeListener(\"change\", this.handleChange);\n }\n }]);\n\n return Textcomplete;\n}(_eventemitter2.default);\n\nexports.default = Textcomplete;\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _eventemitter = __webpack_require__(1);\n\nvar _eventemitter2 = _interopRequireDefault(_eventemitter);\n\nvar _query = __webpack_require__(9);\n\nvar _query2 = _interopRequireDefault(_query);\n\nvar _search_result = __webpack_require__(0);\n\nvar _search_result2 = _interopRequireDefault(_search_result);\n\nvar _strategy = __webpack_require__(2);\n\nvar _strategy2 = _interopRequireDefault(_strategy);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar CALLBACK_METHODS = [\"handleQueryResult\"];\n\n/**\n * Complete engine.\n */\n\nvar Completer = function (_EventEmitter) {\n _inherits(Completer, _EventEmitter);\n\n function Completer() {\n _classCallCheck(this, Completer);\n\n var _this = _possibleConstructorReturn(this, (Completer.__proto__ || Object.getPrototypeOf(Completer)).call(this));\n\n _this.strategies = [];\n\n CALLBACK_METHODS.forEach(function (method) {\n ;_this[method] = _this[method].bind(_this);\n });\n return _this;\n }\n\n /**\n * @return {this}\n */\n\n\n _createClass(Completer, [{\n key: \"destroy\",\n value: function destroy() {\n this.strategies.forEach(function (strategy) {\n return strategy.destroy();\n });\n return this;\n }\n\n /**\n * Register a strategy to the completer.\n *\n * @return {this}\n */\n\n }, {\n key: \"registerStrategy\",\n value: function registerStrategy(strategy) {\n this.strategies.push(strategy);\n return this;\n }\n\n /**\n * @param {string} text - Head to input cursor.\n */\n\n }, {\n key: \"run\",\n value: function run(text) {\n var query = this.extractQuery(text);\n if (query) {\n query.execute(this.handleQueryResult);\n } else {\n this.handleQueryResult([]);\n }\n }\n\n /**\n * Find a query, which matches to the given text.\n *\n * @private\n */\n\n }, {\n key: \"extractQuery\",\n value: function extractQuery(text) {\n for (var i = 0; i < this.strategies.length; i++) {\n var query = _query2.default.build(this.strategies[i], text);\n if (query) {\n return query;\n }\n }\n return null;\n }\n\n /**\n * Callbacked by {@link Query#execute}.\n *\n * @private\n */\n\n }, {\n key: \"handleQueryResult\",\n value: function handleQueryResult(searchResults) {\n this.emit(\"hit\", { searchResults: searchResults });\n }\n }]);\n\n return Completer;\n}(_eventemitter2.default);\n\nexports.default = Completer;\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _search_result = __webpack_require__(0);\n\nvar _search_result2 = _interopRequireDefault(_search_result);\n\nvar _strategy = __webpack_require__(2);\n\nvar _strategy2 = _interopRequireDefault(_strategy);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/**\n * Encapsulate matching condition between a Strategy and current editor's value.\n */\nvar Query = function () {\n _createClass(Query, null, [{\n key: \"build\",\n\n\n /**\n * Build a Query object by the given string if this matches to the string.\n *\n * @param {string} text - Head to input cursor.\n */\n value: function build(strategy, text) {\n if (typeof strategy.props.context === \"function\") {\n var context = strategy.props.context(text);\n if (typeof context === \"string\") {\n text = context;\n } else if (!context) {\n return null;\n }\n }\n var match = strategy.matchText(text);\n return match ? new Query(strategy, match[strategy.index], match) : null;\n }\n }]);\n\n function Query(strategy, term, match) {\n _classCallCheck(this, Query);\n\n this.strategy = strategy;\n this.term = term;\n this.match = match;\n }\n\n /**\n * Invoke search strategy and callback the given function.\n */\n\n\n _createClass(Query, [{\n key: \"execute\",\n value: function execute(callback) {\n var _this = this;\n\n this.strategy.search(this.term, function (results) {\n callback(results.map(function (result) {\n return new _search_result2.default(result, _this.term, _this.strategy);\n }));\n }, this.match);\n }\n }]);\n\n return Query;\n}();\n\nexports.default = Query;\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _eventemitter = __webpack_require__(1);\n\nvar _eventemitter2 = _interopRequireDefault(_eventemitter);\n\nvar _dropdown_item = __webpack_require__(11);\n\nvar _dropdown_item2 = _interopRequireDefault(_dropdown_item);\n\nvar _search_result = __webpack_require__(0);\n\nvar _search_result2 = _interopRequireDefault(_search_result);\n\nvar _utils = __webpack_require__(3);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar DEFAULT_CLASS_NAME = \"dropdown-menu textcomplete-dropdown\";\n\n/** @typedef */\n\n/**\n * Encapsulate a dropdown view.\n *\n * @prop {boolean} shown - Whether the #el is shown or not.\n * @prop {DropdownItem[]} items - The array of rendered dropdown items.\n */\nvar Dropdown = function (_EventEmitter) {\n _inherits(Dropdown, _EventEmitter);\n\n _createClass(Dropdown, null, [{\n key: \"createElement\",\n value: function createElement() {\n var el = document.createElement(\"ul\");\n var style = el.style;\n style.display = \"none\";\n style.position = \"absolute\";\n style.zIndex = \"10000\";\n var body = document.body;\n if (body) {\n body.appendChild(el);\n }\n return el;\n }\n }]);\n\n function Dropdown(options) {\n _classCallCheck(this, Dropdown);\n\n var _this = _possibleConstructorReturn(this, (Dropdown.__proto__ || Object.getPrototypeOf(Dropdown)).call(this));\n\n _this.shown = false;\n _this.items = [];\n _this.activeItem = null;\n _this.footer = options.footer;\n _this.header = options.header;\n _this.maxCount = options.maxCount || 10;\n _this.el.className = options.className || DEFAULT_CLASS_NAME;\n _this.rotate = options.hasOwnProperty(\"rotate\") ? options.rotate : true;\n _this.placement = options.placement;\n _this.itemOptions = options.item || {};\n var style = options.style;\n if (style) {\n Object.keys(style).forEach(function (key) {\n ;_this.el.style[key] = style[key];\n });\n }\n return _this;\n }\n\n /**\n * @return {this}\n */\n\n\n _createClass(Dropdown, [{\n key: \"destroy\",\n value: function destroy() {\n var parentNode = this.el.parentNode;\n if (parentNode) {\n parentNode.removeChild(this.el);\n }\n this.clear()._el = null;\n return this;\n }\n }, {\n key: \"render\",\n\n\n /**\n * Render the given data as dropdown items.\n *\n * @return {this}\n */\n value: function render(searchResults, cursorOffset) {\n var _this2 = this;\n\n var renderEvent = (0, _utils.createCustomEvent)(\"render\", { cancelable: true });\n this.emit(\"render\", renderEvent);\n if (renderEvent.defaultPrevented) {\n return this;\n }\n var rawResults = searchResults.map(function (searchResult) {\n return searchResult.data;\n });\n var dropdownItems = searchResults.slice(0, this.maxCount || searchResults.length).map(function (searchResult) {\n return new _dropdown_item2.default(searchResult, _this2.itemOptions);\n });\n this.clear().setStrategyId(searchResults[0]).renderEdge(rawResults, \"header\").append(dropdownItems).renderEdge(rawResults, \"footer\").show().setOffset(cursorOffset);\n this.emit(\"rendered\", (0, _utils.createCustomEvent)(\"rendered\"));\n return this;\n }\n\n /**\n * Hide the dropdown then sweep out items.\n *\n * @return {this}\n */\n\n }, {\n key: \"deactivate\",\n value: function deactivate() {\n return this.hide().clear();\n }\n\n /**\n * @return {this}\n */\n\n }, {\n key: \"select\",\n value: function select(dropdownItem) {\n var detail = { searchResult: dropdownItem.searchResult };\n var selectEvent = (0, _utils.createCustomEvent)(\"select\", {\n cancelable: true,\n detail: detail\n });\n this.emit(\"select\", selectEvent);\n if (selectEvent.defaultPrevented) {\n return this;\n }\n this.deactivate();\n this.emit(\"selected\", (0, _utils.createCustomEvent)(\"selected\", { detail: detail }));\n return this;\n }\n\n /**\n * @return {this}\n */\n\n }, {\n key: \"up\",\n value: function up(e) {\n return this.shown ? this.moveActiveItem(\"prev\", e) : this;\n }\n\n /**\n * @return {this}\n */\n\n }, {\n key: \"down\",\n value: function down(e) {\n return this.shown ? this.moveActiveItem(\"next\", e) : this;\n }\n\n /**\n * Retrieve the active item.\n */\n\n }, {\n key: \"getActiveItem\",\n value: function getActiveItem() {\n return this.activeItem;\n }\n\n /**\n * Add items to dropdown.\n *\n * @private\n */\n\n }, {\n key: \"append\",\n value: function append(items) {\n var _this3 = this;\n\n var fragment = document.createDocumentFragment();\n items.forEach(function (item) {\n _this3.items.push(item);\n item.appended(_this3);\n fragment.appendChild(item.el);\n });\n this.el.appendChild(fragment);\n return this;\n }\n\n /** @private */\n\n }, {\n key: \"setOffset\",\n value: function setOffset(cursorOffset) {\n var doc = document.documentElement;\n if (doc) {\n var elementWidth = this.el.offsetWidth;\n if (cursorOffset.left) {\n var browserWidth = doc.clientWidth;\n if (cursorOffset.left + elementWidth > browserWidth) {\n cursorOffset.left = browserWidth - elementWidth;\n }\n this.el.style.left = cursorOffset.left + \"px\";\n } else if (cursorOffset.right) {\n if (cursorOffset.right - elementWidth < 0) {\n cursorOffset.right = 0;\n }\n this.el.style.right = cursorOffset.right + \"px\";\n }\n if (this.isPlacementTop()) {\n this.el.style.bottom = doc.clientHeight - cursorOffset.top + cursorOffset.lineHeight + \"px\";\n } else {\n this.el.style.top = cursorOffset.top + \"px\";\n }\n }\n return this;\n }\n\n /**\n * Show the element.\n *\n * @private\n */\n\n }, {\n key: \"show\",\n value: function show() {\n if (!this.shown) {\n var showEvent = (0, _utils.createCustomEvent)(\"show\", { cancelable: true });\n this.emit(\"show\", showEvent);\n if (showEvent.defaultPrevented) {\n return this;\n }\n this.el.style.display = \"block\";\n this.shown = true;\n this.emit(\"shown\", (0, _utils.createCustomEvent)(\"shown\"));\n }\n return this;\n }\n\n /**\n * Hide the element.\n *\n * @private\n */\n\n }, {\n key: \"hide\",\n value: function hide() {\n if (this.shown) {\n var hideEvent = (0, _utils.createCustomEvent)(\"hide\", { cancelable: true });\n this.emit(\"hide\", hideEvent);\n if (hideEvent.defaultPrevented) {\n return this;\n }\n this.el.style.display = \"none\";\n this.shown = false;\n this.emit(\"hidden\", (0, _utils.createCustomEvent)(\"hidden\"));\n }\n return this;\n }\n\n /**\n * Clear search results.\n *\n * @private\n */\n\n }, {\n key: \"clear\",\n value: function clear() {\n this.el.innerHTML = \"\";\n this.items.forEach(function (item) {\n return item.destroy();\n });\n this.items = [];\n return this;\n }\n\n /** @private */\n\n }, {\n key: \"moveActiveItem\",\n value: function moveActiveItem(direction, e) {\n var nextActiveItem = direction === \"next\" ? this.activeItem ? this.activeItem.next : this.items[0] : this.activeItem ? this.activeItem.prev : this.items[this.items.length - 1];\n if (nextActiveItem) {\n nextActiveItem.activate();\n e.preventDefault();\n }\n return this;\n }\n\n /** @private */\n\n }, {\n key: \"setStrategyId\",\n value: function setStrategyId(searchResult) {\n var strategyId = searchResult && searchResult.strategy.props.id;\n if (strategyId) {\n this.el.setAttribute(\"data-strategy\", strategyId);\n } else {\n this.el.removeAttribute(\"data-strategy\");\n }\n return this;\n }\n\n /**\n * @private\n * @param {object[]} rawResults - What callbacked by search function.\n */\n\n }, {\n key: \"renderEdge\",\n value: function renderEdge(rawResults, type) {\n var source = (type === \"header\" ? this.header : this.footer) || \"\";\n var content = typeof source === \"function\" ? source(rawResults) : source;\n var li = document.createElement(\"li\");\n li.classList.add(\"textcomplete-\" + type);\n li.innerHTML = content;\n this.el.appendChild(li);\n return this;\n }\n\n /** @private */\n\n }, {\n key: \"isPlacementTop\",\n value: function isPlacementTop() {\n return this.placement === \"top\";\n }\n }, {\n key: \"el\",\n get: function get() {\n if (!this._el) {\n this._el = Dropdown.createElement();\n }\n return this._el;\n }\n }]);\n\n return Dropdown;\n}(_eventemitter2.default);\n\nexports.default = Dropdown;\n\n/***/ }),\n/* 11 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.DEFAULT_CLASS_NAME = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _search_result = __webpack_require__(0);\n\nvar _search_result2 = _interopRequireDefault(_search_result);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar DEFAULT_CLASS_NAME = exports.DEFAULT_CLASS_NAME = \"textcomplete-item\";\nvar CALLBACK_METHODS = [\"onClick\", \"onMouseover\"];\n\n/** @typedef */\n\n\n// Declare interface instead of importing Dropdown itself to prevent circular dependency.\n\n/**\n * Encapsulate an item of dropdown.\n */\nvar DropdownItem = function () {\n function DropdownItem(searchResult, options) {\n var _this = this;\n\n _classCallCheck(this, DropdownItem);\n\n this.searchResult = searchResult;\n this.active = false;\n this.className = options.className || DEFAULT_CLASS_NAME;\n this.activeClassName = this.className + \" active\";\n\n CALLBACK_METHODS.forEach(function (method) {\n ;_this[method] = _this[method].bind(_this);\n });\n }\n\n _createClass(DropdownItem, [{\n key: \"destroy\",\n\n\n /**\n * Try to free resources and perform other cleanup operations.\n */\n value: function destroy() {\n this.el.removeEventListener(\"mousedown\", this.onClick, false);\n this.el.removeEventListener(\"mouseover\", this.onMouseover, false);\n this.el.removeEventListener(\"touchstart\", this.onClick, false);\n if (this.active) {\n this.dropdown.activeItem = null;\n }\n // This element has already been removed by {@link Dropdown#clear}.\n this._el = null;\n }\n\n /**\n * Callbacked when it is appended to a dropdown.\n *\n * @see Dropdown#append\n */\n\n }, {\n key: \"appended\",\n value: function appended(dropdown) {\n this.dropdown = dropdown;\n this.siblings = dropdown.items;\n this.index = this.siblings.length - 1;\n }\n\n /**\n * Deactivate active item then activate itself.\n *\n * @return {this}\n */\n\n }, {\n key: \"activate\",\n value: function activate() {\n if (!this.active) {\n var _activeItem = this.dropdown.getActiveItem();\n if (_activeItem) {\n _activeItem.deactivate();\n }\n this.dropdown.activeItem = this;\n this.active = true;\n this.el.className = this.activeClassName;\n }\n return this;\n }\n\n /**\n * Get the next sibling.\n */\n\n }, {\n key: \"deactivate\",\n\n\n /** @private */\n value: function deactivate() {\n if (this.active) {\n this.active = false;\n this.el.className = this.className;\n this.dropdown.activeItem = null;\n }\n return this;\n }\n\n /** @private */\n\n }, {\n key: \"onClick\",\n value: function onClick(e) {\n e.preventDefault // Prevent blur event\n ();this.dropdown.select(this);\n }\n\n /** @private */\n\n }, {\n key: \"onMouseover\",\n value: function onMouseover() {\n this.activate();\n }\n }, {\n key: \"el\",\n get: function get() {\n if (this._el) {\n return this._el;\n }\n var li = document.createElement(\"li\");\n li.className = this.active ? this.activeClassName : this.className;\n var a = document.createElement(\"a\");\n a.innerHTML = this.searchResult.render();\n li.appendChild(a);\n this._el = li;\n li.addEventListener(\"mousedown\", this.onClick);\n li.addEventListener(\"mouseover\", this.onMouseover);\n li.addEventListener(\"touchstart\", this.onClick);\n return li;\n }\n }, {\n key: \"next\",\n get: function get() {\n var nextIndex = void 0;\n if (this.index === this.siblings.length - 1) {\n if (!this.dropdown.rotate) {\n return null;\n }\n nextIndex = 0;\n } else {\n nextIndex = this.index + 1;\n }\n return this.siblings[nextIndex];\n }\n\n /**\n * Get the previous sibling.\n */\n\n }, {\n key: \"prev\",\n get: function get() {\n var nextIndex = void 0;\n if (this.index === 0) {\n if (!this.dropdown.rotate) {\n return null;\n }\n nextIndex = this.siblings.length - 1;\n } else {\n nextIndex = this.index - 1;\n }\n return this.siblings[nextIndex];\n }\n }]);\n\n return DropdownItem;\n}();\n\nexports.default = DropdownItem;\n\n/***/ }),\n/* 12 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _update = __webpack_require__(13);\n\nvar _update2 = _interopRequireDefault(_update);\n\nvar _editor = __webpack_require__(4);\n\nvar _editor2 = _interopRequireDefault(_editor);\n\nvar _utils = __webpack_require__(3);\n\nvar _search_result = __webpack_require__(0);\n\nvar _search_result2 = _interopRequireDefault(_search_result);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar getCaretCoordinates = __webpack_require__(14);\n\nvar CALLBACK_METHODS = [\"onInput\", \"onKeydown\"];\n\n/**\n * Encapsulate the target textarea element.\n */\n\nvar Textarea = function (_Editor) {\n _inherits(Textarea, _Editor);\n\n /**\n * @param {HTMLTextAreaElement} el - Where the textcomplete works on.\n */\n function Textarea(el) {\n _classCallCheck(this, Textarea);\n\n var _this = _possibleConstructorReturn(this, (Textarea.__proto__ || Object.getPrototypeOf(Textarea)).call(this));\n\n _this.el = el;\n\n CALLBACK_METHODS.forEach(function (method) {\n ;_this[method] = _this[method].bind(_this);\n });\n\n _this.startListening();\n return _this;\n }\n\n /**\n * @return {this}\n */\n\n\n _createClass(Textarea, [{\n key: \"destroy\",\n value: function destroy() {\n _get(Textarea.prototype.__proto__ || Object.getPrototypeOf(Textarea.prototype), \"destroy\", this).call(this);\n this.stopListening\n // Release the element reference early to help garbage collection.\n ();this.el = null;\n return this;\n }\n\n /**\n * Implementation for {@link Editor#applySearchResult}\n */\n\n }, {\n key: \"applySearchResult\",\n value: function applySearchResult(searchResult) {\n var before = this.getBeforeCursor();\n if (before != null) {\n var replace = searchResult.replace(before, this.getAfterCursor());\n this.el.focus // Clicking a dropdown item removes focus from the element.\n ();if (Array.isArray(replace)) {\n (0, _update2.default)(this.el, replace[0], replace[1]);\n this.el.dispatchEvent(new Event(\"input\"));\n }\n }\n }\n\n /**\n * Implementation for {@link Editor#getCursorOffset}\n */\n\n }, {\n key: \"getCursorOffset\",\n value: function getCursorOffset() {\n var elOffset = (0, _utils.calculateElementOffset)(this.el);\n var elScroll = this.getElScroll();\n var cursorPosition = this.getCursorPosition();\n var lineHeight = (0, _utils.getLineHeightPx)(this.el);\n var top = elOffset.top - elScroll.top + cursorPosition.top + lineHeight;\n var left = elOffset.left - elScroll.left + cursorPosition.left;\n if (this.el.dir !== \"rtl\") {\n return { top: top, left: left, lineHeight: lineHeight };\n } else {\n var right = document.documentElement ? document.documentElement.clientWidth - left : 0;\n return { top: top, right: right, lineHeight: lineHeight };\n }\n }\n\n /**\n * Implementation for {@link Editor#getBeforeCursor}\n */\n\n }, {\n key: \"getBeforeCursor\",\n value: function getBeforeCursor() {\n return this.el.selectionStart !== this.el.selectionEnd ? null : this.el.value.substring(0, this.el.selectionEnd);\n }\n\n /** @private */\n\n }, {\n key: \"getAfterCursor\",\n value: function getAfterCursor() {\n return this.el.value.substring(this.el.selectionEnd);\n }\n\n /** @private */\n\n }, {\n key: \"getElScroll\",\n value: function getElScroll() {\n return { top: this.el.scrollTop, left: this.el.scrollLeft };\n }\n\n /**\n * The input cursor's relative coordinates from the textarea's left\n * top corner.\n *\n * @private\n */\n\n }, {\n key: \"getCursorPosition\",\n value: function getCursorPosition() {\n return getCaretCoordinates(this.el, this.el.selectionEnd);\n }\n\n /** @private */\n\n }, {\n key: \"onInput\",\n value: function onInput() {\n this.emitChangeEvent();\n }\n\n /** @private */\n\n }, {\n key: \"onKeydown\",\n value: function onKeydown(e) {\n var code = this.getCode(e);\n var event = void 0;\n if (code === \"UP\" || code === \"DOWN\") {\n event = this.emitMoveEvent(code);\n } else if (code === \"ENTER\") {\n event = this.emitEnterEvent();\n } else if (code === \"ESC\") {\n event = this.emitEscEvent();\n }\n if (event && event.defaultPrevented) {\n e.preventDefault();\n }\n }\n\n /** @private */\n\n }, {\n key: \"startListening\",\n value: function startListening() {\n this.el.addEventListener(\"input\", this.onInput);\n this.el.addEventListener(\"keydown\", this.onKeydown);\n }\n\n /** @private */\n\n }, {\n key: \"stopListening\",\n value: function stopListening() {\n this.el.removeEventListener(\"input\", this.onInput);\n this.el.removeEventListener(\"keydown\", this.onKeydown);\n }\n }]);\n\n return Textarea;\n}(_editor2.default);\n\nexports.default = Textarea;\n\n/***/ }),\n/* 13 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nexports.default = function (el, headToCursor, cursorToTail) {\n var curr = el.value,\n // strA + strB1 + strC\n next = headToCursor + (cursorToTail || ''),\n // strA + strB2 + strC\n activeElement = document.activeElement;\n\n // Calculate length of strA and strC\n var aLength = 0,\n cLength = 0;\n while (aLength < curr.length && aLength < next.length && curr[aLength] === next[aLength]) {\n aLength++;\n }\n while (curr.length - cLength - 1 >= 0 && next.length - cLength - 1 >= 0 && curr[curr.length - cLength - 1] === next[next.length - cLength - 1]) {\n cLength++;\n }\n aLength = Math.min(aLength, Math.min(curr.length, next.length) - cLength);\n\n // Select strB1\n el.setSelectionRange(aLength, curr.length - cLength);\n\n // Get strB2\n var strB2 = next.substring(aLength, next.length - cLength);\n\n // Replace strB1 with strB2\n el.focus();\n if (!document.execCommand('insertText', false, strB2)) {\n // Document.execCommand returns false if the command is not supported.\n // Firefox and IE returns false in this case.\n el.value = next;\n el.dispatchEvent(createInputEvent());\n }\n\n // Move cursor to the end of headToCursor\n el.setSelectionRange(headToCursor.length, headToCursor.length);\n\n activeElement && activeElement.focus();\n return el;\n};\n\nfunction createInputEvent() {\n if (typeof Event !== \"undefined\") {\n return new Event(\"input\", { bubbles: true, cancelable: true });\n } else {\n var event = document.createEvent(\"Event\");\n event.initEvent(\"input\", true, true);\n return event;\n }\n}\n\n/***/ }),\n/* 14 */\n/***/ (function(module, exports) {\n\n/* jshint browser: true */\n\n(function () {\n\n// The properties that we copy into a mirrored div.\n// Note that some browsers, such as Firefox,\n// do not concatenate properties, i.e. padding-top, bottom etc. -> padding,\n// so we have to do every single property specifically.\nvar properties = [\n 'direction', // RTL support\n 'boxSizing',\n 'width', // on Chrome and IE, exclude the scrollbar, so the mirror div wraps exactly as the textarea does\n 'height',\n 'overflowX',\n 'overflowY', // copy the scrollbar for IE\n\n 'borderTopWidth',\n 'borderRightWidth',\n 'borderBottomWidth',\n 'borderLeftWidth',\n 'borderStyle',\n\n 'paddingTop',\n 'paddingRight',\n 'paddingBottom',\n 'paddingLeft',\n\n // https://developer.mozilla.org/en-US/docs/Web/CSS/font\n 'fontStyle',\n 'fontVariant',\n 'fontWeight',\n 'fontStretch',\n 'fontSize',\n 'fontSizeAdjust',\n 'lineHeight',\n 'fontFamily',\n\n 'textAlign',\n 'textTransform',\n 'textIndent',\n 'textDecoration', // might not make a difference, but better be safe\n\n 'letterSpacing',\n 'wordSpacing',\n\n 'tabSize',\n 'MozTabSize'\n\n];\n\nvar isBrowser = (typeof window !== 'undefined');\nvar isFirefox = (isBrowser && window.mozInnerScreenX != null);\n\nfunction getCaretCoordinates(element, position, options) {\n if(!isBrowser) {\n throw new Error('textarea-caret-position#getCaretCoordinates should only be called in a browser');\n }\n\n var debug = options && options.debug || false;\n if (debug) {\n var el = document.querySelector('#input-textarea-caret-position-mirror-div');\n if ( el ) { el.parentNode.removeChild(el); }\n }\n\n // mirrored div\n var div = document.createElement('div');\n div.id = 'input-textarea-caret-position-mirror-div';\n document.body.appendChild(div);\n\n var style = div.style;\n var computed = window.getComputedStyle? getComputedStyle(element) : element.currentStyle; // currentStyle for IE < 9\n\n // default textarea styles\n style.whiteSpace = 'pre-wrap';\n if (element.nodeName !== 'INPUT')\n style.wordWrap = 'break-word'; // only for textarea-s\n\n // position off-screen\n style.position = 'absolute'; // required to return coordinates properly\n if (!debug)\n style.visibility = 'hidden'; // not 'display: none' because we want rendering\n\n // transfer the element's properties to the div\n properties.forEach(function (prop) {\n style[prop] = computed[prop];\n });\n\n if (isFirefox) {\n // Firefox lies about the overflow property for textareas: https://bugzilla.mozilla.org/show_bug.cgi?id=984275\n if (element.scrollHeight > parseInt(computed.height))\n style.overflowY = 'scroll';\n } else {\n style.overflow = 'hidden'; // for Chrome to not render a scrollbar; IE keeps overflowY = 'scroll'\n }\n\n div.textContent = element.value.substring(0, position);\n // the second special handling for input type=\"text\" vs textarea: spaces need to be replaced with non-breaking spaces - http://stackoverflow.com/a/13402035/1269037\n if (element.nodeName === 'INPUT')\n div.textContent = div.textContent.replace(/\\s/g, '\\u00a0');\n\n var span = document.createElement('span');\n // Wrapping must be replicated *exactly*, including when a long word gets\n // onto the next line, with whitespace at the end of the line before (#7).\n // The *only* reliable way to do that is to copy the *entire* rest of the\n // textarea's content into the <span> created at the caret position.\n // for inputs, just '.' would be enough, but why bother?\n span.textContent = element.value.substring(position) || '.'; // || because a completely empty faux span doesn't render at all\n div.appendChild(span);\n\n var coordinates = {\n top: span.offsetTop + parseInt(computed['borderTopWidth']),\n left: span.offsetLeft + parseInt(computed['borderLeftWidth'])\n };\n\n if (debug) {\n span.style.backgroundColor = '#aaa';\n } else {\n document.body.removeChild(div);\n }\n\n return coordinates;\n}\n\nif (typeof module != 'undefined' && typeof module.exports != 'undefined') {\n module.exports = getCaretCoordinates;\n} else if(isBrowser){\n window.getCaretCoordinates = getCaretCoordinates;\n}\n\n}());\n\n\n/***/ })\n/******/ ]);\n\n\n// WEBPACK FOOTER //\n// textcomplete.min.js"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 5);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 5fdd342a07201b673919","// @flow\n\nimport Strategy from \"./strategy\"\n\n/**\n * Encapsulate an result of each search results.\n */\nexport default class SearchResult {\n data: Object\n term: string\n strategy: Strategy\n\n /**\n * @param {object} data - An element of array callbacked by search function.\n */\n constructor(data: Object, term: string, strategy: Strategy) {\n this.data = data\n this.term = term\n this.strategy = strategy\n }\n\n replace(beforeCursor: string, afterCursor: string) {\n let replacement = this.strategy.replace(this.data)\n if (replacement !== null) {\n if (Array.isArray(replacement)) {\n afterCursor = replacement[1] + afterCursor\n replacement = replacement[0]\n }\n const match = this.strategy.matchText(beforeCursor)\n if (match) {\n replacement = replacement\n .replace(/\\$&/g, match[0])\n .replace(/\\$(\\d)/g, (_, p1) => match[parseInt(p1, 10)])\n return [\n [\n beforeCursor.slice(0, match.index),\n replacement,\n beforeCursor.slice(match.index + match[0].length),\n ].join(\"\"),\n afterCursor,\n ]\n }\n }\n }\n\n render(): string {\n return this.strategy.template(this.data, this.term)\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/search_result.js","'use strict';\n\nvar has = Object.prototype.hasOwnProperty\n , prefix = '~';\n\n/**\n * Constructor to create a storage for our `EE` objects.\n * An `Events` instance is a plain object whose properties are event names.\n *\n * @constructor\n * @api private\n */\nfunction Events() {}\n\n//\n// We try to not inherit from `Object.prototype`. In some engines creating an\n// instance in this way is faster than calling `Object.create(null)` directly.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// character to make sure that the built-in object properties are not\n// overridden or used as an attack vector.\n//\nif (Object.create) {\n Events.prototype = Object.create(null);\n\n //\n // This hack is needed because the `__proto__` property is still inherited in\n // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.\n //\n if (!new Events().__proto__) prefix = false;\n}\n\n/**\n * Representation of a single event listener.\n *\n * @param {Function} fn The listener function.\n * @param {Mixed} context The context to invoke the listener with.\n * @param {Boolean} [once=false] Specify if the listener is a one-time listener.\n * @constructor\n * @api private\n */\nfunction EE(fn, context, once) {\n this.fn = fn;\n this.context = context;\n this.once = once || false;\n}\n\n/**\n * Minimal `EventEmitter` interface that is molded against the Node.js\n * `EventEmitter` interface.\n *\n * @constructor\n * @api public\n */\nfunction EventEmitter() {\n this._events = new Events();\n this._eventsCount = 0;\n}\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @api public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n var names = []\n , events\n , name;\n\n if (this._eventsCount === 0) return names;\n\n for (name in (events = this._events)) {\n if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n }\n\n if (Object.getOwnPropertySymbols) {\n return names.concat(Object.getOwnPropertySymbols(events));\n }\n\n return names;\n};\n\n/**\n * Return the listeners registered for a given event.\n *\n * @param {String|Symbol} event The event name.\n * @param {Boolean} exists Only check if there are listeners.\n * @returns {Array|Boolean}\n * @api public\n */\nEventEmitter.prototype.listeners = function listeners(event, exists) {\n var evt = prefix ? prefix + event : event\n , available = this._events[evt];\n\n if (exists) return !!available;\n if (!available) return [];\n if (available.fn) return [available.fn];\n\n for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) {\n ee[i] = available[i].fn;\n }\n\n return ee;\n};\n\n/**\n * Calls each of the listeners registered for a given event.\n *\n * @param {String|Symbol} event The event name.\n * @returns {Boolean} `true` if the event had listeners, else `false`.\n * @api public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return false;\n\n var listeners = this._events[evt]\n , len = arguments.length\n , args\n , i;\n\n if (listeners.fn) {\n if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n switch (len) {\n case 1: return listeners.fn.call(listeners.context), true;\n case 2: return listeners.fn.call(listeners.context, a1), true;\n case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n }\n\n for (i = 1, args = new Array(len -1); i < len; i++) {\n args[i - 1] = arguments[i];\n }\n\n listeners.fn.apply(listeners.context, args);\n } else {\n var length = listeners.length\n , j;\n\n for (i = 0; i < length; i++) {\n if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n switch (len) {\n case 1: listeners[i].fn.call(listeners[i].context); break;\n case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;\n default:\n if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n args[j - 1] = arguments[j];\n }\n\n listeners[i].fn.apply(listeners[i].context, args);\n }\n }\n }\n\n return true;\n};\n\n/**\n * Add a listener for a given event.\n *\n * @param {String|Symbol} event The event name.\n * @param {Function} fn The listener function.\n * @param {Mixed} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @api public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n var listener = new EE(fn, context || this)\n , evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) this._events[evt] = listener, this._eventsCount++;\n else if (!this._events[evt].fn) this._events[evt].push(listener);\n else this._events[evt] = [this._events[evt], listener];\n\n return this;\n};\n\n/**\n * Add a one-time listener for a given event.\n *\n * @param {String|Symbol} event The event name.\n * @param {Function} fn The listener function.\n * @param {Mixed} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @api public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n var listener = new EE(fn, context || this, true)\n , evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) this._events[evt] = listener, this._eventsCount++;\n else if (!this._events[evt].fn) this._events[evt].push(listener);\n else this._events[evt] = [this._events[evt], listener];\n\n return this;\n};\n\n/**\n * Remove the listeners of a given event.\n *\n * @param {String|Symbol} event The event name.\n * @param {Function} fn Only remove the listeners that match this function.\n * @param {Mixed} context Only remove the listeners that have this context.\n * @param {Boolean} once Only remove one-time listeners.\n * @returns {EventEmitter} `this`.\n * @api public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return this;\n if (!fn) {\n if (--this._eventsCount === 0) this._events = new Events();\n else delete this._events[evt];\n return this;\n }\n\n var listeners = this._events[evt];\n\n if (listeners.fn) {\n if (\n listeners.fn === fn\n && (!once || listeners.once)\n && (!context || listeners.context === context)\n ) {\n if (--this._eventsCount === 0) this._events = new Events();\n else delete this._events[evt];\n }\n } else {\n for (var i = 0, events = [], length = listeners.length; i < length; i++) {\n if (\n listeners[i].fn !== fn\n || (once && !listeners[i].once)\n || (context && listeners[i].context !== context)\n ) {\n events.push(listeners[i]);\n }\n }\n\n //\n // Reset the array, or remove it completely if we have no more listeners.\n //\n if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;\n else if (--this._eventsCount === 0) this._events = new Events();\n else delete this._events[evt];\n }\n\n return this;\n};\n\n/**\n * Remove all listeners, or those of the specified event.\n *\n * @param {String|Symbol} [event] The event name.\n * @returns {EventEmitter} `this`.\n * @api public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n var evt;\n\n if (event) {\n evt = prefix ? prefix + event : event;\n if (this._events[evt]) {\n if (--this._eventsCount === 0) this._events = new Events();\n else delete this._events[evt];\n }\n } else {\n this._events = new Events();\n this._eventsCount = 0;\n }\n\n return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// This function doesn't apply anymore.\n//\nEventEmitter.prototype.setMaxListeners = function setMaxListeners() {\n return this;\n};\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Allow `EventEmitter` to be imported as module namespace.\n//\nEventEmitter.EventEmitter = EventEmitter;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n module.exports = EventEmitter;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/eventemitter3/index.js\n// module id = 1\n// module chunks = 0","// @flow\n\ndeclare class MatchData extends Array<string> {\n index: number;\n}\n\nexport type { MatchData }\n\nconst DEFAULT_INDEX = 2\n\nfunction DEFAULT_TEMPLATE(value) {\n return value\n}\n\n/**\n * Properties for a strategy.\n *\n * @typedef\n */\nexport type StrategyProperties = {\n match: RegExp | (string => MatchData | null),\n search: Function,\n replace: any => string[] | string | null,\n cache?: boolean,\n context?: Function,\n template?: any => string,\n index?: number,\n id?: string,\n}\n\n/**\n * Encapsulate a single strategy.\n */\nexport default class Strategy {\n props: StrategyProperties\n cache: ?Object\n\n constructor(props: StrategyProperties) {\n this.props = props\n this.cache = props.cache ? {} : null\n }\n\n /**\n * @return {this}\n */\n destroy() {\n this.cache = null\n return this\n }\n\n search(term: string, callback: Function, match: MatchData): void {\n if (this.cache) {\n this.searchWithCache(term, callback, match)\n } else {\n this.props.search(term, callback, match)\n }\n }\n\n /**\n * @param {object} data - An element of array callbacked by search function.\n */\n replace(data: any) {\n return this.props.replace(data)\n }\n\n /** @private */\n searchWithCache(term: string, callback: Function, match: MatchData): void {\n if (this.cache && this.cache[term]) {\n callback(this.cache[term])\n } else {\n this.props.search(\n term,\n results => {\n if (this.cache) {\n this.cache[term] = results\n }\n callback(results)\n },\n match,\n )\n }\n }\n\n /** @private */\n matchText(text: string): MatchData | null {\n if (typeof this.match === \"function\") {\n return this.match(text)\n } else {\n return (text.match(this.match): any)\n }\n }\n\n /** @private */\n get match(): $PropertyType<StrategyProperties, \"match\"> {\n return this.props.match\n }\n\n /** @private */\n get index(): number {\n return typeof this.props.index === \"number\"\n ? this.props.index\n : DEFAULT_INDEX\n }\n\n get template(): (...any) => string {\n return this.props.template || DEFAULT_TEMPLATE\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/strategy.js","// @flow\n\n/**\n * Create a custom event\n *\n * @private\n */\nexport const createCustomEvent = (() => {\n if (typeof window.CustomEvent === \"function\") {\n return function(\n type: string,\n options: ?{ detail?: Object, cancelable?: boolean },\n ): CustomEvent {\n return new document.defaultView.CustomEvent(type, {\n cancelable: (options && options.cancelable) || false,\n detail: (options && options.detail) || undefined,\n })\n }\n } else {\n // Custom event polyfill from\n // https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#polyfill\n return function(\n type: string,\n options: ?{ detail?: Object, cancelable?: boolean },\n ): CustomEvent {\n const event = document.createEvent(\"CustomEvent\")\n event.initCustomEvent(\n type,\n /* bubbles */ false,\n (options && options.cancelable) || false,\n (options && options.detail) || undefined,\n )\n return event\n }\n }\n})()\n\n/**\n * Get the current coordinates of the `el` relative to the document.\n *\n * @private\n */\nexport function calculateElementOffset(\n el: HTMLElement,\n): { top: number, left: number } {\n const rect = el.getBoundingClientRect()\n const { defaultView, documentElement } = el.ownerDocument\n const offset = {\n top: rect.top + defaultView.pageYOffset,\n left: rect.left + defaultView.pageXOffset,\n }\n if (documentElement) {\n offset.top -= documentElement.clientTop\n offset.left -= documentElement.clientLeft\n }\n return offset\n}\n\nconst CHAR_CODE_ZERO = \"0\".charCodeAt(0)\nconst CHAR_CODE_NINE = \"9\".charCodeAt(0)\n\nfunction isDigit(charCode: number): boolean {\n return charCode >= CHAR_CODE_ZERO && charCode <= CHAR_CODE_NINE\n}\n\n/**\n * Returns the line-height of the given node in pixels.\n *\n * @private\n */\nexport function getLineHeightPx(node: HTMLElement): number {\n const computedStyle = window.getComputedStyle(node)\n\n // If the char code starts with a digit, it is either a value in pixels,\n // or unitless, as per:\n // https://drafts.csswg.org/css2/visudet.html#propdef-line-height\n // https://drafts.csswg.org/css2/cascade.html#computed-value\n if (isDigit(computedStyle.lineHeight.charCodeAt(0))) {\n // In real browsers the value is *always* in pixels, even for unit-less\n // line-heights. However, we still check as per the spec.\n if (\n isDigit(\n computedStyle.lineHeight.charCodeAt(\n computedStyle.lineHeight.length - 1,\n ),\n )\n ) {\n return (\n parseFloat(computedStyle.lineHeight) *\n parseFloat(computedStyle.fontSize)\n )\n } else {\n return parseFloat(computedStyle.lineHeight)\n }\n }\n\n // Otherwise, the value is \"normal\".\n // If the line-height is \"normal\", calculate by font-size\n return calculateLineHeightPx(node.nodeName, computedStyle)\n}\n\n/**\n * Returns calculated line-height of the given node in pixels.\n *\n * @private\n */\nexport function calculateLineHeightPx(\n nodeName: string,\n computedStyle: CSSStyleDeclaration,\n): number {\n const body = document.body\n if (!body) {\n return 0\n }\n\n const tempNode = document.createElement(nodeName)\n tempNode.innerHTML = \"&nbsp;\"\n tempNode.style.fontSize = computedStyle.fontSize\n tempNode.style.fontFamily = computedStyle.fontFamily\n tempNode.style.padding = \"0\"\n body.appendChild(tempNode)\n\n // Make sure textarea has only 1 row\n if (tempNode instanceof HTMLTextAreaElement) {\n ;(tempNode: HTMLTextAreaElement).rows = 1\n }\n\n // Assume the height of the element is the line-height\n const height = tempNode.offsetHeight\n body.removeChild(tempNode)\n\n return height\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/utils.js","// @flow\n/*eslint no-unused-vars: off*/\n\nimport EventEmitter from \"eventemitter3\"\n\nimport { createCustomEvent } from \"./utils\"\nimport SearchResult from \"./search_result\"\n\n/** @typedef */\nexport type CursorOffset = {\n lineHeight: number,\n top: number,\n left?: number,\n right?: number,\n}\n\ntype KeyCode = \"ESC\" | \"ENTER\" | \"UP\" | \"DOWN\" | \"OTHER\"\n\n/**\n * Abstract class representing a editor target.\n *\n * Editor classes must implement `#applySearchResult`, `#getCursorOffset` and\n * `#getBeforeCursor` methods.\n *\n * Editor classes must invoke `#emitMoveEvent`, `#emitEnterEvent`,\n * `#emitChangeEvent` and `#emitEscEvent` at proper timing.\n *\n * @abstract\n */\nexport default class Editor extends EventEmitter {\n /**\n * It is called when associated textcomplete object is destroyed.\n *\n * @return {this}\n */\n destroy() {\n return this\n }\n\n /**\n * It is called when a search result is selected by a user.\n */\n applySearchResult(_: SearchResult): void {\n throw new Error(\"Not implemented.\")\n }\n\n /**\n * The input cursor's absolute coordinates from the window's left\n * top corner.\n */\n getCursorOffset(): CursorOffset {\n throw new Error(\"Not implemented.\")\n }\n\n /**\n * Editor string value from head to cursor.\n * Returns null if selection type is range not cursor.\n */\n getBeforeCursor(): ?string {\n throw new Error(\"Not implemented.\")\n }\n\n /**\n * Emit a move event, which moves active dropdown element.\n * Child class must call this method at proper timing with proper parameter.\n *\n * @see {@link Textarea} for live example.\n */\n emitMoveEvent(code: \"UP\" | \"DOWN\"): CustomEvent {\n const moveEvent = createCustomEvent(\"move\", {\n cancelable: true,\n detail: {\n code: code,\n },\n })\n this.emit(\"move\", moveEvent)\n return moveEvent\n }\n\n /**\n * Emit a enter event, which selects current search result.\n * Child class must call this method at proper timing.\n *\n * @see {@link Textarea} for live example.\n */\n emitEnterEvent(): CustomEvent {\n const enterEvent = createCustomEvent(\"enter\", { cancelable: true })\n this.emit(\"enter\", enterEvent)\n return enterEvent\n }\n\n /**\n * Emit a change event, which triggers auto completion.\n * Child class must call this method at proper timing.\n *\n * @see {@link Textarea} for live example.\n */\n emitChangeEvent(): CustomEvent {\n const changeEvent = createCustomEvent(\"change\", {\n detail: {\n beforeCursor: this.getBeforeCursor(),\n },\n })\n this.emit(\"change\", changeEvent)\n return changeEvent\n }\n\n /**\n * Emit a esc event, which hides dropdown element.\n * Child class must call this method at proper timing.\n *\n * @see {@link Textarea} for live example.\n */\n emitEscEvent(): CustomEvent {\n const escEvent = createCustomEvent(\"esc\", { cancelable: true })\n this.emit(\"esc\", escEvent)\n return escEvent\n }\n\n /**\n * Helper method for parsing KeyboardEvent.\n *\n * @see {@link Textarea} for live example.\n */\n getCode(e: KeyboardEvent): KeyCode {\n return e.keyCode === 9\n ? \"ENTER\" // tab\n : e.keyCode === 13\n ? \"ENTER\" // enter\n : e.keyCode === 27\n ? \"ESC\" // esc\n : e.keyCode === 38\n ? \"UP\" // up\n : e.keyCode === 40\n ? \"DOWN\" // down\n : e.keyCode === 78 && e.ctrlKey\n ? \"DOWN\" // ctrl-n\n : e.keyCode === 80 && e.ctrlKey\n ? \"UP\" // ctrl-p\n : \"OTHER\"\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/editor.js","import Textcomplete from \"./textcomplete\"\nimport Textarea from \"./textarea\"\n\nlet editors\nif (global.Textcomplete && global.Textcomplete.editors) {\n editors = global.Textcomplete.editors\n} else {\n editors = {}\n}\neditors.Textarea = Textarea\n\nglobal.Textcomplete = Textcomplete\nglobal.Textcomplete.editors = editors\n\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","var g;\r\n\r\n// This works in non-strict mode\r\ng = (function() {\r\n\treturn this;\r\n})();\r\n\r\ntry {\r\n\t// This works if eval is allowed (see CSP)\r\n\tg = g || Function(\"return this\")() || (1,eval)(\"this\");\r\n} catch(e) {\r\n\t// This works if the window reference is available\r\n\tif(typeof window === \"object\")\r\n\t\tg = window;\r\n}\r\n\r\n// g can still be undefined, but nothing to do about it...\r\n// We return undefined, instead of nothing here, so it's\r\n// easier to handle this case. if(!global) { ...}\r\n\r\nmodule.exports = g;\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// (webpack)/buildin/global.js\n// module id = 6\n// module chunks = 0","// @flow\n\nimport Completer from \"./completer\"\nimport Editor from \"./editor\"\nimport Dropdown, { type DropdownOptions } from \"./dropdown\"\nimport Strategy, { type StrategyProperties } from \"./strategy\"\nimport SearchResult from \"./search_result\"\n\nimport EventEmitter from \"eventemitter3\"\n\nconst CALLBACK_METHODS = [\n \"handleChange\",\n \"handleEnter\",\n \"handleEsc\",\n \"handleHit\",\n \"handleMove\",\n \"handleSelect\",\n]\n\n/** @typedef */\ntype TextcompleteOptions = {\n dropdown?: DropdownOptions,\n}\n\n/**\n * The core of textcomplete. It acts as a mediator.\n */\nexport default class Textcomplete extends EventEmitter {\n dropdown: Dropdown\n editor: Editor\n options: TextcompleteOptions\n completer: Completer\n isQueryInFlight: boolean\n nextPendingQuery: string | null\n\n /**\n * @param {Editor} editor - Where the textcomplete works on.\n */\n constructor(editor: Editor, options: TextcompleteOptions = {}) {\n super()\n\n this.completer = new Completer()\n this.isQueryInFlight = false\n this.nextPendingQuery = null\n this.dropdown = new Dropdown(options.dropdown || {})\n this.editor = editor\n this.options = options\n\n CALLBACK_METHODS.forEach(method => {\n ;(this: any)[method] = (this: any)[method].bind(this)\n })\n\n this.startListening()\n }\n\n /**\n * @return {this}\n */\n destroy(destroyEditor: boolean = true) {\n this.completer.destroy()\n this.dropdown.destroy()\n if (destroyEditor) {\n this.editor.destroy()\n }\n this.stopListening()\n return this\n }\n\n /**\n * @return {this}\n */\n hide() {\n this.dropdown.deactivate()\n return this\n }\n\n /**\n * @return {this}\n * @example\n * textcomplete.register([{\n * match: /(^|\\s)(\\w+)$/,\n * search: function (term, callback) {\n * $.ajax({ ... })\n * .done(callback)\n * .fail([]);\n * },\n * replace: function (value) {\n * return '$1' + value + ' ';\n * }\n * }]);\n */\n register(strategyPropsArray: StrategyProperties[]) {\n strategyPropsArray.forEach(props => {\n this.completer.registerStrategy(new Strategy(props))\n })\n return this\n }\n\n /**\n * Start autocompleting.\n *\n * @param {string} text - Head to input cursor.\n * @return {this}\n */\n trigger(text: string) {\n if (this.isQueryInFlight) {\n this.nextPendingQuery = text\n } else {\n this.isQueryInFlight = true\n this.nextPendingQuery = null\n this.completer.run(text)\n }\n return this\n }\n\n /** @private */\n handleHit({ searchResults }: { searchResults: SearchResult[] }) {\n if (searchResults.length) {\n this.dropdown.render(searchResults, this.editor.getCursorOffset())\n } else {\n this.dropdown.deactivate()\n }\n this.isQueryInFlight = false\n if (this.nextPendingQuery !== null) {\n this.trigger(this.nextPendingQuery)\n }\n }\n\n /** @private */\n handleMove(e: CustomEvent) {\n e.detail.code === \"UP\" ? this.dropdown.up(e) : this.dropdown.down(e)\n }\n\n /** @private */\n handleEnter(e: CustomEvent) {\n const activeItem = this.dropdown.getActiveItem()\n if (activeItem) {\n this.dropdown.select(activeItem)\n e.preventDefault()\n } else {\n this.dropdown.deactivate()\n }\n }\n\n /** @private */\n handleEsc(e: CustomEvent) {\n if (this.dropdown.shown) {\n this.dropdown.deactivate()\n e.preventDefault()\n }\n }\n\n /** @private */\n handleChange(e: CustomEvent) {\n if (e.detail.beforeCursor != null) {\n this.trigger(e.detail.beforeCursor)\n } else {\n this.dropdown.deactivate()\n }\n }\n\n /** @private */\n handleSelect(selectEvent: CustomEvent) {\n this.emit(\"select\", selectEvent)\n if (!selectEvent.defaultPrevented) {\n this.editor.applySearchResult(selectEvent.detail.searchResult)\n }\n }\n\n /** @private */\n startListening() {\n this.editor\n .on(\"move\", this.handleMove)\n .on(\"enter\", this.handleEnter)\n .on(\"esc\", this.handleEsc)\n .on(\"change\", this.handleChange)\n this.dropdown.on(\"select\", this.handleSelect)\n ;[\n \"show\",\n \"shown\",\n \"render\",\n \"rendered\",\n \"selected\",\n \"hidden\",\n \"hide\",\n ].forEach(eventName => {\n this.dropdown.on(eventName, () => this.emit(eventName))\n })\n this.completer.on(\"hit\", this.handleHit)\n }\n\n /** @private */\n stopListening() {\n this.completer.removeAllListeners()\n this.dropdown.removeAllListeners()\n this.editor\n .removeListener(\"move\", this.handleMove)\n .removeListener(\"enter\", this.handleEnter)\n .removeListener(\"esc\", this.handleEsc)\n .removeListener(\"change\", this.handleChange)\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/textcomplete.js","// @flow\n\nimport EventEmitter from \"eventemitter3\"\n\nimport Query from \"./query\"\nimport SearchResult from \"./search_result\"\nimport Strategy from \"./strategy\"\n\nconst CALLBACK_METHODS = [\"handleQueryResult\"]\n\n/**\n * Complete engine.\n */\nexport default class Completer extends EventEmitter {\n strategies: Strategy[]\n\n constructor() {\n super()\n this.strategies = []\n\n CALLBACK_METHODS.forEach(method => {\n ;(this: any)[method] = (this: any)[method].bind(this)\n })\n }\n\n /**\n * @return {this}\n */\n destroy() {\n this.strategies.forEach(strategy => strategy.destroy())\n return this\n }\n\n /**\n * Register a strategy to the completer.\n *\n * @return {this}\n */\n registerStrategy(strategy: Strategy) {\n this.strategies.push(strategy)\n return this\n }\n\n /**\n * @param {string} text - Head to input cursor.\n */\n run(text: string): void {\n const query = this.extractQuery(text)\n if (query) {\n query.execute(this.handleQueryResult)\n } else {\n this.handleQueryResult([])\n }\n }\n\n /**\n * Find a query, which matches to the given text.\n *\n * @private\n */\n extractQuery(text: string) {\n for (let i = 0; i < this.strategies.length; i++) {\n const query = Query.build(this.strategies[i], text)\n if (query) {\n return query\n }\n }\n return null\n }\n\n /**\n * Callbacked by {@link Query#execute}.\n *\n * @private\n */\n handleQueryResult(searchResults: SearchResult[]) {\n this.emit(\"hit\", { searchResults })\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/completer.js","// @flow\n\nimport SearchResult from \"./search_result\"\nimport Strategy from \"./strategy\"\nimport type { MatchData } from \"./strategy\"\n\n/**\n * Encapsulate matching condition between a Strategy and current editor's value.\n */\nexport default class Query {\n strategy: Strategy\n term: string\n match: MatchData\n\n /**\n * Build a Query object by the given string if this matches to the string.\n *\n * @param {string} text - Head to input cursor.\n */\n static build(strategy: Strategy, text: string): ?Query {\n if (typeof strategy.props.context === \"function\") {\n const context = strategy.props.context(text)\n if (typeof context === \"string\") {\n text = context\n } else if (!context) {\n return null\n }\n }\n const match = strategy.matchText(text)\n return match ? new Query(strategy, match[strategy.index], match) : null\n }\n\n constructor(strategy: Strategy, term: string, match: MatchData) {\n this.strategy = strategy\n this.term = term\n this.match = match\n }\n\n /**\n * Invoke search strategy and callback the given function.\n */\n execute(callback: (SearchResult[]) => void) {\n this.strategy.search(\n this.term,\n results => {\n callback(\n results.map(result => {\n return new SearchResult(result, this.term, this.strategy)\n }),\n )\n },\n this.match,\n )\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/query.js","// @flow\nimport EventEmitter from \"eventemitter3\"\n\nimport DropdownItem, { type DropdownItemOptions } from \"./dropdown_item\"\nimport SearchResult from \"./search_result\"\nimport { createCustomEvent } from \"./utils\"\nimport type { CursorOffset } from \"./editor\"\n\nconst DEFAULT_CLASS_NAME = \"dropdown-menu textcomplete-dropdown\"\n\n/** @typedef */\nexport type DropdownOptions = {\n className?: string,\n footer?: any => string | string,\n header?: any => string | string,\n maxCount?: number,\n placement?: string,\n rotate?: boolean,\n style?: { [string]: string },\n item?: DropdownItemOptions,\n}\n\n/**\n * Encapsulate a dropdown view.\n *\n * @prop {boolean} shown - Whether the #el is shown or not.\n * @prop {DropdownItem[]} items - The array of rendered dropdown items.\n */\nexport default class Dropdown extends EventEmitter {\n shown: boolean\n items: DropdownItem[]\n activeItem: DropdownItem | null\n footer: $PropertyType<DropdownOptions, \"footer\">\n header: $PropertyType<DropdownOptions, \"header\">\n maxCount: $PropertyType<DropdownOptions, \"maxCount\">\n rotate: $PropertyType<DropdownOptions, \"rotate\">\n placement: $PropertyType<DropdownOptions, \"placement\">\n itemOptions: DropdownItemOptions\n _el: ?HTMLUListElement\n\n static createElement(): HTMLUListElement {\n const el = document.createElement(\"ul\")\n const style = el.style\n style.display = \"none\"\n style.position = \"absolute\"\n style.zIndex = \"10000\"\n const body = document.body\n if (body) {\n body.appendChild(el)\n }\n return el\n }\n\n constructor(options: DropdownOptions) {\n super()\n this.shown = false\n this.items = []\n this.activeItem = null\n this.footer = options.footer\n this.header = options.header\n this.maxCount = options.maxCount || 10\n this.el.className = options.className || DEFAULT_CLASS_NAME\n this.rotate = options.hasOwnProperty(\"rotate\") ? options.rotate : true\n this.placement = options.placement\n this.itemOptions = options.item || {}\n const style = options.style\n if (style) {\n Object.keys(style).forEach(key => {\n ;(this.el.style: any)[key] = style[key]\n })\n }\n }\n\n /**\n * @return {this}\n */\n destroy() {\n const parentNode = this.el.parentNode\n if (parentNode) {\n parentNode.removeChild(this.el)\n }\n this.clear()._el = null\n return this\n }\n\n get el(): HTMLUListElement {\n if (!this._el) {\n this._el = Dropdown.createElement()\n }\n return this._el\n }\n\n /**\n * Render the given data as dropdown items.\n *\n * @return {this}\n */\n render(searchResults: SearchResult[], cursorOffset: CursorOffset) {\n const renderEvent = createCustomEvent(\"render\", { cancelable: true })\n this.emit(\"render\", renderEvent)\n if (renderEvent.defaultPrevented) {\n return this\n }\n const rawResults = searchResults.map(searchResult => searchResult.data)\n const dropdownItems = searchResults\n .slice(0, this.maxCount || searchResults.length)\n .map(searchResult => new DropdownItem(searchResult, this.itemOptions))\n this.clear()\n .setStrategyId(searchResults[0])\n .renderEdge(rawResults, \"header\")\n .append(dropdownItems)\n .renderEdge(rawResults, \"footer\")\n .show()\n .setOffset(cursorOffset)\n this.emit(\"rendered\", createCustomEvent(\"rendered\"))\n return this\n }\n\n /**\n * Hide the dropdown then sweep out items.\n *\n * @return {this}\n */\n deactivate() {\n return this.hide().clear()\n }\n\n /**\n * @return {this}\n */\n select(dropdownItem: DropdownItem) {\n const detail = { searchResult: dropdownItem.searchResult }\n const selectEvent = createCustomEvent(\"select\", {\n cancelable: true,\n detail: detail,\n })\n this.emit(\"select\", selectEvent)\n if (selectEvent.defaultPrevented) {\n return this\n }\n this.deactivate()\n this.emit(\"selected\", createCustomEvent(\"selected\", { detail }))\n return this\n }\n\n /**\n * @return {this}\n */\n up(e: CustomEvent) {\n return this.shown ? this.moveActiveItem(\"prev\", e) : this\n }\n\n /**\n * @return {this}\n */\n down(e: CustomEvent) {\n return this.shown ? this.moveActiveItem(\"next\", e) : this\n }\n\n /**\n * Retrieve the active item.\n */\n getActiveItem(): DropdownItem | null {\n return this.activeItem\n }\n\n /**\n * Add items to dropdown.\n *\n * @private\n */\n append(items: DropdownItem[]) {\n const fragment = document.createDocumentFragment()\n items.forEach(item => {\n this.items.push(item)\n item.appended(this)\n fragment.appendChild(item.el)\n })\n this.el.appendChild(fragment)\n return this\n }\n\n /** @private */\n setOffset(cursorOffset: CursorOffset) {\n const doc = document.documentElement\n if (doc) {\n const elementWidth = this.el.offsetWidth\n if (cursorOffset.left) {\n const browserWidth = doc.clientWidth\n if (cursorOffset.left + elementWidth > browserWidth) {\n cursorOffset.left = browserWidth - elementWidth\n }\n this.el.style.left = `${cursorOffset.left}px`\n } else if (cursorOffset.right) {\n if (cursorOffset.right - elementWidth < 0) {\n cursorOffset.right = 0\n }\n this.el.style.right = `${cursorOffset.right}px`\n }\n if (this.isPlacementTop()) {\n this.el.style.bottom = `${doc.clientHeight -\n cursorOffset.top +\n cursorOffset.lineHeight}px`\n } else {\n this.el.style.top = `${cursorOffset.top}px`\n }\n }\n return this\n }\n\n /**\n * Show the element.\n *\n * @private\n */\n show() {\n if (!this.shown) {\n const showEvent = createCustomEvent(\"show\", { cancelable: true })\n this.emit(\"show\", showEvent)\n if (showEvent.defaultPrevented) {\n return this\n }\n this.el.style.display = \"block\"\n this.shown = true\n this.emit(\"shown\", createCustomEvent(\"shown\"))\n }\n return this\n }\n\n /**\n * Hide the element.\n *\n * @private\n */\n hide() {\n if (this.shown) {\n const hideEvent = createCustomEvent(\"hide\", { cancelable: true })\n this.emit(\"hide\", hideEvent)\n if (hideEvent.defaultPrevented) {\n return this\n }\n this.el.style.display = \"none\"\n this.shown = false\n this.emit(\"hidden\", createCustomEvent(\"hidden\"))\n }\n return this\n }\n\n /**\n * Clear search results.\n *\n * @private\n */\n clear() {\n this.el.innerHTML = \"\"\n this.items.forEach(item => item.destroy())\n this.items = []\n return this\n }\n\n /** @private */\n moveActiveItem(direction: \"next\" | \"prev\", e: CustomEvent) {\n const nextActiveItem =\n direction === \"next\"\n ? this.activeItem ? this.activeItem.next : this.items[0]\n : this.activeItem\n ? this.activeItem.prev\n : this.items[this.items.length - 1]\n if (nextActiveItem) {\n nextActiveItem.activate()\n e.preventDefault()\n }\n return this\n }\n\n /** @private */\n setStrategyId(searchResult: ?SearchResult) {\n const strategyId = searchResult && searchResult.strategy.props.id\n if (strategyId) {\n this.el.setAttribute(\"data-strategy\", strategyId)\n } else {\n this.el.removeAttribute(\"data-strategy\")\n }\n return this\n }\n\n /**\n * @private\n * @param {object[]} rawResults - What callbacked by search function.\n */\n renderEdge(rawResults: Object[], type: \"header\" | \"footer\") {\n const source = (type === \"header\" ? this.header : this.footer) || \"\"\n const content: any =\n typeof source === \"function\" ? source(rawResults) : source\n const li = document.createElement(\"li\")\n li.classList.add(`textcomplete-${type}`)\n li.innerHTML = content\n this.el.appendChild(li)\n return this\n }\n\n /** @private */\n isPlacementTop() {\n return this.placement === \"top\"\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/dropdown.js","// @flow\n\nimport SearchResult from \"./search_result\"\n\nexport const DEFAULT_CLASS_NAME = \"textcomplete-item\"\nconst CALLBACK_METHODS = [\"onClick\", \"onMouseover\"]\n\n/** @typedef */\nexport type DropdownItemOptions = {\n className?: string,\n}\n\n// Declare interface instead of importing Dropdown itself to prevent circular dependency.\ninterface Dropdown {\n activeItem: DropdownItem | null;\n items: DropdownItem[];\n rotate: ?Boolean;\n getActiveItem(): DropdownItem | null;\n select(DropdownItem): DropdownItem;\n}\n\n/**\n * Encapsulate an item of dropdown.\n */\nexport default class DropdownItem {\n searchResult: SearchResult\n active: boolean\n className: string\n activeClassName: string\n siblings: DropdownItem[]\n dropdown: Dropdown\n index: number\n _el: ?HTMLLIElement\n\n constructor(searchResult: SearchResult, options: DropdownItemOptions) {\n this.searchResult = searchResult\n this.active = false\n this.className = options.className || DEFAULT_CLASS_NAME\n this.activeClassName = `${this.className} active`\n\n CALLBACK_METHODS.forEach(method => {\n ;(this: any)[method] = (this: any)[method].bind(this)\n })\n }\n\n get el(): HTMLLIElement {\n if (this._el) {\n return this._el\n }\n const li = document.createElement(\"li\")\n li.className = this.active ? this.activeClassName : this.className\n const a = document.createElement(\"a\")\n a.innerHTML = this.searchResult.render()\n li.appendChild(a)\n this._el = li\n li.addEventListener(\"mousedown\", this.onClick)\n li.addEventListener(\"mouseover\", this.onMouseover)\n li.addEventListener(\"touchstart\", this.onClick)\n return li\n }\n\n /**\n * Try to free resources and perform other cleanup operations.\n */\n destroy() {\n this.el.removeEventListener(\"mousedown\", this.onClick, false)\n this.el.removeEventListener(\"mouseover\", this.onMouseover, false)\n this.el.removeEventListener(\"touchstart\", this.onClick, false)\n if (this.active) {\n this.dropdown.activeItem = null\n }\n // This element has already been removed by {@link Dropdown#clear}.\n this._el = null\n }\n\n /**\n * Callbacked when it is appended to a dropdown.\n *\n * @see Dropdown#append\n */\n appended(dropdown: Dropdown) {\n this.dropdown = dropdown\n this.siblings = dropdown.items\n this.index = this.siblings.length - 1\n }\n\n /**\n * Deactivate active item then activate itself.\n *\n * @return {this}\n */\n activate() {\n if (!this.active) {\n const activeItem = this.dropdown.getActiveItem()\n if (activeItem) {\n activeItem.deactivate()\n }\n this.dropdown.activeItem = this\n this.active = true\n this.el.className = this.activeClassName\n }\n return this\n }\n\n /**\n * Get the next sibling.\n */\n get next(): ?DropdownItem {\n let nextIndex\n if (this.index === this.siblings.length - 1) {\n if (!this.dropdown.rotate) {\n return null\n }\n nextIndex = 0\n } else {\n nextIndex = this.index + 1\n }\n return this.siblings[nextIndex]\n }\n\n /**\n * Get the previous sibling.\n */\n get prev(): ?DropdownItem {\n let nextIndex\n if (this.index === 0) {\n if (!this.dropdown.rotate) {\n return null\n }\n nextIndex = this.siblings.length - 1\n } else {\n nextIndex = this.index - 1\n }\n return this.siblings[nextIndex]\n }\n\n /** @private */\n deactivate() {\n if (this.active) {\n this.active = false\n this.el.className = this.className\n this.dropdown.activeItem = null\n }\n return this\n }\n\n /** @private */\n onClick(e: Event) {\n e.preventDefault() // Prevent blur event\n this.dropdown.select(this)\n }\n\n /** @private */\n onMouseover() {\n this.activate()\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/dropdown_item.js","// @flow\n\nimport update from \"undate/lib/update\"\n\nimport Editor from \"./editor\"\nimport { calculateElementOffset, getLineHeightPx } from \"./utils\"\nimport SearchResult from \"./search_result\"\n\nconst getCaretCoordinates = require(\"textarea-caret\")\n\nconst CALLBACK_METHODS = [\"onInput\", \"onKeydown\"]\n\n/**\n * Encapsulate the target textarea element.\n */\nexport default class Textarea extends Editor {\n el: HTMLTextAreaElement\n\n /**\n * @param {HTMLTextAreaElement} el - Where the textcomplete works on.\n */\n constructor(el: HTMLTextAreaElement) {\n super()\n this.el = el\n\n CALLBACK_METHODS.forEach(method => {\n ;(this: any)[method] = (this: any)[method].bind(this)\n })\n\n this.startListening()\n }\n\n /**\n * @return {this}\n */\n destroy() {\n super.destroy()\n this.stopListening()\n // Release the element reference early to help garbage collection.\n ;(this: any).el = null\n return this\n }\n\n /**\n * Implementation for {@link Editor#applySearchResult}\n */\n applySearchResult(searchResult: SearchResult) {\n const before = this.getBeforeCursor()\n if (before != null) {\n const replace = searchResult.replace(before, this.getAfterCursor())\n this.el.focus() // Clicking a dropdown item removes focus from the element.\n if (Array.isArray(replace)) {\n update(this.el, replace[0], replace[1])\n this.el.dispatchEvent(new Event(\"input\"))\n }\n }\n }\n\n /**\n * Implementation for {@link Editor#getCursorOffset}\n */\n getCursorOffset() {\n const elOffset = calculateElementOffset(this.el)\n const elScroll = this.getElScroll()\n const cursorPosition = this.getCursorPosition()\n const lineHeight = getLineHeightPx(this.el)\n const top = elOffset.top - elScroll.top + cursorPosition.top + lineHeight\n const left = elOffset.left - elScroll.left + cursorPosition.left\n if (this.el.dir !== \"rtl\") {\n return { top, left, lineHeight }\n } else {\n const right = document.documentElement\n ? document.documentElement.clientWidth - left\n : 0\n return { top, right, lineHeight }\n }\n }\n\n /**\n * Implementation for {@link Editor#getBeforeCursor}\n */\n getBeforeCursor() {\n return this.el.selectionStart !== this.el.selectionEnd\n ? null\n : this.el.value.substring(0, this.el.selectionEnd)\n }\n\n /** @private */\n getAfterCursor() {\n return this.el.value.substring(this.el.selectionEnd)\n }\n\n /** @private */\n getElScroll(): { top: number, left: number } {\n return { top: this.el.scrollTop, left: this.el.scrollLeft }\n }\n\n /**\n * The input cursor's relative coordinates from the textarea's left\n * top corner.\n *\n * @private\n */\n getCursorPosition(): { top: number, left: number } {\n return getCaretCoordinates(this.el, this.el.selectionEnd)\n }\n\n /** @private */\n onInput() {\n this.emitChangeEvent()\n }\n\n /** @private */\n onKeydown(e: KeyboardEvent) {\n const code = this.getCode(e)\n let event\n if (code === \"UP\" || code === \"DOWN\") {\n event = this.emitMoveEvent(code)\n } else if (code === \"ENTER\") {\n event = this.emitEnterEvent()\n } else if (code === \"ESC\") {\n event = this.emitEscEvent()\n }\n if (event && event.defaultPrevented) {\n e.preventDefault()\n }\n }\n\n /** @private */\n startListening() {\n this.el.addEventListener(\"input\", this.onInput)\n this.el.addEventListener(\"keydown\", this.onKeydown)\n }\n\n /** @private */\n stopListening() {\n this.el.removeEventListener(\"input\", this.onInput)\n this.el.removeEventListener(\"keydown\", this.onKeydown)\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/textarea.js","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nexports.default = function (el, headToCursor, cursorToTail) {\n var curr = el.value,\n // strA + strB1 + strC\n next = headToCursor + (cursorToTail || ''),\n // strA + strB2 + strC\n activeElement = document.activeElement;\n\n // Calculate length of strA and strC\n var aLength = 0,\n cLength = 0;\n while (aLength < curr.length && aLength < next.length && curr[aLength] === next[aLength]) {\n aLength++;\n }\n while (curr.length - cLength - 1 >= 0 && next.length - cLength - 1 >= 0 && curr[curr.length - cLength - 1] === next[next.length - cLength - 1]) {\n cLength++;\n }\n aLength = Math.min(aLength, Math.min(curr.length, next.length) - cLength);\n\n // Select strB1\n el.setSelectionRange(aLength, curr.length - cLength);\n\n // Get strB2\n var strB2 = next.substring(aLength, next.length - cLength);\n\n // Replace strB1 with strB2\n el.focus();\n if (!document.execCommand('insertText', false, strB2)) {\n // Document.execCommand returns false if the command is not supported.\n // Firefox and IE returns false in this case.\n el.value = next;\n el.dispatchEvent(createInputEvent());\n }\n\n // Move cursor to the end of headToCursor\n el.setSelectionRange(headToCursor.length, headToCursor.length);\n\n activeElement && activeElement.focus();\n return el;\n};\n\nfunction createInputEvent() {\n if (typeof Event !== \"undefined\") {\n return new Event(\"input\", { bubbles: true, cancelable: true });\n } else {\n var event = document.createEvent(\"Event\");\n event.initEvent(\"input\", true, true);\n return event;\n }\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/undate/lib/update.js\n// module id = 13\n// module chunks = 0","/* jshint browser: true */\n\n(function () {\n\n// The properties that we copy into a mirrored div.\n// Note that some browsers, such as Firefox,\n// do not concatenate properties, i.e. padding-top, bottom etc. -> padding,\n// so we have to do every single property specifically.\nvar properties = [\n 'direction', // RTL support\n 'boxSizing',\n 'width', // on Chrome and IE, exclude the scrollbar, so the mirror div wraps exactly as the textarea does\n 'height',\n 'overflowX',\n 'overflowY', // copy the scrollbar for IE\n\n 'borderTopWidth',\n 'borderRightWidth',\n 'borderBottomWidth',\n 'borderLeftWidth',\n 'borderStyle',\n\n 'paddingTop',\n 'paddingRight',\n 'paddingBottom',\n 'paddingLeft',\n\n // https://developer.mozilla.org/en-US/docs/Web/CSS/font\n 'fontStyle',\n 'fontVariant',\n 'fontWeight',\n 'fontStretch',\n 'fontSize',\n 'fontSizeAdjust',\n 'lineHeight',\n 'fontFamily',\n\n 'textAlign',\n 'textTransform',\n 'textIndent',\n 'textDecoration', // might not make a difference, but better be safe\n\n 'letterSpacing',\n 'wordSpacing',\n\n 'tabSize',\n 'MozTabSize'\n\n];\n\nvar isBrowser = (typeof window !== 'undefined');\nvar isFirefox = (isBrowser && window.mozInnerScreenX != null);\n\nfunction getCaretCoordinates(element, position, options) {\n if(!isBrowser) {\n throw new Error('textarea-caret-position#getCaretCoordinates should only be called in a browser');\n }\n\n var debug = options && options.debug || false;\n if (debug) {\n var el = document.querySelector('#input-textarea-caret-position-mirror-div');\n if ( el ) { el.parentNode.removeChild(el); }\n }\n\n // mirrored div\n var div = document.createElement('div');\n div.id = 'input-textarea-caret-position-mirror-div';\n document.body.appendChild(div);\n\n var style = div.style;\n var computed = window.getComputedStyle? getComputedStyle(element) : element.currentStyle; // currentStyle for IE < 9\n\n // default textarea styles\n style.whiteSpace = 'pre-wrap';\n if (element.nodeName !== 'INPUT')\n style.wordWrap = 'break-word'; // only for textarea-s\n\n // position off-screen\n style.position = 'absolute'; // required to return coordinates properly\n if (!debug)\n style.visibility = 'hidden'; // not 'display: none' because we want rendering\n\n // transfer the element's properties to the div\n properties.forEach(function (prop) {\n style[prop] = computed[prop];\n });\n\n if (isFirefox) {\n // Firefox lies about the overflow property for textareas: https://bugzilla.mozilla.org/show_bug.cgi?id=984275\n if (element.scrollHeight > parseInt(computed.height))\n style.overflowY = 'scroll';\n } else {\n style.overflow = 'hidden'; // for Chrome to not render a scrollbar; IE keeps overflowY = 'scroll'\n }\n\n div.textContent = element.value.substring(0, position);\n // the second special handling for input type=\"text\" vs textarea: spaces need to be replaced with non-breaking spaces - http://stackoverflow.com/a/13402035/1269037\n if (element.nodeName === 'INPUT')\n div.textContent = div.textContent.replace(/\\s/g, '\\u00a0');\n\n var span = document.createElement('span');\n // Wrapping must be replicated *exactly*, including when a long word gets\n // onto the next line, with whitespace at the end of the line before (#7).\n // The *only* reliable way to do that is to copy the *entire* rest of the\n // textarea's content into the <span> created at the caret position.\n // for inputs, just '.' would be enough, but why bother?\n span.textContent = element.value.substring(position) || '.'; // || because a completely empty faux span doesn't render at all\n div.appendChild(span);\n\n var coordinates = {\n top: span.offsetTop + parseInt(computed['borderTopWidth']),\n left: span.offsetLeft + parseInt(computed['borderLeftWidth'])\n };\n\n if (debug) {\n span.style.backgroundColor = '#aaa';\n } else {\n document.body.removeChild(div);\n }\n\n return coordinates;\n}\n\nif (typeof module != 'undefined' && typeof module.exports != 'undefined') {\n module.exports = getCaretCoordinates;\n} else if(isBrowser){\n window.getCaretCoordinates = getCaretCoordinates;\n}\n\n}());\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/textarea-caret/index.js\n// module id = 14\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file
diff --git a/view/es-es/hmessages.po b/view/es-es/hmessages.po
index 7089c2eab..ec03b4c2c 100644
--- a/view/es-es/hmessages.po
+++ b/view/es-es/hmessages.po
@@ -14,8 +14,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Redmatrix\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-04-18 08:37+0200\n"
-"PO-Revision-Date: 2018-04-20 09:32+0000\n"
+"POT-Creation-Date: 2018-04-23 11:34+0200\n"
+"PO-Revision-Date: 2018-04-24 09:02+0000\n"
"Last-Translator: Manuel Jiménez Friaza <mjfriaza@disroot.org>\n"
"Language-Team: Spanish (Spain) (http://www.transifex.com/Friendica/red-matrix/language/es_ES/)\n"
"MIME-Version: 1.0\n"
@@ -101,8 +101,8 @@ msgid "Social Networking"
msgstr "Redes sociales"
#: ../../Zotlabs/Access/PermissionRoles.php:284
-msgid "Social - Party"
-msgstr "Social - Extra público"
+msgid "Social - Federation"
+msgstr "Social - Federación"
#: ../../Zotlabs/Access/PermissionRoles.php:285
msgid "Social - Mostly Public"
@@ -461,15 +461,16 @@ msgstr "3. Pulse [conectar]"
#: ../../addon/likebanner/likebanner.php:57
#: ../../addon/redphotos/redphotos.php:136 ../../addon/irc/irc.php:53
#: ../../addon/ljpost/ljpost.php:86 ../../addon/startpage/startpage.php:113
-#: ../../addon/diaspora/diaspora.php:823
+#: ../../addon/diaspora/diaspora.php:825
#: ../../addon/rainbowtag/rainbowtag.php:85 ../../addon/hzfiles/hzfiles.php:84
#: ../../addon/visage/visage.php:170 ../../addon/nsabait/nsabait.php:161
#: ../../addon/mailtest/mailtest.php:100
#: ../../addon/openstreetmap/openstreetmap.php:168
-#: ../../addon/rtof/rtof.php:101 ../../addon/jappixmini/jappixmini.php:371
+#: ../../addon/fuzzloc/fuzzloc.php:191 ../../addon/rtof/rtof.php:101
+#: ../../addon/jappixmini/jappixmini.php:371
#: ../../addon/superblock/superblock.php:120 ../../addon/nofed/nofed.php:80
#: ../../addon/redred/redred.php:119 ../../addon/logrot/logrot.php:35
-#: ../../addon/frphotos/frphotos.php:97 ../../addon/pubcrawl/pubcrawl.php:1069
+#: ../../addon/frphotos/frphotos.php:97 ../../addon/pubcrawl/pubcrawl.php:1072
#: ../../addon/chords/Mod_Chords.php:60 ../../addon/libertree/libertree.php:85
#: ../../addon/flattrwidget/flattrwidget.php:124
#: ../../addon/statusnet/statusnet.php:322
@@ -569,7 +570,7 @@ msgstr "Resumen: "
#: ../../Zotlabs/Module/Photos.php:817 ../../Zotlabs/Module/Photos.php:1273
#: ../../Zotlabs/Lib/Apps.php:754 ../../Zotlabs/Lib/Apps.php:833
#: ../../Zotlabs/Storage/Browser.php:164 ../../Zotlabs/Widget/Portfolio.php:95
-#: ../../Zotlabs/Widget/Album.php:84 ../../addon/pubcrawl/as.php:878
+#: ../../Zotlabs/Widget/Album.php:84 ../../addon/pubcrawl/as.php:891
#: ../../include/conversation.php:1160
msgid "Unknown"
msgstr "Desconocido"
@@ -731,7 +732,7 @@ msgstr "Teléfono"
#: ../../Zotlabs/Module/Connedit.php:910 ../../Zotlabs/Module/Profiles.php:787
#: ../../addon/openid/MysqlProvider.php:56
#: ../../addon/openid/MysqlProvider.php:57 ../../addon/rtof/rtof.php:93
-#: ../../addon/redred/redred.php:107 ../../include/network.php:1769
+#: ../../addon/redred/redred.php:107 ../../include/network.php:1770
msgid "Email"
msgstr "Correo electrónico"
@@ -1093,8 +1094,8 @@ msgstr "Usar la autenticación mágica si está disponible"
#: ../../addon/dwpost/dwpost.php:85 ../../addon/ljpost/ljpost.php:70
#: ../../addon/ljpost/ljpost.php:82 ../../addon/rainbowtag/rainbowtag.php:81
#: ../../addon/visage/visage.php:166 ../../addon/nsabait/nsabait.php:157
-#: ../../addon/rtof/rtof.php:81 ../../addon/rtof/rtof.php:85
-#: ../../addon/jappixmini/jappixmini.php:309
+#: ../../addon/fuzzloc/fuzzloc.php:178 ../../addon/rtof/rtof.php:81
+#: ../../addon/rtof/rtof.php:85 ../../addon/jappixmini/jappixmini.php:309
#: ../../addon/jappixmini/jappixmini.php:313
#: ../../addon/jappixmini/jappixmini.php:343
#: ../../addon/jappixmini/jappixmini.php:351
@@ -1145,8 +1146,8 @@ msgstr "No"
#: ../../addon/dwpost/dwpost.php:85 ../../addon/ljpost/ljpost.php:70
#: ../../addon/ljpost/ljpost.php:82 ../../addon/rainbowtag/rainbowtag.php:81
#: ../../addon/visage/visage.php:166 ../../addon/nsabait/nsabait.php:157
-#: ../../addon/rtof/rtof.php:81 ../../addon/rtof/rtof.php:85
-#: ../../addon/jappixmini/jappixmini.php:309
+#: ../../addon/fuzzloc/fuzzloc.php:178 ../../addon/rtof/rtof.php:81
+#: ../../addon/rtof/rtof.php:85 ../../addon/jappixmini/jappixmini.php:309
#: ../../addon/jappixmini/jappixmini.php:313
#: ../../addon/jappixmini/jappixmini.php:343
#: ../../addon/jappixmini/jappixmini.php:351
@@ -1463,13 +1464,13 @@ msgstr "Servidor no encontrado"
#: ../../Zotlabs/Module/Subthread.php:111 ../../Zotlabs/Module/Tagger.php:69
#: ../../Zotlabs/Module/Like.php:384
#: ../../addon/redphotos/redphotohelper.php:71
-#: ../../addon/diaspora/Receiver.php:1500 ../../addon/pubcrawl/as.php:1388
+#: ../../addon/diaspora/Receiver.php:1500 ../../addon/pubcrawl/as.php:1405
#: ../../include/conversation.php:116 ../../include/text.php:2005
msgid "photo"
msgstr "foto"
#: ../../Zotlabs/Module/Subthread.php:111 ../../Zotlabs/Module/Like.php:384
-#: ../../addon/diaspora/Receiver.php:1500 ../../addon/pubcrawl/as.php:1388
+#: ../../addon/diaspora/Receiver.php:1500 ../../addon/pubcrawl/as.php:1405
#: ../../include/conversation.php:144 ../../include/text.php:2011
msgid "status"
msgstr "el mensaje de estado"
@@ -1577,6 +1578,7 @@ msgid ""
msgstr "Su alias se usará para crear una dirección de canal fácil de recordar, p. ej.: alias%s"
#: ../../Zotlabs/Module/New_channel.php:149
+#: ../../Zotlabs/Module/Settings/Channel.php:539
#: ../../Zotlabs/Module/Register.php:257
msgid "Channel role and privacy"
msgstr "Clase de canal y privacidad"
@@ -1597,10 +1599,18 @@ msgstr "Crear un canal"
#: ../../Zotlabs/Module/New_channel.php:153
msgid ""
-"A channel is your identity on this network. It can represent a person, a "
-"blog, or a forum to name a few. Channels can make connections with other "
-"channels to share information with highly detailed permissions."
-msgstr "Un canal es su identidad en esta red. Puede representar a una persona, un blog o un foro, por nombrar unos pocos ejemplos. Los canales se pueden conectar con otros canales para compartir información con una gama de permisos extremadamente detallada."
+"A channel is a unique network identity. It can represent a person (social "
+"network profile), a forum (group), a business or celebrity page, a newsfeed,"
+" and many other things. Channels can make connections with other channels to"
+" share information with each other."
+msgstr "Un canal es una identidad única en la red. Puede representar a una persona (un perfil de una red social), un foro o grupo, un negocio o una página de una celebridad, un \"feed\" de noticias, y muchas otras cosas. Los canales pueden conectarse con otros canales para compartir información unos con otros."
+
+#: ../../Zotlabs/Module/New_channel.php:153
+msgid ""
+"The type of channel you create affects the basic privacy settings, the "
+"permissions that are granted to connections/friends, and also the channel's "
+"visibility across the network."
+msgstr "El tipo de canal que cree afecta a la configuración básica de privacidad, a los permisos que se conceden a las conexiones/amigos y también a la visibilidad del canal en la red."
#: ../../Zotlabs/Module/New_channel.php:154
msgid ""
@@ -3365,11 +3375,11 @@ msgctxt "acl"
msgid "Profile"
msgstr "Perfil"
-#: ../../Zotlabs/Module/Moderate.php:62
+#: ../../Zotlabs/Module/Moderate.php:65
msgid "Comment approved"
msgstr "El comentario ha sido aprobado"
-#: ../../Zotlabs/Module/Moderate.php:66
+#: ../../Zotlabs/Module/Moderate.php:69
msgid "Comment deleted"
msgstr "Se ha eliminado el comentario"
@@ -3633,10 +3643,6 @@ msgstr "Usar los ajustes de mi audiencia predeterminada para el tipo de publicac
msgid "Profile to assign new connections"
msgstr "Perfil para asignar a las nuevas conexiones"
-#: ../../Zotlabs/Module/Settings/Channel.php:539
-msgid "Channel permissions category:"
-msgstr "Categoría de los permisos del canal:"
-
#: ../../Zotlabs/Module/Settings/Channel.php:540
msgid "Default Permissions Group"
msgstr "Grupo de permisos predeterminados"
@@ -4910,7 +4916,7 @@ msgstr "Ver todo"
#: ../../Zotlabs/Module/Photos.php:1160 ../../Zotlabs/Lib/ThreadItem.php:205
#: ../../include/conversation.php:1981 ../../include/channel.php:1539
-#: ../../include/taxonomy.php:660
+#: ../../include/taxonomy.php:661
msgctxt "noun"
msgid "Like"
msgid_plural "Likes"
@@ -4953,7 +4959,7 @@ msgid "Close"
msgstr "Cerrar"
#: ../../Zotlabs/Module/Photos.php:1365 ../../Zotlabs/Module/Photos.php:1378
-#: ../../Zotlabs/Module/Photos.php:1379 ../../include/photos.php:663
+#: ../../Zotlabs/Module/Photos.php:1379 ../../include/photos.php:667
msgid "Recent Photos"
msgstr "Fotos recientes"
@@ -5266,7 +5272,7 @@ msgstr "Imagen actualizada, pero el recorte de la imagen ha fallado. "
#: ../../Zotlabs/Module/Profile_photo.php:120
#: ../../Zotlabs/Module/Profile_photo.php:248
-#: ../../include/photo/photo_driver.php:740
+#: ../../include/photo/photo_driver.php:741
msgid "Profile Photos"
msgstr "Fotos del perfil"
@@ -6839,12 +6845,12 @@ msgid "Previous action reversed."
msgstr "Acción anterior revocada."
#: ../../Zotlabs/Module/Like.php:438 ../../addon/diaspora/Receiver.php:1529
-#: ../../addon/pubcrawl/as.php:1423 ../../include/conversation.php:160
+#: ../../addon/pubcrawl/as.php:1440 ../../include/conversation.php:160
#, php-format
msgid "%1$s likes %2$s's %3$s"
msgstr "A %1$s le gusta %3$s de %2$s"
-#: ../../Zotlabs/Module/Like.php:440 ../../addon/pubcrawl/as.php:1425
+#: ../../Zotlabs/Module/Like.php:440 ../../addon/pubcrawl/as.php:1442
#: ../../include/conversation.php:163
#, php-format
msgid "%1$s doesn't like %2$s's %3$s"
@@ -8351,11 +8357,11 @@ msgstr "Firma de mensaje incorrecta"
msgid "Add Tag"
msgstr "Añadir etiqueta"
-#: ../../Zotlabs/Lib/ThreadItem.php:281 ../../include/taxonomy.php:574
+#: ../../Zotlabs/Lib/ThreadItem.php:281 ../../include/taxonomy.php:575
msgid "like"
msgstr "me gusta"
-#: ../../Zotlabs/Lib/ThreadItem.php:282 ../../include/taxonomy.php:575
+#: ../../Zotlabs/Lib/ThreadItem.php:282 ../../include/taxonomy.php:576
msgid "dislike"
msgstr "no me gusta"
@@ -8657,9 +8663,9 @@ msgstr "Seleccionar una agenda para importarla"
#: ../../Zotlabs/Widget/Appcategories.php:40
#: ../../include/contact_widgets.php:97 ../../include/contact_widgets.php:141
-#: ../../include/contact_widgets.php:186 ../../include/taxonomy.php:408
-#: ../../include/taxonomy.php:490 ../../include/taxonomy.php:510
-#: ../../include/taxonomy.php:531
+#: ../../include/contact_widgets.php:186 ../../include/taxonomy.php:409
+#: ../../include/taxonomy.php:491 ../../include/taxonomy.php:511
+#: ../../include/taxonomy.php:532
msgid "Categories"
msgstr "Temas"
@@ -8847,8 +8853,8 @@ msgstr "Carpetas guardadas"
msgid "Click to show more"
msgstr "Hacer clic para ver más"
-#: ../../Zotlabs/Widget/Tagcloud.php:22 ../../include/taxonomy.php:319
-#: ../../include/taxonomy.php:448 ../../include/taxonomy.php:469
+#: ../../Zotlabs/Widget/Tagcloud.php:22 ../../include/taxonomy.php:320
+#: ../../include/taxonomy.php:449 ../../include/taxonomy.php:470
msgid "Tags"
msgstr "Etiquetas"
@@ -10166,39 +10172,39 @@ msgstr "una declaración de amor eterno"
msgid "declared undying love for"
msgstr "ha declarado amor eterno a"
-#: ../../addon/diaspora/diaspora.php:779
+#: ../../addon/diaspora/diaspora.php:781
msgid "Diaspora Protocol Settings updated."
msgstr "Los ajustes del protocolo de Diaspora se han actualizado."
-#: ../../addon/diaspora/diaspora.php:798
+#: ../../addon/diaspora/diaspora.php:800
msgid ""
"The Diaspora protocol does not support location independence. Connections "
"you make within that network may be unreachable from alternate channel "
"locations."
msgstr "El protocolo de Diaspora no admite la independencia de la ubicación. Las conexiones que realice dentro de esa red pueden ser inaccesibles desde ubicaciones de canales alternativos."
-#: ../../addon/diaspora/diaspora.php:801
+#: ../../addon/diaspora/diaspora.php:803
msgid "Enable the Diaspora protocol for this channel"
msgstr "Activar el protocolo de Diaspora para este canal"
-#: ../../addon/diaspora/diaspora.php:805
+#: ../../addon/diaspora/diaspora.php:807
msgid "Allow any Diaspora member to comment on your public posts"
msgstr "Permitir a cualquier miembro de Diaspora comentar sus entradas públicas"
-#: ../../addon/diaspora/diaspora.php:809
+#: ../../addon/diaspora/diaspora.php:811
msgid "Prevent your hashtags from being redirected to other sites"
msgstr "Impedir que sus \"hashtags\" sean redirigidos a otros sitios "
-#: ../../addon/diaspora/diaspora.php:813
+#: ../../addon/diaspora/diaspora.php:815
msgid ""
"Sign and forward posts and comments with no existing Diaspora signature"
msgstr "Firmar y enviar entradas y comentarios sin firma de Diaspora"
-#: ../../addon/diaspora/diaspora.php:818
+#: ../../addon/diaspora/diaspora.php:820
msgid "Followed hashtags (comma separated, do not include the #)"
msgstr "\"Hashtags\" seguidos (separados por comas, sin incluir #)"
-#: ../../addon/diaspora/diaspora.php:823
+#: ../../addon/diaspora/diaspora.php:825
msgid "Diaspora Protocol Settings"
msgstr "Ajustes del protocolo de Diaspora"
@@ -10441,6 +10447,32 @@ msgstr "Incluir un marcador en el mapa."
msgid "text to include in all outgoing posts from this site"
msgstr "texto a incluir en todos los mensajes salientes de este sitio"
+#: ../../addon/fuzzloc/fuzzloc.php:148
+msgid "Fuzzloc Settings updated."
+msgstr "Los ajustes de Fuzzloc se han actualizado."
+
+#: ../../addon/fuzzloc/fuzzloc.php:175
+msgid ""
+"Fuzzloc allows you to blur your precise location if your channel uses "
+"browser location mapping."
+msgstr "Fuzzloc le permite desdibujar su ubicación precisa si su canal utiliza la asignación de ubicación del navegador."
+
+#: ../../addon/fuzzloc/fuzzloc.php:178
+msgid "Enable Fuzzloc Plugin"
+msgstr "Habilitar el plugin Fuzzloc"
+
+#: ../../addon/fuzzloc/fuzzloc.php:182
+msgid "Minimum offset in meters"
+msgstr "Offset mínimo en metros"
+
+#: ../../addon/fuzzloc/fuzzloc.php:186
+msgid "Maximum offset in meters"
+msgstr "Offset máximo en metros"
+
+#: ../../addon/fuzzloc/fuzzloc.php:191
+msgid "Fuzzloc Settings"
+msgstr "Ajustes de Fuzzloc"
+
#: ../../addon/rtof/rtof.php:45
msgid "Post to Friendica"
msgstr "Publicar en Friendica"
@@ -10643,35 +10675,35 @@ msgstr "Nombre de inicio de sesión en Friendica"
msgid "Friendica Login Password"
msgstr "Contraseña de inicio de sesión en Friendica"
-#: ../../addon/pubcrawl/as.php:1129 ../../addon/pubcrawl/as.php:1256
-#: ../../addon/pubcrawl/as.php:1432 ../../include/network.php:1768
+#: ../../addon/pubcrawl/as.php:1146 ../../addon/pubcrawl/as.php:1273
+#: ../../addon/pubcrawl/as.php:1449 ../../include/network.php:1769
msgid "ActivityPub"
msgstr "ActivityPub"
-#: ../../addon/pubcrawl/pubcrawl.php:1050
+#: ../../addon/pubcrawl/pubcrawl.php:1053
msgid "ActivityPub Protocol Settings updated."
msgstr "Se han actualizado los ajustes del protocolo ActivityPub."
-#: ../../addon/pubcrawl/pubcrawl.php:1059
+#: ../../addon/pubcrawl/pubcrawl.php:1062
msgid ""
"The ActivityPub protocol does not support location independence. Connections"
" you make within that network may be unreachable from alternate channel "
"locations."
msgstr "El protocolo ActivityPub no soporta la independencia de ubicación. Las conexiones que realice dentro de esa red pueden no ser accesibles desde ubicaciones de canales alternativos."
-#: ../../addon/pubcrawl/pubcrawl.php:1062
+#: ../../addon/pubcrawl/pubcrawl.php:1065
msgid "Enable the ActivityPub protocol for this channel"
msgstr "Activar el protocolo ActivityPub para este canal"
-#: ../../addon/pubcrawl/pubcrawl.php:1065
+#: ../../addon/pubcrawl/pubcrawl.php:1068
msgid "Send multi-media HTML articles"
msgstr "Enviar artículos multimedia en HTML"
-#: ../../addon/pubcrawl/pubcrawl.php:1065
+#: ../../addon/pubcrawl/pubcrawl.php:1068
msgid "Not supported by some microblog services such as Mastodon"
msgstr "No soportado por algunos servicios de microblog como Mastodon"
-#: ../../addon/pubcrawl/pubcrawl.php:1069
+#: ../../addon/pubcrawl/pubcrawl.php:1072
msgid "ActivityPub Protocol Settings"
msgstr "Ajustes del protocolo ActivityPub"
@@ -12232,7 +12264,7 @@ msgid "Profile Details"
msgstr "Detalles del perfil"
#: ../../include/conversation.php:1837 ../../include/nav.php:404
-#: ../../include/photos.php:662
+#: ../../include/photos.php:666
msgid "Photo Albums"
msgstr "Álbumes de fotos"
@@ -13414,43 +13446,43 @@ msgstr "Fax de trabajo"
msgid "view full size"
msgstr "Ver en el tamaño original"
-#: ../../include/network.php:1763 ../../include/network.php:1764
+#: ../../include/network.php:1764 ../../include/network.php:1765
msgid "Friendica"
msgstr "Friendica"
-#: ../../include/network.php:1765
+#: ../../include/network.php:1766
msgid "OStatus"
msgstr "OStatus"
-#: ../../include/network.php:1766
+#: ../../include/network.php:1767
msgid "GNU-Social"
msgstr "GNU Social"
-#: ../../include/network.php:1767
+#: ../../include/network.php:1768
msgid "RSS/Atom"
msgstr "RSS/Atom"
-#: ../../include/network.php:1770
+#: ../../include/network.php:1771
msgid "Diaspora"
msgstr "Diaspora"
-#: ../../include/network.php:1771
+#: ../../include/network.php:1772
msgid "Facebook"
msgstr "Facebook"
-#: ../../include/network.php:1772
+#: ../../include/network.php:1773
msgid "Zot"
msgstr "Zot"
-#: ../../include/network.php:1773
+#: ../../include/network.php:1774
msgid "LinkedIn"
msgstr "LinkedIn"
-#: ../../include/network.php:1774
+#: ../../include/network.php:1775
msgid "XMPP/IM"
msgstr "XMPP/IM"
-#: ../../include/network.php:1775
+#: ../../include/network.php:1776
msgid "MySpace"
msgstr "MySpace"
@@ -13922,35 +13954,35 @@ msgstr "Nube de etiquetas"
msgid "Provide a personal tag cloud on your channel page"
msgstr "Proveer nube de etiquetas personal en su página de canal"
-#: ../../include/taxonomy.php:319
+#: ../../include/taxonomy.php:320
msgid "Trending"
msgstr "Populares"
-#: ../../include/taxonomy.php:551
+#: ../../include/taxonomy.php:552
msgid "Keywords"
msgstr "Palabras clave"
-#: ../../include/taxonomy.php:572
+#: ../../include/taxonomy.php:573
msgid "have"
msgstr "tener"
-#: ../../include/taxonomy.php:572
+#: ../../include/taxonomy.php:573
msgid "has"
msgstr "tiene"
-#: ../../include/taxonomy.php:573
+#: ../../include/taxonomy.php:574
msgid "want"
msgstr "quiero"
-#: ../../include/taxonomy.php:573
+#: ../../include/taxonomy.php:574
msgid "wants"
msgstr "quiere"
-#: ../../include/taxonomy.php:574
+#: ../../include/taxonomy.php:575
msgid "likes"
msgstr "gusta de"
-#: ../../include/taxonomy.php:575
+#: ../../include/taxonomy.php:576
msgid "dislikes"
msgstr "no gusta de"
@@ -14188,21 +14220,21 @@ msgstr "La imagen excede el límite de %lu bytes del sitio"
msgid "Image file is empty."
msgstr "El fichero de imagen está vacío. "
-#: ../../include/photos.php:322
+#: ../../include/photos.php:326
msgid "Photo storage failed."
msgstr "La foto no ha podido ser guardada."
-#: ../../include/photos.php:371
+#: ../../include/photos.php:375
msgid "a new photo"
msgstr "una nueva foto"
-#: ../../include/photos.php:375
+#: ../../include/photos.php:379
#, php-format
msgctxt "photo_upload"
msgid "%1$s posted %2$s to %3$s"
msgstr "%1$s ha publicado %2$s en %3$s"
-#: ../../include/photos.php:667
+#: ../../include/photos.php:671
msgid "Upload New Photos"
msgstr "Subir nuevas fotos"
@@ -14219,7 +14251,7 @@ msgstr "No ha sido posible de verificar la firma del canal"
msgid "Unable to verify site signature for %s"
msgstr "No ha sido posible de verificar la firma del sitio para %s"
-#: ../../include/zot.php:4217
+#: ../../include/zot.php:4219
msgid "invalid target signature"
msgstr "La firma recibida no es válida"
diff --git a/view/js/autocomplete.js b/view/js/autocomplete.js
index 76c3fb69e..60552588e 100644
--- a/view/js/autocomplete.js
+++ b/view/js/autocomplete.js
@@ -8,20 +8,20 @@ function contact_search(term, callback, backend_url, type, extra_channels, spine
$(spinelement).show();
}
// Check if there is a cached result that contains the same information we would get with a full server-side search
- var bt = backend_url+type;
- if(!(bt in contact_search.cache)) contact_search.cache[bt] = {};
+// var bt = backend_url+type;
+// if(!(bt in contact_search.cache)) contact_search.cache[bt] = {};
- var lterm = term.toLowerCase(); // Ignore case
- for(var t in contact_search.cache[bt]) {
- if(lterm.indexOf(t) >= 0) { // A more broad search has been performed already, so use those results
- $(spinelement).hide();
+// var lterm = term.toLowerCase(); // Ignore case
+// for(var t in contact_search.cache[bt]) {
+// if(lterm.indexOf(t) >= 0) { // A more broad search has been performed already, so use those results
+// $(spinelement).hide();
// Filter old results locally
- var matching = contact_search.cache[bt][t].filter(function (x) { return (x.name.toLowerCase().indexOf(lterm) >= 0 || (typeof x.nick !== 'undefined' && x.nick.toLowerCase().indexOf(lterm) >= 0)); }); // Need to check that nick exists because groups don't have one
- matching.unshift({taggable:false, text: term, replace: term});
- setTimeout(function() { callback(matching); } , 1); // Use "pseudo-thread" to avoid some problems
- return;
- }
- }
+// var matching = contact_search.cache[bt][t].filter(function (x) { return (x.name.toLowerCase().indexOf(lterm) >= 0 || (typeof x.nick !== 'undefined' && x.nick.toLowerCase().indexOf(lterm) >= 0)); }); // Need to check that nick exists because groups don't have one
+// matching.unshift({taggable:false, text: term, replace: term});
+// setTimeout(function() { callback(matching); } , 1); // Use "pseudo-thread" to avoid some problems
+// return;
+// }
+// }
var postdata = {
start:0,
@@ -41,9 +41,9 @@ function contact_search(term, callback, backend_url, type, extra_channels, spine
success: function(data){
// Cache results if we got them all (more information would not improve results)
// data.count represents the maximum number of items
- if(data.items.length -1 < data.count) {
- contact_search.cache[bt][lterm] = data.items;
- }
+// if(data.items.length -1 < data.count) {
+// contact_search.cache[bt][lterm] = data.items;
+// }
var items = data.items.slice(0);
items.unshift({taggable:false, text: term, replace: term});
callback(items);
@@ -180,12 +180,17 @@ function string2bb(element) {
*/
(function( $ ) {
$.fn.editor_autocomplete = function(backend_url, extra_channels) {
+
+ if(! this.length)
+ return;
+
if (typeof extra_channels === 'undefined') extra_channels = false;
// Autocomplete contacts
contacts = {
- match: /(^|\s)(@\!*)([^ \n]+)$/,
+ match: /(^|\s)(@\!*)([^ \n]{3,})$/,
index: 3,
+ cache: true,
search: function(term, callback) { contact_search(term, callback, backend_url, 'c', extra_channels, spinelement=false); },
replace: editor_replace,
template: contact_format
@@ -193,8 +198,9 @@ function string2bb(element) {
// Autocomplete forums
forums = {
- match: /(^|\s)(\!\!*)([^ \n]+)$/,
+ match: /(^|\s)(\!\!*)([^ \n]{3,})$/,
index: 3,
+ cache: true,
search: function(term, callback) { contact_search(term, callback, backend_url, 'f', extra_channels, spinelement=false); },
replace: editor_replace,
template: contact_format
@@ -203,8 +209,9 @@ function string2bb(element) {
// Autocomplete hashtags
tags = {
- match: /(^|\s)(\#)([^ \n]{2,})$/,
+ match: /(^|\s)(\#)([^ \n]{3,})$/,
index: 3,
+ cache: true,
search: function(term, callback) { $.getJSON('/hashtags/' + '$f=&t=' + term).done(function(data) { callback($.map(data, function(entry) { return entry.text.toLowerCase().indexOf(term.toLowerCase()) === 0 ? entry : null; })); }); },
replace: function(item) { return "$1$2" + item.text + ' '; },
context: function(text) { return text.toLowerCase(); },
@@ -215,13 +222,23 @@ function string2bb(element) {
smilies = {
match: /(^|\s)(:[a-z_:]{2,})$/,
index: 2,
+ cache: true,
search: function(term, callback) { $.getJSON('/smilies/json').done(function(data) { callback($.map(data, function(entry) { return entry.text.indexOf(term) === 0 ? entry : null; })); }); },
//template: function(item) { return item.icon + item.text; },
replace: function(item) { return "$1" + item.text + ' '; },
template: smiley_format
};
this.attr('autocomplete','off');
- this.textcomplete([contacts,forums,smilies,tags], {className:'acpopup', zIndex:1020});
+
+ var Textarea = Textcomplete.editors.Textarea;
+
+ $(this).each(function() {
+ var editor = new Textarea(this);
+ var textcomplete = new Textcomplete(editor);
+ textcomplete.register([contacts,forums,smilies,tags], {className:'acpopup', zIndex:1020});
+ });
+
+
};
})( jQuery );
@@ -230,10 +247,15 @@ function string2bb(element) {
*/
(function( $ ) {
$.fn.search_autocomplete = function(backend_url) {
+
+ if(! this.length)
+ return;
+
// Autocomplete contacts
contacts = {
match: /(^@)([^\n]{3,})$/,
index: 2,
+ cache: true,
search: function(term, callback) { contact_search(term, callback, backend_url, 'x', [], spinelement='#nav-search-spinner'); },
replace: basic_replace,
template: contact_format,
@@ -243,6 +265,7 @@ function string2bb(element) {
forums = {
match: /(^\!)([^\n]{3,})$/,
index: 2,
+ cache: true,
search: function(term, callback) { contact_search(term, callback, backend_url, 'f', [], spinelement='#nav-search-spinner'); },
replace: basic_replace,
template: contact_format
@@ -252,6 +275,7 @@ function string2bb(element) {
tags = {
match: /(^\#)([^ \n]{3,})$/,
index: 2,
+ cache: true,
search: function(term, callback) { $.getJSON('/hashtags/' + '$f=&t=' + term).done(function(data) { callback($.map(data, function(entry) { return entry.text.toLowerCase().indexOf(term.toLowerCase()) === 0 ? entry : null; })); }); },
replace: function(item) { return "$1" + item.text + ' '; },
context: function(text) { return text.toLowerCase(); },
@@ -259,65 +283,98 @@ function string2bb(element) {
};
this.attr('autocomplete', 'off');
- var a = this.textcomplete([contacts,forums,tags], {className:'acpopup', maxCount:100, zIndex: 1020, appendTo:'nav'});
- a.on('textComplete:select', function(e, value, strategy) { submit_form(this); });
+
+ var Textarea = Textcomplete.editors.Textarea;
+ $(this).each(function() {
+ var editor = new Textarea(this);
+ var textcomplete = new Textcomplete(editor);
+ textcomplete.register([contacts,forums,tags], {className:'acpopup', maxCount:100, zIndex: 1020, appendTo:'nav'});
+ });
+
+ this.on('select', function(e, value, strategy) { submit_form(this); });
};
})( jQuery );
(function( $ ) {
$.fn.contact_autocomplete = function(backend_url, typ, autosubmit, onselect) {
+
+ if(! this.length)
+ return;
+
if(typeof typ === 'undefined') typ = '';
if(typeof autosubmit === 'undefined') autosubmit = false;
// Autocomplete contacts
contacts = {
- match: /(^)([^\n]+)$/,
+ match: /(^)([^\n]{3,})$/,
index: 2,
+ cache: true,
search: function(term, callback) { contact_search(term, callback, backend_url, typ,[], spinelement=false); },
replace: basic_replace,
template: contact_format,
};
this.attr('autocomplete','off');
- var a = this.textcomplete([contacts], {className:'acpopup', zIndex:1020});
+
+ var Textarea = Textcomplete.editors.Textarea;
+ $(this).each(function() {
+ var editor = new Textarea(this);
+ var textcomplete = new Textcomplete(editor);
+ textcomplete.register([contacts], {className:'acpopup', zIndex:1020});
+ });
if(autosubmit)
- a.on('textComplete:select', function(e,value,strategy) { submit_form(this); });
+ this.on('select', function(e,value,strategy) { submit_form(this); });
if(typeof onselect !== 'undefined')
- a.on('textComplete:select', function(e, value, strategy) { onselect(value); });
+ this.on('select', function(e, value, strategy) { onselect(value); });
};
})( jQuery );
(function( $ ) {
$.fn.name_autocomplete = function(backend_url, typ, autosubmit, onselect) {
+
+ if(! this.length)
+ return;
+
if(typeof typ === 'undefined') typ = '';
if(typeof autosubmit === 'undefined') autosubmit = false;
// Autocomplete contacts
names = {
- match: /(^)([^\n]+)$/,
+ match: /(^)([^\n]{3,})$/,
index: 2,
+ cache: true,
search: function(term, callback) { contact_search(term, callback, backend_url, typ,[], spinelement=false); },
replace: trim_replace,
template: contact_format,
};
this.attr('autocomplete','off');
- var a = this.textcomplete([names], {className:'acpopup', zIndex:1020});
+
+ var Textarea = Textcomplete.editors.Textarea;
+
+ $(this).each(function() {
+ var editor = new Textarea(this);
+ var textcomplete = new Textcomplete(editor);
+ textcomplete.register([names], {className:'acpopup', zIndex:1020});
+ });
if(autosubmit)
- a.on('textComplete:select', function(e,value,strategy) { submit_form(this); });
+ this.on('select', function(e,value,strategy) { submit_form(this); });
if(typeof onselect !== 'undefined')
- a.on('textComplete:select', function(e, value, strategy) { onselect(value); });
+ this.on('select', function(e, value, strategy) { onselect(value); });
};
})( jQuery );
(function( $ ) {
$.fn.bbco_autocomplete = function(type) {
+ if(! this.length)
+ return;
+
if(type=='bbcode') {
var open_close_elements = ['bold', 'italic', 'underline', 'overline', 'strike', 'superscript', 'subscript', 'quote', 'code', 'open', 'spoiler', 'map', 'nobb', 'list', 'checklist', 'ul', 'ol', 'dl', 'li', 'table', 'tr', 'th', 'td', 'center', 'color', 'font', 'size', 'zrl', 'zmg', 'rpost', 'qr', 'observer', 'observer.language','embed', 'highlight', 'url', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
var open_elements = ['observer.baseurl', 'observer.address', 'observer.photo', 'observer.name', 'observer.webname', 'observer.url', '*', 'hr', ];
@@ -375,11 +432,18 @@ function string2bb(element) {
};
this.attr('autocomplete','off');
- var a = this.textcomplete([bbco], {className:'acpopup', zIndex:1020});
- a.on('textComplete:select', function(e, value, strategy) { value; });
+ var Textarea = Textcomplete.editors.Textarea;
+
+ $(this).each(function() {
+ var editor = new Textarea(this);
+ var textcomplete = new Textcomplete(editor);
+ textcomplete.register([bbco], {className:'acpopup', zIndex:1020});
+ });
+
+ this.on('select', function(e, value, strategy) { value; });
- a.keypress(function(e){
+ this.keypress(function(e){
if (e.keyCode == 13) {
var x = listNewLineAutocomplete(this.id);
if(x) {
diff --git a/view/php/theme_init.php b/view/php/theme_init.php
index f2c46da28..dd8dcb5ee 100644
--- a/view/php/theme_init.php
+++ b/view/php/theme_init.php
@@ -15,9 +15,8 @@ head_add_js('jquery.js');
head_add_js('/library/justifiedGallery/jquery.justifiedGallery.min.js');
head_add_js('/library/sprintf.js/dist/sprintf.min.js');
-//head_add_js('jquery.textinputs.js');
+head_add_js('/library/textcomplete/textcomplete.min.js');
head_add_js('autocomplete.js');
-head_add_js('/library/jquery-textcomplete/jquery.textcomplete.js');
head_add_js('/library/jquery.timeago.js');
head_add_js('/library/readmore.js/readmore.js');
diff --git a/view/theme/redbasic/schema/dark.css b/view/theme/redbasic/schema/dark.css
index d0154bfb1..dbee67c84 100644
--- a/view/theme/redbasic/schema/dark.css
+++ b/view/theme/redbasic/schema/dark.css
@@ -1,5 +1,4 @@
.generic-content-wrapper {
- border: 1px solid #111;
background-color: transparent;
}
@@ -148,7 +147,8 @@ option {
background-color:#111;
}
-.modal-content {
+.modal-content,
+#notifications_wrapper {
background-color: #111;
}
diff --git a/view/tpl/jot-header.tpl b/view/tpl/jot-header.tpl
index 991a4c8b1..df67e9b2d 100755
--- a/view/tpl/jot-header.tpl
+++ b/view/tpl/jot-header.tpl
@@ -568,11 +568,14 @@ $( document ).on( "click", ".wall-item-delete-link,.page-delete-link,.layout-del
function postSaveChanges(action, type) {
if({{$auto_save_draft}}) {
+ var doctype = $('#jot-webpage').val();
+ var postid = '-' + doctype + '-' + $('#jot-postid').val();
+
if(action != 'clean') {
- localStorage.setItem("post_title", $("#jot-title").val());
- localStorage.setItem("post_body", $("#profile-jot-text").val());
+ localStorage.setItem("post_title" + postid, $("#jot-title").val());
+ localStorage.setItem("post_body" + postid, $("#profile-jot-text").val());
if($("#jot-category").length)
- localStorage.setItem("post_category", $("#jot-category").val());
+ localStorage.setItem("post_category + postid", $("#jot-category").val());
}
if(action == 'start') {
@@ -589,9 +592,9 @@ $( document ).on( "click", ".wall-item-delete-link,.page-delete-link,.layout-del
if(action == 'clean') {
clearTimeout(postSaveTimer);
postSaveTimer = null;
- localStorage.removeItem("post_title");
- localStorage.removeItem("post_body");
- localStorage.removeItem("post_category");
+ localStorage.removeItem("post_title" + postid);
+ localStorage.removeItem("post_body" + postid);
+ localStorage.removeItem("post_category" + postid);
}
}
@@ -602,9 +605,11 @@ $( document ).on( "click", ".wall-item-delete-link,.page-delete-link,.layout-del
var cleaned = false;
if({{$auto_save_draft}}) {
- var postTitle = localStorage.getItem("post_title");
- var postBody = localStorage.getItem("post_body");
- var postCategory = (($("#jot-category").length) ? localStorage.getItem("post_category") : '');
+ var doctype = $('#jot-webpage').val();
+ var postid = '-' + doctype + '-' + $('#jot-postid').val();
+ var postTitle = localStorage.getItem("post_title" + postid);
+ var postBody = localStorage.getItem("post_body" + postid);
+ var postCategory = (($("#jot-category").length) ? localStorage.getItem("post_category" + postid) : '');
var openEditor = false;
if(postTitle) {
diff --git a/view/tpl/jot.tpl b/view/tpl/jot.tpl
index bc9339d4c..9aa330c40 100755
--- a/view/tpl/jot.tpl
+++ b/view/tpl/jot.tpl
@@ -21,8 +21,8 @@
<input type="hidden" name="media_str" id="jot-media" value="" />
<input type="hidden" name="source" id="jot-source" value="{{$source}}" />
<input type="hidden" name="coord" id="jot-coord" value="" />
- <input type="hidden" name="post_id" value="{{$post_id}}" />
- <input type="hidden" name="webpage" value="{{$webpage}}" />
+ <input type="hidden" id="jot-postid" name="post_id" value="{{$post_id}}" />
+ <input type="hidden" id="jot-webpage" name="webpage" value="{{$webpage}}" />
<input type="hidden" name="preview" id="jot-preview" value="0" />
<input type="hidden" id="jot-consensus" name="consensus" value="{{if $consensus}}{{$consensus}}{{else}}0{{/if}}" />
<input type="hidden" id="jot-nocomment" name="nocomment" value="{{if $nocomment}}{{$nocomment}}{{else}}0{{/if}}" />