aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Tommaso Ferrari <raspaccio@gmail.com> 2025-11-05 03:51:33 -0700
committerGravatar GitHub <noreply@github.com> 2025-11-05 11:51:33 +0100
commit63fe7438784cd56b9291d2a0dee3f872a53c7ae0 (patch)
tree3e6302181e6fdaa012c6c043c7ec5de1a6fb2e2f
parent0587ccaff844701b08306440c96c89cefa21b2c9 (diff)
Fix 7307 - Scroll after load (#7962)
* Fix 7307 - Scroll after load Closes https://github.com/FreshRSS/FreshRSS/issues/7307 - Wrap the body of `loadDynamicTags()` into a Promise - inside `mylabels()`, wait for the promise to complete, then scroll - when `loadDynamicTags()` is not being called, return a self-resolving promise How to test the feature manually: 1. Click on an long article 2. press keyboard shortcut `l` to go to "My labels" 3. page should scroll down 4. the `My labels` popup should be fully visible * Rewritten as async/await * Explicit HTTP Accept application/json --------- Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
-rw-r--r--p/scripts/main.js149
1 files changed, 74 insertions, 75 deletions
diff --git a/p/scripts/main.js b/p/scripts/main.js
index fe5e81f6d..73848060b 100644
--- a/p/scripts/main.js
+++ b/p/scripts/main.js
@@ -740,7 +740,7 @@ function user_filter(key) {
}
}
-function show_labels_menu(el) {
+async function show_labels_menu(el) {
const div = el.parentElement;
const dropdownMenu = div.querySelector('.dropdown-menu');
@@ -754,7 +754,7 @@ function show_labels_menu(el) {
const template = document.getElementById(templateId).innerHTML;
div.insertAdjacentHTML('beforeend', template);
- loadDynamicTags(div.closest('.dynamictags'));
+ return loadDynamicTags(div.closest('.dynamictags'));
}
return true;
}
@@ -790,7 +790,7 @@ function show_share_menu(el) {
return true;
}
-function mylabels(key) {
+async function mylabels(key) {
const mylabelsDropdown = document.querySelector('.flux.current.active .dropdown-target[id^="dropdown-labels"]');
if (!mylabelsDropdown) {
@@ -798,7 +798,7 @@ function mylabels(key) {
}
if (typeof key === 'undefined') {
- show_labels_menu(mylabelsDropdown);
+ await show_labels_menu(mylabelsDropdown);
}
// Display the mylabels div
location.hash = mylabelsDropdown.id;
@@ -1539,94 +1539,93 @@ function init_nav_entries() {
// purpose of this flag: minimize the network traffic.
let forceReloadLabelsList = false;
-function loadDynamicTags(div) {
+async function loadDynamicTags(div) {
div.querySelectorAll('li.item').forEach(function (li) { li.remove(); });
const entryId = div.closest('div.flux').id.replace(/^flux_/, '');
- const req = new XMLHttpRequest();
- req.open('GET', './?c=tag&a=getTagsForEntry&id_entry=' + entryId, true);
- req.responseType = 'json';
- req.onerror = function (e) {
- div.querySelectorAll('li.item').forEach(function (li) { li.remove(); });
- };
- req.onload = function (e) {
- if (this.status != 200) {
- return req.onerror(e);
- }
- const json = xmlHttpRequestJson(this);
- if (!json) {
- return req.onerror(e);
+ let json;
+ try {
+ const response = await fetch('./?c=tag&a=getTagsForEntry&id_entry=' + entryId, {
+ headers: {
+ 'Accept': 'application/json',
+ }
+ });
+ if (!response.ok) {
+ throw new Error('HTTP error ' + response.status);
}
+ json = await response.json();
+ } catch (ex) {
+ div.querySelectorAll('li.item').forEach(function (li) { li.remove(); });
+ throw ex;
+ }
- if (!context.anonymous) {
- const li_item0 = document.createElement('li');
- li_item0.setAttribute('class', 'item addItem');
+ if (!context.anonymous) {
+ const li_item0 = document.createElement('li');
+ li_item0.setAttribute('class', 'item addItem');
- const label = document.createElement('label');
- label.setAttribute('class', 'noHover');
+ const label = document.createElement('label');
+ label.setAttribute('class', 'noHover');
- const input_checkboxTag = document.createElement('input');
- input_checkboxTag.setAttribute('class', 'checkboxTag checkboxNewTag');
- input_checkboxTag.setAttribute('name', 't_0');
- input_checkboxTag.setAttribute('type', 'checkbox');
+ const input_checkboxTag = document.createElement('input');
+ input_checkboxTag.setAttribute('class', 'checkboxTag checkboxNewTag');
+ input_checkboxTag.setAttribute('name', 't_0');
+ input_checkboxTag.setAttribute('type', 'checkbox');
- const input_newTag = document.createElement('input');
- input_newTag.setAttribute('type', 'text');
- input_newTag.setAttribute('name', 'newTag');
- input_newTag.setAttribute('class', 'newTag');
- input_newTag.setAttribute('list', 'datalist-labels');
- input_newTag.addEventListener('keydown', function (ev) { if (ev.key.toUpperCase() == 'ENTER') { this.parentNode.previousSibling.click(); } });
+ const input_newTag = document.createElement('input');
+ input_newTag.setAttribute('type', 'text');
+ input_newTag.setAttribute('name', 'newTag');
+ input_newTag.setAttribute('class', 'newTag');
+ input_newTag.setAttribute('list', 'datalist-labels');
+ input_newTag.addEventListener('keydown', function (ev) { if (ev.key.toUpperCase() == 'ENTER') { this.parentNode.previousSibling.click(); } });
- const button_btn = document.createElement('button');
- button_btn.setAttribute('type', 'button');
- button_btn.setAttribute('class', 'btn');
- button_btn.addEventListener('click', function () { this.parentNode.parentNode.click(); });
+ const button_btn = document.createElement('button');
+ button_btn.setAttribute('type', 'button');
+ button_btn.setAttribute('class', 'btn');
+ button_btn.addEventListener('click', function () { this.parentNode.parentNode.click(); });
- const text_plus = document.createTextNode('+');
+ const text_plus = document.createTextNode('+');
- const div_stick = document.createElement('div');
- div_stick.setAttribute('class', 'stick');
+ const div_stick = document.createElement('div');
+ div_stick.setAttribute('class', 'stick');
- button_btn.appendChild(text_plus);
- div_stick.appendChild(input_newTag);
- div_stick.appendChild(button_btn);
- label.appendChild(input_checkboxTag);
- label.appendChild(div_stick);
- li_item0.appendChild(label);
+ button_btn.appendChild(text_plus);
+ div_stick.appendChild(input_newTag);
+ div_stick.appendChild(button_btn);
+ label.appendChild(input_checkboxTag);
+ label.appendChild(div_stick);
+ li_item0.appendChild(label);
- div.querySelector('.dropdown-menu-scrollable').appendChild(li_item0);
- }
+ div.querySelector('.dropdown-menu-scrollable').appendChild(li_item0);
+ }
- let html = '';
- let datalist = '';
- if (json && json.length) {
- let nbLabelsChecked = 0;
- for (let i = 0; i < json.length; i++) {
- const tag = json[i];
- if (context.anonymous && !tag.checked) {
- // In anomymous mode, show only the used tags
- continue;
- }
- if (tag.checked) {
- nbLabelsChecked++;
- }
- html += '<li class="item"><label><input ' +
- (context.anonymous ? '' : 'class="checkboxTag" ') +
- 'name="t_' + tag.id + '"type="checkbox" ' +
- (context.anonymous ? 'disabled="disabled" ' : '') +
- (tag.checked ? 'checked="checked" ' : '') + '/>' + tag.name + '</label></li>';
- datalist += '<option value="' + tag.name + '"></option>';
+ let html = '';
+ let datalist = '';
+ if (json && json.length) {
+ let nbLabelsChecked = 0;
+ for (let i = 0; i < json.length; i++) {
+ const tag = json[i];
+ if (context.anonymous && !tag.checked) {
+ // In anonymous mode, show only the used tags
+ continue;
}
- if (context.anonymous && nbLabelsChecked === 0) {
- html += '<li class="item"><span class="emptyLabels">' + context.i18n.labels_empty + '</span></li>';
+ if (tag.checked) {
+ nbLabelsChecked++;
}
+ html += '<li class="item"><label><input ' +
+ (context.anonymous ? '' : 'class="checkboxTag" ') +
+ 'name="t_' + tag.id + '"type="checkbox" ' +
+ (context.anonymous ? 'disabled="disabled" ' : '') +
+ (tag.checked ? 'checked="checked" ' : '') + '/>' + tag.name + '</label></li>';
+ datalist += '<option value="' + tag.name + '"></option>';
}
- div.querySelector('.dropdown-menu-scrollable').insertAdjacentHTML('beforeend', html);
- const datalistLabels = document.getElementById('datalist-labels');
- datalistLabels.innerHTML = ''; // clear before add the (updated) labels list
- datalistLabels.insertAdjacentHTML('beforeend', datalist);
- };
- req.send();
+ if (context.anonymous && nbLabelsChecked === 0) {
+ html += '<li class="item"><span class="emptyLabels">' + context.i18n.labels_empty + '</span></li>';
+ }
+ }
+ div.querySelector('.dropdown-menu-scrollable').insertAdjacentHTML('beforeend', html);
+ const datalistLabels = document.getElementById('datalist-labels');
+ datalistLabels.innerHTML = ''; // clear before add the (updated) labels list
+ datalistLabels.insertAdjacentHTML('beforeend', datalist);
}
// <actualize>