summaryrefslogtreecommitdiffstats
path: root/sitestatic
diff options
context:
space:
mode:
authorJelle van der Waa <jelle@vdwaa.nl>2018-11-24 22:48:07 +0100
committerJelle van der Waa <jelle@archlinux.org>2019-02-18 16:42:51 +0100
commit37a51bc78902a213dde155a76a9fa290cd776fd7 (patch)
tree31494a41fcb4bd000248e66779b81fed71f8d460 /sitestatic
parentd1674c1d12f3e57c3a22ed6103b2d022016700e5 (diff)
downloadarchweb-37a51bc78902a213dde155a76a9fa290cd776fd7.tar.gz
archweb-37a51bc78902a213dde155a76a9fa290cd776fd7.zip
homepage: use self written typeahead implementation
Use a self written typeahead inmplemenation which gets rid of the jQuery requirement. This saves upgrading issues and reduces the amount of data to be loaded for the homepage by half.
Diffstat (limited to 'sitestatic')
-rw-r--r--sitestatic/archweb.css3
-rw-r--r--sitestatic/homepage.js157
2 files changed, 135 insertions, 25 deletions
diff --git a/sitestatic/archweb.css b/sitestatic/archweb.css
index 209561f9..f4b791ac 100644
--- a/sitestatic/archweb.css
+++ b/sitestatic/archweb.css
@@ -541,7 +541,7 @@ h3 span.arrow {
padding: 0.15em 0.1em;
margin: 0;
min-width: 10em;
- font-size: 0.812em;
+ font-size: 1em;
text-align: left;
list-style: none;
background-color: #f6f9fc;
@@ -552,6 +552,7 @@ h3 span.arrow {
color: #000;
}
+ .pkgsearch-typeahead li:hover a,
.pkgsearch-typeahead li.active a {
color: #07b;
}
diff --git a/sitestatic/homepage.js b/sitestatic/homepage.js
index d0dc3444..b46cf0b4 100644
--- a/sitestatic/homepage.js
+++ b/sitestatic/homepage.js
@@ -1,26 +1,135 @@
-!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.typeahead.defaults,n),this.matcher=this.options.matcher||this.matcher,this.sorter=this.options.sorter||this.sorter,this.highlighter=this.options.highlighter||this.highlighter,this.updater=this.options.updater||this.updater,this.$menu=e(this.options.menu).appendTo("body"),this.source=this.options.source,this.shown=!1,this.listen()};t.prototype={constructor:t,select:function(){var e=this.$menu.find(".active").attr("data-value");return e&&this.$element.val(this.updater(e)).change(),this.hide()},updater:function(e){return e},show:function(){var t=e.extend({},this.$element.offset(),{height:this.$element[0].offsetHeight});return this.$menu.css({top:t.top+t.height,left:t.left}),this.$menu.show(),this.shown=!0,this},hide:function(){return this.$menu.hide(),this.shown=!1,this},lookup:function(t){var n;return this.query=this.$element.val(),!this.query||this.query.length<this.options.minLength?this.shown?this.hide():this:(n=e.isFunction(this.source)?this.source(this.query,e.proxy(this.process,this)):this.source,n?this.process(n):this)},process:function(t){var n=this;return t=e.grep(t,function(e){return n.matcher(e)}),t=this.sorter(t),t.length?this.render(t.slice(0,this.options.items)).show():this.shown?this.hide():this},matcher:function(e){return~e.toLowerCase().indexOf(this.query.toLowerCase())},sorter:function(e){var t=[],n=[],r=[],i;while(i=e.shift())i.toLowerCase().indexOf(this.query.toLowerCase())?~i.indexOf(this.query)?n.push(i):r.push(i):t.push(i);return t.concat(n,r)},highlighter:function(e){var t=this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&");return e.replace(new RegExp("("+t+")","ig"),function(e,t){return"<strong>"+t+"</strong>"})},render:function(t){var n=this;return t=e(t).map(function(t,r){return t=e(n.options.item).attr("data-value",r),t.find("a").html(n.highlighter(r)),t[0]}),this.$menu.html(t),this},next:function(t){var n=this.$menu.find(".active").removeClass("active"),r=n.next();r.length||(r=e(this.$menu.find("li")[0])),r.addClass("active")},prev:function(e){var t=this.$menu.find(".active").removeClass("active"),n=t.prev();n.length||(n=this.$menu.find("li").last()),n.addClass("active")},listen:function(){this.$element.on("blur",e.proxy(this.blur,this)).on("keypress",e.proxy(this.keypress,this)).on("keyup",e.proxy(this.keyup,this)),(e.browser.chrome||e.browser.webkit||e.browser.msie)&&this.$element.on("keydown",e.proxy(this.keydown,this)),this.$menu.on("click",e.proxy(this.click,this)).on("mouseenter","li",e.proxy(this.mouseenter,this))},move:function(e){if(!this.shown)return;switch(e.keyCode){case 9:case 13:case 27:e.preventDefault();break;case 38:e.preventDefault(),this.prev();break;case 40:e.preventDefault(),this.next()}e.stopPropagation()},keydown:function(t){this.suppressKeyPressRepeat=!~e.inArray(t.keyCode,[40,38,9,13,27]),this.move(t)},keypress:function(e){if(this.suppressKeyPressRepeat)return;this.move(e)},keyup:function(e){switch(e.keyCode){case 40:case 38:break;case 9:case 13:if(!this.shown)return;this.select();break;case 27:if(!this.shown)return;this.hide();break;default:this.lookup()}e.stopPropagation(),e.preventDefault()},blur:function(e){var t=this;setTimeout(function(){t.hide()},150)},click:function(e){e.stopPropagation(),e.preventDefault(),this.select()},mouseenter:function(t){this.$menu.find(".active").removeClass("active"),e(t.currentTarget).addClass("active")}},e.fn.typeahead=function(n){return this.each(function(){var r=e(this),i=r.data("typeahead"),s=typeof n=="object"&&n;i||r.data("typeahead",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.typeahead.defaults={source:[],items:8,menu:'<ul class="typeahead dropdown-menu"></ul>',item:'<li><a href="#"></a></li>',minLength:1},e.fn.typeahead.Constructor=t,e(function(){e("body").on("focus.typeahead.data-api",'[data-provide="typeahead"]',function(t){var n=e(this);if(n.data("typeahead"))return;t.preventDefault(),n.typeahead(n.data())})})}(window.jQuery);
-
-function setupTypeahead() {
- $('#pkgsearch-field').typeahead({
- source: function(query, callback) {
- $.getJSON('/opensearch/packages/suggest', {q: query}, function(data) {
- callback(data[1]);
- });
- },
- matcher: function(item) { return true; },
- sorter: function(items) { return items; },
- menu: '<ul class="pkgsearch-typeahead"></ul>',
- items: 10,
- updater: function(item) {
- $('#pkgsearch-field').val(item);
- $('#pkgsearch-form').submit();
- return item;
+"use strict";
+
+(function() {
+ const input = document.getElementById('pkgsearch-field');
+ const form = document.getElementById('pkgsearch-form');
+ var list;
+
+ function resetResults() {
+ if (!list) return;
+ list.style.display = "none";
+ list.innerHTML = "";
+ }
+
+ function getCompleteList() {
+ if (!list) {
+ list = document.createElement("UL");
+ list.setAttribute("class", "pkgsearch-typeahead"); // remove
+ form.appendChild(list);
+ setListLocation();
+ }
+ return list;
+ }
+
+ function onListClick(e) {
+ let target = e.target;
+ while (!target.getAttribute('data-value')) {
+ target = target.parentNode;
+ }
+ input.value = target.getAttribute('data-value');
+ form.submit();
+ }
+
+ function setListLocation() {
+ if (!list) return;
+ const rects = input.getClientRects()[0];
+ list.style.top = (rects.y + rects.height) + "px";
+ list.style.left = rects.x + "px";
+ }
+
+ function loadData(data) {
+ const letter = data[0];
+ const pkgs = data[1].slice(0, 10); // Show maximum of 10 results
+
+ resetResults();
+
+ if (pkgs.length === 0) {
+ return;
+ }
+
+ const ul = getCompleteList();
+ ul.style.display = "block";
+ const fragment = document.createDocumentFragment();
+
+ for (let i = 0; i < pkgs.length; i++) {
+ const item = document.createElement("li");
+ const text = pkgs[i].replace(letter, '<b>' + letter + '</b>');
+ item.innerHTML = '<a href="#">' + text + '</a>';
+ item.setAttribute('data-value', pkgs[i]);
+ fragment.appendChild(item);
+ }
+
+ ul.appendChild(fragment);
+ ul.addEventListener('click', onListClick);
+ }
+
+ function fetchData(letter) {
+ fetch('/opensearch/packages/suggest?q=' + letter).then(function(response) {
+ return response.json();
+ }).then(function(data) {
+ loadData(data);
+ });
+ }
+
+ function onInputClick() {
+ if (input.value === "") {
+ resetResults();
+ return;
+ }
+ fetchData(input.value);
+ }
+
+ function onKeyDown(e) {
+ if (!list) return;
+
+ const elem = document.querySelector(".pkgsearch-typeahead li.active");
+ switch(e.keyCode) {
+ case 13: // enter
+ if (elem) {
+ input.value = elem.getAttribute('data-value');
+ form.submit();
+ } else {
+ form.submit();
}
- }).attr('autocomplete', 'off');
- $('#pkgsearch-field').keyup(function(e) {
- if (e.keyCode === 13 &&
- $('ul.pkgsearch-typeahead li.active').size() === 0) {
- $('#pkgsearch-form').submit();
+ e.preventDefault();
+ break;
+ case 38: // up
+ if (elem && elem.previousElementSibling) {
+ elem.className = "";
+ elem.previousElementSibling.className = "active";
}
- });
-}
+ e.preventDefault();
+ break;
+ case 40: // down
+ if (elem && elem.nextElementSibling) {
+ elem.className = "";
+ elem.nextElementSibling.className = "active";
+ } else if (!elem && list.childElementCount !== 0) {
+ list.children[0].className = "active";
+ }
+ e.preventDefault();
+ break;
+ }
+ }
+
+ // debounce https://davidwalsh.name/javascript-debounce-function
+ function debounce(func, wait, immediate) {
+ var timeout;
+ return function() {
+ var context = this, args = arguments;
+ var later = function() {
+ timeout = null;
+ if (!immediate) func.apply(context, args);
+ };
+ var callNow = immediate && !timeout;
+ clearTimeout(timeout);
+ timeout = setTimeout(later, wait);
+ if (callNow) func.apply(context, args);
+ };
+ }
+
+ input.addEventListener("input", onInputClick);
+ input.addEventListener("keydown", onKeyDown);
+ window.addEventListener('resize', debounce(setListLocation, 150));
+ document.addEventListener("click", resetResults);
+}());