]> git.mxchange.org Git - friendica.git/blobdiff - view/theme/frio/js/hovercard.js
Merge pull request #8131 from nupplaphil/task/cleanup_lock
[friendica.git] / view / theme / frio / js / hovercard.js
index 0236d9a075236bfaf35f436ea882f3c7943a646d..464c7e06e1af84e015fab5f3a9f527d547157892 100644 (file)
@@ -8,18 +8,53 @@
  *
  */
 $(document).ready(function () {
-       // Elements with the class "userinfo" will get a hover-card.
-       // Note that this elements does need a href attribute which links to
-       // a valid profile url
-       $("body").on("mouseover", ".userinfo, .wall-item-responses a, .wall-item-bottom .mention a", function (e) {
+       let $body = $('body');
+       // Prevents normal click action on click hovercard elements
+       $body.on('click', '.userinfo.click-card', function (e) {
+               e.preventDefault();
+       });
+       // This event listener needs to be declared before the one that removes
+       // all cards so that we can stop the immediate propagation of the event
+       // Since the manual popover appears instantly and the hovercard removal is
+       // on a 100ms delay, leaving event propagation immediately hides any click hovercard
+       $body.on('mousedown', '.userinfo.click-card', function (e) {
+               e.stopImmediatePropagation();
+               let timeNow = new Date().getTime();
+
+               let contactUrl = false;
+               let targetElement = $(this);
+
+               // get href-attribute
+               if (targetElement.is('[href]')) {
+                       contactUrl = targetElement.attr('href');
+               } else {
+                       return true;
+               }
+
+               // no hovercard for anchor links
+               if (contactUrl.substring(0, 1) === '#') {
+                       return true;
+               }
+
+               openHovercard(targetElement, contactUrl, timeNow);
+       });
+
+       // hover cards should be removed very easily, e.g. when any of these events happens
+       $body.on('mouseleave touchstart scroll mousedown submit keydown', function (e) {
+               // remove hover card only for desktiop user, since on mobile we open the hovercards
+               // by click event insteadof hover
+               removeAllHovercards(e, new Date().getTime());
+       });
+
+       $body.on('mouseover', '.userinfo.hover-card, .wall-item-responses a, .wall-item-bottom .mention a', function (e) {
                let timeNow = new Date().getTime();
                removeAllHovercards(e, timeNow);
-               let contact_url = false;
+               let contactUrl = false;
                let targetElement = $(this);
 
                // get href-attribute
                if (targetElement.is('[href]')) {
-                       contact_url = targetElement.attr('href');
+                       contactUrl = targetElement.attr('href');
                } else {
                        return true;
                }
@@ -30,88 +65,34 @@ $(document).ready(function () {
                }
 
                // no hovercard for anchor links
-               if (contact_url.substring(0, 1) === '#') {
+               if (contactUrl.substring(0, 1) === '#') {
                        return true;
                }
 
                targetElement.attr('data-awaiting-hover-card', timeNow);
 
-               // store the title in an other data attribute beause bootstrap
-               // popover destroys the title.attribute. We can restore it later
-               let title = targetElement.attr("title");
-               targetElement.attr({"data-orig-title": title, title: ""});
-
-               // if the device is a mobile open the hover card by click and not by hover
-               if (typeof is_mobile != "undefined") {
-                       targetElement[0].removeAttribute("href");
-                       var hctrigger = 'click';
-               } else {
-                       var hctrigger = 'manual';
-               }
-
-               // Timeout until the hover-card does appear
+               // Delay until the hover-card does appear
                setTimeout(function () {
                        if (
-                               targetElement.is(":hover")
+                               targetElement.is(':hover')
                                && parseInt(targetElement.attr('data-awaiting-hover-card'), 10) === timeNow
                                && $('.hovercard').length === 0
-                       ) {     // no card if there already is one open
-                               // get an additional data atribute if the card is active
-                               targetElement.attr('data-hover-card-active', timeNow);
-                               // get the whole html content of the hover card and
-                               // push it to the bootstrap popover
-                               getHoverCardContent(contact_url, function (data) {
-                                       if (data) {
-                                               targetElement.popover({
-                                                       html: true,
-                                                       placement: function () {
-                                                               // Calculate the placement of the the hovercard (if top or bottom)
-                                                               // The placement depence on the distance between window top and the element
-                                                               // which triggers the hover-card
-                                                               var get_position = $(targetElement).offset().top - $(window).scrollTop();
-                                                               if (get_position < 270) {
-                                                                       return "bottom";
-                                                               }
-                                                               return "top";
-                                                       },
-                                                       trigger: hctrigger,
-                                                       template: '<div class="popover hovercard" data-card-created="' + timeNow + '"><div class="arrow"></div><div class="popover-content hovercard-content"></div></div>',
-                                                       content: data,
-                                                       container: "body",
-                                                       sanitizeFn: function (content) {
-                                                               return DOMPurify.sanitize(content)
-                                                       },
-                                               }).popover('show');
-                                       }
-                               });
+                       ) {
+                               openHovercard(targetElement, contactUrl, timeNow);
                        }
                }, 500);
-       }).on("mouseleave", ".userinfo, .wall-item-responses a, .wall-item-bottom .mention a", function (e) { // action when mouse leaves the hover-card
-               var timeNow = new Date().getTime();
-               // copy the original title to the title atribute
-               var title = $(this).attr("data-orig-title");
-               $(this).attr({"data-orig-title": "", title: title});
-               removeAllHovercards(e, timeNow);
-       });
-
-       // hover cards should be removed very easily, e.g. when any of these events happen
-       $('body').on("mouseleave touchstart scroll click dblclick mousedown mouseup submit keydown keypress keyup", function (e) {
-               // remove hover card only for desktiop user, since on mobile we openen the hovercards
-               // by click event insteadof hover
-               if (typeof is_mobile == "undefined") {
-                       var timeNow = new Date().getTime();
-                       removeAllHovercards(e, timeNow);
-               }
+       }).on('mouseleave', '.userinfo.hover-card, .wall-item-responses a, .wall-item-bottom .mention a', function (e) { // action when mouse leaves the hover-card
+               removeAllHovercards(e, new Date().getTime());
        });
 
        // if we're hovering a hover card, give it a class, so we don't remove it
-       $('body').on('mouseover', '.hovercard', function (e) {
+       $body.on('mouseover', '.hovercard', function (e) {
                $(this).addClass('dont-remove-card');
        });
 
-       $('body').on('mouseleave', '.hovercard', function (e) {
+       $body.on('mouseleave', '.hovercard', function (e) {
                $(this).removeClass('dont-remove-card');
-               $(this).popover("hide");
+               $(this).popover('hide');
        });
 }); // End of $(document).ready
 
@@ -120,19 +101,61 @@ function removeAllHovercards(event, priorTo) {
        // don't remove hovercards until after 100ms, so user have time to move the cursor to it (which gives it the dont-remove-card class)
        setTimeout(function () {
                $.each($('.hovercard'), function () {
-                       var title = $(this).attr("data-orig-title");
+                       let title = $(this).attr('data-orig-title');
                        // don't remove card if it was created after removeAllhoverCards() was called
                        if ($(this).data('card-created') < priorTo) {
                                // don't remove it if we're hovering it right now!
                                if (!$(this).hasClass('dont-remove-card')) {
-                                       $('[data-hover-card-active="' + $(this).data('card-created') + '"]').removeAttr('data-hover-card-active');
-                                       $(this).popover("hide");
+                                       let $handle = $('[data-hover-card-active="' + $(this).data('card-created') + '"]');
+                                       $handle.removeAttr('data-hover-card-active');
+
+                                       // Restoring the popover handle title
+                                       let title = $handle.attr('data-orig-title');
+                                       $handle.attr({'data-orig-title': '', title: title});
+
+                                       $(this).popover('hide');
                                }
                        }
                });
        }, 100);
 }
 
+function openHovercard(targetElement, contactUrl, timeNow) {
+       // store the title in a data attribute because Bootstrap
+       // popover destroys the title attribute.
+       let title = targetElement.attr('title');
+       targetElement.attr({'data-orig-title': title, title: ''});
+
+       // get an additional data atribute if the card is active
+       targetElement.attr('data-hover-card-active', timeNow);
+       // get the whole html content of the hover card and
+       // push it to the bootstrap popover
+       getHoverCardContent(contactUrl, function (data) {
+               if (data) {
+                       targetElement.popover({
+                               html: true,
+                               placement: function () {
+                                       // Calculate the placement of the the hovercard (if top or bottom)
+                                       // The placement depence on the distance between window top and the element
+                                       // which triggers the hover-card
+                                       let get_position = $(targetElement).offset().top - $(window).scrollTop();
+                                       if (get_position < 270) {
+                                               return 'bottom';
+                                       }
+                                       return 'top';
+                               },
+                               trigger: 'manual',
+                               template: '<div class="popover hovercard" data-card-created="' + timeNow + '"><div class="arrow"></div><div class="popover-content hovercard-content"></div></div>',
+                               content: data,
+                               container: 'body',
+                               sanitizeFn: function (content) {
+                                       return DOMPurify.sanitize(content)
+                               },
+                       }).popover('show');
+               }
+       });
+}
+
 getHoverCardContent.cache = {};
 
 function getHoverCardContent(contact_url, callback) {
@@ -152,7 +175,7 @@ function getHoverCardContent(contact_url, callback) {
        }
 
        $.ajax({
-               url: baseurl + "/contact/hovercard",
+               url: baseurl + '/contact/hovercard',
                data: postdata,
                success: function (data, textStatus, request) {
                        getHoverCardContent.cache[nurl] = data;