diff --git a/static/css/main.css b/static/css/main.css
index 184ffda..36c26d1 100644
--- a/static/css/main.css
+++ b/static/css/main.css
@@ -122,7 +122,7 @@ a {
background-color: transparent;
border: 2px solid white;
overflow: visible;
- color: #444;
+ color: white;
font: inherit;
padding: .5rem 1.5rem;
margin: .5rem 1rem;
@@ -131,9 +131,9 @@ a {
.mg-tag-filter:hover {
border-color: #b2b2b2;
text-decoration: none; }
- .mg-tag-filter-enabled {
+ .mg-tag-filter-include {
background-color: #33b5e5; }
- .mg-tag-filter-disabled {
+ .mg-tag-filter-exclude {
background-color: #FF9148; }
.mg-nav-small {
diff --git a/templates/index.html b/templates/index.html
index 7440c56..d836c1a 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -6,11 +6,11 @@
{% if MG_LANG_FILTER_TAGS or MG_FILTER_TAGS %}
{% if MG_LANG_FILTER_TAGS %}
-
+
{% endif %}
{% if MG_FILTER_TAGS %}
{% for filter_tag in MG_FILTER_TAGS %}
-
+
{% endfor %}
{% endif %}
diff --git a/templates/js/filter-tags.js b/templates/js/filter-tags.js
index ff93383..a497635 100644
--- a/templates/js/filter-tags.js
+++ b/templates/js/filter-tags.js
@@ -9,23 +9,25 @@ window.tagFilters = {}
function indexOf(array, predicate) {
for (var i = 0; i < array.length; i++) if (predicate(array[i])) return array[i];
}
-function startsWith(searchString, position) {
- position = position || 0;
- return this.substr(position, searchString.length) === searchString;
+function includes(array, value) {
+ return array.indexOf(value) !== -1;
};
function toggleTagFilter(tag) {
var filterState = window.tagFilters[tag]
if (filterState === true) {
- this.classList.remove('mg-tag-filter-enabled');
+ this.classList.remove('mg-tag-filter-exclude');
filterState = false;
- this.classList.add('mg-tag-filter-disabled');
+ this.classList.add('mg-tag-filter-include');
+ this.title = 'Tag filter (include matching articles)';
} else if (filterState === false) {
- this.classList.remove('mg-tag-filter-disabled');
+ this.classList.remove('mg-tag-filter-include');
filterState = undefined;
+ this.title = 'Tag filter (disabled)';
} else {
filterState = true;
- this.classList.add('mg-tag-filter-enabled');
+ this.classList.add('mg-tag-filter-exclude');
+ this.title = 'Tag filter (exclude matching articles)';
}
window.tagFilters[tag] = filterState;
updateArticlesVisibility();
@@ -33,38 +35,38 @@ function toggleTagFilter(tag) {
function toggleLangTagFilter(langs) {
var lang = this.textContent;
- if (lang === 'lang') {
- lang = langs[0];
- window.tagFilters['lang:'+lang] = true;
+ window.tagFilters['lang:'+lang] = undefined;
+ lang = langs[langs.indexOf(lang) + 1];
+ if (typeof lang === 'undefined') {
+ lang = 'lang'
+ this.title = 'Language filter (disabled)';
} else {
- window.tagFilters['lang:'+lang] = undefined;
- lang = langs[langs.indexOf(lang) + 1];
- if (typeof lang === 'undefined') {
- lang = 'lang'
- } else {
- window.tagFilters['lang:'+lang] = true;
- }
+ window.tagFilters['lang:'+lang] = true;
+ this.title = 'Language filter (include only "' + lang + '" articles)';
}
this.textContent = lang;
updateArticlesVisibility();
}
function updateArticlesVisibility() {
- var anyTrueFilter = Object.keys(window.tagFilters).some(function (tagFilter) {
- return !!window.tagFilters[tagFilter];
+ var includeFilters = Object.keys(window.tagFilters).filter(function (tagFilter) {
+ return window.tagFilters[tagFilter] === true;
+ });
+ var excludeFilters = Object.keys(window.tagFilters).filter(function (tagFilter) {
+ return window.tagFilters[tagFilter] === false;
});
Array.prototype.slice.call(document.getElementsByTagName('article')).forEach(function (article) {
if (!article.dataset.tags) { // article-excerpt: we ignore it
return;
}
var articleTags = JSON.parse(article.dataset.tags);
- var anyTagWhitelisted = articleTags.some(function (tag) { return window.tagFilters[tag] === true; });
- var anyTagBlacklisted = articleTags.some(function (tag) { return window.tagFilters[tag] === false; });
+ var allIncludeTags = includeFilters.every(function (tag) { return includes(articleTags, tag); });
+ var anyExcludeTag = excludeFilters.some(function (tag) { return includes(articleTags, tag); });
// Now implementing the core logic
- var shouldDisplay = !anyTagBlacklisted;
- if (shouldDisplay && anyTrueFilter) {
- shouldDisplay = anyTagWhitelisted;
+ var shouldDisplay = !anyExcludeTag;
+ if (shouldDisplay && includeFilters.length > 0) {
+ shouldDisplay = allIncludeTags;
}
if (shouldDisplay) {