This commit is contained in:
James Cole 2020-10-03 15:08:24 +02:00
parent aadcb2cc5b
commit 5ed3d52e9a
No known key found for this signature in database
GPG Key ID: B5669F9493CDE38D
8 changed files with 636 additions and 155 deletions

View File

@ -191,6 +191,102 @@ span.info-box-text a:hover, span.info-box-number a:hover {
border: none; border: none;
} }
span.twitter-typeahead .tt-menu,
span.twitter-typeahead .tt-dropdown-menu {
cursor: pointer;
position: absolute;
top: 100%;
left: 0;
z-index: 1000;
display: none;
float: left;
min-width: 160px;
padding: 5px 0;
margin: 2px 0 0;
list-style: none;
font-size: 14px;
text-align: left;
background-color: #ffffff;
border: 1px solid #cccccc;
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 4px;
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
background-clip: padding-box;
}
span.twitter-typeahead .tt-suggestion {
display: block;
padding: 3px 20px;
clear: both;
font-weight: normal;
line-height: 1.42857143;
color: #333333;
white-space: nowrap;
}
span.twitter-typeahead .tt-suggestion.tt-cursor,
span.twitter-typeahead .tt-suggestion:hover,
span.twitter-typeahead .tt-suggestion:focus {
color: #ffffff;
text-decoration: none;
outline: 0;
background-color: #337ab7;
}
.input-group.input-group-lg span.twitter-typeahead .form-control {
height: 46px;
padding: 10px 16px;
font-size: 18px;
line-height: 1.3333333;
border-radius: 6px;
}
.input-group.input-group-sm span.twitter-typeahead .form-control {
height: 30px;
padding: 5px 10px;
font-size: 12px;
line-height: 1.5;
border-radius: 3px;
}
span.twitter-typeahead {
width: 100%;
}
.input-group span.twitter-typeahead {
display: block !important;
height: 34px;
}
.input-group span.twitter-typeahead .tt-menu,
.input-group span.twitter-typeahead .tt-dropdown-menu {
top: 32px !important;
}
.input-group span.twitter-typeahead:not(:first-child):not(:last-child) .form-control {
border-radius: 0;
}
.input-group span.twitter-typeahead:first-child .form-control {
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.input-group span.twitter-typeahead:last-child .form-control {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
.input-group.input-group-sm span.twitter-typeahead {
height: 30px;
}
.input-group.input-group-sm span.twitter-typeahead .tt-menu,
.input-group.input-group-sm span.twitter-typeahead .tt-dropdown-menu {
top: 30px !important;
}
.input-group.input-group-lg span.twitter-typeahead {
height: 46px;
}
.input-group.input-group-lg span.twitter-typeahead .tt-menu,
.input-group.input-group-lg span.twitter-typeahead .tt-dropdown-menu {
top: 46px !important;
}
/*
.twitter-typeahead { .twitter-typeahead {
width:100%; width:100%;
} }
@ -252,3 +348,4 @@ span.twitter-typeahead {
outline: 0; outline: 0;
background-color: #428bca; background-color: #428bca;
} }
*/

View File

@ -1,18 +1,19 @@
/*! /*!
* typeahead.js 0.11.1 * typeahead.js 1.3.1
* https://github.com/twitter/typeahead.js * https://github.com/corejavascript/typeahead.js
* Copyright 2013-2015 Twitter, Inc. and other contributors; Licensed MIT * Copyright 2013-2020 Twitter, Inc. and other contributors; Licensed MIT
*/ */
(function(root, factory) { (function(root, factory) {
if (typeof define === "function" && define.amd) { if (typeof define === "function" && define.amd) {
define("bloodhound", [ "jquery" ], function(a0) { define([ "jquery" ], function(a0) {
return root["Bloodhound"] = factory(a0); return root["Bloodhound"] = factory(a0);
}); });
} else if (typeof exports === "object") { } else if (typeof module === "object" && module.exports) {
module.exports = factory(require("jquery")); module.exports = factory(require("jquery"));
} else { } else {
root["Bloodhound"] = factory(jQuery); root["Bloodhound"] = factory(root["jQuery"]);
} }
})(this, function($) { })(this, function($) {
var _ = function() { var _ = function() {
@ -148,18 +149,27 @@
stringify: function(val) { stringify: function(val) {
return _.isString(val) ? val : JSON.stringify(val); return _.isString(val) ? val : JSON.stringify(val);
}, },
guid: function() {
function _p8(s) {
var p = (Math.random().toString(16) + "000000000").substr(2, 8);
return s ? "-" + p.substr(0, 4) + "-" + p.substr(4, 4) : p;
}
return "tt-" + _p8() + _p8(true) + _p8(true) + _p8();
},
noop: function() {} noop: function() {}
}; };
}(); }();
var VERSION = "0.11.1"; var VERSION = "1.3.1";
var tokenizers = function() { var tokenizers = function() {
"use strict"; "use strict";
return { return {
nonword: nonword, nonword: nonword,
whitespace: whitespace, whitespace: whitespace,
ngram: ngram,
obj: { obj: {
nonword: getObjTokenizer(nonword), nonword: getObjTokenizer(nonword),
whitespace: getObjTokenizer(whitespace) whitespace: getObjTokenizer(whitespace),
ngram: getObjTokenizer(ngram)
} }
}; };
function whitespace(str) { function whitespace(str) {
@ -170,6 +180,19 @@
str = _.toStr(str); str = _.toStr(str);
return str ? str.split(/\W+/) : []; return str ? str.split(/\W+/) : [];
} }
function ngram(str) {
str = _.toStr(str);
var tokens = [], word = "";
_.each(str.split(""), function(char) {
if (char.match(/\s+/)) {
word = "";
} else {
tokens.push(word + char);
word += char;
}
});
return tokens;
}
function getObjTokenizer(tokenizer) { function getObjTokenizer(tokenizer) {
return function setKey(keys) { return function setKey(keys) {
keys = _.isArray(keys) ? keys : [].slice.call(arguments, 0); keys = _.isArray(keys) ? keys : [].slice.call(arguments, 0);
@ -341,9 +364,10 @@
}(); }();
var Transport = function() { var Transport = function() {
"use strict"; "use strict";
var pendingRequestsCount = 0, pendingRequests = {}, maxPendingRequests = 6, sharedCache = new LruCache(10); var pendingRequestsCount = 0, pendingRequests = {}, sharedCache = new LruCache(10);
function Transport(o) { function Transport(o) {
o = o || {}; o = o || {};
this.maxPendingRequests = o.maxPendingRequests || 6;
this.cancelled = false; this.cancelled = false;
this.lastReq = null; this.lastReq = null;
this._send = o.transport; this._send = o.transport;
@ -351,7 +375,7 @@
this._cache = o.cache === false ? new LruCache(0) : sharedCache; this._cache = o.cache === false ? new LruCache(0) : sharedCache;
} }
Transport.setMaxPendingRequests = function setMaxPendingRequests(num) { Transport.setMaxPendingRequests = function setMaxPendingRequests(num) {
maxPendingRequests = num; this.maxPendingRequests = num;
}; };
Transport.resetCache = function resetCache() { Transport.resetCache = function resetCache() {
sharedCache.reset(); sharedCache.reset();
@ -369,7 +393,7 @@
} }
if (jqXhr = pendingRequests[fingerprint]) { if (jqXhr = pendingRequests[fingerprint]) {
jqXhr.done(done).fail(fail); jqXhr.done(done).fail(fail);
} else if (pendingRequestsCount < maxPendingRequests) { } else if (pendingRequestsCount < this.maxPendingRequests) {
pendingRequestsCount++; pendingRequestsCount++;
pendingRequests[fingerprint] = this._send(o).done(done).fail(fail).always(always); pendingRequests[fingerprint] = this._send(o).done(done).fail(fail).always(always);
} else { } else {
@ -423,6 +447,7 @@
this.identify = o.identify || _.stringify; this.identify = o.identify || _.stringify;
this.datumTokenizer = o.datumTokenizer; this.datumTokenizer = o.datumTokenizer;
this.queryTokenizer = o.queryTokenizer; this.queryTokenizer = o.queryTokenizer;
this.matchAnyQueryToken = o.matchAnyQueryToken;
this.reset(); this.reset();
} }
_.mixin(SearchIndex.prototype, { _.mixin(SearchIndex.prototype, {
@ -459,7 +484,7 @@
tokens = normalizeTokens(this.queryTokenizer(query)); tokens = normalizeTokens(this.queryTokenizer(query));
_.each(tokens, function(token) { _.each(tokens, function(token) {
var node, chars, ch, ids; var node, chars, ch, ids;
if (matches && matches.length === 0) { if (matches && matches.length === 0 && !that.matchAnyQueryToken) {
return false; return false;
} }
node = that.trie; node = that.trie;
@ -471,8 +496,10 @@
ids = node[IDS].slice(0); ids = node[IDS].slice(0);
matches = matches ? getIntersection(matches, ids) : ids; matches = matches ? getIntersection(matches, ids) : ids;
} else { } else {
matches = []; if (!that.matchAnyQueryToken) {
return false; matches = [];
return false;
}
} }
}); });
return matches ? _.map(unique(matches), function(id) { return matches ? _.map(unique(matches), function(id) {
@ -614,10 +641,12 @@
this.url = o.url; this.url = o.url;
this.prepare = o.prepare; this.prepare = o.prepare;
this.transform = o.transform; this.transform = o.transform;
this.indexResponse = o.indexResponse;
this.transport = new Transport({ this.transport = new Transport({
cache: o.cache, cache: o.cache,
limiter: o.limiter, limiter: o.limiter,
transport: o.transport transport: o.transport,
maxPendingRequests: o.maxPendingRequests
}); });
} }
_.mixin(Remote.prototype, { _.mixin(Remote.prototype, {
@ -655,7 +684,9 @@
identify: _.stringify, identify: _.stringify,
datumTokenizer: null, datumTokenizer: null,
queryTokenizer: null, queryTokenizer: null,
matchAnyQueryToken: false,
sufficient: 5, sufficient: 5,
indexRemote: false,
sorter: null, sorter: null,
local: [], local: [],
prefetch: null, prefetch: null,
@ -744,7 +775,7 @@
} else if (o.wildcard) { } else if (o.wildcard) {
prepare = prepareByWildcard; prepare = prepareByWildcard;
} else { } else {
prepare = idenityPrepare; prepare = identityPrepare;
} }
return prepare; return prepare;
function prepareByReplace(query, settings) { function prepareByReplace(query, settings) {
@ -755,7 +786,7 @@
settings.url = settings.url.replace(wildcard, encodeURIComponent(query)); settings.url = settings.url.replace(wildcard, encodeURIComponent(query));
return settings; return settings;
} }
function idenityPrepare(query, settings) { function identityPrepare(query, settings) {
return settings; return settings;
} }
} }
@ -806,6 +837,7 @@
this.sorter = o.sorter; this.sorter = o.sorter;
this.identify = o.identify; this.identify = o.identify;
this.sufficient = o.sufficient; this.sufficient = o.sufficient;
this.indexRemote = o.indexRemote;
this.local = o.local; this.local = o.local;
this.remote = o.remote ? new Remote(o.remote) : null; this.remote = o.remote ? new Remote(o.remote) : null;
this.prefetch = o.prefetch ? new Prefetch(o.prefetch) : null; this.prefetch = o.prefetch ? new Prefetch(o.prefetch) : null;
@ -875,6 +907,8 @@
}, },
search: function search(query, sync, async) { search: function search(query, sync, async) {
var that = this, local; var that = this, local;
sync = sync || _.noop;
async = async || _.noop;
local = this.sorter(this.index.search(query)); local = this.sorter(this.index.search(query));
sync(this.remote ? local.slice() : local); sync(this.remote ? local.slice() : local);
if (this.remote && local.length < this.sufficient) { if (this.remote && local.length < this.sufficient) {
@ -890,7 +924,8 @@
return that.identify(r) === that.identify(l); return that.identify(r) === that.identify(l);
}) && nonDuplicates.push(r); }) && nonDuplicates.push(r);
}); });
async && async(nonDuplicates); that.indexRemote && that.add(nonDuplicates);
async(nonDuplicates);
} }
}, },
all: function all() { all: function all() {

File diff suppressed because one or more lines are too long

View File

@ -1,18 +1,19 @@
/*! /*!
* typeahead.js 0.11.1 * typeahead.js 1.3.1
* https://github.com/twitter/typeahead.js * https://github.com/corejavascript/typeahead.js
* Copyright 2013-2015 Twitter, Inc. and other contributors; Licensed MIT * Copyright 2013-2020 Twitter, Inc. and other contributors; Licensed MIT
*/ */
(function(root, factory) { (function(root, factory) {
if (typeof define === "function" && define.amd) { if (typeof define === "function" && define.amd) {
define("bloodhound", [ "jquery" ], function(a0) { define([ "jquery" ], function(a0) {
return root["Bloodhound"] = factory(a0); return root["Bloodhound"] = factory(a0);
}); });
} else if (typeof exports === "object") { } else if (typeof module === "object" && module.exports) {
module.exports = factory(require("jquery")); module.exports = factory(require("jquery"));
} else { } else {
root["Bloodhound"] = factory(jQuery); root["Bloodhound"] = factory(root["jQuery"]);
} }
})(this, function($) { })(this, function($) {
var _ = function() { var _ = function() {
@ -148,18 +149,27 @@
stringify: function(val) { stringify: function(val) {
return _.isString(val) ? val : JSON.stringify(val); return _.isString(val) ? val : JSON.stringify(val);
}, },
guid: function() {
function _p8(s) {
var p = (Math.random().toString(16) + "000000000").substr(2, 8);
return s ? "-" + p.substr(0, 4) + "-" + p.substr(4, 4) : p;
}
return "tt-" + _p8() + _p8(true) + _p8(true) + _p8();
},
noop: function() {} noop: function() {}
}; };
}(); }();
var VERSION = "0.11.1"; var VERSION = "1.3.1";
var tokenizers = function() { var tokenizers = function() {
"use strict"; "use strict";
return { return {
nonword: nonword, nonword: nonword,
whitespace: whitespace, whitespace: whitespace,
ngram: ngram,
obj: { obj: {
nonword: getObjTokenizer(nonword), nonword: getObjTokenizer(nonword),
whitespace: getObjTokenizer(whitespace) whitespace: getObjTokenizer(whitespace),
ngram: getObjTokenizer(ngram)
} }
}; };
function whitespace(str) { function whitespace(str) {
@ -170,6 +180,19 @@
str = _.toStr(str); str = _.toStr(str);
return str ? str.split(/\W+/) : []; return str ? str.split(/\W+/) : [];
} }
function ngram(str) {
str = _.toStr(str);
var tokens = [], word = "";
_.each(str.split(""), function(char) {
if (char.match(/\s+/)) {
word = "";
} else {
tokens.push(word + char);
word += char;
}
});
return tokens;
}
function getObjTokenizer(tokenizer) { function getObjTokenizer(tokenizer) {
return function setKey(keys) { return function setKey(keys) {
keys = _.isArray(keys) ? keys : [].slice.call(arguments, 0); keys = _.isArray(keys) ? keys : [].slice.call(arguments, 0);
@ -341,9 +364,10 @@
}(); }();
var Transport = function() { var Transport = function() {
"use strict"; "use strict";
var pendingRequestsCount = 0, pendingRequests = {}, maxPendingRequests = 6, sharedCache = new LruCache(10); var pendingRequestsCount = 0, pendingRequests = {}, sharedCache = new LruCache(10);
function Transport(o) { function Transport(o) {
o = o || {}; o = o || {};
this.maxPendingRequests = o.maxPendingRequests || 6;
this.cancelled = false; this.cancelled = false;
this.lastReq = null; this.lastReq = null;
this._send = o.transport; this._send = o.transport;
@ -351,7 +375,7 @@
this._cache = o.cache === false ? new LruCache(0) : sharedCache; this._cache = o.cache === false ? new LruCache(0) : sharedCache;
} }
Transport.setMaxPendingRequests = function setMaxPendingRequests(num) { Transport.setMaxPendingRequests = function setMaxPendingRequests(num) {
maxPendingRequests = num; this.maxPendingRequests = num;
}; };
Transport.resetCache = function resetCache() { Transport.resetCache = function resetCache() {
sharedCache.reset(); sharedCache.reset();
@ -369,7 +393,7 @@
} }
if (jqXhr = pendingRequests[fingerprint]) { if (jqXhr = pendingRequests[fingerprint]) {
jqXhr.done(done).fail(fail); jqXhr.done(done).fail(fail);
} else if (pendingRequestsCount < maxPendingRequests) { } else if (pendingRequestsCount < this.maxPendingRequests) {
pendingRequestsCount++; pendingRequestsCount++;
pendingRequests[fingerprint] = this._send(o).done(done).fail(fail).always(always); pendingRequests[fingerprint] = this._send(o).done(done).fail(fail).always(always);
} else { } else {
@ -423,6 +447,7 @@
this.identify = o.identify || _.stringify; this.identify = o.identify || _.stringify;
this.datumTokenizer = o.datumTokenizer; this.datumTokenizer = o.datumTokenizer;
this.queryTokenizer = o.queryTokenizer; this.queryTokenizer = o.queryTokenizer;
this.matchAnyQueryToken = o.matchAnyQueryToken;
this.reset(); this.reset();
} }
_.mixin(SearchIndex.prototype, { _.mixin(SearchIndex.prototype, {
@ -459,7 +484,7 @@
tokens = normalizeTokens(this.queryTokenizer(query)); tokens = normalizeTokens(this.queryTokenizer(query));
_.each(tokens, function(token) { _.each(tokens, function(token) {
var node, chars, ch, ids; var node, chars, ch, ids;
if (matches && matches.length === 0) { if (matches && matches.length === 0 && !that.matchAnyQueryToken) {
return false; return false;
} }
node = that.trie; node = that.trie;
@ -471,8 +496,10 @@
ids = node[IDS].slice(0); ids = node[IDS].slice(0);
matches = matches ? getIntersection(matches, ids) : ids; matches = matches ? getIntersection(matches, ids) : ids;
} else { } else {
matches = []; if (!that.matchAnyQueryToken) {
return false; matches = [];
return false;
}
} }
}); });
return matches ? _.map(unique(matches), function(id) { return matches ? _.map(unique(matches), function(id) {
@ -614,10 +641,12 @@
this.url = o.url; this.url = o.url;
this.prepare = o.prepare; this.prepare = o.prepare;
this.transform = o.transform; this.transform = o.transform;
this.indexResponse = o.indexResponse;
this.transport = new Transport({ this.transport = new Transport({
cache: o.cache, cache: o.cache,
limiter: o.limiter, limiter: o.limiter,
transport: o.transport transport: o.transport,
maxPendingRequests: o.maxPendingRequests
}); });
} }
_.mixin(Remote.prototype, { _.mixin(Remote.prototype, {
@ -655,7 +684,9 @@
identify: _.stringify, identify: _.stringify,
datumTokenizer: null, datumTokenizer: null,
queryTokenizer: null, queryTokenizer: null,
matchAnyQueryToken: false,
sufficient: 5, sufficient: 5,
indexRemote: false,
sorter: null, sorter: null,
local: [], local: [],
prefetch: null, prefetch: null,
@ -744,7 +775,7 @@
} else if (o.wildcard) { } else if (o.wildcard) {
prepare = prepareByWildcard; prepare = prepareByWildcard;
} else { } else {
prepare = idenityPrepare; prepare = identityPrepare;
} }
return prepare; return prepare;
function prepareByReplace(query, settings) { function prepareByReplace(query, settings) {
@ -755,7 +786,7 @@
settings.url = settings.url.replace(wildcard, encodeURIComponent(query)); settings.url = settings.url.replace(wildcard, encodeURIComponent(query));
return settings; return settings;
} }
function idenityPrepare(query, settings) { function identityPrepare(query, settings) {
return settings; return settings;
} }
} }
@ -806,6 +837,7 @@
this.sorter = o.sorter; this.sorter = o.sorter;
this.identify = o.identify; this.identify = o.identify;
this.sufficient = o.sufficient; this.sufficient = o.sufficient;
this.indexRemote = o.indexRemote;
this.local = o.local; this.local = o.local;
this.remote = o.remote ? new Remote(o.remote) : null; this.remote = o.remote ? new Remote(o.remote) : null;
this.prefetch = o.prefetch ? new Prefetch(o.prefetch) : null; this.prefetch = o.prefetch ? new Prefetch(o.prefetch) : null;
@ -875,6 +907,8 @@
}, },
search: function search(query, sync, async) { search: function search(query, sync, async) {
var that = this, local; var that = this, local;
sync = sync || _.noop;
async = async || _.noop;
local = this.sorter(this.index.search(query)); local = this.sorter(this.index.search(query));
sync(this.remote ? local.slice() : local); sync(this.remote ? local.slice() : local);
if (this.remote && local.length < this.sufficient) { if (this.remote && local.length < this.sufficient) {
@ -890,7 +924,8 @@
return that.identify(r) === that.identify(l); return that.identify(r) === that.identify(l);
}) && nonDuplicates.push(r); }) && nonDuplicates.push(r);
}); });
async && async(nonDuplicates); that.indexRemote && that.add(nonDuplicates);
async(nonDuplicates);
} }
}, },
all: function all() { all: function all() {
@ -919,13 +954,13 @@
(function(root, factory) { (function(root, factory) {
if (typeof define === "function" && define.amd) { if (typeof define === "function" && define.amd) {
define("typeahead.js", [ "jquery" ], function(a0) { define([ "jquery" ], function(a0) {
return factory(a0); return factory(a0);
}); });
} else if (typeof exports === "object") { } else if (typeof module === "object" && module.exports) {
module.exports = factory(require("jquery")); module.exports = factory(require("jquery"));
} else { } else {
factory(jQuery); factory(root["jQuery"]);
} }
})(this, function($) { })(this, function($) {
var _ = function() { var _ = function() {
@ -1061,6 +1096,13 @@
stringify: function(val) { stringify: function(val) {
return _.isString(val) ? val : JSON.stringify(val); return _.isString(val) ? val : JSON.stringify(val);
}, },
guid: function() {
function _p8(s) {
var p = (Math.random().toString(16) + "000000000").substr(2, 8);
return s ? "-" + p.substr(0, 4) + "-" + p.substr(4, 4) : p;
}
return "tt-" + _p8() + _p8(true) + _p8(true) + _p8();
},
noop: function() {} noop: function() {}
}; };
}(); }();
@ -1102,7 +1144,7 @@
function buildHtml(c) { function buildHtml(c) {
return { return {
wrapper: '<span class="' + c.wrapper + '"></span>', wrapper: '<span class="' + c.wrapper + '"></span>',
menu: '<div class="' + c.menu + '"></div>' menu: '<div role="listbox" class="' + c.menu + '"></div>'
}; };
} }
function buildSelectors(classes) { function buildSelectors(classes) {
@ -1177,10 +1219,8 @@
} }
_.mixin(EventBus.prototype, { _.mixin(EventBus.prototype, {
_trigger: function(type, args) { _trigger: function(type, args) {
var $e; var $e = $.Event(namespace + type);
$e = $.Event(namespace + type); this.$el.trigger.call(this.$el, $e, args || []);
(args = args || []).unshift($e);
this.$el.trigger.apply(this.$el, args);
return $e; return $e;
}, },
before: function(type) { before: function(type) {
@ -1297,7 +1337,36 @@
tagName: "strong", tagName: "strong",
className: null, className: null,
wordsOnly: false, wordsOnly: false,
caseSensitive: false caseSensitive: false,
diacriticInsensitive: false
};
var accented = {
A: "[AaªÀ-Åà-åĀ-ąǍǎȀ-ȃȦȧᴬᵃḀḁẚẠ-ảₐ℀℁℻⒜Ⓐⓐ㍱-㍴㎀-㎄㎈㎉㎩-㎯㏂㏊㏟㏿Aa]",
B: "[BbᴮᵇḂ-ḇℬ⒝Ⓑⓑ㍴㎅-㎇㏃㏈㏔㏝Bb]",
C: "[CcÇçĆ-čᶜ℀ℂ℃℅℆ℭⅭⅽ⒞Ⓒⓒ㍶㎈㎉㎝㎠㎤㏄-㏇Cc]",
D: "[DdĎďDŽ-džDZ-dzᴰᵈḊ-ḓⅅⅆⅮⅾ⒟Ⓓⓓ㋏㍲㍷-㍹㎗㎭-㎯㏅㏈Dd]",
E: "[EeÈ-Ëè-ëĒ-ěȄ-ȇȨȩᴱᵉḘ-ḛẸ-ẽₑ℡ℯℰⅇ⒠Ⓔⓔ㉐㋍㋎Ee]",
F: "[FfᶠḞḟ℉℻⒡Ⓕⓕ㎊-㎌㎙ff-fflFf]",
G: "[GgĜ-ģǦǧǴǵᴳᵍḠḡℊ⒢Ⓖⓖ㋌㋍㎇㎍-㎏㎓㎬㏆㏉㏒㏿Gg]",
H: "[HhĤĥȞȟʰᴴḢ-ḫẖℋ-ℎ⒣Ⓗⓗ㋌㍱㎐-㎔㏊㏋㏗Hh]",
I: "[IiÌ-Ïì-ïĨ-İIJijǏǐȈ-ȋᴵᵢḬḭỈ-ịⁱℐℑℹⅈⅠ-ⅣⅥ-ⅨⅪⅫⅰ-ⅳⅵ-ⅸⅺⅻ⒤Ⓘⓘ㍺㏌㏕fiffiIi]",
J: "[JjIJ-ĵLJ-njǰʲᴶⅉ⒥ⒿⓙⱼJj]",
K: "[KkĶķǨǩᴷᵏḰ-ḵK⒦Ⓚⓚ㎄㎅㎉㎏㎑㎘㎞㎢㎦㎪㎸㎾㏀㏆㏍-㏏Kk]",
L: "[LlĹ-ŀLJ-ljˡᴸḶḷḺ-ḽℒℓ℡Ⅼⅼ⒧Ⓛⓛ㋏㎈㎉㏐-㏓㏕㏖㏿flfflLl]",
M: "[MmᴹᵐḾ-ṃ℠™ℳⅯⅿ⒨Ⓜⓜ㍷-㍹㎃㎆㎎㎒㎖㎙-㎨㎫㎳㎷㎹㎽㎿㏁㏂㏎㏐㏔-㏖㏘㏙㏞㏟Mm]",
N: "[NnÑñŃ-ʼnNJ-njǸǹᴺṄ-ṋⁿℕ№⒩Ⓝⓝ㎁㎋㎚㎱㎵㎻㏌㏑Nn]",
O: "[OoºÒ-Öò-öŌ-őƠơǑǒǪǫȌ-ȏȮȯᴼᵒỌ-ỏₒ℅№ℴ⒪Ⓞⓞ㍵㏇㏒㏖Oo]",
P: "[PpᴾᵖṔ-ṗℙ⒫Ⓟⓟ㉐㍱㍶㎀㎊㎩-㎬㎰㎴㎺㏋㏗-㏚Pp]",
Q: "[Qq⒬Ⓠⓠ㏃]",
R: "[RrŔ-řȐ-ȓʳᴿᵣṘ-ṛṞṟ₨ℛ-ℝ⒭Ⓡⓡ㋍㍴㎭-㎯㏚㏛Rr]",
S: "[SsŚ-šſȘșˢṠ-ṣ₨℁℠⒮Ⓢⓢ㎧㎨㎮-㎳㏛㏜stSs]",
T: "[TtŢ-ťȚțᵀᵗṪ-ṱẗ℡™⒯Ⓣⓣ㉐㋏㎔㏏ſtstTt]",
U: "[UuÙ-Üù-üŨ-ųƯưǓǔȔ-ȗᵁᵘᵤṲ-ṷỤ-ủ℆⒰Ⓤⓤ㍳㍺Uu]",
V: "[VvᵛᵥṼ-ṿⅣ-Ⅷⅳ-ⅷ⒱Ⓥⓥⱽ㋎㍵㎴-㎹㏜㏞Vv]",
W: "[WwŴŵʷᵂẀ-ẉẘ⒲Ⓦⓦ㎺-㎿㏝Ww]",
X: "[XxˣẊ-ẍₓ℻Ⅸ-Ⅻⅸ-ⅻ⒳Ⓧⓧ㏓Xx]",
Y: "[YyÝýÿŶ-ŸȲȳʸẎẏẙỲ-ỹ⒴Ⓨⓨ㏉Yy]",
Z: "[ZzŹ-žDZ-dzᶻẐ-ẕℤℨ⒵Ⓩⓩ㎐-㎔Zz]"
}; };
return function hightlight(o) { return function hightlight(o) {
var regex; var regex;
@ -1306,7 +1375,7 @@
return; return;
} }
o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ]; o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ];
regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly); regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly, o.diacriticInsensitive);
traverse(o.node, hightlightTextNode); traverse(o.node, hightlightTextNode);
function hightlightTextNode(textNode) { function hightlightTextNode(textNode) {
var match, patternNode, wrapperNode; var match, patternNode, wrapperNode;
@ -1332,10 +1401,17 @@
} }
} }
}; };
function getRegex(patterns, caseSensitive, wordsOnly) { function accent_replacer(chr) {
return accented[chr.toUpperCase()] || chr;
}
function getRegex(patterns, caseSensitive, wordsOnly, diacriticInsensitive) {
var escapedPatterns = [], regexStr; var escapedPatterns = [], regexStr;
for (var i = 0, len = patterns.length; i < len; i++) { for (var i = 0, len = patterns.length; i < len; i++) {
escapedPatterns.push(_.escapeRegExChars(patterns[i])); var escapedWord = _.escapeRegExChars(patterns[i]);
if (diacriticInsensitive) {
escapedWord = escapedWord.replace(/\S/g, accent_replacer);
}
escapedPatterns.push(escapedWord);
} }
regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")"; regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")";
return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i"); return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i");
@ -1354,6 +1430,7 @@
40: "down" 40: "down"
}; };
function Input(o, www) { function Input(o, www) {
var id;
o = o || {}; o = o || {};
if (!o.input) { if (!o.input) {
$.error("input is missing"); $.error("input is missing");
@ -1361,6 +1438,18 @@
www.mixin(this); www.mixin(this);
this.$hint = $(o.hint); this.$hint = $(o.hint);
this.$input = $(o.input); this.$input = $(o.input);
this.$menu = $(o.menu);
id = this.$input.attr("id") || _.guid();
this.$menu.attr("id", id + "_listbox");
this.$hint.attr({
"aria-hidden": true
});
this.$input.attr({
"aria-owns": id + "_listbox",
role: "combobox",
"aria-autocomplete": "list",
"aria-expanded": false
});
this.query = this.$input.val(); this.query = this.$input.val();
this.queryWhenFocused = this.hasFocus() ? this.query : null; this.queryWhenFocused = this.hasFocus() ? this.query : null;
this.$overflowHelper = buildOverflowHelper(this.$input); this.$overflowHelper = buildOverflowHelper(this.$input);
@ -1368,6 +1457,7 @@
if (this.$hint.length === 0) { if (this.$hint.length === 0) {
this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop; this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop;
} }
this.onSync("cursorchange", this._updateDescendent);
} }
Input.normalizeQuery = function(str) { Input.normalizeQuery = function(str) {
return _.toStr(str).replace(/^\s*/g, "").replace(/\s{2,}/g, " "); return _.toStr(str).replace(/^\s*/g, "").replace(/\s{2,}/g, " ");
@ -1437,6 +1527,9 @@
this.trigger("whitespaceChanged", this.query); this.trigger("whitespaceChanged", this.query);
} }
}, },
_updateDescendent: function updateDescendent(event, id) {
this.$input.attr("aria-activedescendant", id);
},
bind: function() { bind: function() {
var that = this, onBlur, onFocus, onKeydown, onInput; var that = this, onBlur, onFocus, onKeydown, onInput;
onBlur = _.bind(this._onBlur, this); onBlur = _.bind(this._onBlur, this);
@ -1529,6 +1622,9 @@
this.$input.off(".tt"); this.$input.off(".tt");
this.$overflowHelper.remove(); this.$overflowHelper.remove();
this.$hint = this.$input = this.$overflowHelper = $("<div>"); this.$hint = this.$input = this.$overflowHelper = $("<div>");
},
setAriaExpanded: function setAriaExpanded(value) {
this.$input.attr("aria-expanded", value);
} }
}); });
return Input; return Input;
@ -1560,6 +1656,7 @@
"use strict"; "use strict";
var keys, nameGenerator; var keys, nameGenerator;
keys = { keys = {
dataset: "tt-selectable-dataset",
val: "tt-selectable-display", val: "tt-selectable-display",
obj: "tt-selectable-object" obj: "tt-selectable-object"
}; };
@ -1579,19 +1676,20 @@
} }
www.mixin(this); www.mixin(this);
this.highlight = !!o.highlight; this.highlight = !!o.highlight;
this.name = o.name || nameGenerator(); this.name = _.toStr(o.name || nameGenerator());
this.limit = o.limit || 5; this.limit = o.limit || 5;
this.displayFn = getDisplayFn(o.display || o.displayKey); this.displayFn = getDisplayFn(o.display || o.displayKey);
this.templates = getTemplates(o.templates, this.displayFn); this.templates = getTemplates(o.templates, this.displayFn);
this.source = o.source.__ttAdapter ? o.source.__ttAdapter() : o.source; this.source = o.source.__ttAdapter ? o.source.__ttAdapter() : o.source;
this.async = _.isUndefined(o.async) ? this.source.length > 2 : !!o.async; this.async = _.isUndefined(o.async) ? this.source.length > 2 : !!o.async;
this._resetLastSuggestion(); this._resetLastSuggestion();
this.$el = $(o.node).addClass(this.classes.dataset).addClass(this.classes.dataset + "-" + this.name); this.$el = $(o.node).attr("role", "presentation").addClass(this.classes.dataset).addClass(this.classes.dataset + "-" + this.name);
} }
Dataset.extractData = function extractData(el) { Dataset.extractData = function extractData(el) {
var $el = $(el); var $el = $(el);
if ($el.data(keys.obj)) { if ($el.data(keys.obj)) {
return { return {
dataset: $el.data(keys.dataset) || "",
val: $el.data(keys.val) || "", val: $el.data(keys.val) || "",
obj: $el.data(keys.obj) || null obj: $el.data(keys.obj) || null
}; };
@ -1610,7 +1708,7 @@
} else { } else {
this._empty(); this._empty();
} }
this.trigger("rendered", this.name, suggestions, false); this.trigger("rendered", suggestions, false, this.name);
}, },
_append: function append(query, suggestions) { _append: function append(query, suggestions) {
suggestions = suggestions || []; suggestions = suggestions || [];
@ -1621,7 +1719,7 @@
} else if (!this.$lastSuggestion.length && this.templates.notFound) { } else if (!this.$lastSuggestion.length && this.templates.notFound) {
this._renderNotFound(query); this._renderNotFound(query);
} }
this.trigger("rendered", this.name, suggestions, true); this.trigger("rendered", suggestions, true, this.name);
}, },
_renderSuggestions: function renderSuggestions(query, suggestions) { _renderSuggestions: function renderSuggestions(query, suggestions) {
var $fragment; var $fragment;
@ -1662,7 +1760,7 @@
_.each(suggestions, function getSuggestionNode(suggestion) { _.each(suggestions, function getSuggestionNode(suggestion) {
var $el, context; var $el, context;
context = that._injectQuery(query, suggestion); context = that._injectQuery(query, suggestion);
$el = $(that.templates.suggestion(context)).data(keys.obj, suggestion).data(keys.val, that.displayFn(suggestion)).addClass(that.classes.suggestion + " " + that.classes.selectable); $el = $(that.templates.suggestion(context)).data(keys.dataset, that.name).data(keys.obj, suggestion).data(keys.val, that.displayFn(suggestion)).addClass(that.classes.suggestion + " " + that.classes.selectable);
fragment.appendChild($el[0]); fragment.appendChild($el[0]);
}); });
this.highlight && highlight({ this.highlight && highlight({
@ -1700,7 +1798,7 @@
this.cancel = function cancel() { this.cancel = function cancel() {
canceled = true; canceled = true;
that.cancel = $.noop; that.cancel = $.noop;
that.async && that.trigger("asyncCanceled", query); that.async && that.trigger("asyncCanceled", query, that.name);
}; };
this.source(query, sync, async); this.source(query, sync, async);
!syncCalled && sync([]); !syncCalled && sync([]);
@ -1713,16 +1811,17 @@
rendered = suggestions.length; rendered = suggestions.length;
that._overwrite(query, suggestions); that._overwrite(query, suggestions);
if (rendered < that.limit && that.async) { if (rendered < that.limit && that.async) {
that.trigger("asyncRequested", query); that.trigger("asyncRequested", query, that.name);
} }
} }
function async(suggestions) { function async(suggestions) {
suggestions = suggestions || []; suggestions = suggestions || [];
if (!canceled && rendered < that.limit) { if (!canceled && rendered < that.limit) {
that.cancel = $.noop; that.cancel = $.noop;
rendered += suggestions.length; var idx = Math.abs(rendered - that.limit);
that._append(query, suggestions.slice(0, that.limit - rendered)); rendered += idx;
that.async && that.trigger("asyncReceived", query); that._append(query, suggestions.slice(0, idx));
that.async && that.trigger("asyncReceived", query, that.name);
} }
} }
}, },
@ -1753,10 +1852,14 @@
pending: templates.pending && _.templatify(templates.pending), pending: templates.pending && _.templatify(templates.pending),
header: templates.header && _.templatify(templates.header), header: templates.header && _.templatify(templates.header),
footer: templates.footer && _.templatify(templates.footer), footer: templates.footer && _.templatify(templates.footer),
suggestion: templates.suggestion || suggestionTemplate suggestion: templates.suggestion ? userSuggestionTemplate : suggestionTemplate
}; };
function userSuggestionTemplate(context) {
var template = templates.suggestion;
return $(template(context)).attr("id", _.guid());
}
function suggestionTemplate(context) { function suggestionTemplate(context) {
return $("<div>").text(displayFn(context)); return $('<div role="option">').attr("id", _.guid()).text(displayFn(context));
} }
} }
function isValidName(str) { function isValidName(str) {
@ -1797,10 +1900,11 @@
this.trigger.apply(this, arguments); this.trigger.apply(this, arguments);
}, },
_allDatasetsEmpty: function allDatasetsEmpty() { _allDatasetsEmpty: function allDatasetsEmpty() {
return _.every(this.datasets, isDatasetEmpty); return _.every(this.datasets, _.bind(function isDatasetEmpty(dataset) {
function isDatasetEmpty(dataset) { var isEmpty = dataset.isEmpty();
return dataset.isEmpty(); this.$node.attr("aria-expanded", !isEmpty);
} return isEmpty;
}, this));
}, },
_getSelectables: function getSelectables() { _getSelectables: function getSelectables() {
return this.$node.find(this.selectors.selectable); return this.$node.find(this.selectors.selectable);
@ -1825,6 +1929,12 @@
var that = this, onSelectableClick; var that = this, onSelectableClick;
onSelectableClick = _.bind(this._onSelectableClick, this); onSelectableClick = _.bind(this._onSelectableClick, this);
this.$node.on("click.tt", this.selectors.selectable, onSelectableClick); this.$node.on("click.tt", this.selectors.selectable, onSelectableClick);
this.$node.on("mouseover", this.selectors.selectable, function() {
that.setCursor($(this));
});
this.$node.on("mouseleave", function() {
that._removeCursor();
});
_.each(this.datasets, function(dataset) { _.each(this.datasets, function(dataset) {
dataset.onSync("asyncRequested", that._propagate, that).onSync("asyncCanceled", that._propagate, that).onSync("asyncReceived", that._propagate, that).onSync("rendered", that._onRendered, that).onSync("cleared", that._onCleared, that); dataset.onSync("asyncRequested", that._propagate, that).onSync("asyncCanceled", that._propagate, that).onSync("asyncReceived", that._propagate, that).onSync("rendered", that._onRendered, that).onSync("cleared", that._onCleared, that);
}); });
@ -1834,9 +1944,11 @@
return this.$node.hasClass(this.classes.open); return this.$node.hasClass(this.classes.open);
}, },
open: function open() { open: function open() {
this.$node.scrollTop(0);
this.$node.addClass(this.classes.open); this.$node.addClass(this.classes.open);
}, },
close: function close() { close: function close() {
this.$node.attr("aria-expanded", false);
this.$node.removeClass(this.classes.open); this.$node.removeClass(this.classes.open);
this._removeCursor(); this._removeCursor();
}, },
@ -1901,6 +2013,55 @@
}); });
return Menu; return Menu;
}(); }();
var Status = function() {
"use strict";
function Status(options) {
this.$el = $("<span></span>", {
role: "status",
"aria-live": "polite"
}).css({
position: "absolute",
padding: "0",
border: "0",
height: "1px",
width: "1px",
"margin-bottom": "-1px",
"margin-right": "-1px",
overflow: "hidden",
clip: "rect(0 0 0 0)",
"white-space": "nowrap"
});
options.$input.after(this.$el);
_.each(options.menu.datasets, _.bind(function(dataset) {
if (dataset.onSync) {
dataset.onSync("rendered", _.bind(this.update, this));
dataset.onSync("cleared", _.bind(this.cleared, this));
}
}, this));
}
_.mixin(Status.prototype, {
update: function update(event, suggestions) {
var length = suggestions.length;
var words;
if (length === 1) {
words = {
result: "result",
is: "is"
};
} else {
words = {
result: "results",
is: "are"
};
}
this.$el.text(length + " " + words.result + " " + words.is + " available, use up and down arrow keys to navigate.");
},
cleared: function() {
this.$el.text("");
}
});
return Status;
}();
var DefaultMenu = function() { var DefaultMenu = function() {
"use strict"; "use strict";
var s = Menu.prototype; var s = Menu.prototype;
@ -1965,6 +2126,7 @@
this.input = o.input; this.input = o.input;
this.menu = o.menu; this.menu = o.menu;
this.enabled = true; this.enabled = true;
this.autoselect = !!o.autoselect;
this.active = false; this.active = false;
this.input.hasFocus() && this.activate(); this.input.hasFocus() && this.activate();
this.dir = this.input.getLangDir(); this.dir = this.input.getLangDir();
@ -2011,8 +2173,12 @@
_onDatasetCleared: function onDatasetCleared() { _onDatasetCleared: function onDatasetCleared() {
this._updateHint(); this._updateHint();
}, },
_onDatasetRendered: function onDatasetRendered(type, dataset, suggestions, async) { _onDatasetRendered: function onDatasetRendered(type, suggestions, async, dataset) {
this._updateHint(); this._updateHint();
if (this.autoselect) {
var cursorClass = this.selectors.cursor.substr(1);
this.menu.$node.find(this.selectors.suggestion).first().addClass(cursorClass);
}
this.eventBus.trigger("render", suggestions, async, dataset); this.eventBus.trigger("render", suggestions, async, dataset);
}, },
_onAsyncRequested: function onAsyncRequested(type, dataset, query) { _onAsyncRequested: function onAsyncRequested(type, dataset, query) {
@ -2035,15 +2201,25 @@
_onEnterKeyed: function onEnterKeyed(type, $e) { _onEnterKeyed: function onEnterKeyed(type, $e) {
var $selectable; var $selectable;
if ($selectable = this.menu.getActiveSelectable()) { if ($selectable = this.menu.getActiveSelectable()) {
this.select($selectable) && $e.preventDefault(); if (this.select($selectable)) {
$e.preventDefault();
$e.stopPropagation();
}
} else if (this.autoselect) {
if (this.select(this.menu.getTopSelectable())) {
$e.preventDefault();
$e.stopPropagation();
}
} }
}, },
_onTabKeyed: function onTabKeyed(type, $e) { _onTabKeyed: function onTabKeyed(type, $e) {
var $selectable; var $selectable;
if ($selectable = this.menu.getActiveSelectable()) { if ($selectable = this.menu.getActiveSelectable()) {
this.select($selectable) && $e.preventDefault(); this.select($selectable) && $e.preventDefault();
} else if ($selectable = this.menu.getTopSelectable()) { } else if (this.autoselect) {
this.autocomplete($selectable) && $e.preventDefault(); if ($selectable = this.menu.getTopSelectable()) {
this.autocomplete($selectable) && $e.preventDefault();
}
} }
}, },
_onEscKeyed: function onEscKeyed() { _onEscKeyed: function onEscKeyed() {
@ -2057,12 +2233,12 @@
}, },
_onLeftKeyed: function onLeftKeyed() { _onLeftKeyed: function onLeftKeyed() {
if (this.dir === "rtl" && this.input.isCursorAtEnd()) { if (this.dir === "rtl" && this.input.isCursorAtEnd()) {
this.autocomplete(this.menu.getTopSelectable()); this.autocomplete(this.menu.getActiveSelectable() || this.menu.getTopSelectable());
} }
}, },
_onRightKeyed: function onRightKeyed() { _onRightKeyed: function onRightKeyed() {
if (this.dir === "ltr" && this.input.isCursorAtEnd()) { if (this.dir === "ltr" && this.input.isCursorAtEnd()) {
this.autocomplete(this.menu.getTopSelectable()); this.autocomplete(this.menu.getActiveSelectable() || this.menu.getTopSelectable());
} }
}, },
_onQueryChanged: function onQueryChanged(e, query) { _onQueryChanged: function onQueryChanged(e, query) {
@ -2139,6 +2315,7 @@
}, },
open: function open() { open: function open() {
if (!this.isOpen() && !this.eventBus.before("open")) { if (!this.isOpen() && !this.eventBus.before("open")) {
this.input.setAriaExpanded(true);
this.menu.open(); this.menu.open();
this._updateHint(); this._updateHint();
this.eventBus.trigger("open"); this.eventBus.trigger("open");
@ -2147,6 +2324,7 @@
}, },
close: function close() { close: function close() {
if (this.isOpen() && !this.eventBus.before("close")) { if (this.isOpen() && !this.eventBus.before("close")) {
this.input.setAriaExpanded(false);
this.menu.close(); this.menu.close();
this.input.clearHint(); this.input.clearHint();
this.input.resetInputValue(); this.input.resetInputValue();
@ -2162,9 +2340,9 @@
}, },
select: function select($selectable) { select: function select($selectable) {
var data = this.menu.getSelectableData($selectable); var data = this.menu.getSelectableData($selectable);
if (data && !this.eventBus.before("select", data.obj)) { if (data && !this.eventBus.before("select", data.obj, data.dataset)) {
this.input.setQuery(data.val, true); this.input.setQuery(data.val, true);
this.eventBus.trigger("select", data.obj); this.eventBus.trigger("select", data.obj, data.dataset);
this.close(); this.close();
return true; return true;
} }
@ -2175,29 +2353,34 @@
query = this.input.getQuery(); query = this.input.getQuery();
data = this.menu.getSelectableData($selectable); data = this.menu.getSelectableData($selectable);
isValid = data && query !== data.val; isValid = data && query !== data.val;
if (isValid && !this.eventBus.before("autocomplete", data.obj)) { if (isValid && !this.eventBus.before("autocomplete", data.obj, data.dataset)) {
this.input.setQuery(data.val); this.input.setQuery(data.val);
this.eventBus.trigger("autocomplete", data.obj); this.eventBus.trigger("autocomplete", data.obj, data.dataset);
return true; return true;
} }
return false; return false;
}, },
moveCursor: function moveCursor(delta) { moveCursor: function moveCursor(delta) {
var query, $candidate, data, payload, cancelMove; var query, $candidate, data, suggestion, datasetName, cancelMove, id;
query = this.input.getQuery(); query = this.input.getQuery();
$candidate = this.menu.selectableRelativeToCursor(delta); $candidate = this.menu.selectableRelativeToCursor(delta);
data = this.menu.getSelectableData($candidate); data = this.menu.getSelectableData($candidate);
payload = data ? data.obj : null; suggestion = data ? data.obj : null;
datasetName = data ? data.dataset : null;
id = $candidate ? $candidate.attr("id") : null;
this.input.trigger("cursorchange", id);
cancelMove = this._minLengthMet() && this.menu.update(query); cancelMove = this._minLengthMet() && this.menu.update(query);
if (!cancelMove && !this.eventBus.before("cursorchange", payload)) { if (!cancelMove && !this.eventBus.before("cursorchange", suggestion, datasetName)) {
this.menu.setCursor($candidate); this.menu.setCursor($candidate);
if (data) { if (data) {
this.input.setInputValue(data.val); if (typeof data.val === "string") {
this.input.setInputValue(data.val);
}
} else { } else {
this.input.resetInputValue(); this.input.resetInputValue();
this._updateHint(); this._updateHint();
} }
this.eventBus.trigger("cursorchange", payload); this.eventBus.trigger("cursorchange", suggestion, datasetName);
return true; return true;
} }
return false; return false;
@ -2235,7 +2418,7 @@
www = WWW(o.classNames); www = WWW(o.classNames);
return this.each(attach); return this.each(attach);
function attach() { function attach() {
var $input, $wrapper, $hint, $menu, defaultHint, defaultMenu, eventBus, input, menu, typeahead, MenuConstructor; var $input, $wrapper, $hint, $menu, defaultHint, defaultMenu, eventBus, input, menu, status, typeahead, MenuConstructor;
_.each(datasets, function(d) { _.each(datasets, function(d) {
d.highlight = !!o.highlight; d.highlight = !!o.highlight;
}); });
@ -2260,17 +2443,23 @@
}); });
input = new Input({ input = new Input({
hint: $hint, hint: $hint,
input: $input input: $input,
menu: $menu
}, www); }, www);
menu = new MenuConstructor({ menu = new MenuConstructor({
node: $menu, node: $menu,
datasets: datasets datasets: datasets
}, www); }, www);
status = new Status({
$input: $input,
menu: menu
});
typeahead = new Typeahead({ typeahead = new Typeahead({
input: input, input: input,
menu: menu, menu: menu,
eventBus: eventBus, eventBus: eventBus,
minLength: o.minLength minLength: o.minLength,
autoselect: o.autoselect
}, www); }, www);
$input.data(keys.www, www); $input.data(keys.www, www);
$input.data(keys.typeahead, typeahead); $input.data(keys.typeahead, typeahead);
@ -2363,7 +2552,7 @@
return query; return query;
} else { } else {
ttEach(this, function(t) { ttEach(this, function(t) {
t.setVal(newVal); t.setVal(_.toStr(newVal));
}); });
return this; return this;
} }
@ -2394,8 +2583,10 @@
}); });
} }
function buildHintFromInput($input, www) { function buildHintFromInput($input, www) {
return $input.clone().addClass(www.classes.hint).removeData().css(www.css.hint).css(getBackgroundStyles($input)).prop("readonly", true).removeAttr("id name placeholder required").attr({ return $input.clone().addClass(www.classes.hint).removeData().css(www.css.hint).css(getBackgroundStyles($input)).prop({
autocomplete: "off", readonly: true,
required: false
}).removeAttr("id name placeholder").removeClass("required").attr({
spellcheck: "false", spellcheck: "false",
tabindex: -1 tabindex: -1
}); });
@ -2408,7 +2599,6 @@
style: $input.attr("style") style: $input.attr("style")
}); });
$input.addClass(www.classes.input).attr({ $input.addClass(www.classes.input).attr({
autocomplete: "off",
spellcheck: false spellcheck: false
}); });
try { try {

File diff suppressed because one or more lines are too long

View File

@ -1,18 +1,19 @@
/*! /*!
* typeahead.js 0.11.1 * typeahead.js 1.3.1
* https://github.com/twitter/typeahead.js * https://github.com/corejavascript/typeahead.js
* Copyright 2013-2015 Twitter, Inc. and other contributors; Licensed MIT * Copyright 2013-2020 Twitter, Inc. and other contributors; Licensed MIT
*/ */
(function(root, factory) { (function(root, factory) {
if (typeof define === "function" && define.amd) { if (typeof define === "function" && define.amd) {
define("typeahead.js", [ "jquery" ], function(a0) { define([ "jquery" ], function(a0) {
return factory(a0); return factory(a0);
}); });
} else if (typeof exports === "object") { } else if (typeof module === "object" && module.exports) {
module.exports = factory(require("jquery")); module.exports = factory(require("jquery"));
} else { } else {
factory(jQuery); factory(root["jQuery"]);
} }
})(this, function($) { })(this, function($) {
var _ = function() { var _ = function() {
@ -148,6 +149,13 @@
stringify: function(val) { stringify: function(val) {
return _.isString(val) ? val : JSON.stringify(val); return _.isString(val) ? val : JSON.stringify(val);
}, },
guid: function() {
function _p8(s) {
var p = (Math.random().toString(16) + "000000000").substr(2, 8);
return s ? "-" + p.substr(0, 4) + "-" + p.substr(4, 4) : p;
}
return "tt-" + _p8() + _p8(true) + _p8(true) + _p8();
},
noop: function() {} noop: function() {}
}; };
}(); }();
@ -189,7 +197,7 @@
function buildHtml(c) { function buildHtml(c) {
return { return {
wrapper: '<span class="' + c.wrapper + '"></span>', wrapper: '<span class="' + c.wrapper + '"></span>',
menu: '<div class="' + c.menu + '"></div>' menu: '<div role="listbox" class="' + c.menu + '"></div>'
}; };
} }
function buildSelectors(classes) { function buildSelectors(classes) {
@ -264,10 +272,8 @@
} }
_.mixin(EventBus.prototype, { _.mixin(EventBus.prototype, {
_trigger: function(type, args) { _trigger: function(type, args) {
var $e; var $e = $.Event(namespace + type);
$e = $.Event(namespace + type); this.$el.trigger.call(this.$el, $e, args || []);
(args = args || []).unshift($e);
this.$el.trigger.apply(this.$el, args);
return $e; return $e;
}, },
before: function(type) { before: function(type) {
@ -384,7 +390,36 @@
tagName: "strong", tagName: "strong",
className: null, className: null,
wordsOnly: false, wordsOnly: false,
caseSensitive: false caseSensitive: false,
diacriticInsensitive: false
};
var accented = {
A: "[AaªÀ-Åà-åĀ-ąǍǎȀ-ȃȦȧᴬᵃḀḁẚẠ-ảₐ℀℁℻⒜Ⓐⓐ㍱-㍴㎀-㎄㎈㎉㎩-㎯㏂㏊㏟㏿Aa]",
B: "[BbᴮᵇḂ-ḇℬ⒝Ⓑⓑ㍴㎅-㎇㏃㏈㏔㏝Bb]",
C: "[CcÇçĆ-čᶜ℀ℂ℃℅℆ℭⅭⅽ⒞Ⓒⓒ㍶㎈㎉㎝㎠㎤㏄-㏇Cc]",
D: "[DdĎďDŽ-džDZ-dzᴰᵈḊ-ḓⅅⅆⅮⅾ⒟Ⓓⓓ㋏㍲㍷-㍹㎗㎭-㎯㏅㏈Dd]",
E: "[EeÈ-Ëè-ëĒ-ěȄ-ȇȨȩᴱᵉḘ-ḛẸ-ẽₑ℡ℯℰⅇ⒠Ⓔⓔ㉐㋍㋎Ee]",
F: "[FfᶠḞḟ℉℻⒡Ⓕⓕ㎊-㎌㎙ff-fflFf]",
G: "[GgĜ-ģǦǧǴǵᴳᵍḠḡℊ⒢Ⓖⓖ㋌㋍㎇㎍-㎏㎓㎬㏆㏉㏒㏿Gg]",
H: "[HhĤĥȞȟʰᴴḢ-ḫẖℋ-ℎ⒣Ⓗⓗ㋌㍱㎐-㎔㏊㏋㏗Hh]",
I: "[IiÌ-Ïì-ïĨ-İIJijǏǐȈ-ȋᴵᵢḬḭỈ-ịⁱℐℑℹⅈⅠ-ⅣⅥ-ⅨⅪⅫⅰ-ⅳⅵ-ⅸⅺⅻ⒤Ⓘⓘ㍺㏌㏕fiffiIi]",
J: "[JjIJ-ĵLJ-njǰʲᴶⅉ⒥ⒿⓙⱼJj]",
K: "[KkĶķǨǩᴷᵏḰ-ḵK⒦Ⓚⓚ㎄㎅㎉㎏㎑㎘㎞㎢㎦㎪㎸㎾㏀㏆㏍-㏏Kk]",
L: "[LlĹ-ŀLJ-ljˡᴸḶḷḺ-ḽℒℓ℡Ⅼⅼ⒧Ⓛⓛ㋏㎈㎉㏐-㏓㏕㏖㏿flfflLl]",
M: "[MmᴹᵐḾ-ṃ℠™ℳⅯⅿ⒨Ⓜⓜ㍷-㍹㎃㎆㎎㎒㎖㎙-㎨㎫㎳㎷㎹㎽㎿㏁㏂㏎㏐㏔-㏖㏘㏙㏞㏟Mm]",
N: "[NnÑñŃ-ʼnNJ-njǸǹᴺṄ-ṋⁿℕ№⒩Ⓝⓝ㎁㎋㎚㎱㎵㎻㏌㏑Nn]",
O: "[OoºÒ-Öò-öŌ-őƠơǑǒǪǫȌ-ȏȮȯᴼᵒỌ-ỏₒ℅№ℴ⒪Ⓞⓞ㍵㏇㏒㏖Oo]",
P: "[PpᴾᵖṔ-ṗℙ⒫Ⓟⓟ㉐㍱㍶㎀㎊㎩-㎬㎰㎴㎺㏋㏗-㏚Pp]",
Q: "[Qq⒬Ⓠⓠ㏃]",
R: "[RrŔ-řȐ-ȓʳᴿᵣṘ-ṛṞṟ₨ℛ-ℝ⒭Ⓡⓡ㋍㍴㎭-㎯㏚㏛Rr]",
S: "[SsŚ-šſȘșˢṠ-ṣ₨℁℠⒮Ⓢⓢ㎧㎨㎮-㎳㏛㏜stSs]",
T: "[TtŢ-ťȚțᵀᵗṪ-ṱẗ℡™⒯Ⓣⓣ㉐㋏㎔㏏ſtstTt]",
U: "[UuÙ-Üù-üŨ-ųƯưǓǔȔ-ȗᵁᵘᵤṲ-ṷỤ-ủ℆⒰Ⓤⓤ㍳㍺Uu]",
V: "[VvᵛᵥṼ-ṿⅣ-Ⅷⅳ-ⅷ⒱Ⓥⓥⱽ㋎㍵㎴-㎹㏜㏞Vv]",
W: "[WwŴŵʷᵂẀ-ẉẘ⒲Ⓦⓦ㎺-㎿㏝Ww]",
X: "[XxˣẊ-ẍₓ℻Ⅸ-Ⅻⅸ-ⅻ⒳Ⓧⓧ㏓Xx]",
Y: "[YyÝýÿŶ-ŸȲȳʸẎẏẙỲ-ỹ⒴Ⓨⓨ㏉Yy]",
Z: "[ZzŹ-žDZ-dzᶻẐ-ẕℤℨ⒵Ⓩⓩ㎐-㎔Zz]"
}; };
return function hightlight(o) { return function hightlight(o) {
var regex; var regex;
@ -393,7 +428,7 @@
return; return;
} }
o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ]; o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ];
regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly); regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly, o.diacriticInsensitive);
traverse(o.node, hightlightTextNode); traverse(o.node, hightlightTextNode);
function hightlightTextNode(textNode) { function hightlightTextNode(textNode) {
var match, patternNode, wrapperNode; var match, patternNode, wrapperNode;
@ -419,10 +454,17 @@
} }
} }
}; };
function getRegex(patterns, caseSensitive, wordsOnly) { function accent_replacer(chr) {
return accented[chr.toUpperCase()] || chr;
}
function getRegex(patterns, caseSensitive, wordsOnly, diacriticInsensitive) {
var escapedPatterns = [], regexStr; var escapedPatterns = [], regexStr;
for (var i = 0, len = patterns.length; i < len; i++) { for (var i = 0, len = patterns.length; i < len; i++) {
escapedPatterns.push(_.escapeRegExChars(patterns[i])); var escapedWord = _.escapeRegExChars(patterns[i]);
if (diacriticInsensitive) {
escapedWord = escapedWord.replace(/\S/g, accent_replacer);
}
escapedPatterns.push(escapedWord);
} }
regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")"; regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")";
return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i"); return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i");
@ -441,6 +483,7 @@
40: "down" 40: "down"
}; };
function Input(o, www) { function Input(o, www) {
var id;
o = o || {}; o = o || {};
if (!o.input) { if (!o.input) {
$.error("input is missing"); $.error("input is missing");
@ -448,6 +491,18 @@
www.mixin(this); www.mixin(this);
this.$hint = $(o.hint); this.$hint = $(o.hint);
this.$input = $(o.input); this.$input = $(o.input);
this.$menu = $(o.menu);
id = this.$input.attr("id") || _.guid();
this.$menu.attr("id", id + "_listbox");
this.$hint.attr({
"aria-hidden": true
});
this.$input.attr({
"aria-owns": id + "_listbox",
role: "combobox",
"aria-autocomplete": "list",
"aria-expanded": false
});
this.query = this.$input.val(); this.query = this.$input.val();
this.queryWhenFocused = this.hasFocus() ? this.query : null; this.queryWhenFocused = this.hasFocus() ? this.query : null;
this.$overflowHelper = buildOverflowHelper(this.$input); this.$overflowHelper = buildOverflowHelper(this.$input);
@ -455,6 +510,7 @@
if (this.$hint.length === 0) { if (this.$hint.length === 0) {
this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop; this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop;
} }
this.onSync("cursorchange", this._updateDescendent);
} }
Input.normalizeQuery = function(str) { Input.normalizeQuery = function(str) {
return _.toStr(str).replace(/^\s*/g, "").replace(/\s{2,}/g, " "); return _.toStr(str).replace(/^\s*/g, "").replace(/\s{2,}/g, " ");
@ -524,6 +580,9 @@
this.trigger("whitespaceChanged", this.query); this.trigger("whitespaceChanged", this.query);
} }
}, },
_updateDescendent: function updateDescendent(event, id) {
this.$input.attr("aria-activedescendant", id);
},
bind: function() { bind: function() {
var that = this, onBlur, onFocus, onKeydown, onInput; var that = this, onBlur, onFocus, onKeydown, onInput;
onBlur = _.bind(this._onBlur, this); onBlur = _.bind(this._onBlur, this);
@ -616,6 +675,9 @@
this.$input.off(".tt"); this.$input.off(".tt");
this.$overflowHelper.remove(); this.$overflowHelper.remove();
this.$hint = this.$input = this.$overflowHelper = $("<div>"); this.$hint = this.$input = this.$overflowHelper = $("<div>");
},
setAriaExpanded: function setAriaExpanded(value) {
this.$input.attr("aria-expanded", value);
} }
}); });
return Input; return Input;
@ -647,6 +709,7 @@
"use strict"; "use strict";
var keys, nameGenerator; var keys, nameGenerator;
keys = { keys = {
dataset: "tt-selectable-dataset",
val: "tt-selectable-display", val: "tt-selectable-display",
obj: "tt-selectable-object" obj: "tt-selectable-object"
}; };
@ -666,19 +729,20 @@
} }
www.mixin(this); www.mixin(this);
this.highlight = !!o.highlight; this.highlight = !!o.highlight;
this.name = o.name || nameGenerator(); this.name = _.toStr(o.name || nameGenerator());
this.limit = o.limit || 5; this.limit = o.limit || 5;
this.displayFn = getDisplayFn(o.display || o.displayKey); this.displayFn = getDisplayFn(o.display || o.displayKey);
this.templates = getTemplates(o.templates, this.displayFn); this.templates = getTemplates(o.templates, this.displayFn);
this.source = o.source.__ttAdapter ? o.source.__ttAdapter() : o.source; this.source = o.source.__ttAdapter ? o.source.__ttAdapter() : o.source;
this.async = _.isUndefined(o.async) ? this.source.length > 2 : !!o.async; this.async = _.isUndefined(o.async) ? this.source.length > 2 : !!o.async;
this._resetLastSuggestion(); this._resetLastSuggestion();
this.$el = $(o.node).addClass(this.classes.dataset).addClass(this.classes.dataset + "-" + this.name); this.$el = $(o.node).attr("role", "presentation").addClass(this.classes.dataset).addClass(this.classes.dataset + "-" + this.name);
} }
Dataset.extractData = function extractData(el) { Dataset.extractData = function extractData(el) {
var $el = $(el); var $el = $(el);
if ($el.data(keys.obj)) { if ($el.data(keys.obj)) {
return { return {
dataset: $el.data(keys.dataset) || "",
val: $el.data(keys.val) || "", val: $el.data(keys.val) || "",
obj: $el.data(keys.obj) || null obj: $el.data(keys.obj) || null
}; };
@ -697,7 +761,7 @@
} else { } else {
this._empty(); this._empty();
} }
this.trigger("rendered", this.name, suggestions, false); this.trigger("rendered", suggestions, false, this.name);
}, },
_append: function append(query, suggestions) { _append: function append(query, suggestions) {
suggestions = suggestions || []; suggestions = suggestions || [];
@ -708,7 +772,7 @@
} else if (!this.$lastSuggestion.length && this.templates.notFound) { } else if (!this.$lastSuggestion.length && this.templates.notFound) {
this._renderNotFound(query); this._renderNotFound(query);
} }
this.trigger("rendered", this.name, suggestions, true); this.trigger("rendered", suggestions, true, this.name);
}, },
_renderSuggestions: function renderSuggestions(query, suggestions) { _renderSuggestions: function renderSuggestions(query, suggestions) {
var $fragment; var $fragment;
@ -749,7 +813,7 @@
_.each(suggestions, function getSuggestionNode(suggestion) { _.each(suggestions, function getSuggestionNode(suggestion) {
var $el, context; var $el, context;
context = that._injectQuery(query, suggestion); context = that._injectQuery(query, suggestion);
$el = $(that.templates.suggestion(context)).data(keys.obj, suggestion).data(keys.val, that.displayFn(suggestion)).addClass(that.classes.suggestion + " " + that.classes.selectable); $el = $(that.templates.suggestion(context)).data(keys.dataset, that.name).data(keys.obj, suggestion).data(keys.val, that.displayFn(suggestion)).addClass(that.classes.suggestion + " " + that.classes.selectable);
fragment.appendChild($el[0]); fragment.appendChild($el[0]);
}); });
this.highlight && highlight({ this.highlight && highlight({
@ -787,7 +851,7 @@
this.cancel = function cancel() { this.cancel = function cancel() {
canceled = true; canceled = true;
that.cancel = $.noop; that.cancel = $.noop;
that.async && that.trigger("asyncCanceled", query); that.async && that.trigger("asyncCanceled", query, that.name);
}; };
this.source(query, sync, async); this.source(query, sync, async);
!syncCalled && sync([]); !syncCalled && sync([]);
@ -800,16 +864,17 @@
rendered = suggestions.length; rendered = suggestions.length;
that._overwrite(query, suggestions); that._overwrite(query, suggestions);
if (rendered < that.limit && that.async) { if (rendered < that.limit && that.async) {
that.trigger("asyncRequested", query); that.trigger("asyncRequested", query, that.name);
} }
} }
function async(suggestions) { function async(suggestions) {
suggestions = suggestions || []; suggestions = suggestions || [];
if (!canceled && rendered < that.limit) { if (!canceled && rendered < that.limit) {
that.cancel = $.noop; that.cancel = $.noop;
rendered += suggestions.length; var idx = Math.abs(rendered - that.limit);
that._append(query, suggestions.slice(0, that.limit - rendered)); rendered += idx;
that.async && that.trigger("asyncReceived", query); that._append(query, suggestions.slice(0, idx));
that.async && that.trigger("asyncReceived", query, that.name);
} }
} }
}, },
@ -840,10 +905,14 @@
pending: templates.pending && _.templatify(templates.pending), pending: templates.pending && _.templatify(templates.pending),
header: templates.header && _.templatify(templates.header), header: templates.header && _.templatify(templates.header),
footer: templates.footer && _.templatify(templates.footer), footer: templates.footer && _.templatify(templates.footer),
suggestion: templates.suggestion || suggestionTemplate suggestion: templates.suggestion ? userSuggestionTemplate : suggestionTemplate
}; };
function userSuggestionTemplate(context) {
var template = templates.suggestion;
return $(template(context)).attr("id", _.guid());
}
function suggestionTemplate(context) { function suggestionTemplate(context) {
return $("<div>").text(displayFn(context)); return $('<div role="option">').attr("id", _.guid()).text(displayFn(context));
} }
} }
function isValidName(str) { function isValidName(str) {
@ -884,10 +953,11 @@
this.trigger.apply(this, arguments); this.trigger.apply(this, arguments);
}, },
_allDatasetsEmpty: function allDatasetsEmpty() { _allDatasetsEmpty: function allDatasetsEmpty() {
return _.every(this.datasets, isDatasetEmpty); return _.every(this.datasets, _.bind(function isDatasetEmpty(dataset) {
function isDatasetEmpty(dataset) { var isEmpty = dataset.isEmpty();
return dataset.isEmpty(); this.$node.attr("aria-expanded", !isEmpty);
} return isEmpty;
}, this));
}, },
_getSelectables: function getSelectables() { _getSelectables: function getSelectables() {
return this.$node.find(this.selectors.selectable); return this.$node.find(this.selectors.selectable);
@ -912,6 +982,12 @@
var that = this, onSelectableClick; var that = this, onSelectableClick;
onSelectableClick = _.bind(this._onSelectableClick, this); onSelectableClick = _.bind(this._onSelectableClick, this);
this.$node.on("click.tt", this.selectors.selectable, onSelectableClick); this.$node.on("click.tt", this.selectors.selectable, onSelectableClick);
this.$node.on("mouseover", this.selectors.selectable, function() {
that.setCursor($(this));
});
this.$node.on("mouseleave", function() {
that._removeCursor();
});
_.each(this.datasets, function(dataset) { _.each(this.datasets, function(dataset) {
dataset.onSync("asyncRequested", that._propagate, that).onSync("asyncCanceled", that._propagate, that).onSync("asyncReceived", that._propagate, that).onSync("rendered", that._onRendered, that).onSync("cleared", that._onCleared, that); dataset.onSync("asyncRequested", that._propagate, that).onSync("asyncCanceled", that._propagate, that).onSync("asyncReceived", that._propagate, that).onSync("rendered", that._onRendered, that).onSync("cleared", that._onCleared, that);
}); });
@ -921,9 +997,11 @@
return this.$node.hasClass(this.classes.open); return this.$node.hasClass(this.classes.open);
}, },
open: function open() { open: function open() {
this.$node.scrollTop(0);
this.$node.addClass(this.classes.open); this.$node.addClass(this.classes.open);
}, },
close: function close() { close: function close() {
this.$node.attr("aria-expanded", false);
this.$node.removeClass(this.classes.open); this.$node.removeClass(this.classes.open);
this._removeCursor(); this._removeCursor();
}, },
@ -988,6 +1066,55 @@
}); });
return Menu; return Menu;
}(); }();
var Status = function() {
"use strict";
function Status(options) {
this.$el = $("<span></span>", {
role: "status",
"aria-live": "polite"
}).css({
position: "absolute",
padding: "0",
border: "0",
height: "1px",
width: "1px",
"margin-bottom": "-1px",
"margin-right": "-1px",
overflow: "hidden",
clip: "rect(0 0 0 0)",
"white-space": "nowrap"
});
options.$input.after(this.$el);
_.each(options.menu.datasets, _.bind(function(dataset) {
if (dataset.onSync) {
dataset.onSync("rendered", _.bind(this.update, this));
dataset.onSync("cleared", _.bind(this.cleared, this));
}
}, this));
}
_.mixin(Status.prototype, {
update: function update(event, suggestions) {
var length = suggestions.length;
var words;
if (length === 1) {
words = {
result: "result",
is: "is"
};
} else {
words = {
result: "results",
is: "are"
};
}
this.$el.text(length + " " + words.result + " " + words.is + " available, use up and down arrow keys to navigate.");
},
cleared: function() {
this.$el.text("");
}
});
return Status;
}();
var DefaultMenu = function() { var DefaultMenu = function() {
"use strict"; "use strict";
var s = Menu.prototype; var s = Menu.prototype;
@ -1052,6 +1179,7 @@
this.input = o.input; this.input = o.input;
this.menu = o.menu; this.menu = o.menu;
this.enabled = true; this.enabled = true;
this.autoselect = !!o.autoselect;
this.active = false; this.active = false;
this.input.hasFocus() && this.activate(); this.input.hasFocus() && this.activate();
this.dir = this.input.getLangDir(); this.dir = this.input.getLangDir();
@ -1098,8 +1226,12 @@
_onDatasetCleared: function onDatasetCleared() { _onDatasetCleared: function onDatasetCleared() {
this._updateHint(); this._updateHint();
}, },
_onDatasetRendered: function onDatasetRendered(type, dataset, suggestions, async) { _onDatasetRendered: function onDatasetRendered(type, suggestions, async, dataset) {
this._updateHint(); this._updateHint();
if (this.autoselect) {
var cursorClass = this.selectors.cursor.substr(1);
this.menu.$node.find(this.selectors.suggestion).first().addClass(cursorClass);
}
this.eventBus.trigger("render", suggestions, async, dataset); this.eventBus.trigger("render", suggestions, async, dataset);
}, },
_onAsyncRequested: function onAsyncRequested(type, dataset, query) { _onAsyncRequested: function onAsyncRequested(type, dataset, query) {
@ -1122,15 +1254,25 @@
_onEnterKeyed: function onEnterKeyed(type, $e) { _onEnterKeyed: function onEnterKeyed(type, $e) {
var $selectable; var $selectable;
if ($selectable = this.menu.getActiveSelectable()) { if ($selectable = this.menu.getActiveSelectable()) {
this.select($selectable) && $e.preventDefault(); if (this.select($selectable)) {
$e.preventDefault();
$e.stopPropagation();
}
} else if (this.autoselect) {
if (this.select(this.menu.getTopSelectable())) {
$e.preventDefault();
$e.stopPropagation();
}
} }
}, },
_onTabKeyed: function onTabKeyed(type, $e) { _onTabKeyed: function onTabKeyed(type, $e) {
var $selectable; var $selectable;
if ($selectable = this.menu.getActiveSelectable()) { if ($selectable = this.menu.getActiveSelectable()) {
this.select($selectable) && $e.preventDefault(); this.select($selectable) && $e.preventDefault();
} else if ($selectable = this.menu.getTopSelectable()) { } else if (this.autoselect) {
this.autocomplete($selectable) && $e.preventDefault(); if ($selectable = this.menu.getTopSelectable()) {
this.autocomplete($selectable) && $e.preventDefault();
}
} }
}, },
_onEscKeyed: function onEscKeyed() { _onEscKeyed: function onEscKeyed() {
@ -1144,12 +1286,12 @@
}, },
_onLeftKeyed: function onLeftKeyed() { _onLeftKeyed: function onLeftKeyed() {
if (this.dir === "rtl" && this.input.isCursorAtEnd()) { if (this.dir === "rtl" && this.input.isCursorAtEnd()) {
this.autocomplete(this.menu.getTopSelectable()); this.autocomplete(this.menu.getActiveSelectable() || this.menu.getTopSelectable());
} }
}, },
_onRightKeyed: function onRightKeyed() { _onRightKeyed: function onRightKeyed() {
if (this.dir === "ltr" && this.input.isCursorAtEnd()) { if (this.dir === "ltr" && this.input.isCursorAtEnd()) {
this.autocomplete(this.menu.getTopSelectable()); this.autocomplete(this.menu.getActiveSelectable() || this.menu.getTopSelectable());
} }
}, },
_onQueryChanged: function onQueryChanged(e, query) { _onQueryChanged: function onQueryChanged(e, query) {
@ -1226,6 +1368,7 @@
}, },
open: function open() { open: function open() {
if (!this.isOpen() && !this.eventBus.before("open")) { if (!this.isOpen() && !this.eventBus.before("open")) {
this.input.setAriaExpanded(true);
this.menu.open(); this.menu.open();
this._updateHint(); this._updateHint();
this.eventBus.trigger("open"); this.eventBus.trigger("open");
@ -1234,6 +1377,7 @@
}, },
close: function close() { close: function close() {
if (this.isOpen() && !this.eventBus.before("close")) { if (this.isOpen() && !this.eventBus.before("close")) {
this.input.setAriaExpanded(false);
this.menu.close(); this.menu.close();
this.input.clearHint(); this.input.clearHint();
this.input.resetInputValue(); this.input.resetInputValue();
@ -1249,9 +1393,9 @@
}, },
select: function select($selectable) { select: function select($selectable) {
var data = this.menu.getSelectableData($selectable); var data = this.menu.getSelectableData($selectable);
if (data && !this.eventBus.before("select", data.obj)) { if (data && !this.eventBus.before("select", data.obj, data.dataset)) {
this.input.setQuery(data.val, true); this.input.setQuery(data.val, true);
this.eventBus.trigger("select", data.obj); this.eventBus.trigger("select", data.obj, data.dataset);
this.close(); this.close();
return true; return true;
} }
@ -1262,29 +1406,34 @@
query = this.input.getQuery(); query = this.input.getQuery();
data = this.menu.getSelectableData($selectable); data = this.menu.getSelectableData($selectable);
isValid = data && query !== data.val; isValid = data && query !== data.val;
if (isValid && !this.eventBus.before("autocomplete", data.obj)) { if (isValid && !this.eventBus.before("autocomplete", data.obj, data.dataset)) {
this.input.setQuery(data.val); this.input.setQuery(data.val);
this.eventBus.trigger("autocomplete", data.obj); this.eventBus.trigger("autocomplete", data.obj, data.dataset);
return true; return true;
} }
return false; return false;
}, },
moveCursor: function moveCursor(delta) { moveCursor: function moveCursor(delta) {
var query, $candidate, data, payload, cancelMove; var query, $candidate, data, suggestion, datasetName, cancelMove, id;
query = this.input.getQuery(); query = this.input.getQuery();
$candidate = this.menu.selectableRelativeToCursor(delta); $candidate = this.menu.selectableRelativeToCursor(delta);
data = this.menu.getSelectableData($candidate); data = this.menu.getSelectableData($candidate);
payload = data ? data.obj : null; suggestion = data ? data.obj : null;
datasetName = data ? data.dataset : null;
id = $candidate ? $candidate.attr("id") : null;
this.input.trigger("cursorchange", id);
cancelMove = this._minLengthMet() && this.menu.update(query); cancelMove = this._minLengthMet() && this.menu.update(query);
if (!cancelMove && !this.eventBus.before("cursorchange", payload)) { if (!cancelMove && !this.eventBus.before("cursorchange", suggestion, datasetName)) {
this.menu.setCursor($candidate); this.menu.setCursor($candidate);
if (data) { if (data) {
this.input.setInputValue(data.val); if (typeof data.val === "string") {
this.input.setInputValue(data.val);
}
} else { } else {
this.input.resetInputValue(); this.input.resetInputValue();
this._updateHint(); this._updateHint();
} }
this.eventBus.trigger("cursorchange", payload); this.eventBus.trigger("cursorchange", suggestion, datasetName);
return true; return true;
} }
return false; return false;
@ -1322,7 +1471,7 @@
www = WWW(o.classNames); www = WWW(o.classNames);
return this.each(attach); return this.each(attach);
function attach() { function attach() {
var $input, $wrapper, $hint, $menu, defaultHint, defaultMenu, eventBus, input, menu, typeahead, MenuConstructor; var $input, $wrapper, $hint, $menu, defaultHint, defaultMenu, eventBus, input, menu, status, typeahead, MenuConstructor;
_.each(datasets, function(d) { _.each(datasets, function(d) {
d.highlight = !!o.highlight; d.highlight = !!o.highlight;
}); });
@ -1347,17 +1496,23 @@
}); });
input = new Input({ input = new Input({
hint: $hint, hint: $hint,
input: $input input: $input,
menu: $menu
}, www); }, www);
menu = new MenuConstructor({ menu = new MenuConstructor({
node: $menu, node: $menu,
datasets: datasets datasets: datasets
}, www); }, www);
status = new Status({
$input: $input,
menu: menu
});
typeahead = new Typeahead({ typeahead = new Typeahead({
input: input, input: input,
menu: menu, menu: menu,
eventBus: eventBus, eventBus: eventBus,
minLength: o.minLength minLength: o.minLength,
autoselect: o.autoselect
}, www); }, www);
$input.data(keys.www, www); $input.data(keys.www, www);
$input.data(keys.typeahead, typeahead); $input.data(keys.typeahead, typeahead);
@ -1450,7 +1605,7 @@
return query; return query;
} else { } else {
ttEach(this, function(t) { ttEach(this, function(t) {
t.setVal(newVal); t.setVal(_.toStr(newVal));
}); });
return this; return this;
} }
@ -1481,8 +1636,10 @@
}); });
} }
function buildHintFromInput($input, www) { function buildHintFromInput($input, www) {
return $input.clone().addClass(www.classes.hint).removeData().css(www.css.hint).css(getBackgroundStyles($input)).prop("readonly", true).removeAttr("id name placeholder required").attr({ return $input.clone().addClass(www.classes.hint).removeData().css(www.css.hint).css(getBackgroundStyles($input)).prop({
autocomplete: "off", readonly: true,
required: false
}).removeAttr("id name placeholder").removeClass("required").attr({
spellcheck: "false", spellcheck: "false",
tabindex: -1 tabindex: -1
}); });
@ -1495,7 +1652,6 @@
style: $input.attr("style") style: $input.attr("style")
}); });
$input.addClass(www.classes.input).attr({ $input.addClass(www.classes.input).attr({
autocomplete: "off",
spellcheck: false spellcheck: false
}); });
try { try {

File diff suppressed because one or more lines are too long

View File

@ -13,9 +13,9 @@
{% endfor %} {% endfor %}
</select> </select>
</td> </td>
<td style="position: relative;"> <td>
<input autocomplete="off" type="text" value="{{ oldValue }}" name="triggers[{{ count }}][value]"
<input autocomplete="off" type="text" value="{{ oldValue }}" name="triggers[{{ count }}][value]" class="form-control"> class="form-control">
{% if errors.has('triggers.'~count~'.value') %} {% if errors.has('triggers.'~count~'.value') %}
<p class="text-danger"> <p class="text-danger">
{{ errors.first('triggers.'~count~'.value') }} {{ errors.first('triggers.'~count~'.value') }}