diff --git a/.dockerignore b/.dockerignore
index d31068e..4a17686 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -12,5 +12,7 @@ composer.json
composer.lock
CONTRIBUTORS.md
docker-compose.yml
+node_modules
+package.json
Makefile
README.markdown
diff --git a/.gitignore b/.gitignore
index defaaa4..b655fb4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,6 +17,7 @@ Thumbs.db
*.sublime-workspace
.nbproject
nbproject
+node_modules
config.php
!app/helpers/*
!app/models/*
diff --git a/.travis.yml b/.travis.yml
index e178bc2..65e5b05 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -20,8 +20,10 @@ install:
before_script:
- ./tests/ci/install.sh
+ - npm install
script:
+ - ./node_modules/.bin/jshint assets/js/src/*.js
- ./vendor/bin/phpunit -c tests/phpunit.unit.sqlite.xml
- ./vendor/bin/phpunit -c tests/phpunit.unit.postgres.xml
- ./vendor/bin/phpunit -c tests/phpunit.functional.sqlite.xml
diff --git a/ChangeLog b/ChangeLog
index 9852741..cfe27a3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -18,6 +18,7 @@ Version 1.2.0 (unreleased)
* Add Docker compose file
* Add functional tests (Json-RPC API and Fever API)
* Add unit tests
+* Minify Javascript and add automated syntax check on the CI
Migration procedure from 1.1.x to 1.2.0:
diff --git a/Makefile b/Makefile
index 50ead11..e78e6eb 100644
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@
.PHONY: sync-locales
.PHONY: find-locales
-JS_FILE = assets/js/all.js
+JS_FILE = assets/js/app.min.js
CONTAINER = miniflux
IMAGE = miniflux/miniflux
TAG = latest
@@ -28,13 +28,14 @@ docker-run:
js: $(JS_FILE)
-$(JS_FILE): assets/js/app.js \
- assets/js/feed.js \
- assets/js/item.js \
- assets/js/event.js \
- assets/js/nav.js
- @ echo "/* AUTO GENERATED FILE, DO NOT MODIFY THIS FILE, USE 'make js' */" > $@
- @ cat $^ >> $@
+$(JS_FILE): assets/js/src/app.js \
+ assets/js/src/feed.js \
+ assets/js/src/item.js \
+ assets/js/src/event.js \
+ assets/js/src/nav.js
+ @ yarn install || npm install
+ @ ./node_modules/.bin/jshint assets/js/src/*.js
+ @ cat $^ | node_modules/.bin/uglifyjs - > $@
@ echo "Miniflux.App.Run();" >> $@
# Build a new archive: make archive version=1.2.3 dst=/tmp
diff --git a/app/templates/layout.php b/app/templates/layout.php
index 5c34286..7de008d 100644
--- a/app/templates/layout.php
+++ b/app/templates/layout.php
@@ -22,7 +22,7 @@
-
+
diff --git a/assets/js/app.min.js b/assets/js/app.min.js
new file mode 100644
index 0000000..25a7c43
--- /dev/null
+++ b/assets/js/app.min.js
@@ -0,0 +1,2 @@
+var Miniflux={};var DEBUG=false;Miniflux.App=function(){return{Log:function(message){if(DEBUG){console.log(message)}},Run:function(){Miniflux.Event.ListenKeyboardEvents();Miniflux.Event.ListenMouseEvents();Miniflux.Event.ListenVisibilityEvents();Miniflux.Event.ListenTouchEvents();this.FrontendUpdateCheck()},FrontendUpdateCheck:function(){var request=new XMLHttpRequest;request.onload=function(){var response=JSON.parse(this.responseText);if(response.frontend_updatecheck_interval>0){Miniflux.App.Log("Frontend updatecheck interval in minutes: "+response.frontend_updatecheck_interval);Miniflux.Item.CheckForUpdates();setInterval(function(){Miniflux.Item.CheckForUpdates()},response.frontend_updatecheck_interval*60*1e3)}else{Miniflux.App.Log("Frontend updatecheck disabled")}};request.open("POST","?action=get-config",true);request.send(JSON.stringify(["frontend_updatecheck_interval"]))}}}();Miniflux.Feed=function(){var queue=[];var queue_length=5;var updateInterval=null;return{Update:function(feed,callback){var itemsCounter=feed.querySelector("span.items-count");if(!itemsCounter)return;var feed_id=feed.getAttribute("data-feed-id");var heading=feed.querySelector("h2:first-of-type");heading.className="loading-icon";var request=new XMLHttpRequest;request.onload=function(){heading.className="";feed.removeAttribute("data-feed-error");var lastChecked=feed.querySelector(".feed-last-checked");if(lastChecked)lastChecked.innerHTML=lastChecked.getAttribute("data-after-update");var response=JSON.parse(this.responseText);if(response.result){itemsCounter.innerHTML=response.items_count.items_unread+"/"+response.items_count.items_total}else{feed.setAttribute("data-feed-error","1")}if(callback){callback(response)}else{Miniflux.Item.CheckForUpdates()}};request.open("POST","?action=refresh-feed&feed_id="+feed_id,true);request.send()},UpdateAll:function(nb_concurrent_requests){var feeds=Array.prototype.slice.call(document.querySelectorAll("article:not([data-feed-disabled])"));if(nb_concurrent_requests){queue_length=nb_concurrent_requests}updateInterval=setInterval(function(){while(feeds.length>0&&queue.length=0)queue.splice(index,1);if(feeds.length===0&&queue.length===0){clearInterval(updateInterval);Miniflux.Item.CheckForUpdates()}}}}();Miniflux.Item=function(){var latest_feeds_items={};var unreadItems=false;var nbUnreadItems=function(){var navCounterElement=document.getElementById("nav-counter");if(navCounterElement){return parseInt(navCounterElement.textContent,10)||0}}();var nbPageItems=function(){var pageCounterElement=document.getElementById("page-counter");if(pageCounterElement){return parseInt(pageCounterElement.textContent,10)||0}}();function simulateMouseClick(element){var event=document.createEvent("MouseEvents");event.initEvent("mousedown",true,true);element.dispatchEvent(event);event=document.createEvent("MouseEvents");event.initEvent("mouseup",true,true);element.dispatchEvent(event);element.click()}function getItemID(item){return item.getAttribute("data-item-id")}function changeLabel(links){if(links.length===0){return}for(var i=0;i-1&&nbUnreadItems>0){window.location.href="?action=unread"}else if(nbPageItems===0){window.location.reload()}var pageCounterElement=document.getElementById("page-counter");if(pageCounterElement)pageCounterElement.textContent=nbPageItems||"";var navCounterElement=document.getElementById("nav-counter");navCounterElement.textContent=nbUnreadItems||"";var pageHeadingElement=document.querySelector("div.page-header h2:first-of-type");if(pageHeadingElement){pageHeading=pageHeadingElement.firstChild.nodeValue}else{var itemHeading=document.querySelector("article.item h1:first-of-type");if(itemHeading){document.title=itemHeading.textContent;return}}var sectionElement=document.querySelector("section.page");switch(sectionElement.getAttribute("data-item-page")){case"unread":document.title="Miniflux ("+nbUnreadItems+")";break;case"feed-items":document.title="("+nbPageItems+") "+pageHeading;break;default:if(pageCounterElement){document.title=pageHeading+" ("+nbPageItems+")"}else{document.title=pageHeading}break}}function markAsRead(item){var item_id=getItemID(item);var request=new XMLHttpRequest;request.onload=function(){if(Miniflux.Nav.IsListing()){showItemAsRead(item);updateCounters()}};request.open("POST","?action=mark-item-read&id="+item_id,true);request.send()}function markAsUnread(item){var item_id=getItemID(item);var request=new XMLHttpRequest;request.onload=function(){if(Miniflux.Nav.IsListing()){showItemAsUnread(item);updateCounters()}};request.open("POST","?action=mark-item-unread&id="+item_id,true);request.send()}function markAsRemoved(item){var item_id=getItemID(item);var request=new XMLHttpRequest;request.onload=function(){if(Miniflux.Nav.IsListing()){hideItem(item);if(item.getAttribute("data-item-status")==="unread")nbUnreadItems--;updateCounters()}};request.open("POST","?action=mark-item-removed&id="+item_id,true);request.send()}return{MarkAsRead:markAsRead,MarkAsUnread:markAsUnread,MarkAsRemoved:markAsRemoved,SwitchBookmark:function(item){var item_id=getItemID(item);var value=item.getAttribute("data-item-bookmark")==="1"?"0":"1";var request=new XMLHttpRequest;request.onload=function(){var sectionElement=document.querySelector("section.page");if(Miniflux.Nav.IsListing()&§ionElement.getAttribute("data-item-page")==="bookmarks"){hideItem(item);updateCounters()}else{item.setAttribute("data-item-bookmark",value);changeBookmarkLabel(item)}};request.open("POST","?action=bookmark&id="+item_id+"&value="+value,true);request.send()},SwitchStatus:function(item){var status=item.getAttribute("data-item-status");if(status==="read"){markAsUnread(item)}else if(status==="unread"){markAsRead(item)}},Show:function(item){var link=item.querySelector("a.show");if(link)simulateMouseClick(link)},OpenOriginal:function(item){var link=item.querySelector("a.original");if(link){simulateMouseClick(link)}},DownloadContent:function(item){var container=document.getElementById("download-item");if(!container)return;container.innerHTML=" "+container.getAttribute("data-before-message");container.className="loading-icon";var request=new XMLHttpRequest;request.onload=function(){var response=JSON.parse(request.responseText);container.className="";if(response.result){var content=document.getElementById("item-content");if(content)content.innerHTML=response.content;container.innerHTML=container.getAttribute("data-after-message")}else{container.innerHTML=container.getAttribute("data-failure-message")}};var item_id=getItemID(item);request.open("POST","?action=download-item&id="+item_id,true);request.send()},MarkFeedAsRead:function(feed_id){var request=new XMLHttpRequest;request.onload=function(){var articles=document.getElementsByTagName("article");for(var i=0,ilen=articles.length;ilatest_feeds_items[feed_id]){latest_feeds_items[feed_id]=current_feed.updated;current_unread=true}}Miniflux.App.Log("first_run: "+first_run+", current_unread: "+current_unread+", response.nbUnread: "+response.nbUnread+", nbUnreadItems: "+nbUnreadItems);if(!document.hidden&&(response.nb_unread_items!==nbUnreadItems||unreadItems)){Miniflux.App.Log("Counter changed! Updating unread counter.");unreadItems=false;nbUnreadItems=response.nb_unread_items;updateCounters()}else if(document.hidden&&!first_run&¤t_unread){Miniflux.App.Log("New Unread! Updating pagetitle.");unreadItems=true;document.title="↻ "+document.title}else{Miniflux.App.Log("No update.")}Miniflux.App.Log("unreadItems: "+unreadItems)};request.open("GET","?action=latest-feeds-items",true);request.send()}}}();Miniflux.Event=function(){var queue=[];function isEventIgnored(e){if(e.keyCode!==63&&e.which!==63&&(e.ctrlKey||e.shiftKey||e.altKey||e.metaKey)){return true}var target=e.target||e.srcElement;return target.tagName==="INPUT"||target.tagName==="TEXTAREA"}return{lastEventType:"",ListenMouseEvents:function(){document.onclick=function(e){if(e.target.hasAttribute("data-action")&&e.target.className!=="original"){e.preventDefault()}};document.onmouseup=function(e){if(e.button===2){return}if(e.target.nodeName==="INPUT"&&e.target.className==="auto-select"){e.target.select();return}var action=e.target.getAttribute("data-action");if(action){Miniflux.Event.lastEventType="mouse";var currentItem=function(){var element=e.target;while(element&&element.parentNode){element=element.parentNode;if(element.tagName&&element.tagName.toLowerCase()==="article"){return element}}}();switch(action){case"refresh-all":Miniflux.Feed.UpdateAll(e.target.getAttribute("data-concurrent-requests"));break;case"refresh-feed":if(currentItem){Miniflux.Feed.Update(currentItem)}break;case"mark-read":if(currentItem){Miniflux.Item.MarkAsRead(currentItem)}break;case"mark-unread":if(currentItem){Miniflux.Item.MarkAsUnread(currentItem)}break;case"mark-removed":if(currentItem){Miniflux.Item.MarkAsRemoved(currentItem)}break;case"bookmark":if(currentItem){Miniflux.Item.SwitchBookmark(currentItem)}break;case"download-item":if(currentItem){Miniflux.Item.DownloadContent(currentItem)}break;case"mark-feed-read":var feed_id=document.getElementById("listing").getAttribute("data-feed-id");Miniflux.Item.MarkFeedAsRead(feed_id);break;case"close-help":Miniflux.Nav.CloseHelp();break;case"show-search":Miniflux.Nav.ShowSearch();break;case"toggle-menu-more":Miniflux.Nav.ToggleMenuMore();break}}}},ListenKeyboardEvents:function(){document.onkeypress=function(e){if(isEventIgnored(e)){return}Miniflux.Event.lastEventType="keyboard";queue.push(e.key||e.which);if(queue[0]==="g"||queue[0]===103){switch(queue[1]){case undefined:break;case"u":case 117:window.location.href="?action=unread";queue=[];break;case"b":case 98:window.location.href="?action=bookmarks";queue=[];break;case"h":case 104:window.location.href="?action=history";queue=[];break;case"s":case 115:window.location.href="?action=feeds";queue=[];break;case"p":case 112:window.location.href="?action=config";queue=[];break;default:queue=[];break}}else{queue=[];var currentItem=function(){return document.getElementById("current-item")}();switch(e.key||e.which){case"d":case 100:if(currentItem){Miniflux.Item.DownloadContent(currentItem)}break;case"p":case 112:case"k":case 107:Miniflux.Nav.SelectPreviousItem();break;case"n":case 110:case"j":case 106:Miniflux.Nav.SelectNextItem();break;case"v":case 118:if(currentItem){Miniflux.Item.OpenOriginal(currentItem)}break;case"o":case 111:if(currentItem){Miniflux.Item.Show(currentItem)}break;case"m":case 109:if(currentItem){Miniflux.Item.SwitchStatus(currentItem)}break;case"f":case 102:if(currentItem){Miniflux.Item.SwitchBookmark(currentItem)}break;case"h":case 104:Miniflux.Nav.OpenPreviousPage();break;case"l":case 108:Miniflux.Nav.OpenNextPage();break;case"r":case 114:Miniflux.Feed.UpdateAll();break;case"?":case 63:Miniflux.Nav.ShowHelp();break;case"Q":case 81:case"q":case 113:Miniflux.Nav.CloseHelp();break;case"z":case 122:Miniflux.Item.ToggleRTLMode();break}}};document.onkeydown=function(e){if(isEventIgnored(e)){return}Miniflux.Event.lastEventType="keyboard";switch(e.key||e.which){case"ArrowLeft":case"Left":case 37:Miniflux.Nav.SelectPreviousItem();break;case"ArrowRight":case"Right":case 39:Miniflux.Nav.SelectNextItem();break}};document.onkeyup=function(e){if(isEventIgnored(e)){return}Miniflux.Event.lastEventType="keyboard";switch(e.key||e.which){case"/":case 47:Miniflux.Nav.ShowSearch();break}}},ListenVisibilityEvents:function(){document.addEventListener("visibilitychange",function(){Miniflux.App.Log("document.visibilityState: "+document.visibilityState);if(!document.hidden&&Miniflux.Item.hasNewUnread()){Miniflux.App.Log("Need to update the unread counter with fresh values from the database");Miniflux.Item.CheckForUpdates()}})},ListenTouchEvents:function(){var touches=null;var resetTouch=function(){if(touches&&touches.element){touches.element.style.opacity=1;touches.element.style.transform=""}touches={touchstart:{x:-1,y:-1},touchmove:{x:-1,y:-1},touchend:false,direction:"undetermined",swipestarted:false,element:null}};var horizontalSwipe=function(){if(touches.touchstart.x>-1&&touches.touchmove.x>-1&&(touches.touchmove.x-touches.touchstart.x>30||touches.swipestarted)&&Math.abs(touches.touchmove.y-touches.touchstart.y)<75){touches.swipestarted=true;return touches.touchmove.x-touches.touchstart.x}return 0};var closest=function(el,fn){return el&&(fn(el)?el:closest(el.parentNode,fn))};var getTouchElement=function(){return touches.element?touches.element:closest(document.elementFromPoint(touches.touchstart.x,touches.touchstart.y),function(el){return el.tagName==="ARTICLE"})};var drawElement=function(){if(touches&&(touches.touchend===true||touches.touchstart.x==-1)){return}if(touches.element===null){touches.element=getTouchElement()}var swipedistance=horizontalSwipe();if(swipedistance>0){var element=getTouchElement();if(!element){resetTouch();return}touches.element.style.opacity=1-(swipedistance>75?.9:swipedistance/75*.9);touches.element.style.transform="translateX("+(swipedistance>75?75:swipedistance)+"px)";touches.element=element}window.requestAnimationFrame(drawElement)};var touchHandler=function(e){if(typeof e.touches!="undefined"&&e.touches.length<=1){var touch=e.touches[0];var swipedistance=null;var element=null;switch(e.type){case"touchstart":resetTouch();touches[e.type].x=touch.clientX;touches[e.type].y=touch.clientY;drawElement();break;case"touchmove":touches[e.type].x=touch.clientX;touches[e.type].y=touch.clientY;break;case"touchend":touches[e.type]=true;element=getTouchElement();swipedistance=horizontalSwipe();if(swipedistance>75){if(element){Miniflux.Item.MarkAsRead(element)}if(!element.getAttribute("data-hide")){resetTouch()}}else{resetTouch()}break;case"touchcancel":resetTouch();break;default:break}}else{resetTouch()}};resetTouch();document.addEventListener("touchstart",touchHandler,false);document.addEventListener("touchmove",touchHandler,false);document.addEventListener("touchend",touchHandler,false);document.addEventListener("touchcancel",touchHandler,false)}}}();Miniflux.Nav=function(){function scrollPageTo(item){var clientHeight=pageYOffset+document.documentElement.clientHeight;var itemPosition=item.offsetTop+item.offsetHeight;if(clientHeight-itemPosition<0||clientHeight-item.offsetTop>document.documentElement.clientHeight){window.scrollTo(0,item.offsetTop-10)}}function findNextItem(){var items=document.getElementsByTagName("article");if(!document.getElementById("current-item")){items[0].id="current-item";scrollPageTo(items[0])}else{for(var i=0,ilen=items.length;i=0;i--){if(items[i].id==="current-item"){if(i-1>=0){items[i].id="item-"+items[i].getAttribute("data-item-id");items[i-1].id="current-item";scrollPageTo(items[i-1])}break}}}}function isListing(){return!!document.getElementById("listing")}return{OpenNextPage:function(){var link=document.getElementById("next-page");if(link)link.click()},OpenPreviousPage:function(){var link=document.getElementById("previous-page");if(link)link.click()},SelectNextItem:function(){var link=document.getElementById("next-item");if(link){link.click()}else if(isListing()){findNextItem()}},SelectPreviousItem:function(){var link=document.getElementById("previous-item");if(link){link.click()}else if(isListing()){findPreviousItem()}},ShowHelp:function(){var help_layer=document.getElementById("help-layer");help_layer.removeAttribute("class")},CloseHelp:function(){var help_layer=document.getElementById("help-layer");help_layer.setAttribute("class","hide")},ShowSearch:function(){document.getElementById("search-opener").setAttribute("class","hide");document.getElementById("search-form").removeAttribute("class");document.getElementById("form-text").focus()},ToggleMenuMore:function(){var menu=document.getElementById("menu-more");if(menu.hasAttribute("class")){menu.removeAttribute("class")}else{menu.setAttribute("class","hide")}},IsListing:isListing}}();
+Miniflux.App.Run();
diff --git a/assets/js/app.js b/assets/js/src/app.js
similarity index 85%
rename from assets/js/app.js
rename to assets/js/src/app.js
index 599d43c..57ba18c 100644
--- a/assets/js/app.js
+++ b/assets/js/src/app.js
@@ -22,10 +22,10 @@ Miniflux.App = (function() {
request.onload = function() {
var response = JSON.parse(this.responseText);
- if (response['frontend_updatecheck_interval'] > 0) {
- Miniflux.App.Log('Frontend updatecheck interval in minutes: ' + response['frontend_updatecheck_interval']);
+ if (response.frontend_updatecheck_interval > 0) {
+ Miniflux.App.Log('Frontend updatecheck interval in minutes: ' + response.frontend_updatecheck_interval);
Miniflux.Item.CheckForUpdates();
- setInterval(function(){ Miniflux.Item.CheckForUpdates(); }, response['frontend_updatecheck_interval']*60*1000);
+ setInterval(function(){ Miniflux.Item.CheckForUpdates(); }, response.frontend_updatecheck_interval * 60 * 1000);
}
else {
Miniflux.App.Log('Frontend updatecheck disabled');
diff --git a/assets/js/event.js b/assets/js/src/event.js
similarity index 86%
rename from assets/js/event.js
rename to assets/js/src/event.js
index deb4dca..8ac8e3d 100644
--- a/assets/js/event.js
+++ b/assets/js/src/event.js
@@ -10,7 +10,7 @@ Miniflux.Event = (function() {
// Do not handle events when there is a focus in form fields
var target = e.target || e.srcElement;
- return !!(target.tagName === 'INPUT' || target.tagName === 'TEXTAREA');
+ return target.tagName === 'INPUT' || target.tagName === 'TEXTAREA';
}
return {
@@ -58,22 +58,34 @@ Miniflux.Event = (function() {
Miniflux.Feed.UpdateAll(e.target.getAttribute("data-concurrent-requests"));
break;
case 'refresh-feed':
- currentItem && Miniflux.Feed.Update(currentItem);
+ if (currentItem) {
+ Miniflux.Feed.Update(currentItem);
+ }
break;
case 'mark-read':
- currentItem && Miniflux.Item.MarkAsRead(currentItem);
+ if (currentItem) {
+ Miniflux.Item.MarkAsRead(currentItem);
+ }
break;
case 'mark-unread':
- currentItem && Miniflux.Item.MarkAsUnread(currentItem);
+ if (currentItem) {
+ Miniflux.Item.MarkAsUnread(currentItem);
+ }
break;
case 'mark-removed':
- currentItem && Miniflux.Item.MarkAsRemoved(currentItem);
+ if (currentItem) {
+ Miniflux.Item.MarkAsRemoved(currentItem);
+ }
break;
case 'bookmark':
- currentItem && Miniflux.Item.SwitchBookmark(currentItem);
+ if (currentItem) {
+ Miniflux.Item.SwitchBookmark(currentItem);
+ }
break;
case 'download-item':
- currentItem && Miniflux.Item.DownloadContent(currentItem);
+ if (currentItem) {
+ Miniflux.Item.DownloadContent(currentItem);
+ }
break;
case 'mark-feed-read':
var feed_id = document.getElementById('listing').getAttribute('data-feed-id');
@@ -150,7 +162,9 @@ Miniflux.Event = (function() {
switch (e.key || e.which) {
case 'd':
case 100:
- currentItem && Miniflux.Item.DownloadContent(currentItem);
+ if (currentItem) {
+ Miniflux.Item.DownloadContent(currentItem);
+ }
break;
case 'p':
case 112:
@@ -166,19 +180,27 @@ Miniflux.Event = (function() {
break;
case 'v':
case 118:
- currentItem && Miniflux.Item.OpenOriginal(currentItem);
+ if (currentItem) {
+ Miniflux.Item.OpenOriginal(currentItem);
+ }
break;
case 'o':
case 111:
- currentItem && Miniflux.Item.Show(currentItem);
+ if (currentItem) {
+ Miniflux.Item.Show(currentItem);
+ }
break;
case 'm':
case 109:
- currentItem && Miniflux.Item.SwitchStatus(currentItem);
+ if (currentItem) {
+ Miniflux.Item.SwitchStatus(currentItem);
+ }
break;
case 'f':
case 102:
- currentItem && Miniflux.Item.SwitchBookmark(currentItem);
+ if (currentItem) {
+ Miniflux.Item.SwitchBookmark(currentItem);
+ }
break;
case 'h':
case 104:
@@ -261,8 +283,10 @@ Miniflux.Event = (function() {
ListenTouchEvents: function() {
var touches = null;
var resetTouch = function () {
- touches && touches.element && (touches.element.style.opacity = 1);
- touches && touches.element && (touches.element.style.transform = "");
+ if (touches && touches.element) {
+ touches.element.style.opacity = 1;
+ touches.element.style.transform = "";
+ }
touches = {
"touchstart": {"x":-1, "y":-1},
"touchmove" : {"x":-1, "y":-1},
@@ -274,7 +298,7 @@ Miniflux.Event = (function() {
};
var horizontalSwipe = function () {
if((touches.touchstart.x > -1 && touches.touchmove.x > -1 &&
- ((touches.touchmove.x - touches.touchstart.x) > 30 | touches.swipestarted) &&
+ ((touches.touchmove.x - touches.touchstart.x) > 30 || touches.swipestarted) &&
Math.abs(touches.touchmove.y - touches.touchstart.y) < 75)) {
touches.swipestarted = true;
return touches.touchmove.x - touches.touchstart.x;
@@ -334,7 +358,9 @@ Miniflux.Event = (function() {
element = getTouchElement();
swipedistance = horizontalSwipe();
if(swipedistance > 75) {
- element && Miniflux.Item.MarkAsRead(element);
+ if (element) {
+ Miniflux.Item.MarkAsRead(element);
+ }
if(!element.getAttribute("data-hide")){
resetTouch();
}
diff --git a/assets/js/feed.js b/assets/js/src/feed.js
similarity index 75%
rename from assets/js/feed.js
rename to assets/js/src/feed.js
index bb69123..d372bac 100644
--- a/assets/js/feed.js
+++ b/assets/js/src/feed.js
@@ -6,6 +6,8 @@ Miniflux.Feed = (function() {
// Number of concurrent requests when updating all feeds
var queue_length = 5;
+ var updateInterval = null;
+
return {
Update: function(feed, callback) {
var itemsCounter = feed.querySelector("span.items-count");
@@ -25,8 +27,8 @@ Miniflux.Feed = (function() {
if (lastChecked) lastChecked.innerHTML = lastChecked.getAttribute("data-after-update");
var response = JSON.parse(this.responseText);
- if (response['result']) {
- itemsCounter.innerHTML = response['items_count']['items_unread'] + "/" + response['items_count']['items_total'];
+ if (response.result) {
+ itemsCounter.innerHTML = response.items_count.items_unread + "/" + response.items_count.items_total;
} else {
feed.setAttribute("data-feed-error", "1");
}
@@ -50,22 +52,22 @@ Miniflux.Feed = (function() {
queue_length = nb_concurrent_requests;
}
- var interval = setInterval(function() {
+ updateInterval = setInterval(function() {
while (feeds.length > 0 && queue.length < queue_length) {
var feed = feeds.shift();
queue.push(parseInt(feed.getAttribute('data-feed-id'), 10));
-
- Miniflux.Feed.Update(feed, function(response) {
- var index = queue.indexOf(response['feed_id']);
- if (index >= 0) queue.splice(index, 1);
-
- if (feeds.length === 0 && queue.length === 0) {
- clearInterval(interval);
- Miniflux.Item.CheckForUpdates();
- }
- });
+ Miniflux.Feed.Update(feed, Miniflux.Feed.OnFeedUpdated);
}
}, 100);
+ },
+ OnFeedUpdated: function(response) {
+ var index = queue.indexOf(response.feed_id);
+ if (index >= 0) queue.splice(index, 1);
+
+ if (feeds.length === 0 && queue.length === 0) {
+ clearInterval(updateInterval);
+ Miniflux.Item.CheckForUpdates();
+ }
}
};
})();
diff --git a/assets/js/item.js b/assets/js/src/item.js
similarity index 95%
rename from assets/js/item.js
rename to assets/js/src/item.js
index b3c5285..cac2e84 100644
--- a/assets/js/item.js
+++ b/assets/js/src/item.js
@@ -284,7 +284,9 @@ Miniflux.Item = (function() {
},
OpenOriginal: function(item) {
var link = item.querySelector("a.original");
- if (link) simulateMouseClick(link)
+ if (link) {
+ simulateMouseClick(link);
+ }
},
DownloadContent: function(item) {
var container = document.getElementById("download-item");
@@ -299,9 +301,9 @@ Miniflux.Item = (function() {
var response = JSON.parse(request.responseText);
container.className = "";
- if (response['result']) {
+ if (response.result) {
var content = document.getElementById("item-content");
- if (content) content.innerHTML = response['content'];
+ if (content) content.innerHTML = response.content;
container.innerHTML = container.getAttribute("data-after-message");
}
@@ -344,7 +346,7 @@ Miniflux.Item = (function() {
var tag = document.querySelector(tags[i]);
if (tag) {
- tag.dir = tag.dir == "" ? "rtl" : "";
+ tag.dir = tag.dir === "" ? "rtl" : "";
}
}
},
@@ -359,10 +361,10 @@ Miniflux.Item = (function() {
var request = new XMLHttpRequest();
request.onload = function() {
- var first_run = (latest_feeds_items.length === 0);
+ var first_run = latest_feeds_items.length === 0;
var current_unread = false;
var response = JSON.parse(this.responseText);
- var last_items_timestamps = response['last_items_timestamps'];
+ var last_items_timestamps = response.last_items_timestamps;
for (var i = 0; i < last_items_timestamps.length; i++) {
var current_feed = last_items_timestamps[i];
@@ -374,12 +376,12 @@ Miniflux.Item = (function() {
}
}
- Miniflux.App.Log('first_run: ' + first_run + ', current_unread: ' + current_unread + ', response.nbUnread: ' + response['nbUnread'] + ', nbUnreadItems: ' + nbUnreadItems);
+ Miniflux.App.Log('first_run: ' + first_run + ', current_unread: ' + current_unread + ', response.nbUnread: ' + response.nbUnread + ', nbUnreadItems: ' + nbUnreadItems);
- if (! document.hidden && (response['nb_unread_items'] !== nbUnreadItems || unreadItems)) {
+ if (! document.hidden && (response.nb_unread_items !== nbUnreadItems || unreadItems)) {
Miniflux.App.Log('Counter changed! Updating unread counter.');
unreadItems = false;
- nbUnreadItems = response['nb_unread_items'];
+ nbUnreadItems = response.nb_unread_items;
updateCounters();
}
else if (document.hidden && ! first_run && current_unread) {
diff --git a/assets/js/nav.js b/assets/js/src/nav.js
similarity index 95%
rename from assets/js/nav.js
rename to assets/js/src/nav.js
index 5ffcb13..560bc5c 100644
--- a/assets/js/nav.js
+++ b/assets/js/src/nav.js
@@ -114,9 +114,12 @@ Miniflux.Nav = (function() {
},
ToggleMenuMore: function () {
var menu = document.getElementById("menu-more");
- menu.hasAttribute("class")
- ? menu.removeAttribute("class")
- : menu.setAttribute("class", "hide");
+
+ if (menu.hasAttribute("class")) {
+ menu.removeAttribute("class");
+ } else {
+ menu.setAttribute("class", "hide");
+ }
},
IsListing: isListing
};
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..4a01a6b
--- /dev/null
+++ b/package.json
@@ -0,0 +1,6 @@
+{
+ "dependencies": {
+ "jshint": "^2.9.4",
+ "uglify-js": "^2.7.5"
+ }
+}