first commit
This commit is contained in:
@@ -0,0 +1,752 @@
|
||||
/**
|
||||
* @defgroup js_controllers
|
||||
*/
|
||||
/**
|
||||
* @file js/controllers/SiteHandler.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 SiteHandler
|
||||
* @ingroup js_controllers
|
||||
*
|
||||
* @brief Handle the site widget.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @extends $.pkp.classes.Handler
|
||||
*
|
||||
* @param {jQueryObject} $widgetWrapper An HTML element that this handle will
|
||||
* be attached to.
|
||||
* @param {{
|
||||
* fetchNotificationUrl: string,
|
||||
* requestOptions: Object
|
||||
* }} options Handler options.
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler = function($widgetWrapper, options) {
|
||||
this.parent($widgetWrapper, options);
|
||||
|
||||
this.options_ = options;
|
||||
this.unsavedFormElements_ = [];
|
||||
|
||||
$('.go').button();
|
||||
|
||||
this.bind('redirectRequested', this.redirectToUrl);
|
||||
this.bind('notifyUser', this.fetchNotificationHandler_);
|
||||
this.bind('reloadTab', this.reloadTabHandler_);
|
||||
this.bind('callWhenClickOutside', this.callWhenClickOutsideHandler_);
|
||||
this.bind('mousedown', this.mouseDownHandler_);
|
||||
|
||||
// Bind the pageUnloadHandler_ method to the DOM so it is
|
||||
// called.
|
||||
$(window).bind('beforeunload', this.pageUnloadHandler_);
|
||||
|
||||
// Avoid IE8 caching ajax results. If it does, widgets like
|
||||
// grids will not refresh correctly.
|
||||
$.ajaxSetup({cache: false});
|
||||
|
||||
// Check if we have notifications to show.
|
||||
if (options.hasSystemNotifications) {
|
||||
this.trigger('notifyUser');
|
||||
}
|
||||
|
||||
// bind event handlers for form status change events.
|
||||
this.bind('formChanged', this.callbackWrapper(
|
||||
this.registerUnsavedFormElement_));
|
||||
this.bind('unregisterChangedForm', this.callbackWrapper(
|
||||
this.unregisterUnsavedFormElement_));
|
||||
this.bind('unregisterAllForms', this.callbackWrapper(
|
||||
this.unregisterAllFormElements_));
|
||||
|
||||
// React to a modal events
|
||||
this.bind('pkpModalOpen', this.callbackWrapper(this.openModal_));
|
||||
this.bind('pkpModalClose', this.callbackWrapper(this.closeModal_));
|
||||
|
||||
this.bind('pkpObserveScrolling', this.callbackWrapper(
|
||||
this.registerScrollingObserver_));
|
||||
this.bind('pkpRemoveScrollingObserver', this.callbackWrapper(
|
||||
this.unregisterScrollingObserver_));
|
||||
|
||||
this.outsideClickChecks_ = {};
|
||||
|
||||
this.initializeTinyMCE();
|
||||
};
|
||||
$.pkp.classes.Helper.inherits(
|
||||
$.pkp.controllers.SiteHandler, $.pkp.classes.Handler);
|
||||
|
||||
|
||||
//
|
||||
// Private properties
|
||||
//
|
||||
/**
|
||||
* Help context.
|
||||
* @private
|
||||
* @type {string?}
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.helpContext_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Site handler options.
|
||||
* @private
|
||||
* @type {Object}
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.options_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Object with data to be used when checking if user
|
||||
* clicked outside a site element. See callWhenClickOutsideHandler_()
|
||||
* to check the expected check options.
|
||||
* @private
|
||||
* @type {Object}
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.outsideClickChecks_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* A state variable to store the form elements that have unsaved data.
|
||||
* @private
|
||||
* @type {Array}
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.unsavedFormElements_ = null;
|
||||
|
||||
|
||||
//
|
||||
// Public static methods.
|
||||
//
|
||||
/**
|
||||
* Initialize the tinyMCE plugin
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.initializeTinyMCE =
|
||||
function() {
|
||||
|
||||
if (typeof tinyMCE !== 'undefined') {
|
||||
tinyMCE.PluginManager.load('pkpTags', $.pkp.app.baseUrl +
|
||||
'/plugins/generic/tinymce/plugins/pkpTags/plugin.js');
|
||||
tinyMCE.PluginManager.load('pkpwordcount', $.pkp.app.baseUrl +
|
||||
'/plugins/generic/tinymce/plugins/pkpWordcount/plugin.js');
|
||||
|
||||
|
||||
var contentCSS = $.pkp.app.tinyMceContentCSS,
|
||||
tinymceParams,
|
||||
tinymceParamDefaults;
|
||||
|
||||
tinymceParamDefaults = {
|
||||
width: '100%',
|
||||
resize: 'both',
|
||||
entity_encoding: 'raw',
|
||||
plugins: 'paste,fullscreen,link,lists,code,' +
|
||||
'image,-pkpTags,noneditable',
|
||||
convert_urls: false,
|
||||
forced_root_block: 'p',
|
||||
paste_auto_cleanup_on_paste: true,
|
||||
apply_source_formatting: false,
|
||||
toolbar: 'copy paste | bold italic underline | link unlink ' +
|
||||
'code fullscreen | image | pkpTags',
|
||||
richToolbar: 'copy paste | bold italic underline | bullist numlist | ' +
|
||||
'superscript subscript | link unlink code fullscreen | ' +
|
||||
'image | pkpTags',
|
||||
statusbar: false,
|
||||
content_css: contentCSS,
|
||||
browser_spellcheck: true
|
||||
};
|
||||
|
||||
// Support image uploads
|
||||
if (typeof $.pkp.plugins.generic.tinymceplugin !== 'undefined' &&
|
||||
typeof $.pkp.plugins.generic.tinymceplugin.uploadUrl !== 'undefined') {
|
||||
tinymceParamDefaults.paste_data_images = true;
|
||||
tinymceParamDefaults.relative_urls = false;
|
||||
tinymceParamDefaults.remove_script_host = false;
|
||||
// https://www.tiny.cloud/docs/general-configuration-guide/upload-images/
|
||||
tinymceParamDefaults.images_upload_handler = function(
|
||||
blobInfo, success, failure) {
|
||||
|
||||
/*global FormData: false */
|
||||
var data = new FormData();
|
||||
data.append('file', blobInfo.blob(), blobInfo.filename());
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: $.pkp.plugins.generic.tinymceplugin.uploadUrl,
|
||||
data: data,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
headers: {
|
||||
'X-Csrf-Token': pkp.currentUser.csrfToken
|
||||
},
|
||||
success: function(r) {
|
||||
success(r.url);
|
||||
},
|
||||
error: function(r) {
|
||||
failure(r.responseJSON.errorMessage);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// Allow default params to be overridden
|
||||
if (typeof $.pkp.plugins.generic.tinymceplugin !== 'undefined' &&
|
||||
typeof $.pkp.plugins.generic.tinymceplugin.tinymceParams) {
|
||||
tinymceParams = $.extend({}, tinymceParamDefaults,
|
||||
$.pkp.plugins.generic.tinymceplugin.tinymceParams);
|
||||
} else {
|
||||
tinymceParams = $.extend({}, tinymceParamDefaults);
|
||||
}
|
||||
|
||||
// Don't allow the following settings to be overridden
|
||||
tinymceParams.init_instance_callback =
|
||||
$.pkp.controllers.SiteHandler.prototype.triggerTinyMCEInitialized;
|
||||
tinymceParams.setup =
|
||||
$.pkp.controllers.SiteHandler.prototype.triggerTinyMCESetup;
|
||||
|
||||
tinyMCE.init(tinymceParams);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Callback used by the tinyMCE plugin to trigger the tinyMCEInitialized
|
||||
* event in the DOM.
|
||||
* @param {Object} tinyMCEObject The tinyMCE object instance being
|
||||
* initialized.
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.triggerTinyMCEInitialized =
|
||||
function(tinyMCEObject) {
|
||||
|
||||
var $inputElement = $('#' +
|
||||
$.pkp.classes.Helper.escapeJQuerySelector(tinyMCEObject.id));
|
||||
$inputElement.trigger('tinyMCEInitialized', [tinyMCEObject]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Callback used by the tinyMCE plugin upon setup.
|
||||
* @param {Object} tinyMCEObject The tinyMCE object instance being
|
||||
* set up.
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.triggerTinyMCESetup =
|
||||
function(tinyMCEObject) {
|
||||
var target = $('#' +
|
||||
$.pkp.classes.Helper.escapeJQuerySelector(tinyMCEObject.id)),
|
||||
height;
|
||||
|
||||
// For read-only controls, set up TinyMCE read-only mode.
|
||||
if (target.attr('readonly')) {
|
||||
tinyMCEObject.settings.readonly = true;
|
||||
}
|
||||
|
||||
if (target.attr('wordCount') && target.attr('wordCount') > 0) {
|
||||
tinyMCEObject.settings.plugins =
|
||||
tinyMCEObject.settings.plugins + ',pkpwordcount';
|
||||
tinyMCEObject.settings.statusbar = true;
|
||||
}
|
||||
|
||||
if (target.attr('dir')) {
|
||||
tinyMCEObject.settings.directionality = target.attr('dir');
|
||||
}
|
||||
|
||||
// Set height based on textarea rows
|
||||
height = target.attr('rows') || 10; // default: 10
|
||||
height *= 20; // 20 pixels per row
|
||||
tinyMCEObject.settings.height = height.toString() + 'px';
|
||||
|
||||
// Add a fake HTML5 placeholder when the editor is intitialized
|
||||
tinyMCEObject.on('init', function(tinyMCEObject) {
|
||||
var $element = $('#' + tinyMCEObject.id),
|
||||
placeholderText,
|
||||
$placeholder,
|
||||
$placeholderParent;
|
||||
|
||||
// Don't add anything if we don't have a placeholder
|
||||
placeholderText = $('#' + tinyMCEObject.id).attr('placeholder');
|
||||
if (placeholderText === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create placeholder element
|
||||
$placeholder = $('<span></span>');
|
||||
$placeholder.html(/** @type {string} */ (placeholderText));
|
||||
$placeholder.addClass('mcePlaceholder');
|
||||
$placeholder.attr('id', 'mcePlaceholder-' + tinyMCEObject.id);
|
||||
|
||||
if (tinyMCEObject.target.getContent().length) {
|
||||
$placeholder.hide();
|
||||
}
|
||||
|
||||
// Create placeholder wrapper
|
||||
$placeholderParent = $('<div></div>');
|
||||
$placeholderParent.addClass('mcePlaceholderParent');
|
||||
$element.wrap($placeholderParent);
|
||||
$element.parent().append($placeholder);
|
||||
});
|
||||
|
||||
tinyMCEObject.on('activate', function(tinyMCEObject) {
|
||||
// Hide the placeholder when the editor is activated
|
||||
$('#mcePlaceholder-' + tinyMCEObject.id).hide();
|
||||
});
|
||||
|
||||
tinyMCEObject.on('deactivate', function(tinyMCEObject) {
|
||||
// Show the placholder when the editor is deactivated
|
||||
if (!tinyMCEObject.target.getContent().length) {
|
||||
$('#mcePlaceholder-' + tinyMCEObject.id).show();
|
||||
}
|
||||
});
|
||||
|
||||
tinyMCEObject.on('BeforeSetContent', function(e) {
|
||||
var variablesParsed = $.pkp.classes.TinyMCEHelper.prototype.getVariableMap(
|
||||
'#' + $.pkp.classes.Helper.escapeJQuerySelector(tinyMCEObject.id));
|
||||
|
||||
e.content = e.content.replace(
|
||||
/\{\$([a-zA-Z]+)\}(?![^<]*>)/g, function(match, contents, offset, s) {
|
||||
if (variablesParsed[contents] !== undefined) {
|
||||
return $.pkp.classes.TinyMCEHelper.prototype.getVariableElement(
|
||||
contents, variablesParsed[contents], '#' + tinyMCEObject.id)
|
||||
.html();
|
||||
}
|
||||
return match;
|
||||
});
|
||||
});
|
||||
|
||||
// When the field is being saved, replace any tag placeholders
|
||||
tinyMCEObject.on('GetContent', function(e) {
|
||||
var $content = $('<div>' + e.content + '</div>');
|
||||
|
||||
// Replace tag span elements with the raw tags
|
||||
$content.find('.pkpTag').replaceWith(function() {
|
||||
return '{$' + $(this).attr('data-symbolic') + '}';
|
||||
});
|
||||
e.content = $content.html();
|
||||
});
|
||||
|
||||
// In fullscreen mode, also present the toolbar.
|
||||
tinyMCEObject.on('FullscreenStateChanged init', function(e) {
|
||||
var target = e.target, $container = $(target.editorContainer);
|
||||
if (target.plugins.fullscreen) {
|
||||
if (target.plugins.fullscreen.isFullscreen()) {
|
||||
$container.find('.tox-menubar').show();
|
||||
} else {
|
||||
$container.find('.tox-menubar').hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the current window dimensions.
|
||||
* @return {Object} The current window dimensions (height and width)
|
||||
* in pixels.
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.getWindowDimensions =
|
||||
function() {
|
||||
var dimensions = {'height': $(window).height(),
|
||||
'width': $(window).width()};
|
||||
|
||||
return dimensions;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
/**
|
||||
* Callback that is triggered when the page should redirect.
|
||||
*
|
||||
* @param {HTMLElement} sourceElement The element that issued the
|
||||
* "redirectRequested" event.
|
||||
* @param {Event} event The "redirect requested" event.
|
||||
* @param {string} url The URL to redirect to.
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.redirectToUrl =
|
||||
function(sourceElement, event, url) {
|
||||
|
||||
window.location = url;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handler bound to 'formChanged' events propagated by forms
|
||||
* that wish to have their form data tracked.
|
||||
* @private
|
||||
* @param {HTMLElement} siteHandlerElement The html element
|
||||
* attached to this handler.
|
||||
* @param {HTMLElement} sourceElement The element wishes to
|
||||
* register.
|
||||
* @param {Event} event The formChanged event.
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.registerUnsavedFormElement_ =
|
||||
function(siteHandlerElement, sourceElement, event) {
|
||||
var $formElement, formId, index;
|
||||
|
||||
$formElement = $(event.target.lastElementChild);
|
||||
formId = $formElement.attr('id');
|
||||
index = $.inArray(formId, this.unsavedFormElements_);
|
||||
if (index == -1) {
|
||||
this.unsavedFormElements_.push(formId);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handler bound to 'unregisterChangedForm' events propagated by forms
|
||||
* that wish to inform that they no longer wish to be tracked as 'unsaved'.
|
||||
* @private
|
||||
* @param {HTMLElement} siteHandlerElement The html element
|
||||
* attached to this handler.
|
||||
* @param {HTMLElement} sourceElement The element that wishes to
|
||||
* unregister.
|
||||
* @param {Event} event The unregisterChangedForm event.
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.unregisterUnsavedFormElement_ =
|
||||
function(siteHandlerElement, sourceElement, event) {
|
||||
var $formElement, formId, index;
|
||||
|
||||
$formElement = $(event.target.lastElementChild);
|
||||
formId = $formElement.attr('id');
|
||||
index = $.inArray(formId, this.unsavedFormElements_);
|
||||
if (index !== -1) {
|
||||
delete this.unsavedFormElements_[index];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Unregister all unsaved form elements.
|
||||
* @private
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.unregisterAllFormElements_ =
|
||||
function() {
|
||||
this.unsavedFormElements_ = [];
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Private methods.
|
||||
//
|
||||
/**
|
||||
* Fetch the notification data.
|
||||
* @private
|
||||
* @param {HTMLElement} sourceElement The element that issued the
|
||||
* "fetchNotification" event.
|
||||
* @param {Event} event The "fetch notification" event.
|
||||
* @param {Object} jsonData The JSON content representing the
|
||||
* notification.
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.fetchNotificationHandler_ =
|
||||
function(sourceElement, event, jsonData) {
|
||||
|
||||
if (jsonData !== undefined) {
|
||||
// This is an event that came from an inplace notification
|
||||
// widget that was not visible because of the scrolling.
|
||||
this.showNotification_(jsonData);
|
||||
return;
|
||||
}
|
||||
|
||||
// Avoid race conditions with in place notifications.
|
||||
$.ajax({
|
||||
url: this.options_.fetchNotificationUrl,
|
||||
data: this.options_.requestOptions,
|
||||
success: this.callbackWrapper(this.showNotificationResponseHandler_),
|
||||
dataType: 'json',
|
||||
async: false
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reload a tab.
|
||||
* @private
|
||||
* @param {HTMLElement} sourceElement The element that issued the
|
||||
* "reloadTab" event.
|
||||
* @param {Event} event The "reload tab" event.
|
||||
* @param {Object} jsonData The JSON content representing the
|
||||
* reload request.
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.reloadTabHandler_ =
|
||||
function(sourceElement, event, jsonData) {
|
||||
|
||||
$(jsonData.tabsSelector).tabs('load', jsonData.tabSelector);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Call when click outside event handler. Stores the event
|
||||
* parameters as checks to be used later by mouse down handler so we
|
||||
* can track if user clicked outside the passed element or not.
|
||||
* @private
|
||||
* @param {HTMLElement} sourceElement The element that issued the
|
||||
* callWhenClickOutside event.
|
||||
* @param {Event} event The "call when click outside" event.
|
||||
* @param {{
|
||||
* container: jQueryObject,
|
||||
* callback: Function
|
||||
* }} eventParams The event parameters.
|
||||
* - container: a jQuery element to be used to test if user click
|
||||
* outside of it or not.
|
||||
* - callback: a callback function in case test is true.
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.callWhenClickOutsideHandler_ =
|
||||
function(sourceElement, event, eventParams) {
|
||||
// Check the required parameters.
|
||||
if (eventParams.container === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
var id = eventParams.container.attr('id');
|
||||
|
||||
if (eventParams.clear) {
|
||||
delete this.outsideClickChecks_[id];
|
||||
} else if (eventParams.callback !== undefined) {
|
||||
this.outsideClickChecks_[id] = eventParams;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Mouse down event handler attached to the site element.
|
||||
* @private
|
||||
* @param {HTMLElement} sourceElement The element that issued the
|
||||
* click event.
|
||||
* @param {Event} event The "mousedown" event.
|
||||
* @return {?boolean} Event handling status.
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.mouseDownHandler_ =
|
||||
function(sourceElement, event) {
|
||||
|
||||
var $container, callback, id;
|
||||
if (!$.isEmptyObject(this.outsideClickChecks_)) {
|
||||
for (id in this.outsideClickChecks_) {
|
||||
this.processOutsideClickCheck_(
|
||||
this.outsideClickChecks_[id], event);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check if the passed event target is outside the element
|
||||
* inside the passed check data. If true and no other check
|
||||
* option avoids it, use the callback.
|
||||
* @private
|
||||
* @param {{
|
||||
* container: Object,
|
||||
* callback: Function
|
||||
* }} checkOptions Object with data to be used to
|
||||
* check the click.
|
||||
* @param {Event} event The click event to be checked.
|
||||
* @return {boolean} Whether the check was processed or not.
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.processOutsideClickCheck_ =
|
||||
function(checkOptions, event) {
|
||||
|
||||
// Make sure we have a click event.
|
||||
if (event.type !== 'click' &&
|
||||
event.type !== 'mousedown' && event.type !== 'mouseup') {
|
||||
throw new Error('Can not check outside click with the passed event: ' +
|
||||
event.type + '.');
|
||||
}
|
||||
|
||||
// Get the container element.
|
||||
var $container = checkOptions.container;
|
||||
|
||||
// Doesn't make sense to check an outside click
|
||||
// with an invisible element, so skip test if
|
||||
// container is hidden.
|
||||
if ($container.is(':hidden')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Do the click origin checking.
|
||||
if ($container.has(event.target).length === 0) {
|
||||
|
||||
// Once the check was processed, delete it.
|
||||
delete this.outsideClickChecks_[$container.attr('id')];
|
||||
|
||||
checkOptions.callback();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Internal callback called upon page unload. If it returns
|
||||
* anything other than void, a message will be displayed to
|
||||
* the user.
|
||||
* @private
|
||||
* @param {Object} object The window object.
|
||||
* @param {Event} event The before unload event.
|
||||
* @return {string|undefined} The warning message string, if needed.
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.pageUnloadHandler_ =
|
||||
function(object, event) {
|
||||
var handler, unsavedElementCount, element;
|
||||
|
||||
// any registered and then unregistered forms will exist
|
||||
// as properties in the unsavedFormElements_ object. They
|
||||
// will just be undefined. See if there are any that are
|
||||
// not.
|
||||
|
||||
// we need to get the handler this way since this event is bound
|
||||
// to window, not to SiteHandler.
|
||||
handler = $.pkp.classes.Handler.getHandler($('body'));
|
||||
|
||||
unsavedElementCount = 0;
|
||||
for (element in handler.unsavedFormElements_) {
|
||||
if (element) {
|
||||
unsavedElementCount++;
|
||||
}
|
||||
}
|
||||
if (unsavedElementCount > 0) {
|
||||
return pkp.localeKeys['form.dataHasChanged'];
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Method to determine if a form is currently registered as having
|
||||
* unsaved changes.
|
||||
*
|
||||
* @param {string} id the id of the form to check.
|
||||
* @return {boolean} true if the form is unsaved.
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.isFormUnsaved =
|
||||
function(id) {
|
||||
|
||||
if (this.unsavedFormElements_ !== null &&
|
||||
this.unsavedFormElements_[id] !== undefined) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Response handler to the notification fetch.
|
||||
* @private
|
||||
* @param {Object} ajaxContext The data returned from the server.
|
||||
* @param {Object} jsonData A parsed JSON response object.
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.showNotificationResponseHandler_ =
|
||||
function(ajaxContext, jsonData) {
|
||||
this.showNotification_(jsonData);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Show the notification content.
|
||||
* @private
|
||||
* @param {Object} jsonData The JSON-encoded notification data.
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.showNotification_ =
|
||||
function(jsonData) {
|
||||
var workingJsonData, notificationsData, levelId, notificationId,
|
||||
addclass, type;
|
||||
|
||||
workingJsonData = this.handleJson(jsonData);
|
||||
if (workingJsonData !== false) {
|
||||
if (workingJsonData.content.general) {
|
||||
notificationsData = workingJsonData.content.general;
|
||||
for (levelId in notificationsData) {
|
||||
for (notificationId in notificationsData[levelId]) {
|
||||
addclass = notificationsData[levelId][notificationId].addclass;
|
||||
type = 'notice';
|
||||
if (addclass == 'notifySuccess') {
|
||||
type = 'success';
|
||||
} else if (addclass == 'notifyWarning' || addclass == 'notifyError' ||
|
||||
addclass == 'notifyFormError' || addclass == 'notifyForbidden') {
|
||||
type = 'warning';
|
||||
}
|
||||
pkp.eventBus.$emit('notify',
|
||||
notificationsData[levelId][notificationId].text, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reacts to a modal being opened. Adds a class to the body representing
|
||||
* a modal open state.
|
||||
* @private
|
||||
* @param {HTMLElement} handledElement The modal that has been added
|
||||
* @param {HTMLElement} siteHandlerElement The html element
|
||||
* attached to this handler.
|
||||
* @param {HTMLElement} sourceElement The element wishes to
|
||||
* register.
|
||||
* @param {Event} event The formChanged event.
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.openModal_ =
|
||||
function(handledElement, siteHandlerElement, sourceElement, event) {
|
||||
this.getHtmlElement().addClass('modal_is_visible');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reacts to a modal being closed. Removes a class from the body
|
||||
* representing a modal closed state, after checking if no other modals are
|
||||
* open.
|
||||
* @private
|
||||
* @param {HTMLElement} handledElement The modal that has been added
|
||||
* @param {HTMLElement} siteHandlerElement The html element
|
||||
* attached to this handler.
|
||||
* @param {HTMLElement} sourceElement The element wishes to
|
||||
* register.
|
||||
* @param {Event} event The formChanged event.
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.closeModal_ =
|
||||
function(handledElement, siteHandlerElement, sourceElement, event) {
|
||||
|
||||
var $htmlElement = this.getHtmlElement();
|
||||
if (!$htmlElement.find('.pkp_modal.is_visible').length) {
|
||||
$htmlElement.removeClass('modal_is_visible');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Register a function to observe the body scrolling event.
|
||||
* @private
|
||||
* @param {Object} siteHandler The site handler object.
|
||||
* @param {HTMLElement} siteHandlerElement The html element
|
||||
* attached to this handler.
|
||||
* @param {Object} event The pkpObserveScrolling event object.
|
||||
* @param {Function} observerFunction The observer function.
|
||||
* @return {boolean}
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.registerScrollingObserver_ =
|
||||
function(siteHandler, siteHandlerElement, event, observerFunction) {
|
||||
$(document).scroll(observerFunction);
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Unregister a function that was observing the body scrolling event.
|
||||
* @private
|
||||
* @param {Object} siteHandler The site handler object.
|
||||
* @param {HTMLElement} siteHandlerElement The html element
|
||||
* attached to this handler.
|
||||
* @param {Object} event The pkpRemoveScrollingObserver event object.
|
||||
* @param {Function} observerFunction The observer function.
|
||||
* @return {boolean}
|
||||
*/
|
||||
$.pkp.controllers.SiteHandler.prototype.unregisterScrollingObserver_ =
|
||||
function(siteHandler, siteHandlerElement, event, observerFunction) {
|
||||
var castObserverFunction = /** @type {function()} */ (observerFunction);
|
||||
$(document).unbind('scroll', castObserverFunction);
|
||||
return false;
|
||||
};
|
||||
|
||||
}(jQuery));
|
||||
Reference in New Issue
Block a user