Do not use anymore Closure compiler for Javascript
This commit is contained in:
parent
aaf87eb41c
commit
27d094c19e
4
.dockerignore
Normal file
4
.dockerignore
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
.idea
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
.dockerignore
|
22
Makefile
Normal file
22
Makefile
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
JS_FILE = assets/js/all.js
|
||||||
|
CONTAINER = miniflux
|
||||||
|
IMAGE = miniflux/miniflux
|
||||||
|
TAG = latest
|
||||||
|
|
||||||
|
docker-image:
|
||||||
|
@ docker build -t $(IMAGE):$(TAG) .
|
||||||
|
|
||||||
|
docker-push:
|
||||||
|
@ docker push $(IMAGE)
|
||||||
|
|
||||||
|
docker-destroy:
|
||||||
|
@ docker rmi $(IMAGE)
|
||||||
|
|
||||||
|
docker-run:
|
||||||
|
@ docker run --rm --name $(CONTAINER) -P $(IMAGE):$(TAG)
|
||||||
|
|
||||||
|
js:
|
||||||
|
@ rm -f ${JS_FILE}
|
||||||
|
@ echo "/* AUTO GENERATED FILE, DO NOT MODIFY THIS FILE, USE 'make js' */" > ${JS_FILE}
|
||||||
|
@ cat assets/js/app.js assets/js/feed.js assets/js/item.js assets/js/event.js assets/js/nav.js >> ${JS_FILE}
|
||||||
|
@ echo "Miniflux.App.Run();" >> ${JS_FILE}
|
968
assets/js/all.js
Normal file
968
assets/js/all.js
Normal file
@ -0,0 +1,968 @@
|
|||||||
|
/* AUTO GENERATED FILE, DO NOT MODIFY THIS FILE, USE 'make js' */
|
||||||
|
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*1000);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Miniflux.App.Log('Frontend updatecheck disabled');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
request.open("POST", "?action=get-config", true);
|
||||||
|
request.send(JSON.stringify(['frontend_updatecheck_interval']));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
||||||
|
Miniflux.Feed = (function() {
|
||||||
|
|
||||||
|
// List of subscriptions
|
||||||
|
var feeds = [];
|
||||||
|
|
||||||
|
// List of feeds currently updating
|
||||||
|
var queue = [];
|
||||||
|
|
||||||
|
// Number of concurrent requests when updating all feeds
|
||||||
|
var queue_length = 5;
|
||||||
|
|
||||||
|
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])"));
|
||||||
|
|
||||||
|
// Check if a custom amount of concurrent requests was defined
|
||||||
|
if (nb_concurrent_requests) {
|
||||||
|
queue_length = nb_concurrent_requests;
|
||||||
|
}
|
||||||
|
|
||||||
|
var interval = 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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();Miniflux.Item = (function() {
|
||||||
|
|
||||||
|
// timestamp of the latest item per feed ever seen
|
||||||
|
var latest_feeds_items = [];
|
||||||
|
|
||||||
|
// indicator for new unread items
|
||||||
|
var unreadItems = false;
|
||||||
|
|
||||||
|
var nbUnreadItems = function() {
|
||||||
|
var navCounterElement = document.getElementById("nav-counter");
|
||||||
|
|
||||||
|
if (navCounterElement) {
|
||||||
|
counter = parseInt(navCounterElement.textContent, 10) || 0;
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
|
||||||
|
var nbPageItems = function() {
|
||||||
|
var pageCounterElement = document.getElementById("page-counter");
|
||||||
|
|
||||||
|
if (pageCounterElement) {
|
||||||
|
counter = parseInt(pageCounterElement.textContent, 10) || 0;
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
|
||||||
|
function simulateMouseClick(element)
|
||||||
|
{
|
||||||
|
var event = document.createEvent("MouseEvents");
|
||||||
|
event.initEvent("mousedown", true, true);
|
||||||
|
element.dispatchEvent(event);
|
||||||
|
|
||||||
|
var event = document.createEvent("MouseEvents");
|
||||||
|
event.initEvent("mouseup", true, true);
|
||||||
|
element.dispatchEvent(event);
|
||||||
|
|
||||||
|
element.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getItemID(item)
|
||||||
|
{
|
||||||
|
item_id = item.getAttribute("data-item-id");
|
||||||
|
return item_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeLabel(link)
|
||||||
|
{
|
||||||
|
if (link && link.hasAttribute("data-reverse-title") && link.hasAttribute("title")) {
|
||||||
|
var title = link.getAttribute("title");
|
||||||
|
link.setAttribute("title", link.getAttribute("data-reverse-title"));
|
||||||
|
link.setAttribute("data-reverse-title", title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeBookmarkLabel(item)
|
||||||
|
{
|
||||||
|
var link = item.querySelector(".bookmark-icon");
|
||||||
|
changeLabel(link);
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeStatusLabel(item)
|
||||||
|
{
|
||||||
|
var link = item.querySelector(".read-icon");
|
||||||
|
changeLabel(link);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showItemAsRead(item)
|
||||||
|
{
|
||||||
|
if (item.getAttribute("data-item-status") === 'read') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.getAttribute("data-hide")) {
|
||||||
|
hideItem(item);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
item.setAttribute("data-item-status", "read");
|
||||||
|
changeStatusLabel(item);
|
||||||
|
|
||||||
|
// Change action
|
||||||
|
var link = item.querySelector(".read-icon");
|
||||||
|
if (link) link.setAttribute("data-action", "mark-unread");
|
||||||
|
}
|
||||||
|
|
||||||
|
nbUnreadItems--;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showItemAsUnread(item)
|
||||||
|
{
|
||||||
|
if (item.getAttribute("data-item-status") === 'unread') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.getAttribute("data-hide")) {
|
||||||
|
hideItem(item);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
item.setAttribute("data-item-status", "unread");
|
||||||
|
changeStatusLabel(item);
|
||||||
|
|
||||||
|
// Change action
|
||||||
|
var link = item.querySelector(".read-icon");
|
||||||
|
if (link) link.setAttribute("data-action", "mark-read");
|
||||||
|
}
|
||||||
|
|
||||||
|
nbUnreadItems++;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideItem(item)
|
||||||
|
{
|
||||||
|
if (Miniflux.Event.lastEventType !== "mouse") {
|
||||||
|
var items = document.getElementsByTagName("article");
|
||||||
|
|
||||||
|
if (items[items.length-1].id === "current-item") {
|
||||||
|
Miniflux.Nav.SelectPreviousItem();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Miniflux.Nav.SelectNextItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item.parentNode.removeChild(item);
|
||||||
|
nbPageItems--;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCounters()
|
||||||
|
{
|
||||||
|
// redirect to unread if we're on a nothing to read page
|
||||||
|
if (window.location.href.indexOf('nothing_to_read=1') > -1 && nbUnreadItems > 0) {
|
||||||
|
window.location.href = '?action=unread';
|
||||||
|
} // reload to get a nothing to read page
|
||||||
|
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 {
|
||||||
|
// special handling while viewing an article.
|
||||||
|
// 1. The article does not have a page-header element
|
||||||
|
// 2. An article could be opened from any page and has the original
|
||||||
|
// page as data-item-page value
|
||||||
|
var itemHeading = document.querySelector("article.item h1:first-of-type");
|
||||||
|
if (itemHeading) {
|
||||||
|
document.title = itemHeading.textContent;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// pagetitle depends on current page
|
||||||
|
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() && sectionElement.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; i < ilen; i++) {
|
||||||
|
showItemAsRead(articles[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
nbUnreadItems = this.responseText;
|
||||||
|
updateCounters();
|
||||||
|
};
|
||||||
|
|
||||||
|
request.open("POST", "?action=mark-feed-as-read&feed_id=" + feed_id, true);
|
||||||
|
request.send();
|
||||||
|
},
|
||||||
|
ToggleRTLMode: function() {
|
||||||
|
var tags = [
|
||||||
|
"#current-item h1",
|
||||||
|
"#item-content",
|
||||||
|
"#listing #current-item h2",
|
||||||
|
"#listing #current-item .preview",
|
||||||
|
"#listing #current-item .preview-full-content"
|
||||||
|
];
|
||||||
|
|
||||||
|
for (var i = 0; i < tags.length; i++) {
|
||||||
|
var tag = document.querySelector(tags[i]);
|
||||||
|
|
||||||
|
if (tag) {
|
||||||
|
tag.dir = tag.dir == "" ? "rtl" : "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hasNewUnread: function() {
|
||||||
|
return unreadItems;
|
||||||
|
},
|
||||||
|
CheckForUpdates: function() {
|
||||||
|
if (document.hidden && unreadItems) {
|
||||||
|
Miniflux.App.Log('We already have updates, no need to check again');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var request = new XMLHttpRequest();
|
||||||
|
request.onload = function() {
|
||||||
|
var first_run = (latest_feeds_items.length === 0);
|
||||||
|
var current_unread = false;
|
||||||
|
var response = JSON.parse(this.responseText);
|
||||||
|
|
||||||
|
for (var feed_id in response['feeds']) {
|
||||||
|
var current_feed = response['feeds'][feed_id];
|
||||||
|
var feed_id = parseInt(feed_id, 10);
|
||||||
|
|
||||||
|
if (! latest_feeds_items.hasOwnProperty(feed_id) || current_feed.time > latest_feeds_items[feed_id]) {
|
||||||
|
Miniflux.App.Log('feed ' + feed_id + ': New item(s)');
|
||||||
|
latest_feeds_items[feed_id] = current_feed.time;
|
||||||
|
|
||||||
|
if (current_feed.status === 'unread') {
|
||||||
|
Miniflux.App.Log('feed ' + feed_id + ': New unread item(s)');
|
||||||
|
current_unread = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Miniflux.App.Log('first_run: ' + first_run + ', current_unread: ' + current_unread + ', response.nbUnread: ' + response['nbUnread'] + ', nbUnreadItems: ' + nbUnreadItems);
|
||||||
|
|
||||||
|
if (! document.hidden && (response['nbUnread'] !== nbUnreadItems || unreadItems)) {
|
||||||
|
Miniflux.App.Log('Counter changed! Updating unread counter.');
|
||||||
|
unreadItems = false;
|
||||||
|
nbUnreadItems = response['nbUnread'];
|
||||||
|
updateCounters();
|
||||||
|
}
|
||||||
|
else if (document.hidden && ! first_run && current_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("POST", "?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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not handle events when there is a focus in form fields
|
||||||
|
var target = e.target || e.srcElement;
|
||||||
|
if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
lastEventType: "",
|
||||||
|
ListenMouseEvents: function() {
|
||||||
|
|
||||||
|
document.onclick = function(e) {
|
||||||
|
if (e.target.hasAttribute("data-action") && e.target.className !== 'original') {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
document.onmouseup = function(e) {
|
||||||
|
// Ignore right mouse button (context menu)
|
||||||
|
if (e.button === 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-select input content
|
||||||
|
if (e.target.nodeName === "INPUT" && e.target.className === "auto-select") {
|
||||||
|
e.target.select();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Application actions
|
||||||
|
var action = e.target.getAttribute("data-action");
|
||||||
|
|
||||||
|
if (action) {
|
||||||
|
|
||||||
|
Miniflux.Event.lastEventType = "mouse";
|
||||||
|
|
||||||
|
var currentItem = function () {
|
||||||
|
element = e.target;
|
||||||
|
|
||||||
|
while (element && element.parentNode) {
|
||||||
|
element = element.parentNode;
|
||||||
|
if (element.tagName && element.tagName.toLowerCase() === 'article') {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}();
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case 'refresh-all':
|
||||||
|
Miniflux.Feed.UpdateAll(e.target.getAttribute("data-concurrent-requests"));
|
||||||
|
break;
|
||||||
|
case 'refresh-feed':
|
||||||
|
currentItem && Miniflux.Feed.Update(currentItem);
|
||||||
|
break;
|
||||||
|
case 'mark-read':
|
||||||
|
currentItem && Miniflux.Item.MarkAsRead(currentItem);
|
||||||
|
break;
|
||||||
|
case 'mark-unread':
|
||||||
|
currentItem && Miniflux.Item.MarkAsUnread(currentItem);
|
||||||
|
break;
|
||||||
|
case 'mark-removed':
|
||||||
|
currentItem && Miniflux.Item.MarkAsRemoved(currentItem);
|
||||||
|
break;
|
||||||
|
case 'bookmark':
|
||||||
|
currentItem && Miniflux.Item.SwitchBookmark(currentItem);
|
||||||
|
break;
|
||||||
|
case 'download-item':
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
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:
|
||||||
|
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:
|
||||||
|
currentItem && Miniflux.Item.OpenOriginal(currentItem);
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
case 111:
|
||||||
|
currentItem && Miniflux.Item.Show(currentItem);
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
case 109:
|
||||||
|
currentItem && Miniflux.Item.SwitchStatus(currentItem);
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
case 102:
|
||||||
|
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: // Q
|
||||||
|
case 'q':
|
||||||
|
case 113: // q
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
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 () {
|
||||||
|
touches && touches.element && (touches.element.style.opacity = 1);
|
||||||
|
touches && touches.element && (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();
|
||||||
|
}
|
||||||
|
swipedistance = horizontalSwipe();
|
||||||
|
|
||||||
|
if(swipedistance > 0) {
|
||||||
|
var element = getTouchElement();
|
||||||
|
if(!element) {resetTouch(); return;}
|
||||||
|
|
||||||
|
touches.element.style.opacity = 1 -
|
||||||
|
((swipedistance > 75) ? 0.9 : swipedistance/75 *0.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) {
|
||||||
|
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 < ilen; i++) {
|
||||||
|
|
||||||
|
if (items[i].id === "current-item") {
|
||||||
|
|
||||||
|
if (i + 1 < ilen) {
|
||||||
|
items[i].id = "item-" + items[i].getAttribute("data-item-id");
|
||||||
|
|
||||||
|
items[i + 1].id = "current-item";
|
||||||
|
scrollPageTo(items[i + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function findPreviousItem()
|
||||||
|
{
|
||||||
|
var items = document.getElementsByTagName("article");
|
||||||
|
|
||||||
|
if (! document.getElementById("current-item")) {
|
||||||
|
|
||||||
|
items[items.length - 1].id = "current-item";
|
||||||
|
scrollPageTo(items[items.length - 1]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
for (var i = items.length - 1; 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()
|
||||||
|
{
|
||||||
|
if (document.getElementById("listing")) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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")
|
||||||
|
},
|
||||||
|
IsListing: isListing
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
||||||
|
Miniflux.App.Run();
|
20
assets/js/all.min.js
vendored
20
assets/js/all.min.js
vendored
@ -1,20 +0,0 @@
|
|||||||
var h=function(){var b=[],d=5;return{l:function(a,c){var d=a.querySelector("span.items-count");if(d){var b=a.getAttribute("data-feed-id"),q=a.querySelector("h2:first-of-type");q.className="loading-icon";var p=new XMLHttpRequest;p.onload=function(){q.className="";a.removeAttribute("data-feed-error");var b=a.querySelector(".feed-last-checked");b&&(b.innerHTML=b.getAttribute("data-after-update"));b=JSON.parse(this.responseText);b.result?d.innerHTML=b.items_count.items_unread+"/"+b.items_count.items_total:
|
|
||||||
a.setAttribute("data-feed-error","1");c?c(b):f.a()};p.open("POST","?action=refresh-feed&feed_id="+b,!0);p.send()}},m:function(a){var c=Array.prototype.slice.call(document.querySelectorAll("article:not([data-feed-disabled])"));a&&(d=a);var k=setInterval(function(){for(;0<c.length&&b.length<d;){var a=c.shift();b.push(parseInt(a.getAttribute("data-feed-id"),10));h.l(a,function(a){a=b.indexOf(a.feed_id);0<=a&&b.splice(a,1);0===c.length&&0===b.length&&(clearInterval(k),f.a())})}},100)}}}(),f=function(){function b(a){var e=
|
|
||||||
document.createEvent("MouseEvents");e.initEvent("mousedown",!0,!0);a.dispatchEvent(e);e=document.createEvent("MouseEvents");e.initEvent("mouseup",!0,!0);a.dispatchEvent(e);a.click()}function d(a){return item_id=a.getAttribute("data-item-id")}function a(a){if(a&&a.hasAttribute("data-reverse-title")&&a.hasAttribute("title")){var e=a.getAttribute("title");a.setAttribute("title",a.getAttribute("data-reverse-title"));a.setAttribute("data-reverse-title",e)}}function c(g){"read"!==g.getAttribute("data-item-status")&&
|
|
||||||
(g.getAttribute("data-hide")?k(g):(g.setAttribute("data-item-status","read"),a(g.querySelector(".read-icon")),(g=g.querySelector(".read-icon"))&&g.setAttribute("data-action","mark-unread")),l--)}function k(a){if("mouse"!==m.c){var e=document.getElementsByTagName("article");"current-item"===e[e.length-1].id?v.g():v.f()}a.parentNode.removeChild(a);r--}function n(){-1<window.location.href.indexOf("nothing_to_read=1")&&0<l?window.location.href="?action=unread":0===r&&window.location.reload();var a=document.getElementById("page-counter");
|
|
||||||
a&&(a.textContent=r||"");document.getElementById("nav-counter").textContent=l||"";var e=document.querySelector("div.page-header h2:first-of-type");if(e)pageHeading=e.firstChild.nodeValue;else if(e=document.querySelector("article.item h1:first-of-type")){document.title=e.textContent;return}switch(document.querySelector("section.page").getAttribute("data-item-page")){case "unread":document.title="Miniflux ("+l+")";break;case "feed-items":document.title="("+r+") "+pageHeading;break;default:document.title=
|
|
||||||
a?pageHeading+" ("+r+")":pageHeading}}function q(a){var e=d(a),b=new XMLHttpRequest;b.onload=function(){v.b()&&(c(a),n())};b.open("POST","?action=mark-item-read&id="+e,!0);b.send()}function p(g){var e=d(g),c=new XMLHttpRequest;c.onload=function(){if(v.b()){if("unread"!==g.getAttribute("data-item-status")){if(g.getAttribute("data-hide"))k(g);else{g.setAttribute("data-item-status","unread");a(g.querySelector(".read-icon"));var c=g.querySelector(".read-icon");c&&c.setAttribute("data-action","mark-read")}l++}n()}};
|
|
||||||
c.open("POST","?action=mark-item-unread&id="+e,!0);c.send()}var u=[],t=!1,l=function(){var a=document.getElementById("nav-counter");if(a)return counter=parseInt(a.textContent,10)||0}(),r=function(){var a=document.getElementById("page-counter");if(a)return counter=parseInt(a.textContent,10)||0}();return{w:q,B:p,A:function(a){var c=d(a),b=new XMLHttpRequest;b.onload=function(){v.b()&&(k(a),"unread"===a.getAttribute("data-item-status")&&l--,n())};b.open("POST","?action=mark-item-removed&id="+c,!0);b.send()},
|
|
||||||
j:function(c){var e=d(c),b="1"===c.getAttribute("data-item-bookmark")?"0":"1",w=new XMLHttpRequest;w.onload=function(){var e=document.querySelector("section.page");v.b()&&"bookmarks"===e.getAttribute("data-item-page")?(k(c),n()):(c.setAttribute("data-item-bookmark",b),a(c.querySelector(".bookmark-icon")))};w.open("POST","?action=bookmark&id="+e+"&value="+b,!0);w.send()},L:function(a){var c=a.getAttribute("data-item-status");"read"===c?p(a):"unread"===c&&q(a)},I:function(a){(a=a.querySelector("a.show"))&&
|
|
||||||
b(a)},F:function(a){(a=a.querySelector("a.original"))&&b(a)},i:function(a){var c=document.getElementById("download-item");if(c){c.innerHTML=" "+c.getAttribute("data-before-message");c.className="loading-icon";var b=new XMLHttpRequest;b.onload=function(){var a=JSON.parse(b.responseText);c.className="";if(a.result){var d=document.getElementById("item-content");d&&(d.innerHTML=a.content);c.innerHTML=c.getAttribute("data-after-message")}else c.innerHTML=c.getAttribute("data-failure-message")};a=d(a);
|
|
||||||
b.open("POST","?action=download-item&id="+a,!0);b.send()}},C:function(a){var b=new XMLHttpRequest;b.onload=function(){for(var a=document.getElementsByTagName("article"),b=0,d=a.length;b<d;b++)c(a[b]);l=this.responseText;n()};b.open("POST","?action=mark-feed-as-read&feed_id="+a,!0);b.send()},M:function(){for(var a=["#current-item h1","#item-content","#listing #current-item h2","#listing #current-item .preview","#listing #current-item .preview-full-content"],c=0;c<a.length;c++){var b=document.querySelector(a[c]);
|
|
||||||
b&&(b.dir=""==b.dir?"rtl":"")}},N:function(){return t},a:function(){if(!document.hidden||!t){var a=new XMLHttpRequest;a.onload=function(){var a=0===u.length,c=!1,b=JSON.parse(this.responseText),d;for(d in b.feeds){var k=b.feeds[d];d=parseInt(d,10);if(!u.hasOwnProperty(d)||k.time>u[d])u[d]=k.time,"unread"===k.status&&(c=!0)}document.hidden||b.nbUnread===l&&!t?document.hidden&&!a&&c&&(t=!0,document.title="\u21bb "+document.title):(t=!1,l=b.nbUnread,n())};a.open("POST","?action=latest-feeds-items",!0);
|
|
||||||
a.send()}}}}(),m=function(){function b(a){if(63!==a.keyCode&&63!==a.which&&(a.ctrlKey||a.shiftKey||a.altKey||a.metaKey))return!0;a=a.target||a.srcElement;return"INPUT"===a.tagName||"TEXTAREA"===a.tagName?!0:!1}var d=[];return{c:"",u:function(){document.onclick=function(a){a.target.hasAttribute("data-action")&&"original"!==a.target.className&&a.preventDefault()};document.onmouseup=function(a){if(2!==a.button)if("INPUT"===a.target.nodeName&&"auto-select"===a.target.className)a.target.select();else{var c=
|
|
||||||
a.target.getAttribute("data-action");if(c){m.c="mouse";var b;a:{for(element=a.target;element&&element.parentNode;)if(element=element.parentNode,element.tagName&&"article"===element.tagName.toLowerCase()){b=element;break a}b=void 0}switch(c){case "refresh-all":h.m(a.target.getAttribute("data-concurrent-requests"));break;case "refresh-feed":b&&h.l(b);break;case "mark-read":b&&f.w(b);break;case "mark-unread":b&&f.B(b);break;case "mark-removed":b&&f.A(b);break;case "bookmark":b&&f.j(b);break;case "download-item":b&&
|
|
||||||
f.i(b);break;case "mark-feed-read":a=document.getElementById("listing").getAttribute("data-feed-id");f.C(a);break;case "close-help":v.h();break;case "show-search":v.K()}}}}},s:function(){document.onkeypress=function(a){if(!b(a))if(m.c="keyboard",d.push(a.key||a.which),"g"===d[0]||103===d[0])switch(d[1]){case void 0:break;case "u":case 117:window.location.href="?action=unread";d=[];break;case "b":case 98:window.location.href="?action=bookmarks";d=[];break;case "h":case 104:window.location.href="?action=history";
|
|
||||||
d=[];break;case "s":case 115:window.location.href="?action=feeds";d=[];break;case "p":case 112:window.location.href="?action=config";d=[];break;default:d=[]}else{d=[];var c=document.getElementById("current-item");switch(a.key||a.which){case "d":case 100:c&&f.i(c);break;case "p":case 112:case "k":case 107:v.g();break;case "n":case 110:case "j":case 106:v.f();break;case "v":case 118:c&&f.F(c);break;case "o":case 111:c&&f.I(c);break;case "m":case 109:c&&f.L(c);break;case "f":case 102:c&&f.j(c);break;
|
|
||||||
case "h":case 104:v.G();break;case "l":case 108:v.D();break;case "r":case 114:h.m();break;case "?":case 63:v.J();break;case "Q":case 81:case "q":case 113:v.h();break;case "z":case 122:f.M()}}};document.onkeydown=function(a){if(!b(a))switch(m.c="keyboard",a.key||a.which){case "ArrowLeft":case "Left":case 37:v.g();break;case "ArrowRight":case "Right":case 39:v.f()}}},v:function(){document.addEventListener("visibilitychange",function(){!document.hidden&&f.N()&&f.a()})}}}(),v=function(){function b(a){var b=
|
|
||||||
pageYOffset+document.documentElement.clientHeight;(0>b-(a.offsetTop+a.offsetHeight)||b-a.offsetTop>document.documentElement.clientHeight)&&window.scrollTo(0,a.offsetTop-10)}function d(){return document.getElementById("listing")?!0:!1}return{D:function(){var a=document.getElementById("next-page");a&&a.click()},G:function(){var a=document.getElementById("previous-page");a&&a.click()},f:function(){var a=document.getElementById("next-item");if(a)a.click();else if(d())if(a=document.getElementsByTagName("article"),
|
|
||||||
document.getElementById("current-item"))for(var c=0,k=a.length;c<k;c++){if("current-item"===a[c].id){c+1<k&&(a[c].id="item-"+a[c].getAttribute("data-item-id"),a[c+1].id="current-item",b(a[c+1]));break}}else a[0].id="current-item",b(a[0])},g:function(){var a=document.getElementById("previous-item");if(a)a.click();else if(d())if(a=document.getElementsByTagName("article"),document.getElementById("current-item"))for(var c=a.length-1;0<=c;c--){if("current-item"===a[c].id){0<=c-1&&(a[c].id="item-"+a[c].getAttribute("data-item-id"),
|
|
||||||
a[c-1].id="current-item",b(a[c-1]));break}}else a[a.length-1].id="current-item",b(a[a.length-1])},J:function(){document.getElementById("help-layer").removeAttribute("class")},h:function(){document.getElementById("help-layer").setAttribute("class","hide")},K:function(){document.getElementById("search-opener").setAttribute("class","hide");document.getElementById("search-form").removeAttribute("class")},b:d}}();
|
|
||||||
({O:function(){},H:function(){m.s();m.u();m.v();this.o()},o:function(){var b=new XMLHttpRequest;b.onload=function(){var b=JSON.parse(this.responseText);0<b.frontend_updatecheck_interval&&(f.a(),setInterval(function(){f.a()},6E4*b.frontend_updatecheck_interval))};b.open("POST","?action=get-config",!0);b.send(JSON.stringify(["frontend_updatecheck_interval"]))}}).H();
|
|
@ -1,15 +1,12 @@
|
|||||||
var Miniflux = {};
|
var Miniflux = {};
|
||||||
|
|
||||||
/**
|
var DEBUG = false;
|
||||||
* @define {boolean}
|
|
||||||
*/
|
|
||||||
var COMPILED = false;
|
|
||||||
|
|
||||||
Miniflux.App = (function() {
|
Miniflux.App = (function() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
Log: function(message) {
|
Log: function(message) {
|
||||||
if (! COMPILED) {
|
if (DEBUG) {
|
||||||
console.log(message);
|
console.log(message);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -28,21 +28,18 @@ Miniflux.Event = (function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
document.onmouseup = function(e) {
|
document.onmouseup = function(e) {
|
||||||
|
// Ignore right mouse button (context menu)
|
||||||
// ignore right mouse button (context menu)
|
|
||||||
if (e.button === 2) {
|
if (e.button === 2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto-select input content
|
// Auto-select input content
|
||||||
|
|
||||||
if (e.target.nodeName === "INPUT" && e.target.className === "auto-select") {
|
if (e.target.nodeName === "INPUT" && e.target.className === "auto-select") {
|
||||||
e.target.select();
|
e.target.select();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Application actions
|
// Application actions
|
||||||
|
|
||||||
var action = e.target.getAttribute("data-action");
|
var action = e.target.getAttribute("data-action");
|
||||||
|
|
||||||
if (action) {
|
if (action) {
|
||||||
@ -304,7 +301,6 @@ Miniflux.Event = (function() {
|
|||||||
window.requestAnimationFrame(drawElement);
|
window.requestAnimationFrame(drawElement);
|
||||||
};
|
};
|
||||||
var touchHandler = function (e) {
|
var touchHandler = function (e) {
|
||||||
//e.preventDefault();
|
|
||||||
if (typeof e.touches != 'undefined' && e.touches.length <= 1) {
|
if (typeof e.touches != 'undefined' && e.touches.length <= 1) {
|
||||||
var touch = e.touches[0];
|
var touch = e.touches[0];
|
||||||
var swipedistance = null;
|
var swipedistance = null;
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
in=assets/js/all.js
|
|
||||||
out=assets/js/all.min.js
|
|
||||||
|
|
||||||
rm -f $in 2>/dev/null
|
|
||||||
rm -f $out 2>/dev/null
|
|
||||||
|
|
||||||
cat assets/js/app.js assets/js/feed.js assets/js/item.js assets/js/event.js assets/js/nav.js > $in
|
|
||||||
echo "Miniflux.App.Run();" >> $in
|
|
||||||
|
|
||||||
output=$(curl -s \
|
|
||||||
-d compilation_level=ADVANCED_OPTIMIZATIONS \
|
|
||||||
-d output_format=text \
|
|
||||||
-d output_info=warnings \
|
|
||||||
-d output_info=errors \
|
|
||||||
-d warning_level=verbose \
|
|
||||||
-d output_file_name=all.min.js \
|
|
||||||
--data-urlencode "js_code@${in}" \
|
|
||||||
https://closure-compiler.appspot.com/compile)
|
|
||||||
|
|
||||||
if [ $(echo "$output" | wc -l) -gt 1 ]; then
|
|
||||||
echo -e "NOTHING DONE. There are issues:\n"
|
|
||||||
echo "$output"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
curl -s "https://closure-compiler.appspot.com/$output" -o "$out";
|
|
||||||
|
|
||||||
rm -f $in
|
|
@ -22,7 +22,7 @@
|
|||||||
<link rel="apple-touch-icon" sizes="144x144" href="assets/img/touch-icon-ipad-retina.png">
|
<link rel="apple-touch-icon" sizes="144x144" href="assets/img/touch-icon-ipad-retina.png">
|
||||||
|
|
||||||
<link href="<?= Helper\css() ?>" rel="stylesheet" media="screen">
|
<link href="<?= Helper\css() ?>" rel="stylesheet" media="screen">
|
||||||
<script type="text/javascript" src="assets/js/all.min.js?<?= filemtime('assets/js/all.min.js') ?>" defer></script>
|
<script type="text/javascript" src="assets/js/all.js?<?= filemtime('assets/js/all.js') ?>" defer></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
|
Loading…
Reference in New Issue
Block a user