first commit

This commit is contained in:
Roman Pyrih
2026-04-21 15:48:41 +02:00
commit 7483681901
10216 changed files with 3236626 additions and 0 deletions

View File

@@ -0,0 +1,159 @@
/**
* Duplicator Pro Admin Notifications.
*/
'use strict';
var DupAdminNotifications = window.DupAdminNotifications || (function (document, window, $) {
/**
* Elements holder.
*
* @type {object}
*/
var el = {
$notifications: $('#dup-notifications'),
$nextButton: $('#dup-notifications .navigation .next'),
$prevButton: $('#dup-notifications .navigation .prev'),
$adminBarCounter: $('#wp-admin-bar-dup-menu .dup-menu-notification-counter'),
$adminBarMenuItem: $('#wp-admin-bar-dup-notifications'),
};
/**
* Public functions and properties.
*
* @type {object}
*/
var app = {
/**
* Start the engine.
*/
init: function () {
app.updateNavigation();
app.events();
},
/**
* Register JS events.
*/
events: function () {
el.$notifications
.on('click', '.dismiss', app.dismiss)
.on('click', '.next', app.navNext)
.on('click', '.prev', app.navPrev);
},
/**
* Click on the Dismiss notification button.
*
* @param {object} event Event object.
*/
dismiss: function (event) {
if (el.$currentMessage.length === 0) {
return;
}
// Update counter.
var count = parseInt(el.$adminBarCounter.text(), 10);
if (count > 1) {
--count;
el.$adminBarCounter.html(count);
} else {
el.$adminBarCounter.remove();
el.$adminBarMenuItem.remove();
}
// Remove notification.
var $nextMessage = el.$nextMessage.length < 1 ? el.$prevMessage : el.$nextMessage,
messageId = el.$currentMessage.data('message-id');
if ($nextMessage.length === 0) {
el.$notifications.fadeOut(300);
} else {
el.$currentMessage.remove();
$nextMessage.addClass('current');
app.updateNavigation();
}
// AJAX call - update option.
var data = {
action: 'duplicator_notification_dismiss',
nonce: dup_admin_notifications.nonce,
id: messageId,
};
$.post(dup_admin_notifications.ajax_url, data, function (res) {
if (!res.success) {
console.log(res);
}
}).fail(function (xhr, textStatus, e) {
console.log(xhr.responseText);
});
},
/**
* Click on the Next notification button.
*
* @param {object} event Event object.
*/
navNext: function (event) {
if (el.$nextButton.hasClass('disabled')) {
return;
}
el.$currentMessage.removeClass('current');
el.$nextMessage.addClass('current');
app.updateNavigation();
},
/**
* Click on the Previous notification button.
*
* @param {object} event Event object.
*/
navPrev: function (event) {
if (el.$prevButton.hasClass('disabled')) {
return;
}
el.$currentMessage.removeClass('current');
el.$prevMessage.addClass('current');
app.updateNavigation();
},
/**
* Update navigation buttons.
*/
updateNavigation: function () {
if (el.$notifications.find('.dup-notifications-message.current').length === 0) {
el.$notifications.find('.dup-notifications-message:first-child').addClass('current');
}
el.$currentMessage = el.$notifications.find('.dup-notifications-message.current');
el.$nextMessage = el.$currentMessage.next('.dup-notifications-message');
el.$prevMessage = el.$currentMessage.prev('.dup-notifications-message');
if (el.$nextMessage.length === 0) {
el.$nextButton.addClass('disabled');
} else {
el.$nextButton.removeClass('disabled');
}
if (el.$prevMessage.length === 0) {
el.$prevButton.addClass('disabled');
} else {
el.$prevButton.removeClass('disabled');
}
},
};
return app;
}(document, window, jQuery));
// Initialize.
DupAdminNotifications.init();

View File

@@ -0,0 +1,54 @@
/*!
* DP Kickoff Script
*/
jQuery(document).ready(function () {
// Start calling the thing every 15 seconds to ensure it runs in a decent amount of time
var data = {
action: 'duplicator_process_worker',
nonce: dp_gateway.duplicator_process_worker_nonce,
}
dp_kickme = function () {
console.log("dp_kick");
jQuery.ajax({
async: true,
type: "POST",
url: dp_gateway.ajaxurl,
timeout: 10000000,
data: data,
complete: function () {
},
success: function (respData) {
if ('ok' != respData) {
try {
var data = DupliJs.parseJSON(respData);
} catch (err) {
console.error(err);
console.error('JSON parse failed for response data: ' + respData);
return false;
}
if (data['status'] == 0) {
// DupliJs.Schedule.SetUpdateInterval(1);
// alert("Process worker sent");
} else {
// alert("Process worker failed");
console.log(data);
}
}
},
error: function (data) {
// alert(data);
console.log(data);
// console.log(data);
}
});
}
dp_kickme();
window.setInterval(dp_kickme, dp_gateway.client_call_frequency);
});

