fix preview (#4291)

* fix

* Update extra.js

* reorga the scripts

* Update extra.js

* Several fixes
https://github.com/FreshRSS/FreshRSS/pull/4291#issuecomment-1125472321

* More fixes

* Cleaning

* fix pr 4291

* Reorganise some script functions

* Remove unused popup-txt
And associated function openPopupWithMessage

* Fix archiving categories
https://github.com/FreshRSS/FreshRSS/pull/4291#issuecomment-1126924602

* Fix stats
https://github.com/FreshRSS/FreshRSS/pull/4291#issuecomment-1126983134

* Fix direct subscription
E.g. http://localhost/i/?c=subscription&id=735

* Fix subscription add
https://github.com/FreshRSS/FreshRSS/pull/4291#issuecomment-1126991621

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
pull/4370/head
maTh 2 years ago committed by GitHub
parent 0cde4e898f
commit 807ea755e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      app/Controllers/statsController.php
  2. 4
      app/Controllers/subscriptionController.php
  3. 13
      app/layout/layout.phtml
  4. 13
      app/views/helpers/feed/update.phtml
  5. 4
      app/views/helpers/javascript_vars.phtml
  6. 9
      lib/Minz/View.php
  7. 24
      p/scripts/category.js
  8. 176
      p/scripts/extra.js
  9. 153
      p/scripts/feed.js
  10. 158
      p/scripts/main.js
  11. 5
      p/scripts/preview.js
  12. 7
      p/themes/base-theme/template.css
  13. 7
      p/themes/base-theme/template.rtl.css

@ -131,6 +131,7 @@ class FreshRSS_stats_Controller extends FreshRSS_ActionController {
* - last week
*/
public function idleAction() {
FreshRSS_View::appendScript(Minz_Url::display('/scripts/feed.js?' . @filemtime(PUBLIC_PATH . '/scripts/feed.js')));
$feed_dao = FreshRSS_Factory::createFeedDao();
$statsDAO = FreshRSS_Factory::createStatsDAO();
$feeds = $statsDAO->calculateFeedLastDate();

@ -45,6 +45,7 @@ class FreshRSS_subscription_Controller extends FreshRSS_ActionController {
*/
public function indexAction() {
FreshRSS_View::appendScript(Minz_Url::display('/scripts/category.js?' . @filemtime(PUBLIC_PATH . '/scripts/category.js')));
FreshRSS_View::appendScript(Minz_Url::display('/scripts/feed.js?' . @filemtime(PUBLIC_PATH . '/scripts/feed.js')));
FreshRSS_View::prependTitle(_t('sub.title') . ' · ');
$this->view->onlyFeedsWithError = Minz_Request::paramTernary('error');
@ -90,6 +91,8 @@ class FreshRSS_subscription_Controller extends FreshRSS_ActionController {
public function feedAction() {
if (Minz_Request::param('ajax')) {
$this->view->_layout(false);
} else {
FreshRSS_View::appendScript(Minz_Url::display('/scripts/feed.js?' . @filemtime(PUBLIC_PATH . '/scripts/feed.js')));
}
$feedDAO = FreshRSS_Factory::createFeedDao();
@ -323,6 +326,7 @@ class FreshRSS_subscription_Controller extends FreshRSS_ActionController {
* This action displays the page to add a new feed
*/
public function addAction() {
FreshRSS_View::appendScript(Minz_Url::display('/scripts/feed.js?' . @filemtime(PUBLIC_PATH . '/scripts/feed.js')));
FreshRSS_View::prependTitle(_t('sub.title.add') . ' . ');
}
}

@ -77,18 +77,5 @@ if (_t('gen.dir') === 'rtl') {
<span class="msg"><?= $msg ?></span>
<a class="close" href=""><?= _i('close') ?></a>
</div>
<!-- Popup-->
<div id="popup">
<div id="popup-content">
<div id="popup-close" class="popup-row">×</div>
<div id="popup-txt" class="popup-row"></div>
<div id="popup-iframe-container" class="popup-row">
<div id="popup-iframe-sub">
<iframe id="popup-iframe" frameborder="0"></iframe>
</div>
</div>
</div>
</div>
</body>
</html>

@ -1,5 +1,5 @@
<?php /** @var FreshRSS_View $this */ ?>
<div class="post">
<div class="post" id="feed_update">
<h1><?= $this->feed->name() ?></h1>
<div>
@ -591,3 +591,14 @@
</div>
</form>
</div>
<div id="popup">
<div id="popup-content">
<div id="popup-close" class="popup-row">×</div>
<div id="popup-iframe-container" class="popup-row">
<div id="popup-iframe-sub">
<iframe id="popup-iframe" frameborder="0"></iframe>
</div>
</div>
</div>
</div>

@ -22,6 +22,10 @@ echo htmlspecialchars(json_encode(array(
'auth_type' => FreshRSS_Context::$system_conf->auth_type,
'current_view' => Minz_Request::actionName(),
'csrf' => FreshRSS_Auth::csrfToken(),
'mtime' => [
'extra.js' => @filemtime(PUBLIC_PATH . '/scripts/extra.js'),
'feed.js' => @filemtime(PUBLIC_PATH . '/scripts/feed.js'),
],
),
'shortcuts' => array(
'actualize' => @$s['actualize'],

@ -248,6 +248,9 @@ class Minz_View {
}
$scripts .= '<script src="' . $script['url'] . '"';
if (!empty($script['id'])) {
$scripts .= ' id="' . $script['id'] . '"';
}
if ($script['defer']) {
$scripts .= ' defer="defer"';
}
@ -265,20 +268,22 @@ class Minz_View {
return $scripts;
}
public static function prependScript ($url, $cond = false, $defer = true, $async = true) {
public static function prependScript ($url, $cond = false, $defer = true, $async = true, $id = '') {
array_unshift(self::$scripts, array (
'url' => $url,
'cond' => $cond,
'defer' => $defer,
'async' => $async,
'id' => $id,
));
}
public static function appendScript ($url, $cond = false, $defer = true, $async = true) {
public static function appendScript ($url, $cond = false, $defer = true, $async = true, $id = '') {
self::$scripts[] = array (
'url' => $url,
'cond' => $cond,
'defer' => $defer,
'async' => $async,
'id' => $id,
);
}

@ -154,35 +154,11 @@ function init_draggable() {
};
}
function archiving() {
const slider = document.getElementById('slider');
slider.addEventListener('change', function (e) {
if (e.target.id === 'use_default_purge_options') {
slider.querySelectorAll('.archiving').forEach(function (element) {
element.hidden = e.target.checked;
if (!e.target.checked) element.style.visibility = 'visible'; // Help for Edge 44
});
}
});
slider.addEventListener('click', function (e) {
if (e.target.closest('button[type=reset]')) {
const archiving = document.getElementById('use_default_purge_options');
if (archiving) {
slider.querySelectorAll('.archiving').forEach(function (element) {
element.hidden = archiving.getAttribute('data-leave-validation') == 1;
});
}
}
});
}
if (document.readyState && document.readyState !== 'loading') {
init_draggable();
archiving();
} else if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', function () {
init_draggable();
archiving();
}, false);
}
// @license-end

@ -1,23 +1,6 @@
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0
'use strict';
/* globals openNotification, openPopupWithSource, xmlHttpRequestJson */
function fix_popup_preview_selector() {
const link = document.getElementById('popup-preview-selector');
if (!link) {
return;
}
link.addEventListener('click', function (ev) {
const selector_entries = document.getElementById('path_entries').value;
const href = link.href.replace('selector-token', encodeURIComponent(selector_entries));
openPopupWithSource(href);
ev.preventDefault();
});
}
/* globals context, openNotification, xmlHttpRequestJson */
// <crypto form (Web login)>
function poormanSalt() { // If crypto.getRandomValues is not available
@ -98,6 +81,7 @@ function init_crypto_form() {
}
// </crypto form (Web login)>
// <show password>
let timeoutHide;
function showPW_this(ev) {
@ -129,11 +113,83 @@ function hidePW(id_passwordField) {
return false;
}
function init_password_observers() {
document.querySelectorAll('.toggle-password').forEach(function (btn) {
function init_password_observers(parent) {
parent.querySelectorAll('.toggle-password').forEach(function (btn) {
btn.addEventListener('click', showPW_this);
});
}
// </show password>
function init_archiving(parent) {
parent.addEventListener('change', function (e) {
if (e.target.id === 'use_default_purge_options') {
parent.querySelectorAll('.archiving').forEach(function (element) {
element.hidden = e.target.checked;
if (!e.target.checked) element.style.visibility = 'visible'; // Help for Edge 44
});
}
});
parent.addEventListener('click', function (e) {
if (e.target.closest('button[type=reset]')) {
const archiving = document.getElementById('use_default_purge_options');
if (archiving) {
parent.querySelectorAll('.archiving').forEach(function (element) {
element.hidden = archiving.getAttribute('data-leave-validation') == 1;
});
}
}
});
}
// <slider>
const freshrssSliderLoadEvent = new Event('freshrss:slider-load');
function open_slider_listener(ev) {
const a = ev.target.closest('.open-slider');
if (a) {
if (!context.ajax_loading) {
location.href = '#'; // close menu/dropdown
context.ajax_loading = true;
const req = new XMLHttpRequest();
req.open('GET', a.href + '&ajax=1', true);
req.responseType = 'document';
req.onload = function (e) {
const slider = document.getElementById('slider');
const closer = document.getElementById('close-slider');
slider.scrollTop = 0;
slider.innerHTML = this.response.body.innerHTML;
slider.classList.add('active');
closer.classList.add('active');
context.ajax_loading = false;
slider.dispatchEvent(freshrssSliderLoadEvent);
};
req.send();
return false;
}
}
}
function init_slider(slider) {
window.onclick = open_slider_listener;
const closer = document.getElementById('close-slider');
closer.addEventListener('click', function (ev) {
if (data_leave_validation(slider) || confirm(context.i18n.confirmation_default)) {
slider.querySelectorAll('form').forEach(function (f) { f.reset(); });
closer.classList.remove('active');
slider.classList.remove('active');
return true;
} else {
return false;
}
});
if (slider.children.length > 0) {
slider.dispatchEvent(freshrssSliderLoadEvent);
}
}
// </slider>
// overwrites the href attribute from the url input
function updateHref(ev) {
@ -177,8 +233,8 @@ function init_select_observers() {
});
}
function data_leave_validation() {
const ds = document.querySelectorAll('[data-leave-validation]');
function data_leave_validation(parent) {
const ds = parent.querySelectorAll('[data-leave-validation]');
for (let i = ds.length - 1; i >= 0; i--) {
const input = ds[i];
@ -201,71 +257,35 @@ function init_configuration_alert() {
if (window.hasSubmit) {
return;
}
if (!data_leave_validation()) {
if (!data_leave_validation(document.body)) {
return false;
}
};
}
/**
* Allow a <select class="select-show"> to hide/show elements defined by <option data-show="elem-id"></option>
*/
function init_select_show() {
const listener = (select) => {
const options = select.querySelectorAll('option[data-show]');
for (const option of options) {
const elem = document.getElementById(option.dataset.show);
if (elem) {
elem.style.display = option.selected ? 'block' : 'none';
}
}
};
const selects = document.querySelectorAll('select.select-show');
for (const select of selects) {
select.addEventListener('change', (e) => listener(e.target));
listener(select);
}
}
/**
* Automatically validate XPath textarea fields
*/
function init_valid_xpath() {
const listener = (textarea) => {
const evaluator = new XPathEvaluator();
try {
if (textarea.value === '' || evaluator.createExpression(textarea.value) != null) {
textarea.setCustomValidity('');
}
} catch (ex) {
textarea.setCustomValidity(ex);
}
};
const textareas = document.querySelectorAll('textarea.valid-xpath');
for (const textarea of textareas) {
textarea.addEventListener('change', (e) => listener(e.target));
listener(textarea);
}
}
function init_extra() {
function init_extra_afterDOM() {
if (!window.context) {
if (window.console) {
console.log('FreshRSS extra waiting for JS…');
}
window.setTimeout(init_extra, 50); // Wait for all js to be loaded
setTimeout(init_extra_afterDOM, 50);
return;
}
init_crypto_form();
init_password_observers();
init_url_observers();
init_select_observers();
init_configuration_alert();
fix_popup_preview_selector();
init_select_show();
init_valid_xpath();
if (!['normal', 'global', 'reader'].includes(context.current_view)) {
init_crypto_form();
init_password_observers(document.body);
init_url_observers();
init_select_observers();
init_configuration_alert();
const slider = document.getElementById('slider');
if (slider) {
init_slider(slider);
init_archiving(slider);
} else {
init_archiving(document.body);
}
}
if (window.console) {
console.log('FreshRSS extra init done.');
@ -273,13 +293,13 @@ function init_extra() {
}
if (document.readyState && document.readyState !== 'loading') {
init_extra();
init_extra_afterDOM();
} else {
document.addEventListener('DOMContentLoaded', function () {
if (window.console) {
console.log('FreshRSS extra waiting for DOMContentLoaded…');
}
init_extra();
init_extra_afterDOM();
}, false);
}
// @license-end

@ -0,0 +1,153 @@
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0
'use strict';
/* globals init_archiving, init_password_observers, init_slider */
// <popup>
let popup = null;
let popup_iframe_container = null;
let popup_iframe = null;
let popup_working = false;
function openPopupWithSource(source) {
if (popup_working === true) {
return false;
}
popup_working = true;
popup_iframe.src = source;
popup_iframe_container.style.display = 'table-row';
popup.style.display = 'block';
}
function closePopup() {
popup.style.display = 'none';
popup_iframe_container.style.display = 'none';
popup_iframe.src = 'about:blank';
popup_working = false;
}
function init_popup() {
// Fetch elements.
popup = document.getElementById('popup');
if (popup) {
popup_iframe_container = document.getElementById('popup-iframe-container');
popup_iframe = document.getElementById('popup-iframe');
// Configure close button.
document.getElementById('popup-close').addEventListener('click', function (ev) {
closePopup();
});
// Configure close-on-click.
window.addEventListener('click', function (ev) {
if (ev.target == popup) {
closePopup();
}
});
}
}
// </popup>
function init_popup_preview_selector() {
const link = document.getElementById('popup-preview-selector');
if (!link) {
return;
}
link.addEventListener('click', function (ev) {
const selector_entries = document.getElementById('path_entries').value;
const href = link.href.replace('selector-token', encodeURIComponent(selector_entries));
openPopupWithSource(href);
ev.preventDefault();
});
}
/**
* Allow a <select class="select-show"> to hide/show elements defined by <option data-show="elem-id"></option>
*/
function init_select_show(parent) {
const listener = (select) => {
const options = select.querySelectorAll('option[data-show]');
for (const option of options) {
const elem = document.getElementById(option.dataset.show);
if (elem) {
elem.style.display = option.selected ? 'block' : 'none';
}
}
};
const selects = parent.querySelectorAll('select.select-show');
for (const select of selects) {
select.addEventListener('change', (e) => listener(e.target));
listener(select);
}
}
/** Automatically validate XPath textarea fields */
function init_valid_xpath(parent) {
const listener = (textarea) => {
const evaluator = new XPathEvaluator();
try {
if (textarea.value === '' || evaluator.createExpression(textarea.value) != null) {
textarea.setCustomValidity('');
}
} catch (ex) {
textarea.setCustomValidity(ex);
}
};
const textareas = parent.querySelectorAll('textarea.valid-xpath');
for (const textarea of textareas) {
textarea.addEventListener('change', (e) => listener(e.target));
listener(textarea);
}
}
function init_feed_afterDOM() {
if (!window.init_slider) {
if (window.console) {
console.log('FreshRSS feed waiting for JS…');
}
setTimeout(init_feed_afterDOM, 50);
return;
}
const slider = document.getElementById('slider');
if (slider) {
slider.addEventListener('freshrss:slider-load', function (e) {
init_popup();
init_popup_preview_selector();
init_select_show(slider);
init_password_observers(slider);
init_valid_xpath(slider);
});
init_slider(slider);
init_archiving(slider);
} else {
init_archiving(document.body);
init_popup();
init_popup_preview_selector();
init_select_show(document.body);
init_password_observers(document.body);
init_valid_xpath(document.body);
}
if (window.console) {
console.log('FreshRSS feed init done.');
}
}
if (document.readyState && document.readyState !== 'loading') {
init_feed_afterDOM();
} else {
document.addEventListener('DOMContentLoaded', function () {
if (window.console) {
console.log('FreshRSS feed waiting for DOMContentLoaded…');
}
init_feed_afterDOM();
}, false);
}
// @license-end

@ -767,6 +767,17 @@ function openCategory(category_id) {
img.alt = '🔼';
}
function loadJs(name) {
if (!document.getElementById(name)) {
const script = document.createElement('script');
script.setAttribute('id', name);
script.setAttribute('src', '../scripts/' + name + '?' + context.mtime[name]);
script.setAttribute('defer', 'defer');
script.setAttribute('async', 'async');
document.head.appendChild(script);
}
}
function init_column_categories() {
if (context.current_view !== 'normal' && context.current_view !== 'reader') {
return;
@ -821,6 +832,8 @@ function init_column_categories() {
a = ev.target.closest('.tree-folder-items > .feed .dropdown-toggle');
if (a) {
loadJs('extra.js');
loadJs('feed.js');
const itemId = a.closest('.item').id;
const templateId = itemId.substring(0, 2) === 't_' ? 'tag_config_template' : 'feed_config_template';
const id = itemId.substr(2);
@ -1436,139 +1449,6 @@ function init_notifications() {
}
// </notification>
// <slider>
function init_slider_observers() {
const slider = document.getElementById('slider');
const closer = document.getElementById('close-slider');
if (!slider) {
return;
}
window.onclick = open_slider_listener;
closer.addEventListener('click', function (ev) {
if (slider_data_leave_validation() || confirm(context.i18n.confirmation_default)) {
slider.querySelectorAll('form').forEach(function (f) { f.reset(); });
closer.classList.remove('active');
slider.classList.remove('active');
return true;
} else {
return false;
}
});
}
function open_slider_listener(ev) {
const a = ev.target.closest('.open-slider');
if (a) {
if (!context.ajax_loading) {
location.href = '#'; // close menu/dropdown
context.ajax_loading = true;
const req = new XMLHttpRequest();
req.open('GET', a.href + '&ajax=1', true);
req.responseType = 'document';
req.onload = function (e) {
const slider = document.getElementById('slider');
const closer = document.getElementById('close-slider');
slider.innerHTML = this.response.body.innerHTML;
slider.classList.add('active');
closer.classList.add('active');
context.ajax_loading = false;
};
req.send();
return false;
}
}
}
function slider_data_leave_validation() {
const ds = document.querySelectorAll('[data-leave-validation]');
for (let i = ds.length - 1; i >= 0; i--) {
const input = ds[i];
if (input.type === 'checkbox' || input.type === 'radio') {
if (input.checked != input.getAttribute('data-leave-validation')) {
return false;
}
} else if (input.value != input.getAttribute('data-leave-validation')) {
return false;
}
}
return true;
}
// </slider>
// <popup>
let popup = null;
let popup_iframe_container = null;
let popup_iframe = null;
let popup_txt = null;
let popup_working = false;
/* eslint-disable no-unused-vars */
// TODO: Re-enable no-unused-vars
function openPopupWithMessage(msg) {
if (popup_working === true) {
return false;
}
popup_working = true;
popup_txt.innerHTML = msg;
popup_txt.style.display = 'table-row';
popup.style.display = 'block';
}
function openPopupWithSource(source) {
if (popup_working === true) {
return false;
}
popup_working = true;
popup_iframe.src = source;
popup_iframe_container.style.display = 'table-row';
popup.style.display = 'block';
}
/* eslint-enable no-unused-vars */
function closePopup() {
popup.style.display = 'none';
popup_iframe_container.style.display = 'none';
popup_txt.style.display = 'none';
popup_iframe.src = 'about:blank';
popup_working = false;
}
function init_popup() {
// Fetch elements.
popup = document.getElementById('popup');
if (popup) {
popup_iframe_container = document.getElementById('popup-iframe-container');
popup_iframe = document.getElementById('popup-iframe');
popup_txt = document.getElementById('popup-txt');
// Configure close button.
document.getElementById('popup-close').addEventListener('click', function (ev) {
closePopup();
});
// Configure close-on-click.
window.addEventListener('click', function (ev) {
if (ev.target == popup) {
closePopup();
}
});
}
}
// </popup>
// <notifs html5>
let notifs_html5_permission = 'denied';
@ -1853,18 +1733,16 @@ function init_normal() {
};
}
function init_beforeDOM() {
function init_main_beforeDOM() {
document.scrollingElement.scrollTop = 0;
if (['normal', 'reader', 'global'].indexOf(context.current_view) >= 0) {
init_normal();
}
}
function init_afterDOM() {
function init_main_afterDOM() {
removeFirstLoadSpinner();
init_notifications();
init_slider_observers();
init_popup();
init_confirm_action();
const stream = document.getElementById('stream');
if (stream) {
@ -1881,14 +1759,14 @@ function init_afterDOM() {
}
}
init_beforeDOM(); // Can be called before DOM is fully loaded
init_main_beforeDOM(); // Can be called before DOM is fully loaded
if (document.readyState && document.readyState !== 'loading') {
init_afterDOM();
init_main_afterDOM();
} else {
if (window.console) {
console.log('FreshRSS waiting for DOMContentLoaded…');
}
document.addEventListener('DOMContentLoaded', init_afterDOM, false);
document.addEventListener('DOMContentLoaded', init_main_afterDOM, false);
}
// @license-end

@ -18,6 +18,9 @@ function update_ui() {
function init_afterDOM() {
rendered_node = document.getElementById('freshrss_rendered');
if (!rendered_node) {
return;
}
rendered_view = document.getElementById('freshrss_rendered_view');
raw_node = document.getElementById('freshrss_raw');
@ -32,7 +35,7 @@ if (document.readyState && document.readyState !== 'loading') {
} else {
document.addEventListener('DOMContentLoaded', function () {
if (window.console) {
console.log('FreshRSS waiting for DOMContentLoaded…');
console.log('FreshRSS preview waiting for DOMContentLoaded…');
}
init_afterDOM();
}, false);

@ -1222,7 +1222,7 @@ br {
#popup {
display: none;
position: fixed;
z-index: 1;
z-index: 200;
left: 0;
top: 0;
width: 100%;
@ -1265,11 +1265,6 @@ br {
cursor: pointer;
}
#popup-txt {
display: none;
height: 100%;
}
#popup-iframe-container {
display: none;
height: 100%;

@ -1222,7 +1222,7 @@ br {
#popup {
display: none;
position: fixed;
z-index: 1;
z-index: 200;
right: 0;
top: 0;
width: 100%;
@ -1265,11 +1265,6 @@ br {
cursor: pointer;
}
#popup-txt {
display: none;
height: 100%;
}
#popup-iframe-container {
display: none;
height: 100%;

Loading…
Cancel
Save