File "vik-content-builder.js"
Full Path: /home/romayxjt/public_html/wp-content/plugins/vikbooking/admin/resources/quill/vik-content-builder.js
File size: 6.9 KB
MIME-type: text/plain
Charset: utf-8
/**
* @package VikBooking
* @subpackage vik-content-builder
* @author Alessio Gaggii - E4J srl
* @copyright Copyright (C) 2025 E4J srl. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
* @link https://vikwp.com - https://e4j.com - https://e4jconnect.com
*/
/**
* Class handler to store the editor instances and switch building modes.
*
* AJAX requests may load this asset multiple times, so we declare an anonymous class, but
* we assign it to a variable using "var" because it is not block-scoped like "let" or "const".
*/
var VikContentBuilder = class {
/** @var array */
static editors = new Array;
/**
* Push the instance of an editor to the pool.
*
* @param object editor The editor instance.
*
* @return void
*/
static pushEditor(editor) {
this.editors.push(editor);
}
/**
* Switch between building modes.
*
* @param object elem DOM element object clicked.
* @param string mode Optional mode to switch to.
*
* @return void
*/
static switchMode(elem, mode) {
// determine who triggered the mode switch
let btn = jQuery(elem);
if (mode) {
btn = btn.closest('.vik-contentbuilder-wrapper').find('.vik-contentbuilder-switcher-btn[data-switch="' + mode + '"]');
}
// determine the new building mode to activate
let switch_to = btn.attr("data-switch");
// toggle active mode button
btn.parent('.vik-contentbuilder-switcher').find('.vik-contentbuilder-switcher-btn').removeClass('vik-contentbuilder-switcher-btn-active');
btn.addClass('vik-contentbuilder-switcher-btn-active');
// hide any mode content except the wanted one
let ed_conts = btn.closest('.vik-contentbuilder-wrapper');
ed_conts.find('.vik-contentbuilder-inner [data-switch]').not('[data-switch="' + switch_to + '"]').hide();
// target building mode content
let target = ed_conts.find('.vik-contentbuilder-inner [data-switch="' + switch_to + '"]');
// determine how to display the requested building mode
if (switch_to.indexOf('modal') >= 0) {
// modal window
let container_id = target.attr('data-container');
if (!container_id) {
container_id = switch_to;
}
// get the proper visual editor container to move and display
let editor_container = ed_conts.find('.vik-contentbuilder-inner [data-switch="' + container_id + '"]').find('.vik-contentbuilder-editor-wrap');
if (editor_container.length) {
// check if we also have an inline visual editor mode
let has_inline_ve = ed_conts.find('.vik-contentbuilder-inner [data-switch="visual"]').length;
// display the modal window with the visual editor
let modal_body = VBOCore.displayModal({
suffix: 'contentbuilder-' + switch_to,
extra_class: 'vbo-modal-rounded vbo-modal-large vbo-modal-nofooter vik-contentbuilder-modal-content',
lock_scroll: true,
draggable: false,
onDismiss: () => {
// put back the editor container element on its original position
editor_container.appendTo(ed_conts.find('.vik-contentbuilder-inner [data-switch="' + container_id + '"]'));
// switch to text mode or inline visual mode
VikContentBuilder.switchMode(btn, (has_inline_ve ? 'visual' : 'text'));
},
});
// move the editor container element to the body of the modal window
editor_container.appendTo(modal_body);
} else {
// unexpcted markup, fallback to displaying the target
target.show();
}
} else {
// show document target element
target.show();
}
// handle text mode special tag buttons
let text_mode_tags = jQuery('.vik-contentbuilder-textmode-sptags');
if (text_mode_tags.length && switch_to.indexOf('text') >= 0) {
text_mode_tags.show();
} else if (text_mode_tags.length && switch_to.indexOf('visual') >= 0) {
text_mode_tags.hide();
}
}
}
/**
* Class handler for uploading an image file and display it through Quill.
*
* AJAX requests may load this asset multiple times, so we declare an anonymous class, but
* we assign it to a variable using "var" because it is not block-scoped like "let" or "const".
*/
var VikContentBuilderImageHandler = class {
constructor(editor, endpoint) {
this.editor = editor;
this.endpoint = endpoint || null;
}
setEndpoint(endpoint) {
if (endpoint && endpoint.length) {
this.endpoint = endpoint;
}
return this;
}
present() {
var input = document.createElement('input');
input.setAttribute('type', 'file');
input.onchange = () => {
var file = input.files[0];
var rgxi = /^image\//;
if (!file || !file.name || !rgxi.test(file.type)) {
alert('Only images are allowed.');
return;
}
this.upload(file);
};
input.click();
}
upload(file) {
if (!file instanceof File) {
console.error('Invalid file');
return false;
}
if (!this.endpoint) {
console.error('Missing endpoint');
return false;
}
// build form data
var formd = new FormData();
formd.append('file', file);
formd.append('type', 'image');
// start progress
this.startProgress();
// perform the AJAX upload
var that = this;
var jqxhr = jQuery.ajax({
xhr: function() {
var xhrobj = jQuery.ajaxSettings.xhr();
if (xhrobj.upload) {
xhrobj.upload.addEventListener('progress', function(event) {
var percent = 0;
var position = event.loaded || event.position;
var total = event.total;
if (event.lengthComputable) {
percent = Math.ceil(position / total * 100);
}
// update progress
that.setProgress(percent);
}, false);
}
return xhrobj;
},
url: that.endpoint,
type: 'POST',
contentType: false,
processData: false,
cache: false,
data: formd,
success: function(resp) {
try {
resp = JSON.parse(resp);
if (resp.status == 1) {
that.complete(resp);
} else {
throw resp.error ? resp.error : 'An error occurred! Please try again.';
}
} catch (err) {
that.stopProgress();
console.warn(err, resp);
alert(err);
}
},
error: function(err) {
that.stopProgress();
console.error(err.responseText);
alert('An error occurred. Please try again.');
},
});
}
complete(resp) {
this.stopProgress();
this.editor.insertEmbed(this.editor.getSelection().index, 'image', resp.url);
}
startProgress() {
// access the toolbar module
var toolbar = null;
try {
toolbar = this.editor.getModule('toolbar').container;
} catch(e) {
// do nothing
}
if (!toolbar) {
return false;
}
// create progress element
this.progress_el = document.createElement("PROGRESS");
this.progress_el.setAttribute('max', 100);
this.progress_el.setAttribute('value', 0);
// append progress to toolbar
toolbar.appendChild(this.progress_el);
}
setProgress(value) {
if (!this.progress_el) {
return false;
}
this.progress_el.setAttribute('value', value);
}
stopProgress() {
if (!this.progress_el) {
return false;
}
this.progress_el.remove();
this.progress_el = null;
}
}