Download raw (6.5 KB)
(function () { 'use strict'; function forEach (list, callback) { if (list.forEach) { list.forEach(callback); } else { for (var i=0;i<list.length;i++) { callback(list[i], i); } } } function map (list, callback) { var buff = []; forEach(list, function (v, k) { buff.push(callback(v, k)); }); return buff; } function loadPosts (url) { fetch(url, { method: 'GET'}) .then(function(response) { if (response.status == 200) { // success response.text().then(function (html) { var parser = new DOMParser(), dom = parser.parseFromString(html, "text/html"); forEach(dom.querySelectorAll('article.entry'), function (el) { postList.addPost(new Post(el)) }); unifyStrokeWidths(); }); } else { // showError(); } }); } var TagManager = function (tags) { this.activeTags = (tags && Array.isArray(tags)) ? tags : []; this.setBodyClass(); } TagManager.prototype.toggle = function (tag, tagUrl) { if (this.activeTags.includes(tag)) { this.disable(tag); } else { this.enable(tag, tagUrl); } } TagManager.prototype.setBodyClass = function () { document.body.classList.toggle('filter-active', this.activeTags.length > 0); } TagManager.prototype.enable = function (tag, url) { if (!this.activeTags.includes(tag)) { this.activeTags.push(tag); this.setBodyClass(); if (this.activeTags.length == 1) { postList.filter(this.activeTags); } forEach(document.querySelectorAll('.tag[data-slug="' + tag + '"]'), function (el) { el.classList.toggle('active', true );}); loadPosts(url); this.updateURL(); } } TagManager.prototype.disable = function (tag) { if (this.activeTags.includes(tag)) { this.activeTags.splice(this.activeTags.indexOf(tag), 1); postList.filter(this.activeTags); forEach(document.querySelectorAll('.tag[data-slug="' + tag + '"]'), function (el) { el.classList.toggle('active', false );}); this.updateURL(); this.setBodyClass(); if (this.activeTags.length == 0) { loadPosts('/index.html'); } } } TagManager.prototype.updateURL = function () { var params = new URLSearchParams(); params.set('t', this.activeTags.join(',')); console.log(params.toString()); // push } TagManager.prototype.updatePostCount = function (count) { document.getElementById('taglist').dataset.postCount = count; } var Post = function (domEl) { this.el = domEl; this.slug = this.parseSlug(); this.tags = this.parseTags(); this.activeTags(); this.activateToggle(); } Post.prototype.parseSlug = function () { return this.el.dataset.slug; } Post.prototype.parseTags = function () { return map(this.el.querySelectorAll(".tags .tag"), function (el) { return el.dataset.slug }); } Post.prototype.remove = function () { // Perhaps more fancy later on? this.el.parentElement.removeChild(this.el); } Post.prototype.hasTag = function (tag) { return this.tags.includes(tag); } Post.prototype.hasSomeTags = function (tags) { return tags.some(this.hasTag, this); } Post.prototype.activeTags = function () { var tags = this.el.querySelectorAll(".tags .tag"); forEach(tags, function (el) { el.classList.toggle('active', tagManager.activeTags.includes(el.dataset.slug)); el.addEventListener('click', function (e) { e.preventDefault(); tagManager.toggle(el.dataset.slug, el.getAttribute('href')); }); }); } Post.prototype.activateToggle = function () { var toggle = this.el.querySelector('.toggle'), el = this.el; el.dataset.expanded = false; if (toggle) { toggle.addEventListener('click', function (e) { e.preventDefault(); el.dataset.expanded = ('expanded' in el.dataset && el.dataset.expanded == 'true') ? 'false' : 'true'; }); } } var PostList = function (domEl) { this.el = domEl; var posts = this.el.querySelectorAll('.entry'); this.posts = map(posts, function (el) { return new Post(el); }); this.updatePostCount(); }; PostList.prototype.addPost = function (post) { if (!this.has(post.slug)) { this.posts.push(post); var domEl = this.el.appendChild(post.el); this.updatePostCount(); return domEl; } } PostList.prototype.updatePostCount = function () { tagManager.updatePostCount(this.posts.length); } PostList.prototype.removePost = function (i) { this.posts.splice(i, 1).forEach(function (p) { p.remove(); }); this.updatePostCount(); } PostList.prototype.filter = function (tags) { var i = 0; while (i < this.posts.length) { if (this.posts[i].hasSomeTags(tags)) { i++; } else { this.removePost(i); } } } PostList.prototype.removeAllPosts = function () { while (this.postList.length > 0) { this.removePost(0); } } PostList.prototype.has = function (slug) { return this.posts.some(function (p) { return p.slug === slug }); } PostList.prototype.find = function (slug) { return this.posts.find(function (p) { return p.slug === slug }); } PostList.prototype.load = function () { } var TagList = function (list) { this.el = list; this.el.classList.toggle('show-all', false); forEach(list.querySelectorAll('.tag'), function (tag) { tag.addEventListener('click', function (e) { e.preventDefault(); tagManager.toggle(tag.dataset.slug, tag.getAttribute('href')); // list.classList.toggle('show-all', false); }); }); list.querySelector('.show-all-toggle').addEventListener('click', function (e) { this.toggleShowAll(); }.bind(this)); } TagList.prototype.toggleShowAll = function() { this.el.classList.toggle('show-all'); document.body.classList.toggle('filter-list--expanded'); } window.Post = Post; window.PostList = PostList; window.TagManager = TagManager; window.TagList = TagList; window.tagManager = new TagManager(map(document.querySelectorAll('#taglist .tag.active'), function (tag) { return tag.dataset.slug })); window.postList = new PostList(document.querySelector('#postlist')); window.tagList = new TagList(document.querySelector('#taglist')); document.querySelector('#menu-item-tags').addEventListener('click', function (e) { e.preventDefault(); tagList.toggleShowAll(); }); })();