first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-06-08 17:09:23 -04:00
commit df3a033196
17887 changed files with 8637778 additions and 0 deletions
@@ -0,0 +1,384 @@
/**
* @defgroup controllers_wizard_fileUpload
*/
/**
* @file js/controllers/wizard/fileUpload/FileUploadWizardHandler.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 FileUploadWizardHandler
* @ingroup controllers_wizard_fileUpload
*
* @brief File uploader wizard handler.
*/
(function($) {
/** @type {Object} */
$.pkp.controllers.wizard.fileUpload =
$.pkp.controllers.wizard.fileUpload || { };
/**
* @constructor
*
* @extends $.pkp.controllers.wizard.WizardHandler
*
* @param {jQueryObject} $wizard The wrapped HTML form element.
* @param {Object} options Wizard options.
*/
$.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler =
function($wizard, options) {
this.parent($wizard, options);
// Save action urls.
this.csrfToken_ = options.csrfToken;
this.deleteUrl_ = options.deleteUrl;
this.metadataUrl_ = options.metadataUrl;
this.finishUrl_ = options.finishUrl;
this.cancelUrl_ = options.cancelUrl;
// Bind events of the nested upload forms.
this.bind('fileUploaded', this.handleFileUploaded);
this.bind('filesRemoved', this.handleRemovedFiles);
// Initially disable the continue button.
this.disableContinueButton();
};
$.pkp.classes.Helper.inherits(
$.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler,
$.pkp.controllers.wizard.WizardHandler);
//
// Private properties
//
/**
* The CSRF token to use with a cancel event.
* @private
* @type {string}
*/
$.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler.
prototype.csrfToken_ = '';
/**
* The URL to be called when a delete event occurs.
* @private
* @type {string}
*/
$.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler.
prototype.deleteUrl_ = '';
/**
* The URL from which to load the meta-data form.
* @private
* @type {string}
*/
$.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler.
prototype.metadataUrl_ = '';
/**
* The URL from which to load the finish form.
* @private
* @type {string}
*/
$.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler.
prototype.finishUrl_ = '';
/**
* The URL to be called when a cancel event occurs.
* @private
* @type {string}
*/
$.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler.
prototype.cancelUrl_ = '';
/**
* Information about the uploaded file (once there is one).
* @private
* @type {{fileId: number}?}
*/
$.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler.
prototype.uploadedFile_ = null;
/**
* Information about the file being revised.
* @private
* @type {{fileId: number, name: string, uploaderUserId: number}}
*/
$.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler.
prototype.originalFile_ = null;
//
// Public methods
//
/**
* @inheritDoc
*/
$.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler.
prototype.tabsBeforeActivate = function(tabsElement, event, ui) {
// The last two tabs require a file to be uploaded.
if (ui.newTab.index() > 0) {
if (!this.uploadedFile_) {
throw new Error('Uploaded file missing!');
}
// Set the correct URLs.
var $wizard = this.getHtmlElement(), newUrl = '';
switch (ui.newTab.index()) {
case 1:
newUrl = this.metadataUrl_;
break;
case 2:
newUrl = this.finishUrl_;
break;
default:
throw new Error('Unsupported tab index.');
}
newUrl = newUrl + '&submissionFileId=' + this.uploadedFile_.id;
ui.newTab.find('.ui-tabs-anchor').attr('href', newUrl);
}
return /** @type {boolean} */ (
this.parent('tabsBeforeActivate', tabsElement, event, ui));
};
/**
* Overridden version of WizardHandler's wizardAdvance handler.
* This version allows a user to return to all tabs but the very
* first one (the actual file upload).
*
* @param {HTMLElement} wizardElement The wizard's HTMLElement on
* which the event was triggered.
* @param {Event} event The triggered event.
*/
$.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler.
prototype.wizardAdvance = function(wizardElement, event) {
// The wizard can only be advanced one step at a time.
// The step cannot be greater than the number of wizard
// tabs and not less than 1.
var currentStep = this.getCurrentStep(),
lastStep = this.getNumberOfSteps() - 1,
targetStep = currentStep + 1,
$wizard = this.getHtmlElement(),
$continueButton;
// Do not advance beyond the last step.
if (targetStep > lastStep) {
throw new Error('Trying to set an invalid wizard step!');
}
// Enable the target step.
$wizard.tabs('enable', targetStep);
// Advance to the target step.
$wizard.tabs('option', 'active', targetStep);
// Disable the previous step if it is the first one.
if (currentStep === 0) {
$wizard.tabs('disable', currentStep);
}
// If this is the last step then change the text on the
// continue button to finish.
if (targetStep === lastStep) {
$continueButton = this.getContinueButton();
$continueButton.text(
/** @type {string} */ (this.getFinishButtonText()));
this.enableContinueButton();
}
};
/**
* @inheritDoc
*/
$.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler.
prototype.tabsLoad = function(tabsElement, event, ui) {
var $wizard = this.getHtmlElement(),
$newFileButton,
$progressIndicator = this.getProgressIndicator();
// In the last step: Bind click a event to the button that re-starts
// the upload process.
if (ui.tab.index() === 2) {
$newFileButton = $('#newFile', $wizard);
// In some cases only a single file can be uploaded and no new
// file button appears
if ($newFileButton.length) {
$newFileButton.bind('click', this.callbackWrapper(this.startWizard));
}
}
$progressIndicator.hide();
return /** @type {boolean} */ (
this.parent('tabsLoad', tabsElement, event, ui));
};
/**
* @inheritDoc
*/
$.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler.
prototype.formValid = function(formElement, event) {
// Ignore form validation events for the upload form.
if (this.getCurrentStep() === 0 &&
this.getHtmlElement().find('#uploadConfirmationForm').length === 0 &&
!this.uploadedFile_) {
return;
}
this.parent('formValid', formElement, event);
};
/**
* @inheritDoc
*/
$.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler.
prototype.wizardCancelRequested = function(wizardElement, event) {
if (this.parent('wizardCancelRequested', wizardElement, event)) {
// If the user presses cancel after uploading a file then delete the file.
if (this.uploadedFile_) {
this.uploadedFile_.csrfToken = this.csrfToken_;
// Authorization policy expects to find the submissionFileId para
this.uploadedFile_.submissionFileId = this.uploadedFile_.id;
this.uploadedFile_.originalFile = this.originalFile_;
$.post(this.cancelUrl_, this.uploadedFile_,
$.pkp.classes.Helper.curry(this.wizardCancelSuccess, this,
wizardElement, event), 'json');
// The uploaded file is being dealt with; reset.
this.uploadedFile_ = null;
// Do not cancel immediately.
event.preventDefault();
} else {
return true;
}
return false;
} else {
// Stop the cancel request.
return false;
}
};
/**
* Callback triggered when the deletion of a file after clicking
* the cancel button was successful.
*
* @param {HTMLElement} wizardElement The wizard's HTMLElement on
* which the event was triggered.
* @param {Event} event The original event.
* @param {Object} jsonData The JSON data returned by the server on
* file deletion.
*/
$.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler.
prototype.wizardCancelSuccess = function(wizardElement, event, jsonData) {
var processedJsonData = this.handleJson(jsonData);
if (processedJsonData !== false) {
// Cancel the wizard.
this.trigger('wizardCancel');
}
};
/**
* Handle the "file uploaded" event triggered by the
* file upload/revision confirmation forms whenever the
* uploaded file changed.
*
* @param {$.pkp.controllers.form.AjaxFormHandler} callingForm The form
* that triggered the event.
* @param {Event} event The upload event.
* @param {{fileId: number}} uploadedFile Information about the uploaded
* file.
*/
$.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler.
prototype.handleFileUploaded = function(callingForm, event, uploadedFile) {
// Keep the original file data to restore if the wizard is canceled
if (this.originalFile_ === null) {
this.originalFile_ = uploadedFile.originalFile;
}
delete uploadedFile.originalFile;
// Save the uploaded file information
this.uploadedFile_ = uploadedFile;
};
/**
* Handle the filesRemoved event triggered by the associated form. The
* original event is triggered by plupload and passed via
* FileUploadFormHandler.
*
* See the TODO note under FileUPloadFormHandler::handleFilesRemoved
*
* @param {$.pkp.controllers.form.AjaxFormHandler} callingForm The form
* that triggered the event.
* @param {Event} event The upload event.
* @param {Object} pluploader plupload component that fired the original
* event.
* @param {Array} file Array of files removed
*/
$.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler.
prototype.handleRemovedFiles =
function(callingForm, event, pluploader, file) {
var i;
if (typeof file === 'undefined' || !file.length) {
return;
}
// There's no error handling done for the response because we don't
// really have an elegant way to handle or display a failed deletion
for (i in file) {
if (typeof file[i].storedData === 'undefined') {
return;
}
file[i].storedData.csrfToken = this.csrfToken_;
$.post(this.deleteUrl_, file[i].storedData);
}
};
//
// Protected methods
//
/**
* @inheritDoc
*/
$.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler.
prototype.startWizard = function() {
// Reset the uploaded and original file.
this.uploadedFile_ = this.originalFile_ = null;
this.parent('startWizard');
};
}(jQuery));
@@ -0,0 +1,354 @@
/**
* @defgroup js_controllers_wizard_fileUpload_form
*/
/**
* @file js/controllers/wizard/fileUpload/form/FileUploadFormHandler.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 FileUploadFormHandler
* @ingroup js_controllers_wizard_fileUpload_form
*
* @brief File upload tab handler.
*/
(function($) {
/** @type {Object} */
$.pkp.controllers.wizard.fileUpload.form =
$.pkp.controllers.wizard.fileUpload.form || { };
/**
* @constructor
*
* @extends $.pkp.controllers.form.AjaxFormHandler
*
* @param {jQueryObject} $form The wrapped HTML form element.
* @param {Object} options Form validation options.
*/
$.pkp.controllers.wizard.fileUpload.form.FileUploadFormHandler =
function($form, options) {
this.parent($form, options);
// Set internal state properties.
this.hasFileSelector_ = options.hasFileSelector;
this.hasGenreSelector_ = options.hasGenreSelector;
if (options.presetRevisedFileId) {
this.presetRevisedFileId_ = options.presetRevisedFileId;
}
this.fileGenres_ = options.fileGenres;
this.$uploader_ = options.$uploader;
// Attach the uploader handler to the uploader HTML element.
this.attachUploader_(this.$uploader_, options.uploaderOptions);
this.uploaderSetup(options.$uploader);
// Enable/disable the uploader and genre selection based on selection
this.$revisedFileSelector_ = $form.find('#revisedFileId')
.change(this.callbackWrapper(this.revisedFileChange));
if (this.hasGenreSelector_) {
this.$genreSelector = $form.find('#genreId')
.change(this.callbackWrapper(this.genreChange));
}
this.setUploaderVisibility_();
};
$.pkp.classes.Helper.inherits(
$.pkp.controllers.wizard.fileUpload.form.FileUploadFormHandler,
$.pkp.controllers.form.AjaxFormHandler);
//
// Private properties
//
/**
* Whether the file upload form has a file selector.
* @private
* @type {boolean}
*/
$.pkp.controllers.wizard.fileUpload.form.FileUploadFormHandler
.hasFileSelector_ = false;
/**
* The file upload form's file selector if available.
* @private
* @type {boolean?}
*/
$.pkp.controllers.wizard.fileUpload.form.FileUploadFormHandler
.$revisedFileSelector_ = null;
/**
* Whether the file upload form has a genre selector.
* @private
* @type {boolean}
*/
$.pkp.controllers.wizard.fileUpload.form.FileUploadFormHandler
.hasGenreSelector_ = false;
/**
* The file upload form's genre selector if available.
* @private
* @type {boolean?}
*/
$.pkp.controllers.wizard.fileUpload.form.FileUploadFormHandler
.$genreSelector_ = null;
/**
* A preset revised file id (if any).
* @private
* @type {?string}
*/
$.pkp.controllers.wizard.fileUpload.form.FileUploadFormHandler
.presetRevisedFileId_ = null;
/**
* All currently available file genres.
* @private
* @type {Object}
*/
$.pkp.controllers.wizard.fileUpload.form.FileUploadFormHandler
.fileGenres_ = null;
/**
* A jQuery object referencing the DOM element plupload is attached to
* @private
* @type {Object}
*/
$.pkp.controllers.wizard.fileUpload.form.FileUploadFormHandler
.$uploader_ = null;
//
// Public methods
//
/**
* The setup callback of the uploader.
* @param {jQueryObject} $uploader Element that contains the plupload object.
*/
$.pkp.controllers.wizard.fileUpload.form.FileUploadFormHandler.prototype.
uploaderSetup = function($uploader) {
var uploadHandler = $.pkp.classes.Handler.getHandler($uploader);
// Subscribe to uploader events.
uploadHandler.pluploader.bind('BeforeUpload',
this.callbackWrapper(this.prepareFileUploadRequest));
uploadHandler.pluploader.bind('FileUploaded',
this.callbackWrapper(this.handleUploadResponse));
uploadHandler.pluploader.bind('FilesRemoved',
this.callbackWrapper(this.handleRemovedFiles));
};
/**
* Prepare the request parameters for the file upload request.
* @param {Object} caller The original context in which the callback was called.
* @param {Object} pluploader The pluploader object.
*/
$.pkp.controllers.wizard.fileUpload.form.FileUploadFormHandler.prototype.
prepareFileUploadRequest = function(caller, pluploader) {
var $uploadForm = this.getHtmlElement(),
multipartParams = {};
// Add the revised file to the upload message.
if (this.hasFileSelector_) {
this.$revisedFileSelector_.attr('disabled', 'disabled');
multipartParams.revisedFileId = this.$revisedFileSelector_.val();
} else {
if (this.presetRevisedFileId_ !== null) {
multipartParams.revisedFileId = this.presetRevisedFileId_;
} else {
multipartParams.revisedFileId = 0;
}
}
// Add the file genre to the upload message.
if (this.hasGenreSelector_) {
this.$genreSelector.attr('disabled', 'disabled');
multipartParams.genreId = this.$genreSelector.val();
} else {
multipartParams.genreId = '';
}
// Add the upload message parameters to the uploader.
pluploader.settings.multipart_params = multipartParams;
};
/**
* Handle the response of a "file upload" request.
* @param {Object} caller The original context in which the callback was called.
* @param {Object} pluploader The pluploader object.
* @param {Object} file The data of the uploaded file.
* @param {{response: string}} ret The serialized JSON response.
*/
$.pkp.controllers.wizard.fileUpload.form.FileUploadFormHandler.prototype.
handleUploadResponse = function(caller, pluploader, file, ret) {
// Handle the server's JSON response.
var jsonData = this.handleJson($.parseJSON(ret.response)),
$uploadForm = this.getHtmlElement();
if (jsonData !== false) {
// Trigger the file uploaded event.
this.trigger('fileUploaded', jsonData.uploadedFile);
// Display the revision confirmation form.
if (jsonData.content !== '') {
this.replaceWith(jsonData.content);
}
}
// Trigger validation on the form. This doesn't happen automatically
// until `blur` is triggered on the file input field, requiring the
// user to click before any disabled form functions become available.
this.getHtmlElement().valid();
};
/**
* Pass the `FilesRemoved` event from plupload on to FileUploadWizardHandler
* so it can delete the file.
*
* TODO this is necessary because only the FileUploadWizardHandler knows
* the delete URL. But other file upload utilities could benefit from this
* feature, so it would be best to internalize this functionality in the
* UploadHandler by passing in a deleteURL option. This is a task that
* should be handled when the file upload process is rewritten to support
* a multi-file upload workflow.
* @param {Object} caller The original context in which the callback was called.
* @param {Object} pluploader The pluploader object.
* @param {Object} file The data of the uploaded file.
*/
$.pkp.controllers.wizard.fileUpload.form.FileUploadFormHandler.prototype.
handleRemovedFiles = function(caller, pluploader, file) {
this.trigger('filesRemoved', [pluploader, file]);
};
/**
* Internal callback to handle form submission.
*
* @param {Object} validator The validator plug-in.
* @param {HTMLElement} formElement The wrapped HTML form.
*/
$.pkp.controllers.wizard.fileUpload.form.FileUploadFormHandler.prototype.
submitForm = function(validator, formElement) {
// There is no form to submit (file already uploaded).
// Trigger event to signal that user requests the form to be submitted.
this.trigger('formSubmitted');
};
/**
* Handle the "change" event of the revised file selector.
* @param {HTMLElement} revisedFileElement The original context in
* which the event was triggered.
* @param {Event} event The change event.
* @return {boolean} Event handling status.
*/
$.pkp.controllers.wizard.fileUpload.form.FileUploadFormHandler.prototype.
revisedFileChange = function(revisedFileElement, event) {
// Enable/disable the genre field when a revision is selected
if (!this.$revisedFileSelector_.val()) {
this.$genreSelector.removeAttr('disabled');
} else {
this.$genreSelector.val(this.fileGenres_[this.$revisedFileSelector_.val()]);
this.$genreSelector.attr('disabled', 'disabled');
}
this.setUploaderVisibility_();
return false;
};
/**
* Handle the "change" event of the genre selector, if it exists.
* @param {HTMLElement} genreElement The original context in
* which the event was triggered.
* @param {Event} event The change event.
*/
$.pkp.controllers.wizard.fileUpload.form.FileUploadFormHandler.prototype.
genreChange = function(genreElement, event) {
this.setUploaderVisibility_();
};
//
// Private methods
//
/**
* Attach the uploader handler.
* @private
* @param {jQueryObject} $uploader The wrapped HTML uploader element.
* @param {Object} options Uploader options.
*/
$.pkp.controllers.wizard.fileUpload.form.FileUploadFormHandler.prototype.
attachUploader_ = function($uploader, options) {
// Attach the uploader handler to the uploader div.
$uploader.pkpHandler('$.pkp.controllers.UploaderHandler', options);
};
/**
* Adjust the display of the plupload component depending on required
* settings
* @private
*/
$.pkp.controllers.wizard.fileUpload.form.FileUploadFormHandler.prototype.
setUploaderVisibility_ = function() {
if ((this.hasGenreSelector_ && this.$genreSelector.val()) ||
this.$revisedFileSelector_.val()) {
this.showUploader_();
} else if (!this.hasGenreSelector_ && !this.hasFileSelector_) {
this.showUploader_();
} else {
this.hideUploader_();
}
};
/**
* Hide the plupload component
* @private
*/
$.pkp.controllers.wizard.fileUpload.form.FileUploadFormHandler.prototype.
hideUploader_ = function() {
this.$uploader_.addClass('pkp_screen_reader');
};
/**
* Show the the plupload component
* @private
*/
$.pkp.controllers.wizard.fileUpload.form.FileUploadFormHandler.prototype.
showUploader_ = function() {
this.$uploader_.removeClass('pkp_screen_reader');
// Reset the button position
$.pkp.classes.Handler.getHandler(this.$uploader_)
.pluploader.refresh();
};
}(jQuery));