View File

@@ -0,0 +1,49 @@
/**
* Global Namespace Definitions
*
* This file defines the global JavaScript namespaces for the Duplicator plugin.
*/
// Main namespace
window.DupliJs = window.DupliJs || {};
// Package operations
DupliJs.Pack = DupliJs.Pack || {};
// Schedule operations
DupliJs.Schedule = DupliJs.Schedule || {};
// Settings operations
DupliJs.Settings = DupliJs.Settings || {};
DupliJs.Settings.Brand = DupliJs.Settings.Brand || {};
// Storage operations
DupliJs.Storage = DupliJs.Storage || {};
DupliJs.Storage.Dropbox = DupliJs.Storage.Dropbox || {};
DupliJs.Storage.OneDrive = DupliJs.Storage.OneDrive || {};
DupliJs.Storage.S3 = DupliJs.Storage.S3 || {};
DupliJs.Storage.Local = DupliJs.Storage.Local || {};
// Support operations
DupliJs.Support = DupliJs.Support || {};
// Template operations
DupliJs.Template = DupliJs.Template || {};
// Tools operations
DupliJs.Tools = DupliJs.Tools || {};
// UI utilities
DupliJs.UI = DupliJs.UI || {};
// Utility functions
DupliJs.Util = DupliJs.Util || {};
// Debug utilities
DupliJs.Debug = DupliJs.Debug || {};
// Help system
DupliJs.Help = DupliJs.Help || {};
// Staging operations
DupliJs.Staging = DupliJs.Staging || {};

View File

@@ -0,0 +1,168 @@
<?php
use Duplicator\Libs\WpUtils\WpDbUtils;
?>
<script>
/*! ============================================================================
* UI NAMESPACE: All methods at the top of the Duplicator Namespace
* =========================================================================== */
(function($) {
/**
* Indicates if we have any form changes.
* Primarily used to prevent the user from navigating away from a page with unsaved changes.
* @type {boolean}
*/
DupliJs.UI.hasUnsavedChanges = false;
/* Stores the state of a view into the database */
DupliJs.UI.SaveViewStateByPost = function(key, value) {
if (key != undefined && value != undefined) {
jQuery.ajax({
type: "POST",
url: ajaxurl,
dataType: "json",
data: {
action: 'duplicator_view_state_update',
key: key,
value: value,
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_view_state_update')); ?>'
},
success: function(data) {},
error: function(data) {}
});
}
}
DupliJs.UI.SaveMulViewStatesByPost = function(states) {
jQuery.ajax({
type: "POST",
url: ajaxurl,
dataType: "json",
data: {
action: 'duplicator_view_state_update',
states: states,
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_view_state_update')); ?>'
},
success: function(data) {},
error: function(data) {}
});
}
DupliJs.UI.SetScanMode = function() {
var scanMode = jQuery('#scan-mode').val();
if (scanMode == <?php echo (int) WpDbUtils::PHPDUMP_MODE_MULTI; ?>) {
jQuery('#scan-multithread-size').show();
jQuery('#scan-chunk-size-label').show();
} else {
jQuery('#scan-multithread-size').hide();
jQuery('#scan-chunk-size-label').hide();
}
}
DupliJs.UI.IsSaveViewState = true;
/* Toggle MetaBoxes */
DupliJs.UI.ToggleMetaBox = function() {
var $title = jQuery(this);
var $panel = $title.parent().find('.dup-box-panel');
var $arrowParent = $title.parent().find('.dup-box-arrow');
var $arrow = $title.parent().find('.dup-box-arrow i');
var key = $panel.attr('id');
var value = $panel.is(":visible") ? 0 : 1;
if (DupliJs.UI.IsSaveViewState) {
DupliJs.UI.SaveViewStateByPost(key, value);
}
if (value) {
$panel.removeClass('no-display');
$panel.show();
$arrowParent.attr("aria-expanded", true);
$arrow.removeClass().addClass('fa fa-caret-up');
} else {
$panel.hide();
$arrowParent.attr("aria-expanded", false);
$arrow.removeClass().addClass('fa fa-caret-down');
}
return false;
}
DupliJs.UI.ClearTraceLog = function(reload) {
var reload = reload || 0;
jQuery.ajax({
type: "POST",
url: ajaxurl,
data: {
action: 'duplicator_delete_trace_log',
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_delete_trace_log')); ?>'
},
success: function(respData) {
if (reload && respData.success) {
window.location.reload();
}
},
error: function(data) {}
});
return false;
}
/* Clock generator, used to show an active clock.
* Intended use is to be called once per page load
* such as:
* <div id="dupli-clock-container"></div>
* DupliJs.UI.Clock(DupliJs._WordPressInitTime); */
DupliJs.UI.Clock = function() {
var timeDiff;
var timeout;
function addZ(n) {
return (n < 10 ? '0' : '') + n;
}
function formatTime(d) {
return addZ(d.getHours()) + ':' + addZ(d.getMinutes()) + ':' + addZ(d.getSeconds());
}
return function(s) {
var now = new Date();
var then;
// Set lag to just after next full second
var lag = 1015 - now.getMilliseconds();
// Get the time difference when first run
if (s) {
s = s.split(':');
then = new Date(now);
then.setHours(+s[0], +s[1], +s[2], 0);
timeDiff = now - then;
}
now = new Date(now - timeDiff);
jQuery('#dupli-clock-container').html(formatTime(now));
timeout = setTimeout(DupliJs.UI.Clock, lag);
};
}();
/* Runs callback function when form values change */
DupliJs.UI.formOnChangeValues = function(form, callback) {
let previousValues = form.serialize();
$('form :input').on('change input', function() {
if (previousValues !== form.serialize()) {
previousValues = form.serialize();
callback();
}
});
$('.dup-pseudo-checkbox, #dbnone, #dball').on('click', function() {
// Since the pseudo checkbox is not a form input,
// assume the state is changed on click
callback();
});
};
})(jQuery);
</script>

