From 952c06d16141f068287eaca9386d7bc6c43f0fbd Mon Sep 17 00:00:00 2001 From: Cédric Bonhomme Date: Mon, 22 Jun 2020 23:41:06 +0200 Subject: Updated bootstrap to version 5.0.0-alpha1 and removed dependency to jQuery. --- newspipe/static/js/articles.js | 275 +++++++++++++++++-------------------- newspipe/static/js/feed.js | 84 ++++++----- newspipe/templates/categories.html | 2 +- newspipe/templates/layout.html | 8 +- newspipe/templates/management.html | 18 +-- package-lock.json | 52 +------ package.json | 9 +- poetry.lock | 18 +-- 8 files changed, 202 insertions(+), 264 deletions(-) diff --git a/newspipe/static/js/articles.js b/newspipe/static/js/articles.js index 99a5df4a..1075a7ef 100644 --- a/newspipe/static/js/articles.js +++ b/newspipe/static/js/articles.js @@ -20,154 +20,135 @@ API_ROOT = '/api/v2.0/' -if (typeof jQuery === 'undefined') { throw new Error('Requires jQuery') } function change_unread_counter(feed_id, increment) { - var new_value = parseInt($("#unread-"+feed_id).text()) + increment; - $("#unread-"+feed_id).text(new_value); - $("#total-unread").text(parseInt($("#total-unread").text()) + increment); + console.log(document.getElementById("unread-"+feed_id)); + + el = document.getElementById("unread-"+feed_id) + if (el != null) { + var new_value = parseInt(el.textContent) + increment; + document.getElementById("unread-"+feed_id).textContent = new_value; + } + + document.getElementById("total-unread").textContent = parseInt(document.getElementById("total-unread").textContent) + increment; + if (new_value == 0) { - $("#unread-"+feed_id).hide(); - } else { - $("#unread-"+feed_id).show(); + document.getElementById("unread-"+feed_id).display = "none"; } } -+function ($) { - // Mark an article as read when it is opened in a new table - $('.open-article').on('click', function(e) { - var feed_id = $(this).parent().parent().attr("data-feed"); - var filter = $('#filters').attr("data-filter"); - if (filter == "unread") { - $(this).parent().parent().remove(); - change_unread_counter(feed_id, -1); +// Mark an article as read when it is opened in a new table +document.getElementsByClassName('open-article').onclick = function fun() { + var feed_id = $(this).parentNode.parentNode.attr("data-feed"); + var filter = $('#filters').attr("data-filter"); + if (filter == "unread") { + $(this).parentNode.parentNode.remove(); + change_unread_counter(feed_id, -1); + } +}; + + +// Mark an article as read or unread. +var nodes = document.getElementsByClassName('readed'); +Array.prototype.map.call(nodes, function(node) { + node.onclick = function() { + var article_id = node.parentNode.parentNode.parentNode.getAttribute("data-article"); + var feed_id = node.parentNode.parentNode.parentNode.getAttribute("data-feed"); + var filter = document.getElementById('filters').getAttribute("data-filter"); + + var data; + if (node.classList.contains('fa-square-o')) { + data = JSON.stringify({ + readed: false + }) + if (filter == "read") { + node.parentNode.parentNode.parentNode.remove(); + } + else { + // here, filter == "all" + // node.parentNode.parentNode.parentNode.children("td:nth-child(2)").css( "font-weight", "bold" ); + node.classList.remove('fa-square-o'); + node.classList.add('fa-check-square-o'); + } + change_unread_counter(feed_id, 1); + } + else { + data = JSON.stringify({readed: true}) + if (filter == "unread") { + node.parentNode.parentNode.parentNode.remove(); + } + else { + // here, filter == "all" + // node.parentNode.parentNode.parentNode.children("td:nth-child(2)").css( "font-weight", "normal" ); + node.classList.remove('fa-check-square-o'); + node.classList.add('fa-square-o'); + } + change_unread_counter(feed_id, -1); } - }); - - - - // Mark an article as read or unread. - $('.readed').on('click', function() { - var article_id = $(this).parent().parent().parent().attr("data-article"); - var feed_id = $(this).parent().parent().parent().attr("data-feed"); - var filter = $('#filters').attr("data-filter"); - - var data; - if ($(this).hasClass('fa-square-o')) { - data = JSON.stringify({ - readed: false - }) - if (filter == "read") { - $(this).parent().parent().parent().remove(); - } - else { - // here, filter == "all" - $(this).parent().parent().parent().children("td:nth-child(2)").css( "font-weight", "bold" ); - $(this).removeClass('fa-square-o').addClass('fa-check-square-o'); - } - change_unread_counter(feed_id, 1); - } - else { - data = JSON.stringify({readed: true}) - if (filter == "unread") { - $(this).parent().parent().parent().remove(); - } - else { - // here, filter == "all" - $(this).parent().parent().parent().children("td:nth-child(2)").css( "font-weight", "normal" ); - $(this).removeClass('fa-check-square-o').addClass('fa-square-o'); - } - change_unread_counter(feed_id, -1); - } - // sends the updates to the server - $.ajax({ - type: 'PUT', - // Provide correct Content-Type, so that Flask will know how to process it. - contentType: 'application/json', - // Encode your data as JSON. - data: data, - // This is the type of data you're expecting back from the server. - url: API_ROOT + "article/" + article_id, - success: function (result) { - //console.log(result); - }, - error: function(XMLHttpRequest, textStatus, errorThrown){ - console.log(XMLHttpRequest.responseText); - } - }); - }); - - - - // Like or unlike an article - $('.like').on('click', function() { - var article_id = $(this).parent().parent().parent().attr("data-article"); - var data; - if ($(this).hasClass("fa-heart")) { - data = JSON.stringify({like: false}) - $(this).removeClass('fa-heart').addClass('fa-heart-o'); - if(window.location.pathname.indexOf('/favorites') != -1) { - $(this).parent().parent().parent().remove(); - } - } - else { - data = JSON.stringify({like: true}) - $(this).removeClass('fa-heart-o').addClass('fa-heart'); - } + // sends the updates to the server + fetch(API_ROOT + "article/" + article_id, { + method: "PUT", + headers: { + 'Content-Type': 'application/json', + }, + body: data + }).then(res => { + console.log("Request complete! response:", res); + }).catch((error) => { + console.error('Error:', error); + });; + } +}); + + + +// Like or unlike an article +var nodes = document.getElementsByClassName('like'); +Array.prototype.map.call(nodes, function(node) { + node.onclick = function() { + var article_id = node.parentNode.parentNode.parentNode.getAttribute('data-article'); + var data; + if (node.classList.contains("fa-heart")) { + data = JSON.stringify({like: false}); + node.classList.remove('fa-heart'); + node.classList.add('fa-heart-o'); + if(window.location.pathname.indexOf('/favorites') != -1) { + node.parentNode.parentNode.parentNode.remove(); + } + } + else { + data = JSON.stringify({like: true}) + node.classList.remove('fa-heart-o'); + node.classList.add('fa-heart'); + } - // sends the updates to the server - $.ajax({ - type: 'PUT', - // Provide correct Content-Type, so that Flask will know how to process it. - contentType: 'application/json', - // Encode your data as JSON. - data: data, - // This is the type of data you're expecting back from the server. - url: API_ROOT + "article/" + article_id, - success: function (result) { - //console.log(result); - }, - error: function(XMLHttpRequest, textStatus, errorThrown){ - console.log(XMLHttpRequest.responseText); - } - }); - }); - - - - // Delete an article - $('.delete').on('click', function() { - var r = confirm('You are going to delete this article.'); - - if (r == true) { - var feed_id = $(this).parent().parent().parent().attr("data-feed"); - var article_id = $(this).parent().parent().parent().attr("data-article"); - $(this).parent().parent().parent().remove(); - - // sends the updates to the server - $.ajax({ - type: 'DELETE', - url: API_ROOT + "article/" + article_id, - success: function (result) { - change_unread_counter(feed_id, -1); - }, - error: function(XMLHttpRequest, textStatus, errorThrown){ - console.log(XMLHttpRequest.responseText); - } - }); - } - }); + // sends the updates to the server + fetch(API_ROOT + "article/" + article_id, { + method: "PUT", + headers: { + 'Content-Type': 'application/json', + }, + body: data + }).then(res => { + console.log("Request complete! response:", res); + }).catch((error) => { + console.error('Error:', error); + });; + } +}); // Delete all duplicate articles (used in the page /duplicates) - $('.delete-all').click(function(){ + var nodes = document.getElementsByClassName('delete-all'); + Array.prototype.map.call(nodes, function(node) { + node.onclick = function() { var data = []; - var columnNo = $(this).parent().index(); - $(this).closest("table") + var columnNo = node.parentNode.index(); + node.closest("table") .find("tr td:nth-child(" + (columnNo+1) + ")") .each(function(line, column) { data.push(parseInt(column.id)); @@ -176,20 +157,16 @@ function change_unread_counter(feed_id, increment) { data = JSON.stringify(data); // sends the updates to the server - $.ajax({ - type: 'DELETE', - // Provide correct Content-Type, so that Flask will know how to process it. - contentType: 'application/json', - data: data, - url: API_ROOT + "articles", - success: function (result) { - //console.log(result); - }, - error: function(XMLHttpRequest, textStatus, errorThrown){ - console.log(XMLHttpRequest.responseText); - } - }); - - }); - -}(jQuery); + fetch(API_ROOT + "articles", { + method: "DELETE", + headers: { + 'Content-Type': 'application/json', + }, + body: data + }).then(res => { + console.log("Request complete! response:", res); + }).catch((error) => { + console.error('Error:', error); + });; + } + }); diff --git a/newspipe/static/js/feed.js b/newspipe/static/js/feed.js index ab024496..ccbcd54c 100644 --- a/newspipe/static/js/feed.js +++ b/newspipe/static/js/feed.js @@ -1,46 +1,56 @@ -$('.container').on('click', '#add-feed-filter-row', function() { - $('#filters-container').append( - '
' - + ' ' - + ' ' - + ' ' - + ' ' - + ' ' - + '
'); -}); -$('.container').on('click', '.del-feed-filter-row', function() { - $(this).parent().remove(); -}); +var node = document.getElementById('add-feed-filter-row'); +if (node != null) { + node.onclick = function() { + document.getElementById('filters-container').innerHTML = + '
' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '
'; + } +} + +var nodes = document.getElementsByClassName('del-feed-filter-row'); +Array.prototype.map.call(nodes, function(node) { + node.onclick = function() { + node.parentNode.remove(); + } +}) // Delete a feed -$('.delete-feed').on('click', function() { +var nodes = document.getElementsByClassName('delete-feed'); +Array.prototype.map.call(nodes, function(node) { + node.onclick = function() { var r = confirm('You are going to delete this feed.'); if (r == true) { - var feed_id = $(this).parent().parent().parent().attr("data-feed"); - $(this).parent().parent().parent().remove(); - $('.feed-menu[data-feed='+feed_id+']').remove(); + var feed_id = node.parentNode.parentNode.parentNode.getAttribute("data-feed"); + node.parentNode.parentNode.parentNode.remove(); + // $('.feed-menu[data-feed='+feed_id+']').remove(); // sends the updates to the server - $.ajax({ - type: 'DELETE', - url: API_ROOT + "feed/" + feed_id, - success: function (result) { - // change_unread_counter(feed_id, -1); - }, - error: function(XMLHttpRequest, textStatus, errorThrown){ - console.log(XMLHttpRequest.responseText); - } - }); + fetch(API_ROOT + "feed/" + feed_id, { + method: "DELETE", + headers: { + 'Content-Type': 'application/json', + }, + }).then(res => { + console.log("Request complete! response:", res); + }).catch((error) => { + console.error('Error:', error); + });; } -}); + } +}) diff --git a/newspipe/templates/categories.html b/newspipe/templates/categories.html index ea5388a3..57c050df 100644 --- a/newspipe/templates/categories.html +++ b/newspipe/templates/categories.html @@ -1,7 +1,7 @@ {% extends "layout.html" %} {% block content %}
-

{{ _("You have %(categories)d categories · Add a %(start_link)scategory%(end_link)s", categories=categories|count, start_link=("" % url_for("category.form"))|safe, end_link=""|safe) }}

+

{{ _("You have %(categories)d categories · %(start_link)sAdd%(end_link)s a category", categories=categories|count, start_link=("" % url_for("category.form"))|safe, end_link=""|safe) }}

{% if categories|count == 0 %}

{{_("No category")}}

{% else %} diff --git a/newspipe/templates/layout.html b/newspipe/templates/layout.html index 1eedfa52..4783e9d6 100644 --- a/newspipe/templates/layout.html +++ b/newspipe/templates/layout.html @@ -10,22 +10,17 @@ - - - - - - {% endblock %} {% block menu %}
{% endblock %}
diff --git a/newspipe/templates/management.html b/newspipe/templates/management.html index eb5dbeb9..19173a2b 100644 --- a/newspipe/templates/management.html +++ b/newspipe/templates/management.html @@ -68,17 +68,17 @@

{{ _('Export feeds to OPML.') }}

-
- - +
+ +
-
- - +
+ +
-
- - +
+ +
diff --git a/package-lock.json b/package-lock.json index 5c64346f..af1c3bc7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,59 +5,19 @@ "requires": true, "dependencies": { "bootstrap": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.0.tgz", - "integrity": "sha512-Z93QoXvodoVslA+PWNdk23Hze4RBYIkpb5h8I2HY2Tu2h7A0LpAgLcyrhrSUyo2/Oxm2l1fRZPs1e5hnxnliXA==" - }, - "bootstrap-select": { - "version": "1.13.17", - "resolved": "https://registry.npmjs.org/bootstrap-select/-/bootstrap-select-1.13.17.tgz", - "integrity": "sha512-LbzSQumoZNYGuoYMpShKIHbJ2qUWFLI0qVHVeKqw5+nfhtMxz+Gre1+IuI3X74bTzQfalBqDKc8fS8tZMdciWg==" - }, - "datatables": { - "version": "1.10.18", - "resolved": "https://registry.npmjs.org/datatables/-/datatables-1.10.18.tgz", - "integrity": "sha512-ntatMgS9NN6UMpwbmO+QkYJuKlVeMA2Mi0Gu/QxyIh+dW7ZjLSDhPT2tWlzjpIWEkDYgieDzS9Nu7bdQCW0sbQ==", - "requires": { - "jquery": ">=1.7" - } - }, - "datatables.net": { - "version": "1.10.21", - "resolved": "https://registry.npmjs.org/datatables.net/-/datatables.net-1.10.21.tgz", - "integrity": "sha512-/bSZtxmf3GTpYcvEmwZ8q26I1yhSx8qklR2B+s1K8+/51UW/zc2zTYwJMqr/Z+iCYixAc00ildj4g2x0Qamolw==", - "requires": { - "jquery": ">=1.7" - } - }, - "datatables.net-bs4": { - "version": "1.10.21", - "resolved": "https://registry.npmjs.org/datatables.net-bs4/-/datatables.net-bs4-1.10.21.tgz", - "integrity": "sha512-F9zabYw8ZLXfjvj2S+BdnbkEUsL48bJwWxQFrA47cOXrIvsMhW8nmqPZcIMK4ko3k1i74nbpWLO1t+vueQKoXQ==", - "requires": { - "datatables.net": "1.10.21", - "jquery": ">=1.7" - } + "version": "5.0.0-alpha1", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.0.0-alpha1.tgz", + "integrity": "sha512-iwKneP2pLXl8lN0YpnOuOARiNPTzmh/4cw+Un86u4OqrMLuQpyMC7nO07hvivvcg0B/ektJPjuPnS1s+YmRK9A==" }, "fork-awesome": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/fork-awesome/-/fork-awesome-1.1.7.tgz", "integrity": "sha512-IHI7XCSXrKfUIWslse8c/PaaVDT1oBaYge+ju40ihL2ooiQeBpTr4wvIXhgTd2NuhntlvX+M5jYHAPTzNlmv0g==" }, - "jquery": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz", - "integrity": "sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg==" - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - }, "moment": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.26.0.tgz", - "integrity": "sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw==" + "version": "2.27.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.27.0.tgz", + "integrity": "sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==" }, "popper.js": { "version": "1.16.1", diff --git a/package.json b/package.json index 5cb4c04f..114050f7 100644 --- a/package.json +++ b/package.json @@ -4,14 +4,9 @@ "license": "AGPL-3.0", "private": true, "dependencies": { - "bootstrap": "^4.5.0", - "bootstrap-select": "^1.13.17", - "datatables": "^1.10.18", - "datatables.net-bs4": "^1.10.21", + "bootstrap": "^5.0.0-alpha1", "fork-awesome": "^1.1.7", - "jquery": "^3.5.1", - "lodash": "^4.17.15", - "moment": "^2.26.0", + "moment": "^2.27.0", "popper.js": "^1.16.1" }, "engines": { diff --git a/poetry.lock b/poetry.lock index 170cd4e5..85f6728d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -100,7 +100,7 @@ description = "Python package for providing Mozilla's CA Bundle." name = "certifi" optional = false python-versions = "*" -version = "2020.4.5.2" +version = "2020.6.20" [[package]] category = "main" @@ -132,7 +132,7 @@ description = "the modular source code checker: pep8 pyflakes and co" name = "flake8" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" -version = "3.8.2" +version = "3.8.3" [package.dependencies] mccabe = ">=0.6.0,<0.7.0" @@ -443,7 +443,7 @@ description = "Python HTTP for Humans." name = "requests" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "2.23.0" +version = "2.24.0" [package.dependencies] certifi = ">=2017.4.17" @@ -614,8 +614,8 @@ blinker = [ {file = "blinker-1.4.tar.gz", hash = "sha256:471aee25f3992bd325afa3772f1063dbdbbca947a041b8b89466dc00d606f8b6"}, ] certifi = [ - {file = "certifi-2020.4.5.2-py2.py3-none-any.whl", hash = "sha256:9cd41137dc19af6a5e03b630eefe7d1f458d964d406342dd3edf625839b944cc"}, - {file = "certifi-2020.4.5.2.tar.gz", hash = "sha256:5ad7e9a056d25ffa5082862e36f119f7f7cec6457fa07ee2f8c339814b80c9b1"}, + {file = "certifi-2020.6.20-py2.py3-none-any.whl", hash = "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41"}, + {file = "certifi-2020.6.20.tar.gz", hash = "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3"}, ] chardet = [ {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, @@ -631,8 +631,8 @@ feedparser = [ {file = "feedparser-5.2.1.zip", hash = "sha256:cd2485472e41471632ed3029d44033ee420ad0b57111db95c240c9160a85831c"}, ] flake8 = [ - {file = "flake8-3.8.2-py2.py3-none-any.whl", hash = "sha256:ccaa799ef9893cebe69fdfefed76865aeaefbb94cb8545617b2298786a4de9a5"}, - {file = "flake8-3.8.2.tar.gz", hash = "sha256:c69ac1668e434d37a2d2880b3ca9aafd54b3a10a3ac1ab101d22f29e29cf8634"}, + {file = "flake8-3.8.3-py2.py3-none-any.whl", hash = "sha256:15e351d19611c887e482fb960eae4d44845013cc142d42896e9862f775d8cf5c"}, + {file = "flake8-3.8.3.tar.gz", hash = "sha256:f04b9fcbac03b0a3e58c0ab3a0ecc462e023a9faf046d57794184028123aa208"}, ] flask = [ {file = "Flask-1.1.2-py2.py3-none-any.whl", hash = "sha256:8a4fdd8936eba2512e9c85df320a37e694c93945b33ef33c89946a340a238557"}, @@ -843,8 +843,8 @@ pytz = [ {file = "pytz-2020.1.tar.gz", hash = "sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048"}, ] requests = [ - {file = "requests-2.23.0-py2.py3-none-any.whl", hash = "sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee"}, - {file = "requests-2.23.0.tar.gz", hash = "sha256:b3f43d496c6daba4493e7c431722aeb7dbc6288f52a6e04e7b6023b0247817e6"}, + {file = "requests-2.24.0-py2.py3-none-any.whl", hash = "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"}, + {file = "requests-2.24.0.tar.gz", hash = "sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b"}, ] requests-futures = [ {file = "requests-futures-1.0.0.tar.gz", hash = "sha256:35547502bf1958044716a03a2f47092a89efe8f9789ab0c4c528d9c9c30bc148"}, -- cgit