aboutsummaryrefslogtreecommitdiff
path: root/p/scripts/user.query.js
diff options
context:
space:
mode:
authorGravatar Alexis Degrugillier <aledeg@users.noreply.github.com> 2021-01-13 14:34:45 -0500
committerGravatar GitHub <noreply@github.com> 2021-01-13 20:34:45 +0100
commite3457f7d7b56509048e3c1f53f05f278656e976c (patch)
treef9bd9fb43436e7958b70bc0a91e0431afd480f17 /p/scripts/user.query.js
parentb43b94dff8b2d7e8f052907f2459d2ad54b5cb68 (diff)
Add drag & drop marker on user query list (#3355)
Before, it was nearly impossible to know exactly where the dragged item will land when dropping it. Now, there is a visual marker to show the drop location. An HR tag is inserted dynamically in the DOM. It's possible to style it if needed.
Diffstat (limited to 'p/scripts/user.query.js')
-rw-r--r--p/scripts/user.query.js68
1 files changed, 58 insertions, 10 deletions
diff --git a/p/scripts/user.query.js b/p/scripts/user.query.js
index c828cef19..2652442c3 100644
--- a/p/scripts/user.query.js
+++ b/p/scripts/user.query.js
@@ -2,7 +2,7 @@
"use strict";
/* jshint esversion:6, strict:global */
-function init_draggable() {
+const init_draggable = function() {
if (!window.context) {
if (window.console) {
console.log('FreshRSS user query waiting for JS…');
@@ -13,32 +13,80 @@ function init_draggable() {
let source;
const configureQueries = document.querySelector('#configureQueries');
+ const addMarker = (position, element) => {
+ const hr = configureQueries.querySelector('hr.drag-drop-marker');
+ if (null === hr) {
+ element.insertAdjacentHTML(position, '<hr class="drag-drop-marker" />');
+ }
+ };
+ const removeMarker = () => {
+ const hr = configureQueries.querySelector('hr.drag-drop-marker');
+ if (null !== hr) {
+ hr.remove();
+ }
+ };
configureQueries.addEventListener('dragstart', event => {
source = event.target.closest('[draggable="true"]');
event.dataTransfer.setData('text/html', source.outerHTML);
event.dataTransfer.effectAllowed = 'move';
});
- configureQueries.addEventListener('dragover', event => event.preventDefault());
- configureQueries.addEventListener('dragleave', event => event.preventDefault());
+ configureQueries.addEventListener('dragover', event => {
+ event.preventDefault();
+ if (!event.target || !event.target.closest) {
+ return;
+ }
+
+ const dropQuery = event.target.closest('[draggable="true"]');
+ if (null === dropQuery || source === dropQuery) {
+ return;
+ }
+
+ const rect = dropQuery.getBoundingClientRect();
+ if (event.clientY < (rect.top + rect.height / 2)) {
+ addMarker('beforebegin', dropQuery);
+ } else {
+ addMarker('afterend', dropQuery);
+ }
+ });
+ configureQueries.addEventListener('dragleave', event => {
+ event.preventDefault();
+ removeMarker();
+ });
configureQueries.addEventListener('drop', event => {
event.preventDefault();
event.stopPropagation();
+ if (!event.target || !event.target.closest) {
+ return;
+ }
+
const dropQuery = event.target.closest('[draggable="true"]');
- if (null === dropQuery) {
- source.remove();
- configureQueries.querySelector('legend').insertAdjacentHTML('afterend', event.dataTransfer.getData('text/html'));
- } else if (source !== dropQuery) {
- source.remove();
+ if (null === dropQuery || source === dropQuery) {
+ return;
+ }
+
+ const rect = dropQuery.getBoundingClientRect();
+ if (event.clientY < (rect.top + rect.height / 2)) {
+ dropQuery.insertAdjacentHTML('beforebegin', event.dataTransfer.getData('text/html'));
+ } else {
dropQuery.insertAdjacentHTML('afterend', event.dataTransfer.getData('text/html'));
}
+ source.remove();
+ removeMarker();
});
// This is needed to work around a Firefox bug → https://bugzilla.mozilla.org/show_bug.cgi?id=800050
configureQueries.addEventListener('focusin', event => {
- event.target.closest('input[id^="queries_"][id$="_name"]').select();
+ if (!event.target || !event.target.closest) {
+ return;
+ }
+
+ const queryName = event.target.closest('input[id^="queries_"][id$="_name"]');
+ if (null !== queryName) {
+ queryName.select();
+ }
});
-}
+};
if (document.readyState && document.readyState !== 'loading') {
init_draggable();