View File

@@ -0,0 +1,159 @@
<?php
/*! ============================================================================
* UTIL NAMESPACE: All methods at the top of the Duplicator Namespace
* =========================================================================== */
defined("ABSPATH") or die("");
?>
<script>
DupliJs.Util.ajaxProgress = null;
DupliJs.Util.ajaxProgressShow = function() {
if (DupliJs.Util.ajaxProgress === null) {
DupliJs.Util.ajaxProgress = jQuery('#dup-ajax-loader')
}
DupliJs.Util.ajaxProgress
.stop(true, true)
.css('display', 'block')
.delay(1000)
.animate({
opacity: 1
}, 500);
}
DupliJs.Util.ajaxProgressHide = function() {
if (DupliJs.Util.ajaxProgress === null) {
return;
}
DupliJs.Util.ajaxProgress
.stop(true, true)
.delay(500)
.animate({
opacity: 0
}, 300, function() {
jQuery(this).css({
'display': 'none'
});
});
}
DupliJs.Util.ajaxWrapper = function(ajaxData, callbackSuccess, callbackFail, options = {}) {
let opts = jQuery.extend({
showProgress: true, // Is true show the ajax loader, can be disabled for custom progress handling
timeout: 30000
}, options);
jQuery.ajax({
type: "POST",
url: ajaxurl,
timeout: opts.timeout,
dataType: "json",
data: ajaxData,
beforeSend: function(xhr) {
if (opts.showProgress) {
DupliJs.Util.ajaxProgressShow();
}
},
success: function(result, textStatus, jqXHR) {
var message = '';
if (result.success) {
if (typeof callbackSuccess === "function") {
try {
message = callbackSuccess(result, result.data, result.data.funcData, textStatus, jqXHR);
} catch (error) {
console.error(error);
DupliJs.addAdminMessage(error.message, 'error');
message = '';
}
} else {
message = '<?php echo esc_js(__('RESPONSE SUCCESS', 'duplicator-pro')); ?>';
}
if (message != null && String(message).length) {
DupliJs.addAdminMessage(message, 'notice');
}
} else {
if (typeof callbackFail === "function") {
try {
message = callbackFail(result, result.data, result.data.funcData, textStatus, jqXHR);
} catch (error) {
console.error(error);
message = error.message;
}
} else {
message = '<?php echo esc_js(__('RESPONSE ERROR!', 'duplicator-pro')); ?>' + '<br><br>' + result.data.message;
}
if (message != null && String(message).length) {
DupliJs.addAdminMessage(message, 'error');
}
}
},
error: function(result) {
// Make sure the progress is hidden even if the request fails
DupliJs.Util.ajaxProgressHide();
DupliJs.addAdminMessage(
<?php echo wp_json_encode(__('AJAX ERROR! <br> Ajax request error', 'duplicator-pro')); ?>,
'error'
);
},
complete: function() {
if (opts.showProgress) {
DupliJs.Util.ajaxProgressHide();
}
}
});
};
/**
* Get human size from bytes number.
* Is size is -1 return unknown
*
* @param {size} int bytes size
*/
DupliJs.Util.humanFileSize = function(size) {
if (size < 0) {
return "unknown";
} else if (size == 0) {
return "0";
} else {
var i = Math.floor(Math.log(size) / Math.log(1024));
return (size / Math.pow(1024, i)).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
}
};
DupliJs.Util.isEmpty = function(val) {
return (val === undefined || val == null || val.length <= 0) ? true : false;
};
DupliJs.Util.toggleShow = function(selector, show = 'auto') {
var element = jQuery(selector);
if (show === 'auto') {
show = !element.is(":visible");
}
if (show) {
element.hide().removeClass('no-display');
element.fadeIn();
} else {
element.fadeOut();
}
};
DupliJs.Util.dynamicFormSubmit = function(url, method, params) {
var form = jQuery('<form>', {
method: method,
action: url
});
jQuery.each(params, function(key, value) {
form.append(jQuery('<input>', {
'type': 'hidden',
'name': key,
'value': value
}));
});
jQuery("body").append(form);
form.submit();
};
</script>

