first
This commit is contained in:
@ -0,0 +1,179 @@
|
||||
'use strict';
|
||||
|
||||
class ShortPixelScreenBase
|
||||
{
|
||||
isCustom = true;
|
||||
isMedia = true;
|
||||
processor;
|
||||
strings = [];
|
||||
|
||||
constructor(MainScreen, processor)
|
||||
{
|
||||
this.processor = processor;
|
||||
this.strings = spio_screenStrings;
|
||||
}
|
||||
|
||||
// Function for subclasses to add more init. Seperated because of screens that need to call Process functions when starting.
|
||||
Init()
|
||||
{
|
||||
}
|
||||
|
||||
// var message = {status: false, http_status: response.status, http_text: text, status_text: response.statusText };
|
||||
HandleError(data)
|
||||
{
|
||||
if (this.processor.debugIsActive == 'false')
|
||||
return; // stay silent when debug is not active.
|
||||
|
||||
var text = String(data.http_text);
|
||||
var title = this.strings.fatalError;
|
||||
var notice = this.GetErrorNotice(title, text);
|
||||
|
||||
var el = this.GetErrorPosition();
|
||||
if (el === null)
|
||||
{
|
||||
console.error('Cannot display error - no position found!');
|
||||
return;
|
||||
}
|
||||
el.prepend(notice);
|
||||
}
|
||||
|
||||
// No actions at the base.
|
||||
HandleItemError(result)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HandleErrorStop()
|
||||
{
|
||||
if (this.processor.debugIsActive == 'false')
|
||||
return; // stay silent when debug is not active.
|
||||
|
||||
var title = this.strings.fatalErrorStop;
|
||||
var text = this.strings.fatalErrorStopText;
|
||||
|
||||
var notice = this.GetErrorNotice(title, text);
|
||||
var el = this.GetErrorPosition();
|
||||
if (el === null)
|
||||
{
|
||||
console.error('Cannot display error - no position found!');
|
||||
return;
|
||||
}
|
||||
el.prepend(notice);
|
||||
}
|
||||
|
||||
|
||||
GetErrorNotice(title, text)
|
||||
{
|
||||
var notice = document.createElement('div');
|
||||
|
||||
var button = document.createElement('button'); // '<button type="button" class="notice-dismiss"></button>';
|
||||
button.classList.add('notice-dismiss');
|
||||
button.type = 'button';
|
||||
button.addEventListener('click', this.EventCloseErrorNotice);
|
||||
|
||||
notice.classList.add('notice', 'notice-error', 'is-dismissible');
|
||||
|
||||
notice.innerHTML += '<p><strong>' + title + '</strong></p>';
|
||||
notice.innerHTML += '<div class="error-details">' + text + '</div>';
|
||||
|
||||
notice.append(button);
|
||||
|
||||
return notice;
|
||||
}
|
||||
|
||||
EventCloseErrorNotice(event)
|
||||
{
|
||||
event.target.parentElement.remove();
|
||||
}
|
||||
|
||||
// Search for where to insert the notice before ( ala WP system )
|
||||
GetErrorPosition()
|
||||
{
|
||||
var el = document.querySelector('.is-shortpixel-settings-page');
|
||||
if (el !== null) // we are on settings page .
|
||||
{
|
||||
return el;
|
||||
}
|
||||
|
||||
var el = document.querySelector('.wrap');
|
||||
if (el !== null)
|
||||
return el;
|
||||
|
||||
|
||||
var el = document.querySelector('#wpbody-content');
|
||||
if (el !== null)
|
||||
return el;
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
HandleImage(result, type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
UpdateStats()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
RenderItemView(e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// @todo Find a better home for this. Global screen class?
|
||||
ParseNumber(str)
|
||||
{
|
||||
str = str.replace(',','', str).replace('.','',str);
|
||||
return parseInt(str);
|
||||
}
|
||||
|
||||
|
||||
// ** FADE OUT FUNCTION **
|
||||
FadeOut(el) {
|
||||
el.style.opacity = 0;
|
||||
el.style.display = 'none';
|
||||
|
||||
/*
|
||||
el.style.opacity = 1;
|
||||
(function fade() {
|
||||
if ((el.style.opacity -= .1) < 0) {
|
||||
el.style.display = "none";
|
||||
el.style.opacity = 0;
|
||||
|
||||
} else {
|
||||
requestAnimationFrame(fade);
|
||||
}
|
||||
})(); */
|
||||
};
|
||||
|
||||
// ** FADE IN FUNCTION **
|
||||
FadeIn(el, display) {
|
||||
el.style.opacity = 1;
|
||||
el.style.display = "block";
|
||||
/*
|
||||
(function fade() {
|
||||
var val = parseFloat(el.style.opacity);
|
||||
if (!((val += .1) > 1)) {
|
||||
el.style.opacity = val;
|
||||
requestAnimationFrame(fade);
|
||||
}
|
||||
})(); */
|
||||
};
|
||||
|
||||
Show(el)
|
||||
{
|
||||
el.style.display = 'block';
|
||||
}
|
||||
|
||||
Hide(el)
|
||||
{
|
||||
el.style.display = 'none';
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // class
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,544 @@
|
||||
'use strict';
|
||||
// MainScreen as an option for delegate functions
|
||||
class ShortPixelScreen extends ShortPixelScreenItemBase
|
||||
{
|
||||
isCustom = true;
|
||||
isMedia = true;
|
||||
type = 'custom';
|
||||
folderTree = null;
|
||||
currentSelectedPath = null;
|
||||
stopSignal = false;
|
||||
|
||||
Init()
|
||||
{
|
||||
super.Init();
|
||||
|
||||
this.InitFolderSelector();
|
||||
this.InitScanButtons();
|
||||
this.InitFileScreenAction();
|
||||
}
|
||||
|
||||
RenderItemView(e)
|
||||
{
|
||||
var data = e.detail;
|
||||
|
||||
if (data.custom)
|
||||
{
|
||||
var id = data.custom.id;
|
||||
var element = document.getElementById('sp-msg-' + id);
|
||||
element.outerHTML = data.custom.itemView;
|
||||
|
||||
var isOptimizable = data.custom.is_optimizable;
|
||||
var isRestorable = data.custom.is_restorable;
|
||||
|
||||
var inputSelect = document.querySelector('.item-' + id + ' input[name="select[]"]');
|
||||
|
||||
if (null === inputSelect)
|
||||
{
|
||||
console.warn('Checkbox not found ' + id);
|
||||
}
|
||||
|
||||
inputSelect.classList.remove('is-optimizable', 'is-restorable');
|
||||
if (true === isOptimizable)
|
||||
inputSelect.classList.add('is-optimizable');
|
||||
|
||||
if (true === isRestorable)
|
||||
inputSelect.classList.add('is-restorable');
|
||||
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the processor needs to start when items are being added / folders refreshed
|
||||
CheckProcessorStart()
|
||||
{
|
||||
// If automedia is active, see if something is to process.
|
||||
if (this.processor.IsAutoMediaActive())
|
||||
{
|
||||
this.processor.SetInterval(-1);
|
||||
this.processor.RunProcess();
|
||||
}
|
||||
}
|
||||
|
||||
RefreshFolder(id)
|
||||
{
|
||||
var data = {};
|
||||
data.id = id;
|
||||
data.type = 'folder';
|
||||
data.screen_action = 'refreshFolder';
|
||||
data.callback = 'shortpixel.folder.HandleFolderResult';
|
||||
|
||||
window.addEventListener('shortpixel.folder.HandleFolderResult', this.HandleFolderResult.bind(this), {'once':true});
|
||||
|
||||
// AjaxRequest should return result, which will go through Handleresponse, then LoaditemView.
|
||||
this.processor.AjaxRequest(data);
|
||||
}
|
||||
|
||||
StopMonitoringFolder(id)
|
||||
{
|
||||
|
||||
if (confirm('Are you sure you want to stop optimizing this folder? '))
|
||||
{
|
||||
var data = {};
|
||||
data.id = id;
|
||||
data.type = 'folder';
|
||||
data.screen_action = 'removeCustomFolder';
|
||||
data.callback = 'shortpixel.folder.HandleFolderResult';
|
||||
|
||||
window.addEventListener('shortpixel.folder.HandleFolderResult', this.HandleFolderResult.bind(this), {'once':true});
|
||||
this.processor.AjaxRequest(data);
|
||||
}
|
||||
}
|
||||
|
||||
HandleFolderResult(e)
|
||||
{
|
||||
var data = e.detail;
|
||||
|
||||
if (data.folder)
|
||||
{
|
||||
var folder_id = data.folder.id;
|
||||
if (data.folder.message)
|
||||
{
|
||||
var el = document.querySelector('.shortpixel-other-media .item.item-' + folder_id + ' .status');
|
||||
if (null !== el)
|
||||
{
|
||||
el.innerHTML = data.folder.message;
|
||||
}
|
||||
else {
|
||||
console.error('Status Element not found for ' + folder_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (data.folder.fileCount)
|
||||
{
|
||||
var el = document.querySelector('.shortpixel-other-media .item.item-' + folder_id + ' .files-number');
|
||||
if (null !== el)
|
||||
{
|
||||
el.innerText = data.folder.fileCount;
|
||||
}
|
||||
else {
|
||||
console.error('FileCount Element not found for ' + folder_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (data.folder.action == 'remove')
|
||||
{
|
||||
if (true == data.folder.is_done)
|
||||
{
|
||||
var el = document.querySelector('.shortpixel-other-media .item.item-' + folder_id);
|
||||
if ( null !== el)
|
||||
{
|
||||
el.remove();
|
||||
}
|
||||
else {
|
||||
console.error('Row Element not found for ' + folder_id);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.CheckProcessorStart();
|
||||
}
|
||||
|
||||
InitScanButtons()
|
||||
{
|
||||
var scanButtons = document.querySelectorAll('.scan-button');
|
||||
var self = this;
|
||||
|
||||
if (null !== scanButtons)
|
||||
{
|
||||
scanButtons.forEach(function (scanButton) {
|
||||
scanButton.addEventListener('click', self.StartFolderScanEvent.bind(self));
|
||||
});
|
||||
}
|
||||
|
||||
var stopButton = document.querySelector('.scan-actions .stop-button');
|
||||
if (null !== stopButton)
|
||||
{
|
||||
stopButton.addEventListener('click', this.StopScanEvent.bind(this));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
InitFolderSelector()
|
||||
{
|
||||
var openModalButton = document.querySelector('.open-selectfolder-modal');
|
||||
if (null !== openModalButton)
|
||||
{
|
||||
openModalButton.addEventListener('click', this.OpenFolderModal.bind(this));
|
||||
}
|
||||
|
||||
var closeModalButtons = document.querySelectorAll('.shortpixel-modal input.select-folder-cancel, .sp-folder-picker-shade');
|
||||
|
||||
var self = this;
|
||||
closeModalButtons.forEach(function (button, index)
|
||||
{
|
||||
button.addEventListener('click', self.CloseFolderModal.bind(self));
|
||||
});
|
||||
|
||||
var addFolderButton = document.querySelector('.modal-folder-picker .select-folder')
|
||||
if (null !== addFolderButton)
|
||||
{
|
||||
addFolderButton.addEventListener('click', this.AddNewFolderEvent.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
InitFileScreenAction()
|
||||
{
|
||||
var selectAll = document.querySelector('input[name="select-all"]');
|
||||
if (null !== selectAll)
|
||||
selectAll.addEventListener('change', this.SelectAllItemsEvent.bind(this));
|
||||
|
||||
|
||||
var bulkAction = document.querySelector('button[name="doBulkAction"]');
|
||||
if (null !== bulkAction)
|
||||
bulkAction.addEventListener('click', this.BulkActionEvent.bind(this));
|
||||
|
||||
}
|
||||
|
||||
SelectAllItemsEvent(event)
|
||||
{
|
||||
var parent = event.target;
|
||||
var inputs = document.querySelectorAll('input[name="select[]"]');
|
||||
|
||||
var toggle = (true === parent.checked) ? true : false;
|
||||
|
||||
for(var i = 0; i < inputs.length; i++)
|
||||
{
|
||||
inputs[i].checked = toggle;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BulkActionEvent(event)
|
||||
{
|
||||
event.preventDefault();
|
||||
var target = event.target;
|
||||
|
||||
var items = document.querySelectorAll('input[name="select[]"]:checked');
|
||||
var selectBox = document.querySelector('select[name="bulk-actions"]');
|
||||
var selectedAction = selectBox.options[selectBox.selectedIndex];
|
||||
selectBox.selectedIndex = 0; // Return to default
|
||||
|
||||
var action = selectedAction.value;
|
||||
|
||||
|
||||
for (var i = 0; i < items.length; i++)
|
||||
{
|
||||
var item = items[i];
|
||||
if (false == item.checked) // failsafe
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var item_id = item.value;
|
||||
|
||||
if ('optimize' === action)
|
||||
{
|
||||
if (item.classList.contains('is-optimizable'))
|
||||
{
|
||||
this.Optimize(item_id);
|
||||
}
|
||||
}
|
||||
else if ('restore' === action)
|
||||
{
|
||||
if (item.classList.contains('is-restorable'))
|
||||
{
|
||||
this.RestoreItem(item_id);
|
||||
}
|
||||
}
|
||||
else if ('mark-completed' === action)
|
||||
{
|
||||
if (item.classList.contains('is-optimizable'))
|
||||
{
|
||||
this.MarkCompleted(item_id);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
}
|
||||
|
||||
item.checked = false;
|
||||
}
|
||||
|
||||
var selectAll = document.querySelector('input[name="select-all"]');
|
||||
selectAll.checked = false;
|
||||
}
|
||||
|
||||
OpenFolderModal()
|
||||
{
|
||||
var shade = document.querySelector(".sp-folder-picker-shade");
|
||||
// this.FadeIn(shade, 500);
|
||||
this.Show(shade);
|
||||
|
||||
var picker = document.querySelector(".shortpixel-modal.modal-folder-picker");
|
||||
picker.classList.remove('shortpixel-hide');
|
||||
picker.style.display = 'block';
|
||||
|
||||
var picker = document.querySelector(".sp-folder-picker");
|
||||
|
||||
if (null === this.folderTree)
|
||||
{
|
||||
this.folderTree = new ShortPixelFolderTree(picker, this.processor);
|
||||
picker.addEventListener('shortpixel-folder.selected', this.HandleFolderSelectedEvent.bind(this));
|
||||
}
|
||||
|
||||
this.Show(picker);
|
||||
}
|
||||
|
||||
HandleFolderSelectedEvent(event)
|
||||
{
|
||||
var data = event.detail;
|
||||
var relpath = data.relpath;
|
||||
|
||||
var selectedField = document.querySelector('.sp-folder-picker-selected');
|
||||
selectedField.textContent = relpath;
|
||||
|
||||
this.currentSelectedPath = relpath;
|
||||
|
||||
if (null !== this.currentSelectedPath)
|
||||
{
|
||||
var addFolderButton = document.querySelector('.modal-folder-picker .select-folder');
|
||||
if (null !== addFolderButton)
|
||||
{
|
||||
addFolderButton.disabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CloseFolderModal()
|
||||
{
|
||||
var shade = document.querySelector(".sp-folder-picker-shade");
|
||||
this.Hide(shade);
|
||||
|
||||
// @todo FadeOut function here
|
||||
var picker = document.querySelector('.shortpixel-modal.modal-folder-picker');
|
||||
this.Hide(picker);
|
||||
}
|
||||
|
||||
AddNewFolderEvent(event)
|
||||
{
|
||||
var data = {};
|
||||
data.relpath = this.currentSelectedPath;
|
||||
data.type = 'folder';
|
||||
data.screen_action = 'addCustomFolder';
|
||||
data.callback = 'shortpixel.folder.AddNewDirectory';
|
||||
|
||||
// @todo this message logic should prob. become part of the folder selector js proper.
|
||||
var messageEl = document.querySelector('.modal-folder-picker .folder-message');
|
||||
if (null !== messageEl)
|
||||
{
|
||||
if ( false == messageEl.classList.contains('hidden'))
|
||||
{
|
||||
messageEl.classList.add('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('shortpixel.folder.AddNewDirectory', this.UpdateFolderViewEvent.bind(this), {'once':true});
|
||||
|
||||
this.processor.AjaxRequest(data);
|
||||
|
||||
|
||||
}
|
||||
|
||||
UpdateFolderViewEvent(event)
|
||||
{
|
||||
var data = event.detail;
|
||||
|
||||
// not for us.
|
||||
if (false === data.folder)
|
||||
return false;
|
||||
|
||||
if (data.folder.result && data.folder.result.itemView)
|
||||
{
|
||||
var element = document.querySelector('.list-overview .item');
|
||||
var elementHeading = document.querySelector('.list-overview .heading');
|
||||
|
||||
if (null !== element)
|
||||
{
|
||||
element.insertAdjacentHTML('beforebegin', data.folder.result.itemView);
|
||||
}
|
||||
else if (null !== elementHeading) // In case list is empty.
|
||||
{
|
||||
elementHeading.insertAdjacentHTML('afterend', data.folder.result.itemView);
|
||||
var noitems = document.querySelector('.list-overview .no-items');
|
||||
if (null !== noitems)
|
||||
noitems.remove();
|
||||
}
|
||||
|
||||
this.CloseFolderModal();
|
||||
this.CheckProcessorStart();
|
||||
|
||||
}
|
||||
else if (data.folder.is_error == true && data.folder.message)
|
||||
{
|
||||
var messageEl = document.querySelector('.modal-folder-picker .folder-message');
|
||||
if (null !== messageEl)
|
||||
{
|
||||
messageEl.textContent = data.folder.message;
|
||||
messageEl.classList.remove('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
StartFolderScanEvent(event)
|
||||
{
|
||||
var element = event.target;
|
||||
this.stopSignal = false;
|
||||
this.ToggleScanInterface(true);
|
||||
|
||||
var force = false;
|
||||
if ('mode' in element.dataset)
|
||||
{
|
||||
var force = true;
|
||||
}
|
||||
|
||||
var reportElement = document.querySelector('.scan-area .result-table');
|
||||
while(reportElement.firstChild)
|
||||
{
|
||||
reportElement.firstChild.remove();
|
||||
}
|
||||
|
||||
var args = [];
|
||||
args.force = force;
|
||||
|
||||
if (true === force)
|
||||
{
|
||||
var data = {};
|
||||
data.type = 'folder';
|
||||
data.screen_action = 'resetScanFolderChecked';
|
||||
data.callback = 'shortpixel.folder.ScanFolder';
|
||||
|
||||
window.addEventListener('shortpixel.folder.ScanFolder', this.ScanFolder.bind(this, args), {'once':true});
|
||||
this.processor.AjaxRequest(data);
|
||||
|
||||
}
|
||||
else {
|
||||
this.ScanFolder(args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ScanFolder(args)
|
||||
{
|
||||
if (true === this.stopSignal)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var data = {};
|
||||
data.type = 'folder';
|
||||
data.screen_action = 'scanNextFolder';
|
||||
data.callback = 'shortpixel.folder.ScannedDirectoryEvent';
|
||||
|
||||
if (true === args.force)
|
||||
{
|
||||
data.force = args.force;
|
||||
}
|
||||
|
||||
window.addEventListener('shortpixel.folder.ScannedDirectoryEvent', this.ScannedDirectoryEvent.bind(this, args), {'once':true});
|
||||
this.processor.AjaxRequest(data);
|
||||
}
|
||||
|
||||
ScannedDirectoryEvent(args, event)
|
||||
{
|
||||
var data = event.detail;
|
||||
data = data.folder;
|
||||
|
||||
var reportElement = document.querySelector('.scan-area .result-table');
|
||||
if ( null === reportElement)
|
||||
{
|
||||
console.error('Something wrong with reporting element');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (data.is_done === true)
|
||||
{
|
||||
// @todo Probably emit some done status here
|
||||
var div = document.createElement('div');
|
||||
div.classList.add('message');
|
||||
div.textContent = data.result.message;
|
||||
this.ToggleScanInterface(false);
|
||||
|
||||
reportElement.appendChild(div);
|
||||
}
|
||||
else if (data.result)
|
||||
{
|
||||
var div = document.createElement('div');
|
||||
var span_path = document.createElement('span');
|
||||
var span_filecount = document.createElement('span');
|
||||
var span_message = document.createElement('span');
|
||||
|
||||
span_path.textContent = data.result.path;
|
||||
span_filecount.textContent = data.result.new_count;
|
||||
span_message.textContent = data.result.message;
|
||||
|
||||
div.appendChild(span_path);
|
||||
div.appendChild(span_filecount);
|
||||
div.appendChild(span_message);
|
||||
reportElement.appendChild(div);
|
||||
|
||||
var self = this;
|
||||
setTimeout( function () { self.ScanFolder(args) }, 200);
|
||||
}
|
||||
}
|
||||
|
||||
StopScanEvent(event)
|
||||
{
|
||||
this.stopSignal = true;
|
||||
|
||||
var reportElement = document.querySelector('.scan-area .result-table');
|
||||
if ( null === reportElement)
|
||||
{
|
||||
console.error('Something wrong with reporting element');
|
||||
return false;
|
||||
}
|
||||
|
||||
var div = document.createElement('div');
|
||||
div.classList.add('message');
|
||||
div.textContent = this.strings.stopActionMessage;
|
||||
|
||||
reportElement.appendChild(div);
|
||||
|
||||
this.ToggleScanInterface(false);
|
||||
|
||||
}
|
||||
|
||||
ToggleScanInterface(show)
|
||||
{
|
||||
if (typeof show === 'undefined')
|
||||
{
|
||||
var show = true;
|
||||
}
|
||||
|
||||
var divs = document.querySelectorAll('.scan-actions > div');
|
||||
|
||||
divs.forEach(function(div){
|
||||
if (div.classList.contains('action-scan') && true === show)
|
||||
{
|
||||
div.classList.add('not-visible');
|
||||
}
|
||||
else if (div.classList.contains('action-scan') && false === show) {
|
||||
div.classList.remove('not-visible');
|
||||
}
|
||||
else if ( div.classList.contains('action-stop') && true === show)
|
||||
{
|
||||
div.classList.remove('not-visible');
|
||||
}
|
||||
else {
|
||||
div.classList.add('not-visible');
|
||||
}
|
||||
});
|
||||
|
||||
var output = document.querySelector('.scan-area .output');
|
||||
if (null !== output && true === show)
|
||||
{
|
||||
output.classList.remove('not-visible');
|
||||
}
|
||||
}
|
||||
|
||||
} // class
|
@ -0,0 +1,278 @@
|
||||
'use strict';
|
||||
|
||||
class ShortPixelScreenItemBase extends ShortPixelScreenBase
|
||||
{
|
||||
|
||||
type; // media / custom
|
||||
currentMessage = '';
|
||||
|
||||
constructor(MainScreen, processor)
|
||||
{
|
||||
super(MainScreen, processor);
|
||||
}
|
||||
|
||||
Init()
|
||||
{
|
||||
super.Init();
|
||||
|
||||
window.addEventListener('shortpixel.' + this.type + '.resumeprocessing', this.processor.ResumeProcess.bind(this.processor));
|
||||
window.addEventListener('shortpixel.RenderItemView', this.RenderItemView.bind(this) );
|
||||
}
|
||||
|
||||
HandleImage(resultItem, type)
|
||||
{
|
||||
if (type != this.type ) // We don't eat that here.
|
||||
return false;
|
||||
|
||||
if (typeof resultItem.result !== 'undefined')
|
||||
{
|
||||
// This is final, not more messing with this. In results (multiple) defined one level higher than result object, if single, it's in result.
|
||||
var item_id = typeof resultItem.item_id !== 'undefined' ? resultItem.item_id : resultItem.result.item_id;
|
||||
var message = resultItem.result.message;
|
||||
|
||||
var element = document.getElementById('sp-msg-' + item_id); // empty result box while getting
|
||||
if (typeof message !== 'undefined')
|
||||
{
|
||||
var isError = false;
|
||||
if (resultItem.result.is_error == true)
|
||||
isError = true;
|
||||
this.UpdateMessage(item_id, message, isError);
|
||||
}
|
||||
if (element !== null)
|
||||
{
|
||||
element.innerHTML = '';
|
||||
// var event = new CustomEvent('shortpixel.loadItemView', {detail: {'type' : type, 'id': result.id }}); // send for new item view.
|
||||
var fileStatus = this.processor.fStatus[resultItem.fileStatus];
|
||||
|
||||
if (fileStatus == 'FILE_SUCCESS' || fileStatus == 'FILE_RESTORED' || resultItem.result.is_done == true)
|
||||
{
|
||||
this.processor.LoadItemView({id: item_id, type: type});
|
||||
}
|
||||
else if (fileStatus == 'FILE_PENDING')
|
||||
{
|
||||
element.style.display = 'none';
|
||||
}
|
||||
//window.dispatchEvent(event);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
console.error('handleImage without Result', resultItem);
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
UpdateMessage(id, message, isError)
|
||||
{
|
||||
|
||||
var element = document.getElementById('sp-message-' + id);
|
||||
if (typeof isError === 'undefined')
|
||||
isError = false;
|
||||
|
||||
this.currentMessage = message;
|
||||
|
||||
if (element == null)
|
||||
{
|
||||
var parent = document.getElementById('sp-msg-' + id);
|
||||
if (parent !== null)
|
||||
{
|
||||
var element = document.createElement('div');
|
||||
element.classList.add('message');
|
||||
element.setAttribute('id', 'sp-message-' + id);
|
||||
parent.parentNode.insertBefore(element, parent.nextSibling);
|
||||
}
|
||||
}
|
||||
|
||||
if (element !== null)
|
||||
{
|
||||
if (element.classList.contains('error'))
|
||||
element.classList.remove('error');
|
||||
|
||||
element.innerHTML = message;
|
||||
|
||||
if (isError)
|
||||
element.classList.add('error');
|
||||
}
|
||||
else
|
||||
{
|
||||
this.processor.Debug('Update Message Column not found - ' + id);
|
||||
}
|
||||
}
|
||||
|
||||
// Show a message that an action has started.
|
||||
SetMessageProcessing(id)
|
||||
{
|
||||
var message = this.strings.startAction;
|
||||
|
||||
var loading = document.createElement('img');
|
||||
loading.width = 20;
|
||||
loading.height = 20;
|
||||
loading.src = this.processor.GetPluginUrl() + '/res/img/bulk/loading-hourglass.svg';
|
||||
|
||||
message += loading.outerHTML;
|
||||
this.UpdateMessage(id, message);
|
||||
}
|
||||
|
||||
UpdateStats(stats, type)
|
||||
{
|
||||
// for now, since we process both, only update the totals in tooltip.
|
||||
if ( type !== 'total')
|
||||
return;
|
||||
|
||||
var waiting = stats.in_queue + stats.in_process;
|
||||
this.processor.tooltip.RefreshStats(waiting);
|
||||
}
|
||||
|
||||
GeneralResponses(responses)
|
||||
{
|
||||
var self = this;
|
||||
|
||||
if (responses.length == 0) // no responses.
|
||||
return;
|
||||
|
||||
var shownId = []; // prevent the same ID from creating multiple tooltips. There will be punishment for this.
|
||||
|
||||
responses.forEach(function (element, index)
|
||||
{
|
||||
|
||||
if (element.id)
|
||||
{
|
||||
if (shownId.indexOf(element.id) > -1)
|
||||
{
|
||||
return; // skip
|
||||
}
|
||||
else
|
||||
{
|
||||
shownId.push(element.id);
|
||||
}
|
||||
}
|
||||
|
||||
var message = element.message;
|
||||
if (element.filename)
|
||||
message += ' - ' + element.filename;
|
||||
|
||||
self.processor.tooltip.AddNotice(message);
|
||||
if (self.processor.rStatus[element.code] == 'RESPONSE_ERROR')
|
||||
{
|
||||
|
||||
if (element.id)
|
||||
{
|
||||
var message = self.currentMessage;
|
||||
self.UpdateMessage(element.id, message + '<br>' + element.message);
|
||||
self.currentMessage = message; // don't overwrite with this, to prevent echo.
|
||||
}
|
||||
else
|
||||
{
|
||||
var errorBox = document.getElementById('shortpixel-errorbox');
|
||||
if (errorBox)
|
||||
{
|
||||
var error = document.createElement('div');
|
||||
error.classList.add('error');
|
||||
error.innerHTML = element.message;
|
||||
errorBox.append(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// HandleItemError is handling from results / result, not ResponseController. Check if it has negative effects it's kinda off now.
|
||||
HandleItemError(result)
|
||||
{
|
||||
if (result.message && result.item_id)
|
||||
{
|
||||
this.UpdateMessage(result.item_id, result.message, true);
|
||||
}
|
||||
|
||||
if (typeof result.item_id !== 'undefined')
|
||||
{
|
||||
this.processor.LoadItemView({id: result.item_id, type: 'media'});
|
||||
}
|
||||
}
|
||||
|
||||
RestoreItem(id)
|
||||
{
|
||||
var data = {};
|
||||
data.id = id;
|
||||
data.type = this.type;
|
||||
data.screen_action = 'restoreItem';
|
||||
// AjaxRequest should return result, which will go through Handleresponse, then LoaditemView.
|
||||
this.SetMessageProcessing(id);
|
||||
this.processor.AjaxRequest(data);
|
||||
}
|
||||
|
||||
CancelOptimizeItem(id)
|
||||
{
|
||||
var data = {};
|
||||
data.id = id;
|
||||
data.type = this.type;
|
||||
data.screen_action = 'cancelOptimize';
|
||||
// AjaxRequest should return result, which will go through Handleresponse, then LoaditemView.
|
||||
|
||||
this.processor.AjaxRequest(data);
|
||||
}
|
||||
|
||||
ReOptimize(id, compression, action)
|
||||
{
|
||||
var data = {
|
||||
id : id ,
|
||||
compressionType: compression,
|
||||
type: this.type,
|
||||
screen_action: 'reOptimizeItem'
|
||||
};
|
||||
|
||||
if (typeof action !== 'undefined')
|
||||
{
|
||||
data.actionType = action;
|
||||
}
|
||||
|
||||
if (! this.processor.CheckActive())
|
||||
data.callback = 'shortpixel.' + this.type + '.resumeprocessing';
|
||||
|
||||
this.SetMessageProcessing(id);
|
||||
this.processor.AjaxRequest(data);
|
||||
}
|
||||
|
||||
Optimize(id, force)
|
||||
{
|
||||
var data = {
|
||||
id: id,
|
||||
type: this.type,
|
||||
screen_action: 'optimizeItem'
|
||||
}
|
||||
|
||||
if (typeof force !== 'undefined' && true == force)
|
||||
{
|
||||
data.flags = 'force';
|
||||
}
|
||||
|
||||
if (! this.processor.CheckActive())
|
||||
data.callback = 'shortpixel.' + this.type + '.resumeprocessing';
|
||||
|
||||
this.SetMessageProcessing(id);
|
||||
this.processor.AjaxRequest(data);
|
||||
}
|
||||
|
||||
MarkCompleted(id)
|
||||
{
|
||||
var data = {};
|
||||
data.id = id;
|
||||
data.type = this.type;
|
||||
data.screen_action = 'markCompleted';
|
||||
|
||||
this.processor.AjaxRequest(data);
|
||||
}
|
||||
UnMarkCompleted(id)
|
||||
{
|
||||
var data = {};
|
||||
data.id = id;
|
||||
data.type = this.type;
|
||||
data.screen_action = 'unMarkCompleted';
|
||||
|
||||
this.processor.AjaxRequest(data);
|
||||
}
|
||||
|
||||
} // class
|
@ -0,0 +1,256 @@
|
||||
'use strict';
|
||||
|
||||
// MainScreen as an option for delegate functions
|
||||
class ShortPixelScreen extends ShortPixelScreenItemBase //= function (MainScreen, processor)
|
||||
{
|
||||
isCustom = true;
|
||||
isMedia = true;
|
||||
type = 'media';
|
||||
|
||||
Init()
|
||||
{
|
||||
super.Init();
|
||||
this.ListenGallery();
|
||||
}
|
||||
|
||||
RenderItemView(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
var data = e.detail;
|
||||
if (data.media)
|
||||
{
|
||||
var id = data.media.id;
|
||||
|
||||
var element = document.getElementById('sp-msg-' + id);
|
||||
if (element !== null) // Could be other page / not visible / whatever.
|
||||
element.outerHTML = data.media.itemView;
|
||||
else {
|
||||
console.error('Render element not found');
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.error('Data not found - RenderItemview on media screen');
|
||||
}
|
||||
return false; // callback shouldn't do more, see processor.
|
||||
}
|
||||
|
||||
HandleImage(resultItem, type)
|
||||
{
|
||||
var res = super.HandleImage(resultItem, type);
|
||||
var fileStatus = this.processor.fStatus[resultItem.fileStatus];
|
||||
|
||||
// If image editor is active and file is being restored because of this reason ( or otherwise ), remove the warning if this one exists.
|
||||
if (fileStatus == 'FILE_RESTORED')
|
||||
{
|
||||
var warning = document.getElementById('shortpixel-edit-image-warning');
|
||||
if (warning !== null)
|
||||
{
|
||||
warning.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RedoLegacy(id)
|
||||
{
|
||||
var data = {
|
||||
id: id,
|
||||
type: 'media',
|
||||
screen_action: 'redoLegacy',
|
||||
}
|
||||
data.callback = 'shortpixel.LoadItemView';
|
||||
|
||||
window.addEventListener('shortpixel.LoadItemView', function (e) {
|
||||
var itemData = { id: e.detail.media.id, type: 'media' };
|
||||
this.processor.timesEmpty = 0; // reset the defer on this.
|
||||
this.processor.LoadItemView(itemData);
|
||||
this.UpdateMessage(itemData.id, '');
|
||||
|
||||
}.bind(this), {'once': true} );
|
||||
|
||||
this.SetMessageProcessing(id);
|
||||
this.processor.AjaxRequest(data);
|
||||
}
|
||||
|
||||
ListenGallery()
|
||||
{
|
||||
var self = this;
|
||||
if (typeof wp.media === 'undefined')
|
||||
{
|
||||
this.ListenEditAttachment(); // Edit Media edit attachment screen
|
||||
return;
|
||||
}
|
||||
|
||||
// This taken from S3-offload / media.js / Grid media gallery
|
||||
if (typeof wp.media.view.Attachment.Details.TwoColumn !== 'undefined')
|
||||
{
|
||||
var detailsColumn = wp.media.view.Attachment.Details.TwoColumn;
|
||||
var twoCol = true;
|
||||
}
|
||||
else {
|
||||
var detailsColumn = wp.media.view.Attachment.Details;
|
||||
var twoCol = false;
|
||||
}
|
||||
|
||||
var extended = detailsColumn.extend ({
|
||||
render: function()
|
||||
{
|
||||
detailsColumn.prototype.render.apply( this );
|
||||
this.fetchSPIOData(this.model.get( 'id' ));
|
||||
|
||||
return this;
|
||||
},
|
||||
fetchSPIOData : function (id)
|
||||
{
|
||||
var data = {};
|
||||
data.id = id;
|
||||
data.type = self.type;
|
||||
data.action = 'getItemView';
|
||||
data.callback = 'shortpixel.MediaRenderView';
|
||||
|
||||
window.addEventListener('shortpixel.MediaRenderView', this.renderSPIOView.bind(this), {'once':true});
|
||||
self.processor.LoadItemView(data);
|
||||
},
|
||||
|
||||
renderSPIOView: function(e, timed)
|
||||
{
|
||||
if (! e.detail || ! e.detail.media || ! e.detail.media.itemView)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var $spSpace = this.$el.find('.attachment-info .details');
|
||||
if ($spSpace.length === 0 && (typeof timed === 'undefined' || timed < 5))
|
||||
{
|
||||
// It's possible the render is slow or blocked by other plugins. Added a delay and retry bit later to draw.
|
||||
if (typeof timed === 'undefined')
|
||||
{
|
||||
var timed = 0;
|
||||
}
|
||||
else {
|
||||
timed++;
|
||||
}
|
||||
setTimeout(function () { this.renderSPIOView(e, true) }.bind(this), 1000);
|
||||
}
|
||||
|
||||
var html = this.doSPIORow(e.detail.media.itemView);
|
||||
|
||||
$spSpace.after(html);
|
||||
},
|
||||
doSPIORow : function(dataHtml)
|
||||
{
|
||||
var html = '';
|
||||
html += '<div class="shortpixel-popup-info">';
|
||||
html += '<label class="name">ShortPixel</label>';
|
||||
html += dataHtml;
|
||||
html += '</div>';
|
||||
return html;
|
||||
},
|
||||
editAttachment: function(event)
|
||||
{
|
||||
event.preventDefault();
|
||||
self.AjaxOptimizeWarningFromUnderscore(this.model.get( 'id' ));
|
||||
detailsColumn.prototype.editAttachment.apply( this, [event]);
|
||||
}
|
||||
});
|
||||
|
||||
if (true === twoCol)
|
||||
{
|
||||
wp.media.view.Attachment.Details.TwoColumn = extended; //wpAttachmentDetailsTwoColumn;
|
||||
}
|
||||
else {
|
||||
wp.media.view.Attachment.Details = extended;
|
||||
}
|
||||
}
|
||||
|
||||
AjaxOptimizeWarningFromUnderscore(id)
|
||||
{
|
||||
var data = {
|
||||
id: id,
|
||||
type: 'media',
|
||||
screen_action: 'getItemEditWarning',
|
||||
callback: 'ShortPixelMedia.getItemEditWarning'
|
||||
};
|
||||
|
||||
window.addEventListener('ShortPixelMedia.getItemEditWarning', this.CheckOptimizeWarning.bind(this), {'once': true} );
|
||||
this.processor.AjaxRequest(data);
|
||||
}
|
||||
|
||||
CheckOptimizeWarning(event)
|
||||
{
|
||||
var data = event.detail;
|
||||
|
||||
var image_post_id = data.id;
|
||||
var is_restorable = data.is_restorable;
|
||||
var is_optimized = data.is_optimized;
|
||||
|
||||
if ('true' === is_restorable || 'true' === is_optimized)
|
||||
{
|
||||
this.ShowOptimizeWarning(image_post_id, is_restorable, is_optimized);
|
||||
}
|
||||
}
|
||||
|
||||
ShowOptimizeWarning(image_post_id, is_restorable, is_optimized)
|
||||
{
|
||||
var div = document.createElement('div');
|
||||
div.id = 'shortpixel-edit-image-warning';
|
||||
div.classList.add('shortpixel', 'shortpixel-notice', 'notice-warning');
|
||||
|
||||
|
||||
if ('true' == is_restorable)
|
||||
{
|
||||
var restore_link = spio_media.restore_link.replace('#post_id#', image_post_id);
|
||||
div.innerHTML = '<p>' + spio_media.optimized_text + ' <a href="' + restore_link + '">' + spio_media.restore_link_text + '</a></p>' ;
|
||||
}
|
||||
else {
|
||||
div.innerHTML = '<p>' + spio_media.optimized_text + ' ' + spio_media.restore_link_text_unrestorable + '</p>' ;
|
||||
|
||||
}
|
||||
// only if not existing.
|
||||
if (document.getElementById('shortpixel-edit-image-warning') == null)
|
||||
{
|
||||
var $menu = jQuery('.imgedit-menu');
|
||||
if ($menu.length > 0)
|
||||
{
|
||||
$menu.append(div);
|
||||
}
|
||||
else {
|
||||
jQuery(document).one('image-editor-ui-ready', function() // one!
|
||||
{
|
||||
jQuery('.imgedit-menu').append(div);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// This should be the edit-attachment screen
|
||||
ListenEditAttachment()
|
||||
{
|
||||
var self = this;
|
||||
var imageEdit = window.imageEdit;
|
||||
|
||||
jQuery(document).on('image-editor-ui-ready', function()
|
||||
{
|
||||
var element = document.querySelector('input[name="post_ID"]');
|
||||
if (null === element)
|
||||
{
|
||||
console.error('Could not fetch post id on this screen');
|
||||
return;
|
||||
}
|
||||
|
||||
var post_id = element.value;
|
||||
|
||||
var data = {
|
||||
id: post_id,
|
||||
type: 'media',
|
||||
screen_action: 'getItemEditWarning',
|
||||
callback: 'ShortPixelMedia.getItemEditWarning'
|
||||
};
|
||||
|
||||
window.addEventListener('ShortPixelMedia.getItemEditWarning', self.CheckOptimizeWarning.bind(self), {'once': true} );
|
||||
window.ShortPixelProcessor.AjaxRequest(data);
|
||||
});
|
||||
}
|
||||
|
||||
} // class
|
@ -0,0 +1,31 @@
|
||||
'use strict';
|
||||
|
||||
// MainScreen as an option for delegate functions
|
||||
class ShortPixelScreen extends ShortPixelScreenBase
|
||||
{
|
||||
|
||||
Init()
|
||||
{
|
||||
super.Init();
|
||||
this.ListenPLUpload();
|
||||
}
|
||||
|
||||
|
||||
// Only listening on the nolist ( and more specific -> media addnew) , since the post editor classic/ gutenberg and others have this interface otherwise hidden.
|
||||
ListenPLUpload() {
|
||||
|
||||
// Most screen will not have uploader defined or ready.
|
||||
if (typeof uploader === 'undefined' || uploader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
uploader.bind('UploadComplete', function (up, file, response)
|
||||
{
|
||||
// Give processor a swoop when uploading is done, while respecting set boundaries.
|
||||
self.processor.RunProcess();
|
||||
});
|
||||
}
|
||||
|
||||
} // class
|
Reference in New Issue
Block a user