first commit
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
/**
|
||||
* @defgroup js_classes_notification
|
||||
*/
|
||||
/**
|
||||
* @file js/classes/notification/NotificationHelper.js
|
||||
*
|
||||
* Copyright (c) 2014-2021 Simon Fraser University
|
||||
* Copyright (c) 2000-2021 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class NotificationHelper
|
||||
* @ingroup js_classes_notification
|
||||
*
|
||||
* @brief Class that perform notification helper actions.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
/** @type {Object} */
|
||||
$.pkp.classes.notification = $.pkp.classes.notification || {};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
$.pkp.classes.notification.NotificationHelper = function() {
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Public static helper methods
|
||||
//
|
||||
/**
|
||||
* Decides which notification will be used: in place or general.
|
||||
* This method finds all notification widgets that are inside of the
|
||||
* handled element of the controller that is handling the current
|
||||
* notify user event (page or modal). We need to make sure that all
|
||||
* notifications will be shown inside the same widget where the notify
|
||||
* user was triggered. Beyond that, we also need to make sure that,
|
||||
* inside some widgets (tabs and accordions, for example) we use the
|
||||
* right notification controller.
|
||||
* To do this, the notification element must follow these rules:
|
||||
*
|
||||
* 1 - the notification element must not have a hidden parent, although
|
||||
* it can be hidden itself.
|
||||
*
|
||||
* 2 - the notification element first widget parent also needs to contain
|
||||
* the element that triggered the notify user event.
|
||||
*
|
||||
* 3 - if the notification element is inside an accordion container, it
|
||||
* will only notify user from events that have the trigger element also
|
||||
* inside the accordion container.
|
||||
*
|
||||
* At the final, if this method find and select more than one
|
||||
* notification element, we get the closest comparing to the element
|
||||
* that triggered the event. If it don't find any visible element, it
|
||||
* bubbles up the event so the site handler can show general
|
||||
* notifications.
|
||||
*
|
||||
* @param {$.pkp.classes.Handler} handler The widget handler that is
|
||||
* handling the notify user event.
|
||||
* @param {HTMLElement|Object} triggerElement The element that triggered the
|
||||
* notify user event.
|
||||
*/
|
||||
$.pkp.classes.notification.NotificationHelper.redirectNotifyUserEvent =
|
||||
function(handler, triggerElement) {
|
||||
|
||||
// Get the selector for a notification element.
|
||||
var $notificationSelector = '.pkp_notification',
|
||||
$handledElement,
|
||||
trivialAlreadyHandled,
|
||||
$pageNotificationElements,
|
||||
possibleNotificationWidgets,
|
||||
i, length,
|
||||
notificationsData,
|
||||
$accordionContainer,
|
||||
$element,
|
||||
$elementParents, parentHandler,
|
||||
j, parentsLength, $elementParentWidget;
|
||||
|
||||
|
||||
// Sometimes the notification handler will bubble up
|
||||
// the notifyUser event when in place notifications are
|
||||
// not visible because of scrolling. When this happens, the
|
||||
// trigger element will not be an element, but the notifications
|
||||
// data that were shown by the in place but no visible. In those
|
||||
// cases, just bubble up again the event until it gets the right
|
||||
// handler (the site handler).
|
||||
if (triggerElement !== undefined && triggerElement.content !== undefined) {
|
||||
notificationsData = triggerElement;
|
||||
handler.getHtmlElement().parent().trigger(
|
||||
'notifyUser', [notificationsData]);
|
||||
return; // no need to do any other event redirection.
|
||||
}
|
||||
|
||||
// Get the html element of the handler.
|
||||
$handledElement = handler.getHtmlElement();
|
||||
|
||||
// If the trigger element is inside a grid, let the site
|
||||
// handler show TRIVIAL notifications.
|
||||
trivialAlreadyHandled = false;
|
||||
if (!(handler instanceof $.pkp.controllers.SiteHandler)) {
|
||||
if (triggerElement !== undefined &&
|
||||
$(triggerElement).parents('.pkp_controllers_grid').length > 0) {
|
||||
$handledElement.parent().trigger('notifyUser');
|
||||
trivialAlreadyHandled = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Find all notification elements inside the handled element.
|
||||
$pageNotificationElements = $($notificationSelector, $handledElement);
|
||||
|
||||
// Create a variable to store all possible notification widgets
|
||||
// that can notify this event.
|
||||
possibleNotificationWidgets = [];
|
||||
|
||||
for (i = 0, length = $pageNotificationElements.length; i < length; i++) {
|
||||
$element = $($pageNotificationElements[i]);
|
||||
|
||||
// If it is inside a hidden parent, get next element.
|
||||
if ($element.parents(':hidden').length > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find its parent widget.
|
||||
// FIXME If we use a class to identify pkp widgets, we can avoid
|
||||
// this code duplication from the get handler method in Handler class,
|
||||
// unnecessary access to the element data and unnecessary loop.
|
||||
$elementParents = $element.parents();
|
||||
for (j = 0, parentsLength = $elementParents.length;
|
||||
j < parentsLength; j++) {
|
||||
parentHandler = $($elementParents[j]).data('pkp.handler');
|
||||
if ((parentHandler instanceof $.pkp.classes.Handler)) {
|
||||
$elementParentWidget = $($elementParents[j]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If the element that triggered the event is inside of
|
||||
// this widget or is the widget...
|
||||
if (triggerElement !== undefined &&
|
||||
($elementParentWidget.has(triggerElement[0]).length ||
|
||||
$elementParentWidget[0] === triggerElement[0])) {
|
||||
|
||||
// If it is inside an accordion container, and this accordion container
|
||||
// doesn't also contain the element that triggered the event, get other
|
||||
// element.
|
||||
if ($element.parents('.ui-accordion:first').length > 0) {
|
||||
$accordionContainer = $element.parents('.ui-accordion:first');
|
||||
|
||||
if (!$accordionContainer.has(triggerElement[0])) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// This notification element is able to notify this event.
|
||||
possibleNotificationWidgets.push($element);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we found a notification element.
|
||||
if (possibleNotificationWidgets.length) {
|
||||
|
||||
// Trigger all in place notification widgets found, from the
|
||||
// closest to the element that triggered the action to the top.
|
||||
for (i = possibleNotificationWidgets.length - 1; i > -1; i--) {
|
||||
// Show in place notification to user.
|
||||
possibleNotificationWidgets[i].triggerHandler('notifyUser');
|
||||
}
|
||||
} else {
|
||||
if (!trivialAlreadyHandled) {
|
||||
// Bubble up the notify user event so the site can handle the
|
||||
// general notification.
|
||||
handler.getHtmlElement().parent().trigger('notifyUser');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}(jQuery));
|
||||
Reference in New Issue
Block a user