View File

@@ -0,0 +1,67 @@
/*! dup admin script */
jQuery(document).ready(function ($) {
$(document).on('click', '.dupli-admin-notice[data-to-dismiss] .notice-dismiss', function (event) {
event.preventDefault();
event.stopImmediatePropagation();
var notice = $(this).closest('.dupli-admin-notice[data-to-dismiss]');
$.post(ajaxurl, {
action: 'duplicator_admin_notice_to_dismiss',
notice: notice.data('to-dismiss'),
nonce: dupli_global_data.nonce_admin_notice_to_dismiss
});
});
function dupDashboardUpdate() {
jQuery.ajax({
type: "POST",
url: dupli_global_data.ajaxurl,
dataType: "json",
data: {
action: 'duplicator_dashboad_widget_info',
nonce: dupli_global_data.nonce_dashboard_widged_info
},
success: function (result, textStatus, jqXHR) {
if (result.success) {
$('#duplicator_dashboard_widget .dup-last-backup-info').html(result.data.funcData.lastBackupInfo);
if (result.data.funcData.isRunning) {
$('#duplicator_dashboard_widget #dupli-create-new').addClass('disabled');
} else {
$('#duplicator_dashboard_widget #dupli-create-new').removeClass('disabled');
}
}
},
complete: function() {
setTimeout(
function(){
dupDashboardUpdate();
},
5000
);
}
});
}
if ($('#duplicator_dashboard_widget').length) {
dupDashboardUpdate();
$('#duplicator_dashboard_widget #dup-dash-widget-section-recommended').on('click', function (event) {
event.stopPropagation();
$(this).closest('.dup-section-recommended').fadeOut();
jQuery.ajax({
type: "POST",
url: dupli_global_data.ajaxurl,
dataType: "json",
data: {
action: 'duplicator_dismiss_recommended_plugin',
nonce: dupli_global_data.nonce_dashboard_widged_dismiss_recommended
},
success: function (result, textStatus, jqXHR) {
// do nothing
}
});
});
}
});

View File

@@ -0,0 +1,28 @@
/*! dup import installer */
(function ($) {
DupliImportInstaller = {
installerIframe: $('#dupli-import-installer-iframe'),
init: function () {
DupliImportInstaller.installerIframe.on("load", function () {
DupliImportInstaller.installerIframe.contents()
.find('#page-step1')
.on('click', '> .ui-dialog #db-install-dialog-confirm-button', function () {
$('#dupli-import-installer-modal').removeClass('no-display');
});
});
},
resizeIframe: function () {
let height = DupliImportInstaller.installerIframe.contents()
.find('html').css('overflow', 'hidden')
.outerHeight(true);
console.log('height', height);
DupliImportInstaller.installerIframe.css({
'height': height + 'px'
})
}
}
DupliImportInstaller.init();
DuplicatorTooltip.load();
})(jQuery);

View File

@@ -0,0 +1,3 @@
<?php
//silent

View File

