summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorElliot Smith <elliot.smith@intel.com>2016-04-18 16:59:05 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-06-15 08:35:03 +0100
commit79e0eb9e52e9b954aa3b6bc6dee15a75b5eb990c (patch)
tree877e2062bf18fe0fe659baa16b6493c468c13fe6
parentcd7b48cd0da27f415194d3aaeb330ba6eb7d5d9d (diff)
downloadpoky-79e0eb9e52e9b954aa3b6bc6dee15a75b5eb990c.tar.gz
bitbake: toaster: work-around our lack of a synchronous fetch for typeaheads
The Twitter typeahead.js library expects the developer to use a source which does a local search for matching suggestions, then falls back to a remote search if that doesn't return enough results. However, in Toaster, we don't do any caching of the suggestions for a typeahead, so our source only works in asynchronous mode. Consequently, we see fewer than the expected number of suggestions if the typeahead has already shown suggestions matching a query. For example, searching for "meta-n" in the layers typeahead will show the results for this query; but when the query changes to "meta-ne", a new set of results is fetched, which mostly overlaps with the results for "meta-n". The typeahead assumes that the overlapping items are locally cached and have been delivered synchronously, and just appends the new results which don't overlap with the previous query. But because we don't provide any results synchronously, we just end up with the single non-overlapping result in the drop-down. This can be fixed by hacking typeahead.js so that instead of appending asynchronous results, we always overwrite and redraw the whole typeahead menu. This is a temporary fix, and should be properly fixed (when we have time), perhaps by using typeahead.js's associated Bloodhound library. Added a note about the hack to the license file as an explanation of why the unminified JS file is included in Toaster. (Bitbake rev: afbaf326e1123c92952fa71e0e820a4ff83488ca) Signed-off-by: Elliot Smith <elliot.smith@intel.com> Signed-off-by: Michael Wood <michael.g.wood@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--bitbake/LICENSE2
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/typeahead.jquery.js1551
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/typeahead.jquery.min.js7
-rw-r--r--bitbake/lib/toaster/toastergui/templates/base.html2
4 files changed, 1553 insertions, 9 deletions
diff --git a/bitbake/LICENSE b/bitbake/LICENSE
index 4ceabf7a73..0a6905e94e 100644
--- a/bitbake/LICENSE
+++ b/bitbake/LICENSE
@@ -9,6 +9,6 @@ Foundation and individual contributors.
9 9
10* jQuery is redistributed under the MIT license. 10* jQuery is redistributed under the MIT license.
11 11
12* Twitter typeahead.js redistributed under the MIT license. 12* Twitter typeahead.js redistributed under the MIT license. Note that the JS source has one small modification, so the full unminified file is currently included to make it obvious where this is.
13 13
14* QUnit is redistributed under the MIT license. 14* QUnit is redistributed under the MIT license.
diff --git a/bitbake/lib/toaster/toastergui/static/js/typeahead.jquery.js b/bitbake/lib/toaster/toastergui/static/js/typeahead.jquery.js
new file mode 100644
index 0000000000..f3efd80cb3
--- /dev/null
+++ b/bitbake/lib/toaster/toastergui/static/js/typeahead.jquery.js
@@ -0,0 +1,1551 @@
1/*!
2 * typeahead.js 0.11.1
3 * https://github.com/twitter/typeahead.js
4 * Copyright 2013-2015 Twitter, Inc. and other contributors; Licensed MIT
5 */
6
7(function(root, factory) {
8 if (typeof define === "function" && define.amd) {
9 define("typeahead.js", [ "jquery" ], function(a0) {
10 return factory(a0);
11 });
12 } else if (typeof exports === "object") {
13 module.exports = factory(require("jquery"));
14 } else {
15 factory(jQuery);
16 }
17})(this, function($) {
18 var _ = function() {
19 "use strict";
20 return {
21 isMsie: function() {
22 return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false;
23 },
24 isBlankString: function(str) {
25 return !str || /^\s*$/.test(str);
26 },
27 escapeRegExChars: function(str) {
28 return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
29 },
30 isString: function(obj) {
31 return typeof obj === "string";
32 },
33 isNumber: function(obj) {
34 return typeof obj === "number";
35 },
36 isArray: $.isArray,
37 isFunction: $.isFunction,
38 isObject: $.isPlainObject,
39 isUndefined: function(obj) {
40 return typeof obj === "undefined";
41 },
42 isElement: function(obj) {
43 return !!(obj && obj.nodeType === 1);
44 },
45 isJQuery: function(obj) {
46 return obj instanceof $;
47 },
48 toStr: function toStr(s) {
49 return _.isUndefined(s) || s === null ? "" : s + "";
50 },
51 bind: $.proxy,
52 each: function(collection, cb) {
53 $.each(collection, reverseArgs);
54 function reverseArgs(index, value) {
55 return cb(value, index);
56 }
57 },
58 map: $.map,
59 filter: $.grep,
60 every: function(obj, test) {
61 var result = true;
62 if (!obj) {
63 return result;
64 }
65 $.each(obj, function(key, val) {
66 if (!(result = test.call(null, val, key, obj))) {
67 return false;
68 }
69 });
70 return !!result;
71 },
72 some: function(obj, test) {
73 var result = false;
74 if (!obj) {
75 return result;
76 }
77 $.each(obj, function(key, val) {
78 if (result = test.call(null, val, key, obj)) {
79 return false;
80 }
81 });
82 return !!result;
83 },
84 mixin: $.extend,
85 identity: function(x) {
86 return x;
87 },
88 clone: function(obj) {
89 return $.extend(true, {}, obj);
90 },
91 getIdGenerator: function() {
92 var counter = 0;
93 return function() {
94 return counter++;
95 };
96 },
97 templatify: function templatify(obj) {
98 return $.isFunction(obj) ? obj : template;
99 function template() {
100 return String(obj);
101 }
102 },
103 defer: function(fn) {
104 setTimeout(fn, 0);
105 },
106 debounce: function(func, wait, immediate) {
107 var timeout, result;
108 return function() {
109 var context = this, args = arguments, later, callNow;
110 later = function() {
111 timeout = null;
112 if (!immediate) {
113 result = func.apply(context, args);
114 }
115 };
116 callNow = immediate && !timeout;
117 clearTimeout(timeout);
118 timeout = setTimeout(later, wait);
119 if (callNow) {
120 result = func.apply(context, args);
121 }
122 return result;
123 };
124 },
125 throttle: function(func, wait) {
126 var context, args, timeout, result, previous, later;
127 previous = 0;
128 later = function() {
129 previous = new Date();
130 timeout = null;
131 result = func.apply(context, args);
132 };
133 return function() {
134 var now = new Date(), remaining = wait - (now - previous);
135 context = this;
136 args = arguments;
137 if (remaining <= 0) {
138 clearTimeout(timeout);
139 timeout = null;
140 previous = now;
141 result = func.apply(context, args);
142 } else if (!timeout) {
143 timeout = setTimeout(later, remaining);
144 }
145 return result;
146 };
147 },
148 stringify: function(val) {
149 return _.isString(val) ? val : JSON.stringify(val);
150 },
151 noop: function() {}
152 };
153 }();
154 var WWW = function() {
155 "use strict";
156 var defaultClassNames = {
157 wrapper: "twitter-typeahead",
158 input: "tt-input",
159 hint: "tt-hint",
160 menu: "tt-menu",
161 dataset: "tt-dataset",
162 suggestion: "tt-suggestion",
163 selectable: "tt-selectable",
164 empty: "tt-empty",
165 open: "tt-open",
166 cursor: "tt-cursor",
167 highlight: "tt-highlight"
168 };
169 return build;
170 function build(o) {
171 var www, classes;
172 classes = _.mixin({}, defaultClassNames, o);
173 www = {
174 css: buildCss(),
175 classes: classes,
176 html: buildHtml(classes),
177 selectors: buildSelectors(classes)
178 };
179 return {
180 css: www.css,
181 html: www.html,
182 classes: www.classes,
183 selectors: www.selectors,
184 mixin: function(o) {
185 _.mixin(o, www);
186 }
187 };
188 }
189 function buildHtml(c) {
190 return {
191 wrapper: '<span class="' + c.wrapper + '"></span>',
192 menu: '<div class="' + c.menu + '"></div>'
193 };
194 }
195 function buildSelectors(classes) {
196 var selectors = {};
197 _.each(classes, function(v, k) {
198 selectors[k] = "." + v;
199 });
200 return selectors;
201 }
202 function buildCss() {
203 var css = {
204 wrapper: {
205 position: "relative",
206 display: "inline-block"
207 },
208 hint: {
209 position: "absolute",
210 top: "0",
211 left: "0",
212 borderColor: "transparent",
213 boxShadow: "none",
214 opacity: "1"
215 },
216 input: {
217 position: "relative",
218 verticalAlign: "top",
219 backgroundColor: "transparent"
220 },
221 inputWithNoHint: {
222 position: "relative",
223 verticalAlign: "top"
224 },
225 menu: {
226 position: "absolute",
227 top: "100%",
228 left: "0",
229 zIndex: "100",
230 display: "none"
231 },
232 ltr: {
233 left: "0",
234 right: "auto"
235 },
236 rtl: {
237 left: "auto",
238 right: " 0"
239 }
240 };
241 if (_.isMsie()) {
242 _.mixin(css.input, {
243 backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"
244 });
245 }
246 return css;
247 }
248 }();
249 var EventBus = function() {
250 "use strict";
251 var namespace, deprecationMap;
252 namespace = "typeahead:";
253 deprecationMap = {
254 render: "rendered",
255 cursorchange: "cursorchanged",
256 select: "selected",
257 autocomplete: "autocompleted"
258 };
259 function EventBus(o) {
260 if (!o || !o.el) {
261 $.error("EventBus initialized without el");
262 }
263 this.$el = $(o.el);
264 }
265 _.mixin(EventBus.prototype, {
266 _trigger: function(type, args) {
267 var $e;
268 $e = $.Event(namespace + type);
269 (args = args || []).unshift($e);
270 this.$el.trigger.apply(this.$el, args);
271 return $e;
272 },
273 before: function(type) {
274 var args, $e;
275 args = [].slice.call(arguments, 1);
276 $e = this._trigger("before" + type, args);
277 return $e.isDefaultPrevented();
278 },
279 trigger: function(type) {
280 var deprecatedType;
281 this._trigger(type, [].slice.call(arguments, 1));
282 if (deprecatedType = deprecationMap[type]) {
283 this._trigger(deprecatedType, [].slice.call(arguments, 1));
284 }
285 }
286 });
287 return EventBus;
288 }();
289 var EventEmitter = function() {
290 "use strict";
291 var splitter = /\s+/, nextTick = getNextTick();
292 return {
293 onSync: onSync,
294 onAsync: onAsync,
295 off: off,
296 trigger: trigger
297 };
298 function on(method, types, cb, context) {
299 var type;
300 if (!cb) {
301 return this;
302 }
303 types = types.split(splitter);
304 cb = context ? bindContext(cb, context) : cb;
305 this._callbacks = this._callbacks || {};
306 while (type = types.shift()) {
307 this._callbacks[type] = this._callbacks[type] || {
308 sync: [],
309 async: []
310 };
311 this._callbacks[type][method].push(cb);
312 }
313 return this;
314 }
315 function onAsync(types, cb, context) {
316 return on.call(this, "async", types, cb, context);
317 }
318 function onSync(types, cb, context) {
319 return on.call(this, "sync", types, cb, context);
320 }
321 function off(types) {
322 var type;
323 if (!this._callbacks) {
324 return this;
325 }
326 types = types.split(splitter);
327 while (type = types.shift()) {
328 delete this._callbacks[type];
329 }
330 return this;
331 }
332 function trigger(types) {
333 var type, callbacks, args, syncFlush, asyncFlush;
334 if (!this._callbacks) {
335 return this;
336 }
337 types = types.split(splitter);
338 args = [].slice.call(arguments, 1);
339 while ((type = types.shift()) && (callbacks = this._callbacks[type])) {
340 syncFlush = getFlush(callbacks.sync, this, [ type ].concat(args));
341 asyncFlush = getFlush(callbacks.async, this, [ type ].concat(args));
342 syncFlush() && nextTick(asyncFlush);
343 }
344 return this;
345 }
346 function getFlush(callbacks, context, args) {
347 return flush;
348 function flush() {
349 var cancelled;
350 for (var i = 0, len = callbacks.length; !cancelled && i < len; i += 1) {
351 cancelled = callbacks[i].apply(context, args) === false;
352 }
353 return !cancelled;
354 }
355 }
356 function getNextTick() {
357 var nextTickFn;
358 if (window.setImmediate) {
359 nextTickFn = function nextTickSetImmediate(fn) {
360 setImmediate(function() {
361 fn();
362 });
363 };
364 } else {
365 nextTickFn = function nextTickSetTimeout(fn) {
366 setTimeout(function() {
367 fn();
368 }, 0);
369 };
370 }
371 return nextTickFn;
372 }
373 function bindContext(fn, context) {
374 return fn.bind ? fn.bind(context) : function() {
375 fn.apply(context, [].slice.call(arguments, 0));
376 };
377 }
378 }();
379 var highlight = function(doc) {
380 "use strict";
381 var defaults = {
382 node: null,
383 pattern: null,
384 tagName: "strong",
385 className: null,
386 wordsOnly: false,
387 caseSensitive: false
388 };
389 return function hightlight(o) {
390 var regex;
391 o = _.mixin({}, defaults, o);
392 if (!o.node || !o.pattern) {
393 return;
394 }
395 o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ];
396 regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly);
397 traverse(o.node, hightlightTextNode);
398 function hightlightTextNode(textNode) {
399 var match, patternNode, wrapperNode;
400 if (match = regex.exec(textNode.data)) {
401 wrapperNode = doc.createElement(o.tagName);
402 o.className && (wrapperNode.className = o.className);
403 patternNode = textNode.splitText(match.index);
404 patternNode.splitText(match[0].length);
405 wrapperNode.appendChild(patternNode.cloneNode(true));
406 textNode.parentNode.replaceChild(wrapperNode, patternNode);
407 }
408 return !!match;
409 }
410 function traverse(el, hightlightTextNode) {
411 var childNode, TEXT_NODE_TYPE = 3;
412 for (var i = 0; i < el.childNodes.length; i++) {
413 childNode = el.childNodes[i];
414 if (childNode.nodeType === TEXT_NODE_TYPE) {
415 i += hightlightTextNode(childNode) ? 1 : 0;
416 } else {
417 traverse(childNode, hightlightTextNode);
418 }
419 }
420 }
421 };
422 function getRegex(patterns, caseSensitive, wordsOnly) {
423 var escapedPatterns = [], regexStr;
424 for (var i = 0, len = patterns.length; i < len; i++) {
425 escapedPatterns.push(_.escapeRegExChars(patterns[i]));
426 }
427 regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")";
428 return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i");
429 }
430 }(window.document);
431 var Input = function() {
432 "use strict";
433 var specialKeyCodeMap;
434 specialKeyCodeMap = {
435 9: "tab",
436 27: "esc",
437 37: "left",
438 39: "right",
439 13: "enter",
440 38: "up",
441 40: "down"
442 };
443 function Input(o, www) {
444 o = o || {};
445 if (!o.input) {
446 $.error("input is missing");
447 }
448 www.mixin(this);
449 this.$hint = $(o.hint);
450 this.$input = $(o.input);
451 this.query = this.$input.val();
452 this.queryWhenFocused = this.hasFocus() ? this.query : null;
453 this.$overflowHelper = buildOverflowHelper(this.$input);
454 this._checkLanguageDirection();
455 if (this.$hint.length === 0) {
456 this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop;
457 }
458 }
459 Input.normalizeQuery = function(str) {
460 return _.toStr(str).replace(/^\s*/g, "").replace(/\s{2,}/g, " ");
461 };
462 _.mixin(Input.prototype, EventEmitter, {
463 _onBlur: function onBlur() {
464 this.resetInputValue();
465 this.trigger("blurred");
466 },
467 _onFocus: function onFocus() {
468 this.queryWhenFocused = this.query;
469 this.trigger("focused");
470 },
471 _onKeydown: function onKeydown($e) {
472 var keyName = specialKeyCodeMap[$e.which || $e.keyCode];
473 this._managePreventDefault(keyName, $e);
474 if (keyName && this._shouldTrigger(keyName, $e)) {
475 this.trigger(keyName + "Keyed", $e);
476 }
477 },
478 _onInput: function onInput() {
479 this._setQuery(this.getInputValue());
480 this.clearHintIfInvalid();
481 this._checkLanguageDirection();
482 },
483 _managePreventDefault: function managePreventDefault(keyName, $e) {
484 var preventDefault;
485 switch (keyName) {
486 case "up":
487 case "down":
488 preventDefault = !withModifier($e);
489 break;
490
491 default:
492 preventDefault = false;
493 }
494 preventDefault && $e.preventDefault();
495 },
496 _shouldTrigger: function shouldTrigger(keyName, $e) {
497 var trigger;
498 switch (keyName) {
499 case "tab":
500 trigger = !withModifier($e);
501 break;
502
503 default:
504 trigger = true;
505 }
506 return trigger;
507 },
508 _checkLanguageDirection: function checkLanguageDirection() {
509 var dir = (this.$input.css("direction") || "ltr").toLowerCase();
510 if (this.dir !== dir) {
511 this.dir = dir;
512 this.$hint.attr("dir", dir);
513 this.trigger("langDirChanged", dir);
514 }
515 },
516 _setQuery: function setQuery(val, silent) {
517 var areEquivalent, hasDifferentWhitespace;
518 areEquivalent = areQueriesEquivalent(val, this.query);
519 hasDifferentWhitespace = areEquivalent ? this.query.length !== val.length : false;
520 this.query = val;
521 if (!silent && !areEquivalent) {
522 this.trigger("queryChanged", this.query);
523 } else if (!silent && hasDifferentWhitespace) {
524 this.trigger("whitespaceChanged", this.query);
525 }
526 },
527 bind: function() {
528 var that = this, onBlur, onFocus, onKeydown, onInput;
529 onBlur = _.bind(this._onBlur, this);
530 onFocus = _.bind(this._onFocus, this);
531 onKeydown = _.bind(this._onKeydown, this);
532 onInput = _.bind(this._onInput, this);
533 this.$input.on("blur.tt", onBlur).on("focus.tt", onFocus).on("keydown.tt", onKeydown);
534 if (!_.isMsie() || _.isMsie() > 9) {
535 this.$input.on("input.tt", onInput);
536 } else {
537 this.$input.on("keydown.tt keypress.tt cut.tt paste.tt", function($e) {
538 if (specialKeyCodeMap[$e.which || $e.keyCode]) {
539 return;
540 }
541 _.defer(_.bind(that._onInput, that, $e));
542 });
543 }
544 return this;
545 },
546 focus: function focus() {
547 this.$input.focus();
548 },
549 blur: function blur() {
550 this.$input.blur();
551 },
552 getLangDir: function getLangDir() {
553 return this.dir;
554 },
555 getQuery: function getQuery() {
556 return this.query || "";
557 },
558 setQuery: function setQuery(val, silent) {
559 this.setInputValue(val);
560 this._setQuery(val, silent);
561 },
562 hasQueryChangedSinceLastFocus: function hasQueryChangedSinceLastFocus() {
563 return this.query !== this.queryWhenFocused;
564 },
565 getInputValue: function getInputValue() {
566 return this.$input.val();
567 },
568 setInputValue: function setInputValue(value) {
569 this.$input.val(value);
570 this.clearHintIfInvalid();
571 this._checkLanguageDirection();
572 },
573 resetInputValue: function resetInputValue() {
574 this.setInputValue(this.query);
575 },
576 getHint: function getHint() {
577 return this.$hint.val();
578 },
579 setHint: function setHint(value) {
580 this.$hint.val(value);
581 },
582 clearHint: function clearHint() {
583 this.setHint("");
584 },
585 clearHintIfInvalid: function clearHintIfInvalid() {
586 var val, hint, valIsPrefixOfHint, isValid;
587 val = this.getInputValue();
588 hint = this.getHint();
589 valIsPrefixOfHint = val !== hint && hint.indexOf(val) === 0;
590 isValid = val !== "" && valIsPrefixOfHint && !this.hasOverflow();
591 !isValid && this.clearHint();
592 },
593 hasFocus: function hasFocus() {
594 return this.$input.is(":focus");
595 },
596 hasOverflow: function hasOverflow() {
597 var constraint = this.$input.width() - 2;
598 this.$overflowHelper.text(this.getInputValue());
599 return this.$overflowHelper.width() >= constraint;
600 },
601 isCursorAtEnd: function() {
602 var valueLength, selectionStart, range;
603 valueLength = this.$input.val().length;
604 selectionStart = this.$input[0].selectionStart;
605 if (_.isNumber(selectionStart)) {
606 return selectionStart === valueLength;
607 } else if (document.selection) {
608 range = document.selection.createRange();
609 range.moveStart("character", -valueLength);
610 return valueLength === range.text.length;
611 }
612 return true;
613 },
614 destroy: function destroy() {
615 this.$hint.off(".tt");
616 this.$input.off(".tt");
617 this.$overflowHelper.remove();
618 this.$hint = this.$input = this.$overflowHelper = $("<div>");
619 }
620 });
621 return Input;
622 function buildOverflowHelper($input) {
623 return $('<pre aria-hidden="true"></pre>').css({
624 position: "absolute",
625 visibility: "hidden",
626 whiteSpace: "pre",
627 fontFamily: $input.css("font-family"),
628 fontSize: $input.css("font-size"),
629 fontStyle: $input.css("font-style"),
630 fontVariant: $input.css("font-variant"),
631 fontWeight: $input.css("font-weight"),
632 wordSpacing: $input.css("word-spacing"),
633 letterSpacing: $input.css("letter-spacing"),
634 textIndent: $input.css("text-indent"),
635 textRendering: $input.css("text-rendering"),
636 textTransform: $input.css("text-transform")
637 }).insertAfter($input);
638 }
639 function areQueriesEquivalent(a, b) {
640 return Input.normalizeQuery(a) === Input.normalizeQuery(b);
641 }
642 function withModifier($e) {
643 return $e.altKey || $e.ctrlKey || $e.metaKey || $e.shiftKey;
644 }
645 }();
646 var Dataset = function() {
647 "use strict";
648 var keys, nameGenerator;
649 keys = {
650 val: "tt-selectable-display",
651 obj: "tt-selectable-object"
652 };
653 nameGenerator = _.getIdGenerator();
654 function Dataset(o, www) {
655 o = o || {};
656 o.templates = o.templates || {};
657 o.templates.notFound = o.templates.notFound || o.templates.empty;
658 if (!o.source) {
659 $.error("missing source");
660 }
661 if (!o.node) {
662 $.error("missing node");
663 }
664 if (o.name && !isValidName(o.name)) {
665 $.error("invalid dataset name: " + o.name);
666 }
667 www.mixin(this);
668 this.highlight = !!o.highlight;
669 this.name = o.name || nameGenerator();
670 this.limit = o.limit || 5;
671 this.displayFn = getDisplayFn(o.display || o.displayKey);
672 this.templates = getTemplates(o.templates, this.displayFn);
673 this.source = o.source.__ttAdapter ? o.source.__ttAdapter() : o.source;
674 this.async = _.isUndefined(o.async) ? this.source.length > 2 : !!o.async;
675 this._resetLastSuggestion();
676 this.$el = $(o.node).addClass(this.classes.dataset).addClass(this.classes.dataset + "-" + this.name);
677 }
678 Dataset.extractData = function extractData(el) {
679 var $el = $(el);
680 if ($el.data(keys.obj)) {
681 return {
682 val: $el.data(keys.val) || "",
683 obj: $el.data(keys.obj) || null
684 };
685 }
686 return null;
687 };
688 _.mixin(Dataset.prototype, EventEmitter, {
689 _overwrite: function overwrite(query, suggestions) {
690 suggestions = suggestions || [];
691 if (suggestions.length) {
692 this._renderSuggestions(query, suggestions);
693 } else if (this.async && this.templates.pending) {
694 this._renderPending(query);
695 } else if (!this.async && this.templates.notFound) {
696 this._renderNotFound(query);
697 } else {
698 this._empty();
699 }
700 this.trigger("rendered", this.name, suggestions, false);
701 },
702 _append: function append(query, suggestions) {
703 suggestions = suggestions || [];
704 if (suggestions.length && this.$lastSuggestion.length) {
705 this._appendSuggestions(query, suggestions);
706 } else if (suggestions.length) {
707 this._renderSuggestions(query, suggestions);
708 } else if (!this.$lastSuggestion.length && this.templates.notFound) {
709 this._renderNotFound(query);
710 }
711 this.trigger("rendered", this.name, suggestions, true);
712 },
713 _renderSuggestions: function renderSuggestions(query, suggestions) {
714 var $fragment;
715 $fragment = this._getSuggestionsFragment(query, suggestions);
716 this.$lastSuggestion = $fragment.children().last();
717 this.$el.html($fragment).prepend(this._getHeader(query, suggestions)).append(this._getFooter(query, suggestions));
718 },
719 _appendSuggestions: function appendSuggestions(query, suggestions) {
720 var $fragment, $lastSuggestion;
721 $fragment = this._getSuggestionsFragment(query, suggestions);
722 $lastSuggestion = $fragment.children().last();
723 this.$lastSuggestion.after($fragment);
724 this.$lastSuggestion = $lastSuggestion;
725 },
726 _renderPending: function renderPending(query) {
727 var template = this.templates.pending;
728 this._resetLastSuggestion();
729 template && this.$el.html(template({
730 query: query,
731 dataset: this.name
732 }));
733 },
734 _renderNotFound: function renderNotFound(query) {
735 var template = this.templates.notFound;
736 this._resetLastSuggestion();
737 template && this.$el.html(template({
738 query: query,
739 dataset: this.name
740 }));
741 },
742 _empty: function empty() {
743 this.$el.empty();
744 this._resetLastSuggestion();
745 },
746 _getSuggestionsFragment: function getSuggestionsFragment(query, suggestions) {
747 var that = this, fragment;
748 fragment = document.createDocumentFragment();
749 _.each(suggestions, function getSuggestionNode(suggestion) {
750 var $el, context;
751 context = that._injectQuery(query, suggestion);
752 $el = $(that.templates.suggestion(context)).data(keys.obj, suggestion).data(keys.val, that.displayFn(suggestion)).addClass(that.classes.suggestion + " " + that.classes.selectable);
753 fragment.appendChild($el[0]);
754 });
755 this.highlight && highlight({
756 className: this.classes.highlight,
757 node: fragment,
758 pattern: query
759 });
760 return $(fragment);
761 },
762 _getFooter: function getFooter(query, suggestions) {
763 return this.templates.footer ? this.templates.footer({
764 query: query,
765 suggestions: suggestions,
766 dataset: this.name
767 }) : null;
768 },
769 _getHeader: function getHeader(query, suggestions) {
770 return this.templates.header ? this.templates.header({
771 query: query,
772 suggestions: suggestions,
773 dataset: this.name
774 }) : null;
775 },
776 _resetLastSuggestion: function resetLastSuggestion() {
777 this.$lastSuggestion = $();
778 },
779 _injectQuery: function injectQuery(query, obj) {
780 return _.isObject(obj) ? _.mixin({
781 _query: query
782 }, obj) : obj;
783 },
784 update: function update(query) {
785 var that = this, canceled = false, syncCalled = false, rendered = 0;
786 this.cancel();
787 this.cancel = function cancel() {
788 canceled = true;
789 that.cancel = $.noop;
790 that.async && that.trigger("asyncCanceled", query);
791 };
792 this.source(query, sync, async);
793 !syncCalled && sync([]);
794 function sync(suggestions) {
795 if (syncCalled) {
796 return;
797 }
798 syncCalled = true;
799 suggestions = (suggestions || []).slice(0, that.limit);
800 rendered = suggestions.length;
801 that._overwrite(query, suggestions);
802 if (rendered < that.limit && that.async) {
803 that.trigger("asyncRequested", query);
804 }
805 }
806 function async(suggestions) {
807 suggestions = suggestions || [];
808 if (!canceled && rendered < that.limit) {
809 that.cancel = $.noop;
810 rendered += suggestions.length;
811
812 // HACK: because we don't have a synchronous way of
813 // retrieving results, we use the async function every
814 // time we update the drop-down; however, the typeahead
815 // does some internal book-keeping which means that we
816 // only get the additional items in the drop-down when
817 // the next set of results is fetched, instead of all
818 // of them (it appears to implicitly track which
819 // results have already been shown in the drop-down); by
820 // forcing an overwrite, we see all of the new results
821 // every time we fetch a set of suggestions
822 //that._append(query, suggestions.slice(0, that.limit - rendered));
823 that._overwrite(query, suggestions);
824
825 that.async && that.trigger("asyncReceived", query);
826 }
827 }
828 },
829 cancel: $.noop,
830 clear: function clear() {
831 this._empty();
832 this.cancel();
833 this.trigger("cleared");
834 },
835 isEmpty: function isEmpty() {
836 return this.$el.is(":empty");
837 },
838 destroy: function destroy() {
839 this.$el = $("<div>");
840 }
841 });
842 return Dataset;
843 function getDisplayFn(display) {
844 display = display || _.stringify;
845 return _.isFunction(display) ? display : displayFn;
846 function displayFn(obj) {
847 return obj[display];
848 }
849 }
850 function getTemplates(templates, displayFn) {
851 return {
852 notFound: templates.notFound && _.templatify(templates.notFound),
853 pending: templates.pending && _.templatify(templates.pending),
854 header: templates.header && _.templatify(templates.header),
855 footer: templates.footer && _.templatify(templates.footer),
856 suggestion: templates.suggestion || suggestionTemplate
857 };
858 function suggestionTemplate(context) {
859 return $("<div>").text(displayFn(context));
860 }
861 }
862 function isValidName(str) {
863 return /^[_a-zA-Z0-9-]+$/.test(str);
864 }
865 }();
866 var Menu = function() {
867 "use strict";
868 function Menu(o, www) {
869 var that = this;
870 o = o || {};
871 if (!o.node) {
872 $.error("node is required");
873 }
874 www.mixin(this);
875 this.$node = $(o.node);
876 this.query = null;
877 this.datasets = _.map(o.datasets, initializeDataset);
878 function initializeDataset(oDataset) {
879 var node = that.$node.find(oDataset.node).first();
880 oDataset.node = node.length ? node : $("<div>").appendTo(that.$node);
881 return new Dataset(oDataset, www);
882 }
883 }
884 _.mixin(Menu.prototype, EventEmitter, {
885 _onSelectableClick: function onSelectableClick($e) {
886 this.trigger("selectableClicked", $($e.currentTarget));
887 },
888 _onRendered: function onRendered(type, dataset, suggestions, async) {
889 this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty());
890 this.trigger("datasetRendered", dataset, suggestions, async);
891 },
892 _onCleared: function onCleared() {
893 this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty());
894 this.trigger("datasetCleared");
895 },
896 _propagate: function propagate() {
897 this.trigger.apply(this, arguments);
898 },
899 _allDatasetsEmpty: function allDatasetsEmpty() {
900 return _.every(this.datasets, isDatasetEmpty);
901 function isDatasetEmpty(dataset) {
902 return dataset.isEmpty();
903 }
904 },
905 _getSelectables: function getSelectables() {
906 return this.$node.find(this.selectors.selectable);
907 },
908 _removeCursor: function _removeCursor() {
909 var $selectable = this.getActiveSelectable();
910 $selectable && $selectable.removeClass(this.classes.cursor);
911 },
912 _ensureVisible: function ensureVisible($el) {
913 var elTop, elBottom, nodeScrollTop, nodeHeight;
914 elTop = $el.position().top;
915 elBottom = elTop + $el.outerHeight(true);
916 nodeScrollTop = this.$node.scrollTop();
917 nodeHeight = this.$node.height() + parseInt(this.$node.css("paddingTop"), 10) + parseInt(this.$node.css("paddingBottom"), 10);
918 if (elTop < 0) {
919 this.$node.scrollTop(nodeScrollTop + elTop);
920 } else if (nodeHeight < elBottom) {
921 this.$node.scrollTop(nodeScrollTop + (elBottom - nodeHeight));
922 }
923 },
924 bind: function() {
925 var that = this, onSelectableClick;
926 onSelectableClick = _.bind(this._onSelectableClick, this);
927 this.$node.on("click.tt", this.selectors.selectable, onSelectableClick);
928 _.each(this.datasets, function(dataset) {
929 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);
930 });
931 return this;
932 },
933 isOpen: function isOpen() {
934 return this.$node.hasClass(this.classes.open);
935 },
936 open: function open() {
937 this.$node.addClass(this.classes.open);
938 },
939 close: function close() {
940 this.$node.removeClass(this.classes.open);
941 this._removeCursor();
942 },
943 setLanguageDirection: function setLanguageDirection(dir) {
944 this.$node.attr("dir", dir);
945 },
946 selectableRelativeToCursor: function selectableRelativeToCursor(delta) {
947 var $selectables, $oldCursor, oldIndex, newIndex;
948 $oldCursor = this.getActiveSelectable();
949 $selectables = this._getSelectables();
950 oldIndex = $oldCursor ? $selectables.index($oldCursor) : -1;
951 newIndex = oldIndex + delta;
952 newIndex = (newIndex + 1) % ($selectables.length + 1) - 1;
953 newIndex = newIndex < -1 ? $selectables.length - 1 : newIndex;
954 return newIndex === -1 ? null : $selectables.eq(newIndex);
955 },
956 setCursor: function setCursor($selectable) {
957 this._removeCursor();
958 if ($selectable = $selectable && $selectable.first()) {
959 $selectable.addClass(this.classes.cursor);
960 this._ensureVisible($selectable);
961 }
962 },
963 getSelectableData: function getSelectableData($el) {
964 return $el && $el.length ? Dataset.extractData($el) : null;
965 },
966 getActiveSelectable: function getActiveSelectable() {
967 var $selectable = this._getSelectables().filter(this.selectors.cursor).first();
968 return $selectable.length ? $selectable : null;
969 },
970 getTopSelectable: function getTopSelectable() {
971 var $selectable = this._getSelectables().first();
972 return $selectable.length ? $selectable : null;
973 },
974 update: function update(query) {
975 var isValidUpdate = query !== this.query;
976 if (isValidUpdate) {
977 this.query = query;
978 _.each(this.datasets, updateDataset);
979 }
980 return isValidUpdate;
981 function updateDataset(dataset) {
982 dataset.update(query);
983 }
984 },
985 empty: function empty() {
986 _.each(this.datasets, clearDataset);
987 this.query = null;
988 this.$node.addClass(this.classes.empty);
989 function clearDataset(dataset) {
990 dataset.clear();
991 }
992 },
993 destroy: function destroy() {
994 this.$node.off(".tt");
995 this.$node = $("<div>");
996 _.each(this.datasets, destroyDataset);
997 function destroyDataset(dataset) {
998 dataset.destroy();
999 }
1000 }
1001 });
1002 return Menu;
1003 }();
1004 var DefaultMenu = function() {
1005 "use strict";
1006 var s = Menu.prototype;
1007 function DefaultMenu() {
1008 Menu.apply(this, [].slice.call(arguments, 0));
1009 }
1010 _.mixin(DefaultMenu.prototype, Menu.prototype, {
1011 open: function open() {
1012 !this._allDatasetsEmpty() && this._show();
1013 return s.open.apply(this, [].slice.call(arguments, 0));
1014 },
1015 close: function close() {
1016 this._hide();
1017 return s.close.apply(this, [].slice.call(arguments, 0));
1018 },
1019 _onRendered: function onRendered() {
1020 if (this._allDatasetsEmpty()) {
1021 this._hide();
1022 } else {
1023 this.isOpen() && this._show();
1024 }
1025 return s._onRendered.apply(this, [].slice.call(arguments, 0));
1026 },
1027 _onCleared: function onCleared() {
1028 if (this._allDatasetsEmpty()) {
1029 this._hide();
1030 } else {
1031 this.isOpen() && this._show();
1032 }
1033 return s._onCleared.apply(this, [].slice.call(arguments, 0));
1034 },
1035 setLanguageDirection: function setLanguageDirection(dir) {
1036 this.$node.css(dir === "ltr" ? this.css.ltr : this.css.rtl);
1037 return s.setLanguageDirection.apply(this, [].slice.call(arguments, 0));
1038 },
1039 _hide: function hide() {
1040 this.$node.hide();
1041 },
1042 _show: function show() {
1043 this.$node.css("display", "block");
1044 }
1045 });
1046 return DefaultMenu;
1047 }();
1048 var Typeahead = function() {
1049 "use strict";
1050 function Typeahead(o, www) {
1051 var onFocused, onBlurred, onEnterKeyed, onTabKeyed, onEscKeyed, onUpKeyed, onDownKeyed, onLeftKeyed, onRightKeyed, onQueryChanged, onWhitespaceChanged;
1052 o = o || {};
1053 if (!o.input) {
1054 $.error("missing input");
1055 }
1056 if (!o.menu) {
1057 $.error("missing menu");
1058 }
1059 if (!o.eventBus) {
1060 $.error("missing event bus");
1061 }
1062 www.mixin(this);
1063 this.eventBus = o.eventBus;
1064 this.minLength = _.isNumber(o.minLength) ? o.minLength : 1;
1065 this.input = o.input;
1066 this.menu = o.menu;
1067 this.enabled = true;
1068 this.active = false;
1069 this.input.hasFocus() && this.activate();
1070 this.dir = this.input.getLangDir();
1071 this._hacks();
1072 this.menu.bind().onSync("selectableClicked", this._onSelectableClicked, this).onSync("asyncRequested", this._onAsyncRequested, this).onSync("asyncCanceled", this._onAsyncCanceled, this).onSync("asyncReceived", this._onAsyncReceived, this).onSync("datasetRendered", this._onDatasetRendered, this).onSync("datasetCleared", this._onDatasetCleared, this);
1073 onFocused = c(this, "activate", "open", "_onFocused");
1074 onBlurred = c(this, "deactivate", "_onBlurred");
1075 onEnterKeyed = c(this, "isActive", "isOpen", "_onEnterKeyed");
1076 onTabKeyed = c(this, "isActive", "isOpen", "_onTabKeyed");
1077 onEscKeyed = c(this, "isActive", "_onEscKeyed");
1078 onUpKeyed = c(this, "isActive", "open", "_onUpKeyed");
1079 onDownKeyed = c(this, "isActive", "open", "_onDownKeyed");
1080 onLeftKeyed = c(this, "isActive", "isOpen", "_onLeftKeyed");
1081 onRightKeyed = c(this, "isActive", "isOpen", "_onRightKeyed");
1082 onQueryChanged = c(this, "_openIfActive", "_onQueryChanged");
1083 onWhitespaceChanged = c(this, "_openIfActive", "_onWhitespaceChanged");
1084 this.input.bind().onSync("focused", onFocused, this).onSync("blurred", onBlurred, this).onSync("enterKeyed", onEnterKeyed, this).onSync("tabKeyed", onTabKeyed, this).onSync("escKeyed", onEscKeyed, this).onSync("upKeyed", onUpKeyed, this).onSync("downKeyed", onDownKeyed, this).onSync("leftKeyed", onLeftKeyed, this).onSync("rightKeyed", onRightKeyed, this).onSync("queryChanged", onQueryChanged, this).onSync("whitespaceChanged", onWhitespaceChanged, this).onSync("langDirChanged", this._onLangDirChanged, this);
1085 }
1086 _.mixin(Typeahead.prototype, {
1087 _hacks: function hacks() {
1088 var $input, $menu;
1089 $input = this.input.$input || $("<div>");
1090 $menu = this.menu.$node || $("<div>");
1091 $input.on("blur.tt", function($e) {
1092 var active, isActive, hasActive;
1093 active = document.activeElement;
1094 isActive = $menu.is(active);
1095 hasActive = $menu.has(active).length > 0;
1096 if (_.isMsie() && (isActive || hasActive)) {
1097 $e.preventDefault();
1098 $e.stopImmediatePropagation();
1099 _.defer(function() {
1100 $input.focus();
1101 });
1102 }
1103 });
1104 $menu.on("mousedown.tt", function($e) {
1105 $e.preventDefault();
1106 });
1107 },
1108 _onSelectableClicked: function onSelectableClicked(type, $el) {
1109 this.select($el);
1110 },
1111 _onDatasetCleared: function onDatasetCleared() {
1112 this._updateHint();
1113 },
1114 _onDatasetRendered: function onDatasetRendered(type, dataset, suggestions, async) {
1115 this._updateHint();
1116 this.eventBus.trigger("render", suggestions, async, dataset);
1117 },
1118 _onAsyncRequested: function onAsyncRequested(type, dataset, query) {
1119 this.eventBus.trigger("asyncrequest", query, dataset);
1120 },
1121 _onAsyncCanceled: function onAsyncCanceled(type, dataset, query) {
1122 this.eventBus.trigger("asynccancel", query, dataset);
1123 },
1124 _onAsyncReceived: function onAsyncReceived(type, dataset, query) {
1125 this.eventBus.trigger("asyncreceive", query, dataset);
1126 },
1127 _onFocused: function onFocused() {
1128 this._minLengthMet() && this.menu.update(this.input.getQuery());
1129 },
1130 _onBlurred: function onBlurred() {
1131 if (this.input.hasQueryChangedSinceLastFocus()) {
1132 this.eventBus.trigger("change", this.input.getQuery());
1133 }
1134 },
1135 _onEnterKeyed: function onEnterKeyed(type, $e) {
1136 var $selectable;
1137 if ($selectable = this.menu.getActiveSelectable()) {
1138 this.select($selectable) && $e.preventDefault();
1139 }
1140 },
1141 _onTabKeyed: function onTabKeyed(type, $e) {
1142 var $selectable;
1143 if ($selectable = this.menu.getActiveSelectable()) {
1144 this.select($selectable) && $e.preventDefault();
1145 } else if ($selectable = this.menu.getTopSelectable()) {
1146 this.autocomplete($selectable) && $e.preventDefault();
1147 }
1148 },
1149 _onEscKeyed: function onEscKeyed() {
1150 this.close();
1151 },
1152 _onUpKeyed: function onUpKeyed() {
1153 this.moveCursor(-1);
1154 },
1155 _onDownKeyed: function onDownKeyed() {
1156 this.moveCursor(+1);
1157 },
1158 _onLeftKeyed: function onLeftKeyed() {
1159 if (this.dir === "rtl" && this.input.isCursorAtEnd()) {
1160 this.autocomplete(this.menu.getTopSelectable());
1161 }
1162 },
1163 _onRightKeyed: function onRightKeyed() {
1164 if (this.dir === "ltr" && this.input.isCursorAtEnd()) {
1165 this.autocomplete(this.menu.getTopSelectable());
1166 }
1167 },
1168 _onQueryChanged: function onQueryChanged(e, query) {
1169 this._minLengthMet(query) ? this.menu.update(query) : this.menu.empty();
1170 },
1171 _onWhitespaceChanged: function onWhitespaceChanged() {
1172 this._updateHint();
1173 },
1174 _onLangDirChanged: function onLangDirChanged(e, dir) {
1175 if (this.dir !== dir) {
1176 this.dir = dir;
1177 this.menu.setLanguageDirection(dir);
1178 }
1179 },
1180 _openIfActive: function openIfActive() {
1181 this.isActive() && this.open();
1182 },
1183 _minLengthMet: function minLengthMet(query) {
1184 query = _.isString(query) ? query : this.input.getQuery() || "";
1185 return query.length >= this.minLength;
1186 },
1187 _updateHint: function updateHint() {
1188 var $selectable, data, val, query, escapedQuery, frontMatchRegEx, match;
1189 $selectable = this.menu.getTopSelectable();
1190 data = this.menu.getSelectableData($selectable);
1191 val = this.input.getInputValue();
1192 if (data && !_.isBlankString(val) && !this.input.hasOverflow()) {
1193 query = Input.normalizeQuery(val);
1194 escapedQuery = _.escapeRegExChars(query);
1195 frontMatchRegEx = new RegExp("^(?:" + escapedQuery + ")(.+$)", "i");
1196 match = frontMatchRegEx.exec(data.val);
1197 match && this.input.setHint(val + match[1]);
1198 } else {
1199 this.input.clearHint();
1200 }
1201 },
1202 isEnabled: function isEnabled() {
1203 return this.enabled;
1204 },
1205 enable: function enable() {
1206 this.enabled = true;
1207 },
1208 disable: function disable() {
1209 this.enabled = false;
1210 },
1211 isActive: function isActive() {
1212 return this.active;
1213 },
1214 activate: function activate() {
1215 if (this.isActive()) {
1216 return true;
1217 } else if (!this.isEnabled() || this.eventBus.before("active")) {
1218 return false;
1219 } else {
1220 this.active = true;
1221 this.eventBus.trigger("active");
1222 return true;
1223 }
1224 },
1225 deactivate: function deactivate() {
1226 if (!this.isActive()) {
1227 return true;
1228 } else if (this.eventBus.before("idle")) {
1229 return false;
1230 } else {
1231 this.active = false;
1232 this.close();
1233 this.eventBus.trigger("idle");
1234 return true;
1235 }
1236 },
1237 isOpen: function isOpen() {
1238 return this.menu.isOpen();
1239 },
1240 open: function open() {
1241 if (!this.isOpen() && !this.eventBus.before("open")) {
1242 this.menu.open();
1243 this._updateHint();
1244 this.eventBus.trigger("open");
1245 }
1246 return this.isOpen();
1247 },
1248 close: function close() {
1249 if (this.isOpen() && !this.eventBus.before("close")) {
1250 this.menu.close();
1251 this.input.clearHint();
1252 this.input.resetInputValue();
1253 this.eventBus.trigger("close");
1254 }
1255 return !this.isOpen();
1256 },
1257 setVal: function setVal(val) {
1258 this.input.setQuery(_.toStr(val));
1259 },
1260 getVal: function getVal() {
1261 return this.input.getQuery();
1262 },
1263 select: function select($selectable) {
1264 var data = this.menu.getSelectableData($selectable);
1265 if (data && !this.eventBus.before("select", data.obj)) {
1266 this.input.setQuery(data.val, true);
1267 this.eventBus.trigger("select", data.obj);
1268 this.close();
1269 return true;
1270 }
1271 return false;
1272 },
1273 autocomplete: function autocomplete($selectable) {
1274 var query, data, isValid;
1275 query = this.input.getQuery();
1276 data = this.menu.getSelectableData($selectable);
1277 isValid = data && query !== data.val;
1278 if (isValid && !this.eventBus.before("autocomplete", data.obj)) {
1279 this.input.setQuery(data.val);
1280 this.eventBus.trigger("autocomplete", data.obj);
1281 return true;
1282 }
1283 return false;
1284 },
1285 moveCursor: function moveCursor(delta) {
1286 var query, $candidate, data, payload, cancelMove;
1287 query = this.input.getQuery();
1288 $candidate = this.menu.selectableRelativeToCursor(delta);
1289 data = this.menu.getSelectableData($candidate);
1290 payload = data ? data.obj : null;
1291 cancelMove = this._minLengthMet() && this.menu.update(query);
1292 if (!cancelMove && !this.eventBus.before("cursorchange", payload)) {
1293 this.menu.setCursor($candidate);
1294 if (data) {
1295 this.input.setInputValue(data.val);
1296 } else {
1297 this.input.resetInputValue();
1298 this._updateHint();
1299 }
1300 this.eventBus.trigger("cursorchange", payload);
1301 return true;
1302 }
1303 return false;
1304 },
1305 destroy: function destroy() {
1306 this.input.destroy();
1307 this.menu.destroy();
1308 }
1309 });
1310 return Typeahead;
1311 function c(ctx) {
1312 var methods = [].slice.call(arguments, 1);
1313 return function() {
1314 var args = [].slice.call(arguments);
1315 _.each(methods, function(method) {
1316 return ctx[method].apply(ctx, args);
1317 });
1318 };
1319 }
1320 }();
1321 (function() {
1322 "use strict";
1323 var old, keys, methods;
1324 old = $.fn.typeahead;
1325 keys = {
1326 www: "tt-www",
1327 attrs: "tt-attrs",
1328 typeahead: "tt-typeahead"
1329 };
1330 methods = {
1331 initialize: function initialize(o, datasets) {
1332 var www;
1333 datasets = _.isArray(datasets) ? datasets : [].slice.call(arguments, 1);
1334 o = o || {};
1335 www = WWW(o.classNames);
1336 return this.each(attach);
1337 function attach() {
1338 var $input, $wrapper, $hint, $menu, defaultHint, defaultMenu, eventBus, input, menu, typeahead, MenuConstructor;
1339 _.each(datasets, function(d) {
1340 d.highlight = !!o.highlight;
1341 });
1342 $input = $(this);
1343 $wrapper = $(www.html.wrapper);
1344 $hint = $elOrNull(o.hint);
1345 $menu = $elOrNull(o.menu);
1346 defaultHint = o.hint !== false && !$hint;
1347 defaultMenu = o.menu !== false && !$menu;
1348 defaultHint && ($hint = buildHintFromInput($input, www));
1349 defaultMenu && ($menu = $(www.html.menu).css(www.css.menu));
1350 $hint && $hint.val("");
1351 $input = prepInput($input, www);
1352 if (defaultHint || defaultMenu) {
1353 $wrapper.css(www.css.wrapper);
1354 $input.css(defaultHint ? www.css.input : www.css.inputWithNoHint);
1355 $input.wrap($wrapper).parent().prepend(defaultHint ? $hint : null).append(defaultMenu ? $menu : null);
1356 }
1357 MenuConstructor = defaultMenu ? DefaultMenu : Menu;
1358 eventBus = new EventBus({
1359 el: $input
1360 });
1361 input = new Input({
1362 hint: $hint,
1363 input: $input
1364 }, www);
1365 menu = new MenuConstructor({
1366 node: $menu,
1367 datasets: datasets
1368 }, www);
1369 typeahead = new Typeahead({
1370 input: input,
1371 menu: menu,
1372 eventBus: eventBus,
1373 minLength: o.minLength
1374 }, www);
1375 $input.data(keys.www, www);
1376 $input.data(keys.typeahead, typeahead);
1377 }
1378 },
1379 isEnabled: function isEnabled() {
1380 var enabled;
1381 ttEach(this.first(), function(t) {
1382 enabled = t.isEnabled();
1383 });
1384 return enabled;
1385 },
1386 enable: function enable() {
1387 ttEach(this, function(t) {
1388 t.enable();
1389 });
1390 return this;
1391 },
1392 disable: function disable() {
1393 ttEach(this, function(t) {
1394 t.disable();
1395 });
1396 return this;
1397 },
1398 isActive: function isActive() {
1399 var active;
1400 ttEach(this.first(), function(t) {
1401 active = t.isActive();
1402 });
1403 return active;
1404 },
1405 activate: function activate() {
1406 ttEach(this, function(t) {
1407 t.activate();
1408 });
1409 return this;
1410 },
1411 deactivate: function deactivate() {
1412 ttEach(this, function(t) {
1413 t.deactivate();
1414 });
1415 return this;
1416 },
1417 isOpen: function isOpen() {
1418 var open;
1419 ttEach(this.first(), function(t) {
1420 open = t.isOpen();
1421 });
1422 return open;
1423 },
1424 open: function open() {
1425 ttEach(this, function(t) {
1426 t.open();
1427 });
1428 return this;
1429 },
1430 close: function close() {
1431 ttEach(this, function(t) {
1432 t.close();
1433 });
1434 return this;
1435 },
1436 select: function select(el) {
1437 var success = false, $el = $(el);
1438 ttEach(this.first(), function(t) {
1439 success = t.select($el);
1440 });
1441 return success;
1442 },
1443 autocomplete: function autocomplete(el) {
1444 var success = false, $el = $(el);
1445 ttEach(this.first(), function(t) {
1446 success = t.autocomplete($el);
1447 });
1448 return success;
1449 },
1450 moveCursor: function moveCursoe(delta) {
1451 var success = false;
1452 ttEach(this.first(), function(t) {
1453 success = t.moveCursor(delta);
1454 });
1455 return success;
1456 },
1457 val: function val(newVal) {
1458 var query;
1459 if (!arguments.length) {
1460 ttEach(this.first(), function(t) {
1461 query = t.getVal();
1462 });
1463 return query;
1464 } else {
1465 ttEach(this, function(t) {
1466 t.setVal(newVal);
1467 });
1468 return this;
1469 }
1470 },
1471 destroy: function destroy() {
1472 ttEach(this, function(typeahead, $input) {
1473 revert($input);
1474 typeahead.destroy();
1475 });
1476 return this;
1477 }
1478 };
1479 $.fn.typeahead = function(method) {
1480 if (methods[method]) {
1481 return methods[method].apply(this, [].slice.call(arguments, 1));
1482 } else {
1483 return methods.initialize.apply(this, arguments);
1484 }
1485 };
1486 $.fn.typeahead.noConflict = function noConflict() {
1487 $.fn.typeahead = old;
1488 return this;
1489 };
1490 function ttEach($els, fn) {
1491 $els.each(function() {
1492 var $input = $(this), typeahead;
1493 (typeahead = $input.data(keys.typeahead)) && fn(typeahead, $input);
1494 });
1495 }
1496 function buildHintFromInput($input, www) {
1497 return $input.clone().addClass(www.classes.hint).removeData().css(www.css.hint).css(getBackgroundStyles($input)).prop("readonly", true).removeAttr("id name placeholder required").attr({
1498 autocomplete: "off",
1499 spellcheck: "false",
1500 tabindex: -1
1501 });
1502 }
1503 function prepInput($input, www) {
1504 $input.data(keys.attrs, {
1505 dir: $input.attr("dir"),
1506 autocomplete: $input.attr("autocomplete"),
1507 spellcheck: $input.attr("spellcheck"),
1508 style: $input.attr("style")
1509 });
1510 $input.addClass(www.classes.input).attr({
1511 autocomplete: "off",
1512 spellcheck: false
1513 });
1514 try {
1515 !$input.attr("dir") && $input.attr("dir", "auto");
1516 } catch (e) {}
1517 return $input;
1518 }
1519 function getBackgroundStyles($el) {
1520 return {
1521 backgroundAttachment: $el.css("background-attachment"),
1522 backgroundClip: $el.css("background-clip"),
1523 backgroundColor: $el.css("background-color"),
1524 backgroundImage: $el.css("background-image"),
1525 backgroundOrigin: $el.css("background-origin"),
1526 backgroundPosition: $el.css("background-position"),
1527 backgroundRepeat: $el.css("background-repeat"),
1528 backgroundSize: $el.css("background-size")
1529 };
1530 }
1531 function revert($input) {
1532 var www, $wrapper;
1533 www = $input.data(keys.www);
1534 $wrapper = $input.parent().filter(www.selectors.wrapper);
1535 _.each($input.data(keys.attrs), function(val, key) {
1536 _.isUndefined(val) ? $input.removeAttr(key) : $input.attr(key, val);
1537 });
1538 $input.removeData(keys.typeahead).removeData(keys.www).removeData(keys.attr).removeClass(www.classes.input);
1539 if ($wrapper.length) {
1540 $input.detach().insertAfter($wrapper);
1541 $wrapper.remove();
1542 }
1543 }
1544 function $elOrNull(obj) {
1545 var isValid, $el;
1546 isValid = _.isJQuery(obj) || _.isElement(obj);
1547 $el = isValid ? $(obj).first() : [];
1548 return $el.length ? $el : null;
1549 }
1550 })();
1551}); \ No newline at end of file
diff --git a/bitbake/lib/toaster/toastergui/static/js/typeahead.jquery.min.js b/bitbake/lib/toaster/toastergui/static/js/typeahead.jquery.min.js
deleted file mode 100644
index 962133a40b..0000000000
--- a/bitbake/lib/toaster/toastergui/static/js/typeahead.jquery.min.js
+++ /dev/null
@@ -1,7 +0,0 @@
1/*!
2 * typeahead.js 0.11.1
3 * https://github.com/twitter/typeahead.js
4 * Copyright 2013-2015 Twitter, Inc. and other contributors; Licensed MIT
5 */
6
7!function(a,b){"function"==typeof define&&define.amd?define("typeahead.js",["jquery"],function(a){return b(a)}):"object"==typeof exports?module.exports=b(require("jquery")):b(jQuery)}(this,function(a){var b=function(){"use strict";return{isMsie:function(){return/(msie|trident)/i.test(navigator.userAgent)?navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2]:!1},isBlankString:function(a){return!a||/^\s*$/.test(a)},escapeRegExChars:function(a){return a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isString:function(a){return"string"==typeof a},isNumber:function(a){return"number"==typeof a},isArray:a.isArray,isFunction:a.isFunction,isObject:a.isPlainObject,isUndefined:function(a){return"undefined"==typeof a},isElement:function(a){return!(!a||1!==a.nodeType)},isJQuery:function(b){return b instanceof a},toStr:function(a){return b.isUndefined(a)||null===a?"":a+""},bind:a.proxy,each:function(b,c){function d(a,b){return c(b,a)}a.each(b,d)},map:a.map,filter:a.grep,every:function(b,c){var d=!0;return b?(a.each(b,function(a,e){return(d=c.call(null,e,a,b))?void 0:!1}),!!d):d},some:function(b,c){var d=!1;return b?(a.each(b,function(a,e){return(d=c.call(null,e,a,b))?!1:void 0}),!!d):d},mixin:a.extend,identity:function(a){return a},clone:function(b){return a.extend(!0,{},b)},getIdGenerator:function(){var a=0;return function(){return a++}},templatify:function(b){function c(){return String(b)}return a.isFunction(b)?b:c},defer:function(a){setTimeout(a,0)},debounce:function(a,b,c){var d,e;return function(){var f,g,h=this,i=arguments;return f=function(){d=null,c||(e=a.apply(h,i))},g=c&&!d,clearTimeout(d),d=setTimeout(f,b),g&&(e=a.apply(h,i)),e}},throttle:function(a,b){var c,d,e,f,g,h;return g=0,h=function(){g=new Date,e=null,f=a.apply(c,d)},function(){var i=new Date,j=b-(i-g);return c=this,d=arguments,0>=j?(clearTimeout(e),e=null,g=i,f=a.apply(c,d)):e||(e=setTimeout(h,j)),f}},stringify:function(a){return b.isString(a)?a:JSON.stringify(a)},noop:function(){}}}(),c=function(){"use strict";function a(a){var g,h;return h=b.mixin({},f,a),g={css:e(),classes:h,html:c(h),selectors:d(h)},{css:g.css,html:g.html,classes:g.classes,selectors:g.selectors,mixin:function(a){b.mixin(a,g)}}}function c(a){return{wrapper:'<span class="'+a.wrapper+'"></span>',menu:'<div class="'+a.menu+'"></div>'}}function d(a){var c={};return b.each(a,function(a,b){c[b]="."+a}),c}function e(){var a={wrapper:{position:"relative",display:"inline-block"},hint:{position:"absolute",top:"0",left:"0",borderColor:"transparent",boxShadow:"none",opacity:"1"},input:{position:"relative",verticalAlign:"top",backgroundColor:"transparent"},inputWithNoHint:{position:"relative",verticalAlign:"top"},menu:{position:"absolute",top:"100%",left:"0",zIndex:"100",display:"none"},ltr:{left:"0",right:"auto"},rtl:{left:"auto",right:" 0"}};return b.isMsie()&&b.mixin(a.input,{backgroundImage:"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"}),a}var f={wrapper:"twitter-typeahead",input:"tt-input",hint:"tt-hint",menu:"tt-menu",dataset:"tt-dataset",suggestion:"tt-suggestion",selectable:"tt-selectable",empty:"tt-empty",open:"tt-open",cursor:"tt-cursor",highlight:"tt-highlight"};return a}(),d=function(){"use strict";function c(b){b&&b.el||a.error("EventBus initialized without el"),this.$el=a(b.el)}var d,e;return d="typeahead:",e={render:"rendered",cursorchange:"cursorchanged",select:"selected",autocomplete:"autocompleted"},b.mixin(c.prototype,{_trigger:function(b,c){var e;return e=a.Event(d+b),(c=c||[]).unshift(e),this.$el.trigger.apply(this.$el,c),e},before:function(a){var b,c;return b=[].slice.call(arguments,1),c=this._trigger("before"+a,b),c.isDefaultPrevented()},trigger:function(a){var b;this._trigger(a,[].slice.call(arguments,1)),(b=e[a])&&this._trigger(b,[].slice.call(arguments,1))}}),c}(),e=function(){"use strict";function a(a,b,c,d){var e;if(!c)return this;for(b=b.split(i),c=d?h(c,d):c,this._callbacks=this._callbacks||{};e=b.shift();)this._callbacks[e]=this._callbacks[e]||{sync:[],async:[]},this._callbacks[e][a].push(c);return this}function b(b,c,d){return a.call(this,"async",b,c,d)}function c(b,c,d){return a.call(this,"sync",b,c,d)}function d(a){var b;if(!this._callbacks)return this;for(a=a.split(i);b=a.shift();)delete this._callbacks[b];return this}function e(a){var b,c,d,e,g;if(!this._callbacks)return this;for(a=a.split(i),d=[].slice.call(arguments,1);(b=a.shift())&&(c=this._callbacks[b]);)e=f(c.sync,this,[b].concat(d)),g=f(c.async,this,[b].concat(d)),e()&&j(g);return this}function f(a,b,c){function d(){for(var d,e=0,f=a.length;!d&&f>e;e+=1)d=a[e].apply(b,c)===!1;return!d}return d}function g(){var a;return a=window.setImmediate?function(a){setImmediate(function(){a()})}:function(a){setTimeout(function(){a()},0)}}function h(a,b){return a.bind?a.bind(b):function(){a.apply(b,[].slice.call(arguments,0))}}var i=/\s+/,j=g();return{onSync:c,onAsync:b,off:d,trigger:e}}(),f=function(a){"use strict";function c(a,c,d){for(var e,f=[],g=0,h=a.length;h>g;g++)f.push(b.escapeRegExChars(a[g]));return e=d?"\\b("+f.join("|")+")\\b":"("+f.join("|")+")",c?new RegExp(e):new RegExp(e,"i")}var d={node:null,pattern:null,tagName:"strong",className:null,wordsOnly:!1,caseSensitive:!1};return function(e){function f(b){var c,d,f;return(c=h.exec(b.data))&&(f=a.createElement(e.tagName),e.className&&(f.className=e.className),d=b.splitText(c.index),d.splitText(c[0].length),f.appendChild(d.cloneNode(!0)),b.parentNode.replaceChild(f,d)),!!c}function g(a,b){for(var c,d=3,e=0;e<a.childNodes.length;e++)c=a.childNodes[e],c.nodeType===d?e+=b(c)?1:0:g(c,b)}var h;e=b.mixin({},d,e),e.node&&e.pattern&&(e.pattern=b.isArray(e.pattern)?e.pattern:[e.pattern],h=c(e.pattern,e.caseSensitive,e.wordsOnly),g(e.node,f))}}(window.document),g=function(){"use strict";function c(c,e){c=c||{},c.input||a.error("input is missing"),e.mixin(this),this.$hint=a(c.hint),this.$input=a(c.input),this.query=this.$input.val(),this.queryWhenFocused=this.hasFocus()?this.query:null,this.$overflowHelper=d(this.$input),this._checkLanguageDirection(),0===this.$hint.length&&(this.setHint=this.getHint=this.clearHint=this.clearHintIfInvalid=b.noop)}function d(b){return a('<pre aria-hidden="true"></pre>').css({position:"absolute",visibility:"hidden",whiteSpace:"pre",fontFamily:b.css("font-family"),fontSize:b.css("font-size"),fontStyle:b.css("font-style"),fontVariant:b.css("font-variant"),fontWeight:b.css("font-weight"),wordSpacing:b.css("word-spacing"),letterSpacing:b.css("letter-spacing"),textIndent:b.css("text-indent"),textRendering:b.css("text-rendering"),textTransform:b.css("text-transform")}).insertAfter(b)}function f(a,b){return c.normalizeQuery(a)===c.normalizeQuery(b)}function g(a){return a.altKey||a.ctrlKey||a.metaKey||a.shiftKey}var h;return h={9:"tab",27:"esc",37:"left",39:"right",13:"enter",38:"up",40:"down"},c.normalizeQuery=function(a){return b.toStr(a).replace(/^\s*/g,"").replace(/\s{2,}/g," ")},b.mixin(c.prototype,e,{_onBlur:function(){this.resetInputValue(),this.trigger("blurred")},_onFocus:function(){this.queryWhenFocused=this.query,this.trigger("focused")},_onKeydown:function(a){var b=h[a.which||a.keyCode];this._managePreventDefault(b,a),b&&this._shouldTrigger(b,a)&&this.trigger(b+"Keyed",a)},_onInput:function(){this._setQuery(this.getInputValue()),this.clearHintIfInvalid(),this._checkLanguageDirection()},_managePreventDefault:function(a,b){var c;switch(a){case"up":case"down":c=!g(b);break;default:c=!1}c&&b.preventDefault()},_shouldTrigger:function(a,b){var c;switch(a){case"tab":c=!g(b);break;default:c=!0}return c},_checkLanguageDirection:function(){var a=(this.$input.css("direction")||"ltr").toLowerCase();this.dir!==a&&(this.dir=a,this.$hint.attr("dir",a),this.trigger("langDirChanged",a))},_setQuery:function(a,b){var c,d;c=f(a,this.query),d=c?this.query.length!==a.length:!1,this.query=a,b||c?!b&&d&&this.trigger("whitespaceChanged",this.query):this.trigger("queryChanged",this.query)},bind:function(){var a,c,d,e,f=this;return a=b.bind(this._onBlur,this),c=b.bind(this._onFocus,this),d=b.bind(this._onKeydown,this),e=b.bind(this._onInput,this),this.$input.on("blur.tt",a).on("focus.tt",c).on("keydown.tt",d),!b.isMsie()||b.isMsie()>9?this.$input.on("input.tt",e):this.$input.on("keydown.tt keypress.tt cut.tt paste.tt",function(a){h[a.which||a.keyCode]||b.defer(b.bind(f._onInput,f,a))}),this},focus:function(){this.$input.focus()},blur:function(){this.$input.blur()},getLangDir:function(){return this.dir},getQuery:function(){return this.query||""},setQuery:function(a,b){this.setInputValue(a),this._setQuery(a,b)},hasQueryChangedSinceLastFocus:function(){return this.query!==this.queryWhenFocused},getInputValue:function(){return this.$input.val()},setInputValue:function(a){this.$input.val(a),this.clearHintIfInvalid(),this._checkLanguageDirection()},resetInputValue:function(){this.setInputValue(this.query)},getHint:function(){return this.$hint.val()},setHint:function(a){this.$hint.val(a)},clearHint:function(){this.setHint("")},clearHintIfInvalid:function(){var a,b,c,d;a=this.getInputValue(),b=this.getHint(),c=a!==b&&0===b.indexOf(a),d=""!==a&&c&&!this.hasOverflow(),!d&&this.clearHint()},hasFocus:function(){return this.$input.is(":focus")},hasOverflow:function(){var a=this.$input.width()-2;return this.$overflowHelper.text(this.getInputValue()),this.$overflowHelper.width()>=a},isCursorAtEnd:function(){var a,c,d;return a=this.$input.val().length,c=this.$input[0].selectionStart,b.isNumber(c)?c===a:document.selection?(d=document.selection.createRange(),d.moveStart("character",-a),a===d.text.length):!0},destroy:function(){this.$hint.off(".tt"),this.$input.off(".tt"),this.$overflowHelper.remove(),this.$hint=this.$input=this.$overflowHelper=a("<div>")}}),c}(),h=function(){"use strict";function c(c,e){c=c||{},c.templates=c.templates||{},c.templates.notFound=c.templates.notFound||c.templates.empty,c.source||a.error("missing source"),c.node||a.error("missing node"),c.name&&!h(c.name)&&a.error("invalid dataset name: "+c.name),e.mixin(this),this.highlight=!!c.highlight,this.name=c.name||j(),this.limit=c.limit||5,this.displayFn=d(c.display||c.displayKey),this.templates=g(c.templates,this.displayFn),this.source=c.source.__ttAdapter?c.source.__ttAdapter():c.source,this.async=b.isUndefined(c.async)?this.source.length>2:!!c.async,this._resetLastSuggestion(),this.$el=a(c.node).addClass(this.classes.dataset).addClass(this.classes.dataset+"-"+this.name)}function d(a){function c(b){return b[a]}return a=a||b.stringify,b.isFunction(a)?a:c}function g(c,d){function e(b){return a("<div>").text(d(b))}return{notFound:c.notFound&&b.templatify(c.notFound),pending:c.pending&&b.templatify(c.pending),header:c.header&&b.templatify(c.header),footer:c.footer&&b.templatify(c.footer),suggestion:c.suggestion||e}}function h(a){return/^[_a-zA-Z0-9-]+$/.test(a)}var i,j;return i={val:"tt-selectable-display",obj:"tt-selectable-object"},j=b.getIdGenerator(),c.extractData=function(b){var c=a(b);return c.data(i.obj)?{val:c.data(i.val)||"",obj:c.data(i.obj)||null}:null},b.mixin(c.prototype,e,{_overwrite:function(a,b){b=b||[],b.length?this._renderSuggestions(a,b):this.async&&this.templates.pending?this._renderPending(a):!this.async&&this.templates.notFound?this._renderNotFound(a):this._empty(),this.trigger("rendered",this.name,b,!1)},_append:function(a,b){b=b||[],b.length&&this.$lastSuggestion.length?this._appendSuggestions(a,b):b.length?this._renderSuggestions(a,b):!this.$lastSuggestion.length&&this.templates.notFound&&this._renderNotFound(a),this.trigger("rendered",this.name,b,!0)},_renderSuggestions:function(a,b){var c;c=this._getSuggestionsFragment(a,b),this.$lastSuggestion=c.children().last(),this.$el.html(c).prepend(this._getHeader(a,b)).append(this._getFooter(a,b))},_appendSuggestions:function(a,b){var c,d;c=this._getSuggestionsFragment(a,b),d=c.children().last(),this.$lastSuggestion.after(c),this.$lastSuggestion=d},_renderPending:function(a){var b=this.templates.pending;this._resetLastSuggestion(),b&&this.$el.html(b({query:a,dataset:this.name}))},_renderNotFound:function(a){var b=this.templates.notFound;this._resetLastSuggestion(),b&&this.$el.html(b({query:a,dataset:this.name}))},_empty:function(){this.$el.empty(),this._resetLastSuggestion()},_getSuggestionsFragment:function(c,d){var e,g=this;return e=document.createDocumentFragment(),b.each(d,function(b){var d,f;f=g._injectQuery(c,b),d=a(g.templates.suggestion(f)).data(i.obj,b).data(i.val,g.displayFn(b)).addClass(g.classes.suggestion+" "+g.classes.selectable),e.appendChild(d[0])}),this.highlight&&f({className:this.classes.highlight,node:e,pattern:c}),a(e)},_getFooter:function(a,b){return this.templates.footer?this.templates.footer({query:a,suggestions:b,dataset:this.name}):null},_getHeader:function(a,b){return this.templates.header?this.templates.header({query:a,suggestions:b,dataset:this.name}):null},_resetLastSuggestion:function(){this.$lastSuggestion=a()},_injectQuery:function(a,c){return b.isObject(c)?b.mixin({_query:a},c):c},update:function(b){function c(a){g||(g=!0,a=(a||[]).slice(0,e.limit),h=a.length,e._overwrite(b,a),h<e.limit&&e.async&&e.trigger("asyncRequested",b))}function d(c){c=c||[],!f&&h<e.limit&&(e.cancel=a.noop,h+=c.length,e._append(b,c.slice(0,e.limit-h)),e.async&&e.trigger("asyncReceived",b))}var e=this,f=!1,g=!1,h=0;this.cancel(),this.cancel=function(){f=!0,e.cancel=a.noop,e.async&&e.trigger("asyncCanceled",b)},this.source(b,c,d),!g&&c([])},cancel:a.noop,clear:function(){this._empty(),this.cancel(),this.trigger("cleared")},isEmpty:function(){return this.$el.is(":empty")},destroy:function(){this.$el=a("<div>")}}),c}(),i=function(){"use strict";function c(c,d){function e(b){var c=f.$node.find(b.node).first();return b.node=c.length?c:a("<div>").appendTo(f.$node),new h(b,d)}var f=this;c=c||{},c.node||a.error("node is required"),d.mixin(this),this.$node=a(c.node),this.query=null,this.datasets=b.map(c.datasets,e)}return b.mixin(c.prototype,e,{_onSelectableClick:function(b){this.trigger("selectableClicked",a(b.currentTarget))},_onRendered:function(a,b,c,d){this.$node.toggleClass(this.classes.empty,this._allDatasetsEmpty()),this.trigger("datasetRendered",b,c,d)},_onCleared:function(){this.$node.toggleClass(this.classes.empty,this._allDatasetsEmpty()),this.trigger("datasetCleared")},_propagate:function(){this.trigger.apply(this,arguments)},_allDatasetsEmpty:function(){function a(a){return a.isEmpty()}return b.every(this.datasets,a)},_getSelectables:function(){return this.$node.find(this.selectors.selectable)},_removeCursor:function(){var a=this.getActiveSelectable();a&&a.removeClass(this.classes.cursor)},_ensureVisible:function(a){var b,c,d,e;b=a.position().top,c=b+a.outerHeight(!0),d=this.$node.scrollTop(),e=this.$node.height()+parseInt(this.$node.css("paddingTop"),10)+parseInt(this.$node.css("paddingBottom"),10),0>b?this.$node.scrollTop(d+b):c>e&&this.$node.scrollTop(d+(c-e))},bind:function(){var a,c=this;return a=b.bind(this._onSelectableClick,this),this.$node.on("click.tt",this.selectors.selectable,a),b.each(this.datasets,function(a){a.onSync("asyncRequested",c._propagate,c).onSync("asyncCanceled",c._propagate,c).onSync("asyncReceived",c._propagate,c).onSync("rendered",c._onRendered,c).onSync("cleared",c._onCleared,c)}),this},isOpen:function(){return this.$node.hasClass(this.classes.open)},open:function(){this.$node.addClass(this.classes.open)},close:function(){this.$node.removeClass(this.classes.open),this._removeCursor()},setLanguageDirection:function(a){this.$node.attr("dir",a)},selectableRelativeToCursor:function(a){var b,c,d,e;return c=this.getActiveSelectable(),b=this._getSelectables(),d=c?b.index(c):-1,e=d+a,e=(e+1)%(b.length+1)-1,e=-1>e?b.length-1:e,-1===e?null:b.eq(e)},setCursor:function(a){this._removeCursor(),(a=a&&a.first())&&(a.addClass(this.classes.cursor),this._ensureVisible(a))},getSelectableData:function(a){return a&&a.length?h.extractData(a):null},getActiveSelectable:function(){var a=this._getSelectables().filter(this.selectors.cursor).first();return a.length?a:null},getTopSelectable:function(){var a=this._getSelectables().first();return a.length?a:null},update:function(a){function c(b){b.update(a)}var d=a!==this.query;return d&&(this.query=a,b.each(this.datasets,c)),d},empty:function(){function a(a){a.clear()}b.each(this.datasets,a),this.query=null,this.$node.addClass(this.classes.empty)},destroy:function(){function c(a){a.destroy()}this.$node.off(".tt"),this.$node=a("<div>"),b.each(this.datasets,c)}}),c}(),j=function(){"use strict";function a(){i.apply(this,[].slice.call(arguments,0))}var c=i.prototype;return b.mixin(a.prototype,i.prototype,{open:function(){return!this._allDatasetsEmpty()&&this._show(),c.open.apply(this,[].slice.call(arguments,0))},close:function(){return this._hide(),c.close.apply(this,[].slice.call(arguments,0))},_onRendered:function(){return this._allDatasetsEmpty()?this._hide():this.isOpen()&&this._show(),c._onRendered.apply(this,[].slice.call(arguments,0))},_onCleared:function(){return this._allDatasetsEmpty()?this._hide():this.isOpen()&&this._show(),c._onCleared.apply(this,[].slice.call(arguments,0))},setLanguageDirection:function(a){return this.$node.css("ltr"===a?this.css.ltr:this.css.rtl),c.setLanguageDirection.apply(this,[].slice.call(arguments,0))},_hide:function(){this.$node.hide()},_show:function(){this.$node.css("display","block")}}),a}(),k=function(){"use strict";function c(c,e){var f,g,h,i,j,k,l,m,n,o,p;c=c||{},c.input||a.error("missing input"),c.menu||a.error("missing menu"),c.eventBus||a.error("missing event bus"),e.mixin(this),this.eventBus=c.eventBus,this.minLength=b.isNumber(c.minLength)?c.minLength:1,this.input=c.input,this.menu=c.menu,this.enabled=!0,this.active=!1,this.input.hasFocus()&&this.activate(),this.dir=this.input.getLangDir(),this._hacks(),this.menu.bind().onSync("selectableClicked",this._onSelectableClicked,this).onSync("asyncRequested",this._onAsyncRequested,this).onSync("asyncCanceled",this._onAsyncCanceled,this).onSync("asyncReceived",this._onAsyncReceived,this).onSync("datasetRendered",this._onDatasetRendered,this).onSync("datasetCleared",this._onDatasetCleared,this),f=d(this,"activate","open","_onFocused"),g=d(this,"deactivate","_onBlurred"),h=d(this,"isActive","isOpen","_onEnterKeyed"),i=d(this,"isActive","isOpen","_onTabKeyed"),j=d(this,"isActive","_onEscKeyed"),k=d(this,"isActive","open","_onUpKeyed"),l=d(this,"isActive","open","_onDownKeyed"),m=d(this,"isActive","isOpen","_onLeftKeyed"),n=d(this,"isActive","isOpen","_onRightKeyed"),o=d(this,"_openIfActive","_onQueryChanged"),p=d(this,"_openIfActive","_onWhitespaceChanged"),this.input.bind().onSync("focused",f,this).onSync("blurred",g,this).onSync("enterKeyed",h,this).onSync("tabKeyed",i,this).onSync("escKeyed",j,this).onSync("upKeyed",k,this).onSync("downKeyed",l,this).onSync("leftKeyed",m,this).onSync("rightKeyed",n,this).onSync("queryChanged",o,this).onSync("whitespaceChanged",p,this).onSync("langDirChanged",this._onLangDirChanged,this)}function d(a){var c=[].slice.call(arguments,1);return function(){var d=[].slice.call(arguments);b.each(c,function(b){return a[b].apply(a,d)})}}return b.mixin(c.prototype,{_hacks:function(){var c,d;c=this.input.$input||a("<div>"),d=this.menu.$node||a("<div>"),c.on("blur.tt",function(a){var e,f,g;e=document.activeElement,f=d.is(e),g=d.has(e).length>0,b.isMsie()&&(f||g)&&(a.preventDefault(),a.stopImmediatePropagation(),b.defer(function(){c.focus()}))}),d.on("mousedown.tt",function(a){a.preventDefault()})},_onSelectableClicked:function(a,b){this.select(b)},_onDatasetCleared:function(){this._updateHint()},_onDatasetRendered:function(a,b,c,d){this._updateHint(),this.eventBus.trigger("render",c,d,b)},_onAsyncRequested:function(a,b,c){this.eventBus.trigger("asyncrequest",c,b)},_onAsyncCanceled:function(a,b,c){this.eventBus.trigger("asynccancel",c,b)},_onAsyncReceived:function(a,b,c){this.eventBus.trigger("asyncreceive",c,b)},_onFocused:function(){this._minLengthMet()&&this.menu.update(this.input.getQuery())},_onBlurred:function(){this.input.hasQueryChangedSinceLastFocus()&&this.eventBus.trigger("change",this.input.getQuery())},_onEnterKeyed:function(a,b){var c;(c=this.menu.getActiveSelectable())&&this.select(c)&&b.preventDefault()},_onTabKeyed:function(a,b){var c;(c=this.menu.getActiveSelectable())?this.select(c)&&b.preventDefault():(c=this.menu.getTopSelectable())&&this.autocomplete(c)&&b.preventDefault()},_onEscKeyed:function(){this.close()},_onUpKeyed:function(){this.moveCursor(-1)},_onDownKeyed:function(){this.moveCursor(1)},_onLeftKeyed:function(){"rtl"===this.dir&&this.input.isCursorAtEnd()&&this.autocomplete(this.menu.getTopSelectable())},_onRightKeyed:function(){"ltr"===this.dir&&this.input.isCursorAtEnd()&&this.autocomplete(this.menu.getTopSelectable())},_onQueryChanged:function(a,b){this._minLengthMet(b)?this.menu.update(b):this.menu.empty()},_onWhitespaceChanged:function(){this._updateHint()},_onLangDirChanged:function(a,b){this.dir!==b&&(this.dir=b,this.menu.setLanguageDirection(b))},_openIfActive:function(){this.isActive()&&this.open()},_minLengthMet:function(a){return a=b.isString(a)?a:this.input.getQuery()||"",a.length>=this.minLength},_updateHint:function(){var a,c,d,e,f,h,i;a=this.menu.getTopSelectable(),c=this.menu.getSelectableData(a),d=this.input.getInputValue(),!c||b.isBlankString(d)||this.input.hasOverflow()?this.input.clearHint():(e=g.normalizeQuery(d),f=b.escapeRegExChars(e),h=new RegExp("^(?:"+f+")(.+$)","i"),i=h.exec(c.val),i&&this.input.setHint(d+i[1]))},isEnabled:function(){return this.enabled},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},isActive:function(){return this.active},activate:function(){return this.isActive()?!0:!this.isEnabled()||this.eventBus.before("active")?!1:(this.active=!0,this.eventBus.trigger("active"),!0)},deactivate:function(){return this.isActive()?this.eventBus.before("idle")?!1:(this.active=!1,this.close(),this.eventBus.trigger("idle"),!0):!0},isOpen:function(){return this.menu.isOpen()},open:function(){return this.isOpen()||this.eventBus.before("open")||(this.menu.open(),this._updateHint(),this.eventBus.trigger("open")),this.isOpen()},close:function(){return this.isOpen()&&!this.eventBus.before("close")&&(this.menu.close(),this.input.clearHint(),this.input.resetInputValue(),this.eventBus.trigger("close")),!this.isOpen()},setVal:function(a){this.input.setQuery(b.toStr(a))},getVal:function(){return this.input.getQuery()},select:function(a){var b=this.menu.getSelectableData(a);return b&&!this.eventBus.before("select",b.obj)?(this.input.setQuery(b.val,!0),this.eventBus.trigger("select",b.obj),this.close(),!0):!1},autocomplete:function(a){var b,c,d;return b=this.input.getQuery(),c=this.menu.getSelectableData(a),d=c&&b!==c.val,d&&!this.eventBus.before("autocomplete",c.obj)?(this.input.setQuery(c.val),this.eventBus.trigger("autocomplete",c.obj),!0):!1},moveCursor:function(a){var b,c,d,e,f;return b=this.input.getQuery(),c=this.menu.selectableRelativeToCursor(a),d=this.menu.getSelectableData(c),e=d?d.obj:null,f=this._minLengthMet()&&this.menu.update(b),f||this.eventBus.before("cursorchange",e)?!1:(this.menu.setCursor(c),d?this.input.setInputValue(d.val):(this.input.resetInputValue(),this._updateHint()),this.eventBus.trigger("cursorchange",e),!0)},destroy:function(){this.input.destroy(),this.menu.destroy()}}),c}();!function(){"use strict";function e(b,c){b.each(function(){var b,d=a(this);(b=d.data(p.typeahead))&&c(b,d)})}function f(a,b){return a.clone().addClass(b.classes.hint).removeData().css(b.css.hint).css(l(a)).prop("readonly",!0).removeAttr("id name placeholder required").attr({autocomplete:"off",spellcheck:"false",tabindex:-1})}function h(a,b){a.data(p.attrs,{dir:a.attr("dir"),autocomplete:a.attr("autocomplete"),spellcheck:a.attr("spellcheck"),style:a.attr("style")}),a.addClass(b.classes.input).attr({autocomplete:"off",spellcheck:!1});try{!a.attr("dir")&&a.attr("dir","auto")}catch(c){}return a}function l(a){return{backgroundAttachment:a.css("background-attachment"),backgroundClip:a.css("background-clip"),backgroundColor:a.css("background-color"),backgroundImage:a.css("background-image"),backgroundOrigin:a.css("background-origin"),backgroundPosition:a.css("background-position"),backgroundRepeat:a.css("background-repeat"),backgroundSize:a.css("background-size")}}function m(a){var c,d;c=a.data(p.www),d=a.parent().filter(c.selectors.wrapper),b.each(a.data(p.attrs),function(c,d){b.isUndefined(c)?a.removeAttr(d):a.attr(d,c)}),a.removeData(p.typeahead).removeData(p.www).removeData(p.attr).removeClass(c.classes.input),d.length&&(a.detach().insertAfter(d),d.remove())}function n(c){var d,e;return d=b.isJQuery(c)||b.isElement(c),e=d?a(c).first():[],e.length?e:null}var o,p,q;o=a.fn.typeahead,p={www:"tt-www",attrs:"tt-attrs",typeahead:"tt-typeahead"},q={initialize:function(e,l){function m(){var c,m,q,r,s,t,u,v,w,x,y;b.each(l,function(a){a.highlight=!!e.highlight}),c=a(this),m=a(o.html.wrapper),q=n(e.hint),r=n(e.menu),s=e.hint!==!1&&!q,t=e.menu!==!1&&!r,s&&(q=f(c,o)),t&&(r=a(o.html.menu).css(o.css.menu)),q&&q.val(""),c=h(c,o),(s||t)&&(m.css(o.css.wrapper),c.css(s?o.css.input:o.css.inputWithNoHint),c.wrap(m).parent().prepend(s?q:null).append(t?r:null)),y=t?j:i,u=new d({el:c}),v=new g({hint:q,input:c},o),w=new y({node:r,datasets:l},o),x=new k({input:v,menu:w,eventBus:u,minLength:e.minLength},o),c.data(p.www,o),c.data(p.typeahead,x)}var o;return l=b.isArray(l)?l:[].slice.call(arguments,1),e=e||{},o=c(e.classNames),this.each(m)},isEnabled:function(){var a;return e(this.first(),function(b){a=b.isEnabled()}),a},enable:function(){return e(this,function(a){a.enable()}),this},disable:function(){return e(this,function(a){a.disable()}),this},isActive:function(){var a;return e(this.first(),function(b){a=b.isActive()}),a},activate:function(){return e(this,function(a){a.activate()}),this},deactivate:function(){return e(this,function(a){a.deactivate()}),this},isOpen:function(){var a;return e(this.first(),function(b){a=b.isOpen()}),a},open:function(){return e(this,function(a){a.open()}),this},close:function(){return e(this,function(a){a.close()}),this},select:function(b){var c=!1,d=a(b);return e(this.first(),function(a){c=a.select(d)}),c},autocomplete:function(b){var c=!1,d=a(b);return e(this.first(),function(a){c=a.autocomplete(d)}),c},moveCursor:function(a){var b=!1;return e(this.first(),function(c){b=c.moveCursor(a)}),b},val:function(a){var b;return arguments.length?(e(this,function(b){b.setVal(a)}),this):(e(this.first(),function(a){b=a.getVal()}),b)},destroy:function(){return e(this,function(a,b){m(b),a.destroy()}),this}},a.fn.typeahead=function(a){return q[a]?q[a].apply(this,[].slice.call(arguments,1)):q.initialize.apply(this,arguments)},a.fn.typeahead.noConflict=function(){return a.fn.typeahead=o,this}}()}); \ No newline at end of file
diff --git a/bitbake/lib/toaster/toastergui/templates/base.html b/bitbake/lib/toaster/toastergui/templates/base.html
index e26a429daa..2cbc1872e8 100644
--- a/bitbake/lib/toaster/toastergui/templates/base.html
+++ b/bitbake/lib/toaster/toastergui/templates/base.html
@@ -21,7 +21,7 @@
21 </script> 21 </script>
22 <script src="{% static 'js/bootstrap.min.js' %}"> 22 <script src="{% static 'js/bootstrap.min.js' %}">
23 </script> 23 </script>
24 <script src="{% static 'js/typeahead.jquery.min.js' %}"> 24 <script src="{% static 'js/typeahead.jquery.js' %}">
25 </script> 25 </script>
26 <script src="{% static 'js/prettify.js' %}"> 26 <script src="{% static 'js/prettify.js' %}">
27 </script> 27 </script>