From bc503d49cd573263d6494372f728e6c712017a40 Mon Sep 17 00:00:00 2001 From: Frederic Guillot Date: Mon, 2 Jan 2017 19:21:15 -0500 Subject: [PATCH] Minify Javascript and add automated syntax check on the CI --- .dockerignore | 2 ++ .gitignore | 1 + .travis.yml | 2 ++ ChangeLog | 1 + Makefile | 17 ++++++----- app/templates/layout.php | 2 +- assets/js/app.min.js | 2 ++ assets/js/{ => src}/app.js | 6 ++-- assets/js/{ => src}/event.js | 58 ++++++++++++++++++++++++++---------- assets/js/{ => src}/feed.js | 28 +++++++++-------- assets/js/{ => src}/item.js | 20 +++++++------ assets/js/{ => src}/nav.js | 9 ++++-- package.json | 6 ++++ 13 files changed, 101 insertions(+), 53 deletions(-) create mode 100644 assets/js/app.min.js rename assets/js/{ => src}/app.js (85%) rename assets/js/{ => src}/event.js (86%) rename assets/js/{ => src}/feed.js (75%) rename assets/js/{ => src}/item.js (95%) rename assets/js/{ => src}/nav.js (95%) create mode 100644 package.json 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" + } +}