@@ -0,0 +1,461 @@
<?php
defined("ABSPATH") or die("");
?>
<script>
/*! ============================================================================
* DESCRIPTION: Methods and Objects in this file are global and common in nature
* use this file to place all shared methods and varibles
* NAMESPACE: DupliJs (defined in dupli-namespace.js, loaded via main.js bundle)
* ============================================================================ */
DupliJs.Pack.DownloadFile = function (url, fileName='') {
var link = document.createElement('a');
link.className = "dupli-dnload-menu-item";
link.href = url;
if (fileName !== '') {
link.download = fileName;
}
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
return false;
};
(function ($) {
/* ============================================================================
* BASE NAMESPACE: All methods at the top of the Duplicator Namespace
* ============================================================================ */
DupliJs._WordPressInitDateTime = '<?php echo esc_js(current_time("D M d Y H:i:s O")) ?>';
DupliJs._WordPressInitTime = '<?php echo esc_js(current_time("H:i:s")) ?>';
DupliJs._ServerInitDateTime = '<?php echo esc_js(date("D M d Y H:i:s O")) ?>';
DupliJs._ClientInitDateTime = new Date();
DupliJs.parseJSON = function (mixData) {
try {
var parsed = JSON.parse(mixData);
return parsed;
} catch (e) {
console.log("JSON parse failed - 1");
console.log(mixData);
}
if (mixData.indexOf('[') > -1 && mixData.indexOf('{') > -1) {
if (mixData.indexOf('{') < mixData.indexOf('[')) {
var startBracket = '{';
var endBracket = '}';
} else {
var startBracket = '[';
var endBracket = ']';
}
} else if (mixData.indexOf('[') > -1 && mixData.indexOf('{') === -1) {
var startBracket = '[';
var endBracket = ']';
} else {
var startBracket = '{';
var endBracket = '}';
}
var jsonStartPos = mixData.indexOf(startBracket);
var jsonLastPos = mixData.lastIndexOf(endBracket);
if (jsonStartPos > -1 && jsonLastPos > -1) {
var expectedJsonStr = mixData.slice(jsonStartPos, jsonLastPos + 1);
try {
var parsed = JSON.parse(expectedJsonStr);
return parsed;
} catch (e) {
console.log("JSON parse failed - 2");
console.log(mixData);
throw e;
// errorCallback(xHr, textstatus, 'extract');
return false;
}
}
// errorCallback(xHr, textstatus, 'extract');
throw "could not parse the JSON";
return false;
}
DupliJs.escapeHtml = function(str) {
return str
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
};
DupliJs.isInViewport = function ( $element ) {
const rect = $element[ 0 ].getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= ( window.innerHeight || document.documentElement.clientHeight ) &&
rect.right <= ( window.innerWidth || document.documentElement.clientWidth )
);
};
/**
*
* @param string message // html message conent
* @param string errLevel // notice warning error
* @param function updateCallback // called after message content is updated
*
* @returns void
*/
DupliJs.addAdminMessage = function (message, errLevel, options) {
let settings = $.extend({}, {
'isDismissible': true,
'hideDelay': 0, // 0 no hide or millisec
'updateCallback': false
}, options);
var classErrLevel = 'notice';
switch (errLevel) {
case 'error':
classErrLevel = 'notice-error';
break;
case 'warning':
classErrLevel = 'update-nag';
break;
case 'notice':
default:
classErrLevel = 'updated notice-success';
break;
}
var noticeCLasses = 'dupli-admin-notice notice ' + classErrLevel + ' no-display';
if (settings.isDismissible) {
noticeCLasses += ' is-dismissible';
}
var msgNode = $('<div class="' + noticeCLasses + '">' +
'<div class="msg-content">' + message + '</div>' +
'</div>');
var dismissButton = $('<button type="button" class="notice-dismiss">' +
'<span class="screen-reader-text">Dismiss this notice.</span>' +
'</button>');
let anchor = $(".wp-header-end").first();
msgNode.insertAfter(anchor);
if (settings.isDismissible) {
dismissButton.appendTo(msgNode).click(function () {
dismissButton.closest('.is-dismissible').fadeOut("slow", function () {
$(this).remove();
});
});
}
if (typeof settings.updateCallback === "function") {
settings.updateCallback(msgNode);
}
$("body, html").animate({scrollTop: 0}, 500);
$(msgNode).css('display', 'none').removeClass("no-display").fadeIn("slow", function () {
if (settings.hideDelay > 0) {
setTimeout(function () {
dismissButton.closest('.is-dismissible').fadeOut("slow", function () {
$(this).remove();
});
}, settings.hideDelay);
}
});
};
/**
*
* @param string filename
* @param string content
* @param string mimeType // text/html, text/plain
* @returns {undefined}
*/
DupliJs.downloadContentAsfile = function (filename, content, mimeType) {
mimeType = (typeof mimeType !== 'undefined') ? mimeType : 'text/plain';
var element = document.createElement('a');
element.setAttribute('href', 'data:' + mimeType + ';charset=utf-8,' + encodeURIComponent(content));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
DupliJs.openWindow = function () {
$("[data-dup-open-window]").each(function () {
let url = $(this).data('dup-open-window');
let name = $(this).data('dup-window-name');
$(this).click(function () {
window.open(url, name);
});
});
}
DupliJs.passwordToggle = function () {
$('.dup-password-toggle').each(function () {
let inputElem = $(this).find('input');
let buttonElem = $(this).find('button');
let iconElem = $(this).find('button i');
buttonElem.click(function () {
if (inputElem.attr('type') == 'password') {
inputElem.attr('type','text');
iconElem.removeClass('fa-eye').addClass('fa-eye-slash');
} else {
inputElem.attr('type','password');
iconElem.removeClass('fa-eye-slash').addClass('fa-eye');
}
});
});
}
})(jQuery);
</script>
<?php
require_once(DUPLICATOR____PATH . '/assets/js/duplicator/dup.ui.php');
require_once(DUPLICATOR____PATH . '/assets/js/duplicator/dup.util.php');
?>
<script>
<?php
require_once(DUPLICATOR____PATH . '/assets/js/modal-box.js');
?>
</script>
<script>
//Init
jQuery(document).ready(function ($)
{
DupliJs.openWindow();
//INIT: DupliJs Tabs
$("div[data-dupli-tabs='true']").each(function ()
{
//Load Tab Setup
var $root = $(this);
var $lblRoot = $root.find('> ul:first-child')
var $lblKids = $lblRoot.children('li');
var $lblButton = $lblKids.find('button');
var $pnls = $root.children('div');
//Apply Styles
$root.addClass('categorydiv');
$lblRoot.addClass('category-tabs');
$pnls.addClass('tabs-panel').css('display', 'none');
//Init accessibility improvement
$lblKids.each(function () {
var $content = $(this).text();
$(this).html("<button role='tabs' aria-selected='false'>" +
"<span class='screen-reader-text'><?php esc_html_e('Toggle Tab: ', 'duplicator-pro') ?></span> "+$content+
"</button>")
})
//Activate first tab
$lblKids.eq(0).addClass('tabs').css('font-weight', 'bold');
$lblKids.eq(0).find('button').attr("aria-selected", true)
$pnls.eq(0).show();
//Initialize tab click event
var _clickEvt = function (evt)
{
var $target = $(evt.target);
if (evt.target.nodeName === 'BUTTON') {
$target = $(evt.target).parent();
}
var $lbls = $target.parent().children('li');
var $pnls = $target.parent().parent().children('div');
var index = $target.index();
$lbls.removeClass('tabs').css('font-weight', 'normal');
$lbls.find("button").attr("aria-selected", false);
$lbls.eq(index).addClass('tabs').css('font-weight', 'bold');
$lbls.eq(index).find("button").attr("aria-selected", true);
$pnls.hide();
$pnls.eq(index).show();
return false;
}
//Attach Events
$lblKids.click(_clickEvt);
$lblButton.on("click", _clickEvt);
});
//INIT: Toggle MetaBoxes
$('div.dup-box div.dup-box-title').each(function () {
var $title = $(this);
var $panel = $title.parent().find('.dup-box-panel');
var $arrow = $title.find('.dup-box-arrow');
$title.click(DupliJs.UI.ToggleMetaBox);
//$arrow.on("keypress", DupliJs.UI.ToggleMetaBox)
$arrow.attr("aria-haspopup", true);
if ($panel.is(":visible")) {
$arrow.attr("aria-expanded", true);
$arrow.append('<i class="fa fa-caret-up"></i>');
} else {
$arrow.attr("aria-expanded", false);
$arrow.append('<i class="fa fa-caret-down"></i>')
}
});
DuplicatorTooltip.load();
DupliJs.passwordToggle();
//HANDLEBARS HELPERS
if (typeof (Handlebars) != "undefined") {
function _handleBarscheckCondition(v1, operator, v2) {
switch (operator) {
case '==':
return (v1 == v2);
case '===':
return (v1 === v2);
case '!==':
return (v1 !== v2);
case '<':
return (v1 < v2);
case '<=':
return (v1 <= v2);
case '>':
return (v1 > v2);
case '>=':
return (v1 >= v2);
case '&&':
return (v1 && v2);
case '||':
return (v1 || v2);
case 'obj||':
v1 = typeof (v1) == 'object' ? v1.length : v1;
v2 = typeof (v2) == 'object' ? v2.length : v2;
return (v1 != 0 || v2 != 0);
default:
return false;
}
}
Handlebars.registerHelper('ifCond', function (v1, operator, v2, options) {
return _handleBarscheckCondition(v1, operator, v2)
? options.fn(this)
: options.inverse(this);
});
Handlebars.registerHelper('if_eq', function (a, b, opts) {
return (a == b) ? opts.fn(this) : opts.inverse(this);
});
Handlebars.registerHelper('if_neq', function (a, b, opts) {
return (a != b) ? opts.fn(this) : opts.inverse(this);
});
}
$('.dup-pseudo-checkbox').each(function () {
let checkbox = $(this);
checkbox.attr("tabindex", 0);
checkbox.attr("role", "checkbox")
checkbox.on('click', function(e) {
e.stopPropagation();
if (checkbox.hasClass('disabled')) {
return;
}
checkbox.toggleClass('checked');
});
checkbox.on('keypress', function(e) {
e.stopPropagation();
e.preventDefault();
if (checkbox.hasClass('disabled')) {
return;
}
checkbox.toggleClass('checked');
});
checkbox.closest('label').on('click', function () {
checkbox.trigger('click');
});
});
/**
* Register a change event handler for all forms with the class 'dup-monitored-form'.
* This will set a flag to indicate that the form has unsaved changes.
*/
$('form.dup-monitored-form').each(function (index, form) {
DupliJs.UI.formOnChangeValues($(form), function() {
DupliJs.UI.hasUnsavedChanges = true;
});
});
/**
* Accordion
*/
$('.dup-accordion-wrapper .accordion-header').on('click', function () {
let accordion = $(this).parent();
let content = accordion.find('.accordion-content');
if (accordion.hasClass('close')) {
accordion.removeClass('close').addClass('open');
content.css('opacity', 0).animate({
opacity: 1
}, 300);
} else {
content.animate({
opacity: 0
}, 300, function() {
accordion.removeClass('open').addClass('close');
});
}
});
/**
* Meta Screen
*/
if ($('#screen-meta-links').length && $('body').hasClass('duplicator-page')) {
$('#wpcontent').css('position', 'relative');
}
$('#screen-meta-links, #screen-meta').prependTo('#dup-meta-screen');
$('#screen-meta-links').show();
/**
* Header tabs scroll
*/
if($('.dup-nav-item:last-child').length > 0) {
let $header = $('.dup-body-header').first();
let $lastTab = $header.find('.dup-nav-item:last-child');
if (!DupliJs.isInViewport($lastTab)) {
$header.addClass('dup-scrollable-header');
}
$header.on('scroll', function() {
$header.toggleClass('dup-scrollable-header', !DupliJs.isInViewport($lastTab));
});
}
/**
* When a form is submitting, we want to clear the unsaved changes flag.
* Otherwise, the user will be prompted to save changes when they are not actually leaving the page.
*/
window.addEventListener('submit', function (e) {
DupliJs.UI.hasUnsavedChanges = false;
});
/**
* Check if we have unsaved changes, and if so, prevent the user from navigating away from the page.
*/
window.addEventListener('beforeunload', function (e) {
if (DupliJs.UI.hasUnsavedChanges) {
e.preventDefault();
// Most browsers ignore the value, but historically some browsers are known to honor this value. So it's here as a backup
e.returnValue = '<?php echo esc_js(__('Changes you made may not be saved.', 'duplicator-pro')) ?>';
}
});
});
</script>

View File

@@ -0,0 +1,39 @@
/**
* Main script for Duplicator Plugin
*/
// Import and initialize global namespace (must be first)
import './dupli-namespace.js';
// Import jQuery and make it globally available
import jquery from 'jquery';
window.$ = window.jQuery = jquery;
// Import Tippy and make it globally available
import tippy from 'tippy.js';
window.tippy = tippy;
// Import Handlebars dist (browser-compatible) and make it globally available
import Handlebars from 'handlebars/dist/handlebars';
window.Handlebars = Handlebars;
/**
* Scripts
*/
import "parsleyjs";
import "@popperjs/core";
import "select2";
import "js-cookie";
import "jstree";
import "formstone";
import "formstone/dist/js/upload.js";
import "./duplicator-tooltip.js";
import "./dynamic-help.js";
/**
* Styles
*/
import "select2/dist/css/select2.css";
import "jstree/dist/themes/default/style.css"
console.log('Duplicator Plugin vendor bundle loaded successfully');

View File

@@ -0,0 +1,276 @@
/*! Duplicator iframe modal box */
class DuplicatorModalBox {
#url;
#modal;
#iframe;
#htmlContent;
#canClose;
#closeButton;
#openCallack;
#closeInContent;
#fullscreen;
#defaultOptions;
#closeColor = '#fff';
constructor(options = {}) {
this.#defaultOptions = {
url: null,
htmlContent: '',
openCallback: null,
closeColor: '#fff',
closeInContent: false,
fullscreen: false
};
this.setOptions(options);
this.#modal = null;
this.#iframe = null;
this.#canClose = true;
this.#closeButton = null;
}
setOptions(options = {}) {
if (options.url) {
this.#url = options.url;
this.#htmlContent = '';
} else if (!options.url && !options.htmlContent) {
this.#url = null;
this.#htmlContent = '';
} else {
this.#url = null;
this.#htmlContent = options.htmlContent;
}
if (options.openCallback && typeof options.openCallback === 'function') {
this.#openCallack = options.openCallback;
} else {
this.#openCallack = this.#defaultOptions.openCallback;
}
if (options.closeColor) {
this.#closeColor = options.closeColor;
}
if (options.closeInContent) {
this.#closeInContent = options.closeInContent;
} else {
this.#closeInContent = this.#defaultOptions.closeInContent;
}
if (options.fullscreen) {
this.#fullscreen = options.fullscreen;
} else {
this.#fullscreen = this.#defaultOptions.fullscreen;
}
if (this.#modal !== null) {
this.#updateContent();
}
}
open() {
// If modal is already open, do nothing
if (this.#modal !== null) {
return;
}
// Create modal element
this.#modal = document.createElement('div');
this.#modal.classList.add('dup-modal-wrapper');
this.#modal.classList.add('dup-styles');
// Add modal styles
this.#addModalStyles();
// Create close button
this.#closeButton = document.createElement('div');
this.#closeButton.classList.add('dup-modal-close-button');
this.#closeButton.innerHTML = '<i class="fa-regular fa-circle-xmark"></i>';
this.#closeButton.style.color = this.#closeColor;
// Add event listener to close button
this.#closeButton.addEventListener('click', () => {
this.close();
});
// Update content
this.#updateContent();
// Add close button to modal
if (this.#closeInContent) {
this.#modal.querySelector('.dup-modal-content').appendChild(this.#closeButton);
} else {
this.#modal.appendChild(this.#closeButton);
}
// Set overflow property of body to hidden
document.body.style.overflow = 'hidden';
// Add opacity animation
this.#modal.animate([
{ opacity: '0' },
{ opacity: '1' }
], {
duration: 500,
iterations: 1,
});
// Add modal to document
document.body.appendChild(this.#modal);
}
close() {
if (!this.#canClose || !this.#modal) {
return;
}
// Remove modal from document
document.body.removeChild(this.#modal);
// Set overflow property of body to hidden
document.body.style.overflow = 'auto';
// Reset modal and iframe variables
this.#modal = null;
this.#iframe = null;
}
enableClose() {
this.#canClose = true;
this.#closeButton.removeAttribute('disabled');
}
disableClose() {
this.#canClose = false;
this.#closeButton.setAttribute('disabled', 'disabled');
}
#insertContentAsHtml() {
let content = document.createElement('div');
content.classList.add('dup-modal-content');
if (this.#fullscreen) {
content.classList.add('fullscreen');
}
content.innerHTML = this.#htmlContent;
// Add content to modal
this.#modal.appendChild(content);
if (typeof this.#openCallack == 'function') {
this.#openCallack(content, this);
}
}
#insertContentAsIframe() {
// Create iframe element
this.#iframe = document.createElement('iframe');
this.#iframe.classList.add('dup-modal-iframe');
// Add open callback function
if (typeof this.#openCallack == 'function') {
let openCallack = this.#openCallack;
let iframe = this.#iframe;
let modalObj = this;
this.#iframe.onload = function () {
openCallack(iframe, modalObj);
};
}
this.#iframe.src = this.#url;
this.#iframe.setAttribute('frameborder', '0');
this.#iframe.setAttribute('allowfullscreen', '');
// Add iframe to modal
this.#modal.appendChild(this.#iframe);
}
#updateContent() {
if (!this.#modal) {
return;
}
// Remove existing content
if (this.#iframe) {
this.#modal.removeChild(this.#iframe);
this.#iframe = null;
} else {
const existingContent = this.#modal.querySelector('.dup-modal-content');
if (existingContent) {
this.#modal.removeChild(existingContent);
}
}
// Update content
if (this.#url) {
this.#insertContentAsIframe();
} else {
this.#insertContentAsHtml();
}
}
#addModalStyles() {
const style = document.createElement('style');
style.innerHTML = `
.dup-modal-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.7);
z-index: 1000005;
display: flex;
justify-content: center;
align-items: center;
}
.dup-styles.dup-modal-wrapper .dup-modal-iframe {
width: 100%;
height: 100%;
}
.dup-styles.dup-modal-wrapper .dup-modal-close-button {
position: absolute;
top: 0;
right: 0;
font-size: 23px;
color: #fff;
cursor: pointer;
line-height: 0;
text-align: center;
z-index: 2;
padding: 20px;
}
.dup-styles.dup-modal-wrapper .dup-modal-close-button i {
font-size: 23px;
line-height: normal;
}
.dup-styles.dup-modal-wrapper .dup-modal-close-button[disabled] {
opacity: 0.5;
cursor: not-allowed;
}
.dup-styles.dup-modal-wrapper .dup-modal-content {
position: relative;
max-height: calc(100vh - 40px);
max-width: calc(100vw - 40px);
overflow: auto;
}
.dup-styles.dup-modal-wrapper .dup-modal-content.fullscreen {
width: 100vw!important;
height: 100vh!important;
max-width: none;
max-height: none;
}
.dup-styles.dup-modal-wrapper .dup-modal-content .dup-modal-close-button {
padding: 9px;
}
`;
document.head.appendChild(style);
}
}