document.addEventListener('DOMContentLoaded', () => {
const PhotonicWizard = () => {
let photonicLastActiveScreen = 1;
let photonicMustPost = false;
let photonicPermittedGalleries = ['wp', 'default', 'flickr', 'smugmug', 'google', 'zenfolio', 'instagram'];
let photonicShortcodeObjectEditor;
let photonicParentShortcode = '';
let photonicParentSelectionError;
let photonicIFramePort;
let isEditor = false, isMCE = false, isWidget = false, isBlock = false;
let photonicActiveScreenElementMediaLibrary, photonicClickedNodeMediaLibrary;
let startupConnectionError;
// setWaitingVisibility(true);
window.addEventListener('message', initializeWizardPort);
function initializeWizardPort(event) {
// Perform a secure port transfer
if (event.ports[0] && event.origin === Photonic_Wizard_JS.safe_origin) {
photonicIFramePort = event.ports[0];
photonicIFramePort.onmessage = handleMessageFromParent;
}
else if (event.origin !== Photonic_Wizard_JS.safe_origin) {
startupConnectionError = 'ERROR: Photonic wizard failed to initiate communication with main page.
Main window is on ' + event.origin + ' Wizard is in ' + Photonic_Wizard_JS.safe_origin + ' ';
console.error('Photonic failed to initialize communication. Main window is in ' + event.origin + ', Wizard is in ' + Photonic_Wizard_JS.safe_origin);
if (startupConnectionError) {
document.querySelector('.photonic-editor-info').innerHTML += '' + startupConnectionError + '
';
}
}
}
function handleMessageFromParent(event) {
if (event.data.type === 'photonicShortcode' || event.data.type === 'photonicMCENode' || event.data.type === 'photonicWidget' || event.data.type === 'photonicBlock') {
receiveEditorShortcode(event);
}
else if (event.data.type === 'photonicReceiveMediaLibrarySelections') {
receiveMediaLibrarySelections(event.data.selection, event.data.options);
}
}
function receiveEditorShortcode(event) {
let selection = event.data.object;
// Selection = null if something went wrong
// Selection = shortcode object if valid shortcode
// Selection = null shortcode object and error, if not a valid shortcode
// Selection = '' if nothing was selected
if (selection !== null && selection.shortcode !== undefined && selection.shortcode !== null) {
if (selection.shortcode.content !== undefined) { // Selection is a valid shortcode
photonicParentShortcode = selection.shortcode.content;
photonicShortcodeObjectEditor = selection.shortcode;
}
else {
photonicParentShortcode = selection.shortcode; // Selection = ''
}
}
else if (selection !== null && selection.error !== undefined) {
photonicParentSelectionError = selection.error;
}
isEditor = event.data.type === 'photonicShortcode';
isWidget = event.data.type === 'photonicWidget';
isBlock = event.data.type === 'photonicBlock';
isMCE = event.data.type === 'photonicMCENode';
photonicIFramePort.postMessage(event.data);
photonicIFramePort.postMessage({type: 'photonicAddTBClass'});
wizardLogic(1);
}
function post(url, args, callback) {
const xhr = new XMLHttpRequest();
xhr.open('POST', url);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
const data = xhr.responseText;
callback(data);
}
}
};
let form = new FormData();
const parameters = new URLSearchParams(args);
for (const [key, value] of parameters.entries()) {
form.append(key, value);
}
xhr.send(form);
}
function getElement(value) {
const parser = new DOMParser();
const doc = parser.parseFromString(value, 'text/html');
return doc.body;
}
function log(value) {
if (console !== undefined && Photonic_Wizard_JS.debug_on !== '0' && Photonic_Wizard_JS.debug_on !== '') {
console.log(value);
}
}
const postFlowData = (activeScreen, nextScreen, activeScreenElement, screenParameters, parameters) => {
post(Photonic_Wizard_JS.ajaxurl, parameters, data => {
let ret = getElement(data);
if (ret.querySelector('.photonic-flow-error')) {
if (document.querySelector('.photonic-flow-error')) {
document.querySelector('.photonic-flow-error').remove();
}
document.querySelector('.photonic-flow-screen[data-screen="' + activeScreen + '"]').before(ret.querySelector('.photonic-flow-error'));
activeScreenElement.setAttribute('data-submitted', '');
log('Parameters causing failure: activeScreen = ' + activeScreen + ', nextScreen = ' + nextScreen);
log(screenParameters);
log(parameters);
}
else {
if (document.querySelector('.photonic-flow-error')) {
document.querySelector('.photonic-flow-error').style.display = 'none';
}
let forceScreen = ret.querySelector('input[name="force_next_screen"]');
if (forceScreen) {
if (parseInt(forceScreen.value, 10) > -1) {
nextScreen = parseInt(forceScreen.value, 10);
}
}
let nextScreenContent = document.querySelector('.photonic-flow-screen[data-screen="' + nextScreen + '"]');
nextScreenContent.replaceChildren();
nextScreenContent.insertAdjacentHTML('beforeend', data);
wizardLogic(nextScreen);
if (nextScreen <= 3) {
const existing = document.querySelector('input[name="existing_selection"]') ? document.querySelector('input[name="existing_selection"]').value : undefined;
const selection = document.querySelector('input[name="selected_data"]');
const passworded = document.querySelector('input[name="selection_passworded"]');
if (existing !== undefined && existing !== '') {
selection.value = existing;
}
else {
selection.value = '';
passworded.value = '';
}
}
photonicLastActiveScreen = nextScreen;
activeScreenElement.setAttribute('data-submitted', screenParameters);
photonicMustPost = false;
}
setWaitingVisibility(false);
});
};
function receiveMediaLibrarySelections(selected_data, options) {
document.querySelector('input[name="selected_data"]').value = selected_data
const form = document.getElementById('photonic-flow');
const formData = new FormData(form);
let formParameters = new URLSearchParams(formData).toString();
formParameters += ((formParameters === '') ? '' : '&') + 'action=photonic_wizard_next_screen&screen=' + (options.activeScreen) + '&_ajax_nonce=' + photonicClickedNodeMediaLibrary.getAttribute('data-photonic-nonce');
postFlowData(options.activeScreen, options.nextScreen, photonicActiveScreenElementMediaLibrary, options.screenParameters, formParameters);
if (selected_data !== '') {
wizardLogic(options.nextScreen);
}
}
const initializeWPMediaLibrary = (activeScreen, nextScreen, activeScreenElement, screenParameters, clicked) => {
let mode = document.querySelector('select[name="display_type"]').value;
if (mode === '') {
alert(Photonic_Wizard_JS.error_mandatory);
}
else {
mode = mode === 'single-photo' ? 'single' : 'add';
// These 2 are needed as we cannot pass elements to postMessage -->
photonicActiveScreenElementMediaLibrary = activeScreenElement;
photonicClickedNodeMediaLibrary = clicked;
// <--
photonicIFramePort.postMessage({
type: 'photonicInitializeMediaLibrary',
mediaOptions: {
multiple: mode,
title: Photonic_Wizard_JS.media_library_title,
library: {type: 'image'},
button: {text: Photonic_Wizard_JS.media_library_button}
},
photonicOptions: {
shortcodeTag: Photonic_Wizard_JS.shortcode,
activeScreen: activeScreen,
nextScreen: nextScreen,
screenParameters: screenParameters,
currentShortcode: photonicParentShortcode,
selectedIds: document.querySelector('input[name="selected_data"]').value,
isBlock: isBlock
}
});
}
};
const checkCondition = (conditions) => {
let conditionMet = true;
Object.entries(conditions).forEach(([key, condition]) => {
const keyField = document.querySelector('input[type="radio"][name="' + key + '"]:checked, select[name="' + key + '"], input[type="text"][name="' + key + '"], input[type="hidden"][name="' + key + '"]');
if (keyField === null) {
conditionMet = false;
}
else {
conditionMet = conditionMet && condition.includes(keyField.value);
}
});
return conditionMet;
};
const updateSelection = (clicked) => {
const parent = clicked.closest('.photonic-flow-selector-container');
let selection = [];
parent.querySelectorAll('.photonic-flow-selector.selected .photonic-flow-selector-inner').forEach(item => {
selection.push(item.getAttribute('data-photonic-selection-id'));
});
selection = selection.join();
let selectorFor = parent.getAttribute('data-photonic-flow-selector-for');
photonicMustPost = true;
document.querySelector('input[name="' + selectorFor + '"]').value = selection;
};
const showConditionalFieldValues = (sibling) => {
const siblingFieldValues = sibling.querySelectorAll('input[type="radio"], option');
siblingFieldValues.forEach(input => {
if (input.getAttribute('data-photonic-option-condition')) {
const conditionMet = checkCondition(JSON.parse(input.getAttribute('data-photonic-option-condition')));
if (conditionMet) {
if (input.type === 'radio') {
input.closest('.photonic-flow-field-radio').style.display = 'block';
}
else {
input.style.display = 'block';
}
}
else {
if (input.type === 'radio') {
input.checked = false;
input.closest('.photonic-flow-field-radio').style.display = 'none';
}
else {
input.style.display = 'none';
}
}
}
});
};
// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#solution_2_%E2%80%93_rewriting_atob_and_btoa_using_typedarrays_and_utf-8, to handle https://wordpress.org/support/topic/set-load-more-button-default/ ...
/*\
|*|
|*| Base64 / binary data / UTF-8 strings utilities
|*|
|*| https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding
|*|
\*/
/* Array of bytes to Base64 string decoding */
const photonicB64ToUint6 = (nChr) => {
return nChr > 64 && nChr < 91 ?
nChr - 65
: nChr > 96 && nChr < 123 ?
nChr - 71
: nChr > 47 && nChr < 58 ?
nChr + 4
: nChr === 43 ?
62
: nChr === 47 ?
63
:
0;
};
const photonicBase64DecToArr = (sBase64, nBlocksSize) => {
let
sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen = sB64Enc.length,
nOutLen = nBlocksSize ? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize : nInLen * 3 + 1 >> 2,
taBytes = new Uint8Array(nOutLen);
for (let nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {
nMod4 = nInIdx & 3;
nUint24 |= photonicB64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 6 * (3 - nMod4);
if (nMod4 === 3 || nInLen - nInIdx === 1) {
for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {
taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255;
}
nUint24 = 0;
}
}
return taBytes;
};
/* Base64 string to array encoding */
const photonicUint6ToB64 = (nUint6) => {
return nUint6 < 26 ?
nUint6 + 65
: nUint6 < 52 ?
nUint6 + 71
: nUint6 < 62 ?
nUint6 - 4
: nUint6 === 62 ?
43
: nUint6 === 63 ?
47
:
65;
};
const photonicBase64EncArr = (aBytes) => {
let nMod3 = 2, sB64Enc = "";
for (let nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) {
nMod3 = nIdx % 3;
if (nIdx > 0 && (nIdx * 4 / 3) % 76 === 0) {
sB64Enc += "\r\n";
}
nUint24 |= aBytes[nIdx] << (16 >>> nMod3 & 24);
if (nMod3 === 2 || aBytes.length - nIdx === 1) {
sB64Enc += String.fromCodePoint(photonicUint6ToB64(nUint24 >>> 18 & 63), photonicUint6ToB64(nUint24 >>> 12 & 63), photonicUint6ToB64(nUint24 >>> 6 & 63), photonicUint6ToB64(nUint24 & 63));
nUint24 = 0;
}
}
return sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) + (nMod3 === 2 ? '' : nMod3 === 1 ? '=' : '==');
};
/* UTF-8 array to JS string and vice versa */
const photonicUTF8ArrToStr = (aBytes) => {
let sView = "";
for (let nPart, nLen = aBytes.length, nIdx = 0; nIdx < nLen; nIdx++) {
nPart = aBytes[nIdx];
sView += String.fromCodePoint(
nPart > 251 && nPart < 254 && nIdx + 5 < nLen ? /* six bytes */
/* (nPart - 252 << 30) may be not so safe in ECMAScript! So…: */
(nPart - 252) * 1073741824 + (aBytes[++nIdx] - 128 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128
: nPart > 247 && nPart < 252 && nIdx + 4 < nLen ? /* five bytes */
(nPart - 248 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128
: nPart > 239 && nPart < 248 && nIdx + 3 < nLen ? /* four bytes */
(nPart - 240 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128
: nPart > 223 && nPart < 240 && nIdx + 2 < nLen ? /* three bytes */
(nPart - 224 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128
: nPart > 191 && nPart < 224 && nIdx + 1 < nLen ? /* two bytes */
(nPart - 192 << 6) + aBytes[++nIdx] - 128
: /* nPart < 127 ? */ /* one byte */
nPart
);
}
return sView;
};
const photonicStrToUTF8Arr = (sDOMStr) => {
let aBytes, nChr, nStrLen = sDOMStr.length, nArrLen = 0;
/* mapping… */
for (let nMapIdx = 0; nMapIdx < nStrLen; nMapIdx++) {
nChr = sDOMStr.codePointAt(nMapIdx);
if (nChr > 65536) {
nMapIdx++;
}
nArrLen += nChr < 0x80 ? 1 : nChr < 0x800 ? 2 : nChr < 0x10000 ? 3 : nChr < 0x200000 ? 4 : nChr < 0x4000000 ? 5 : 6;
}
aBytes = new Uint8Array(nArrLen);
/* transcription… */
for (let nIdx = 0, nChrIdx = 0; nIdx < nArrLen; nChrIdx++) {
nChr = sDOMStr.codePointAt(nChrIdx);
if (nChr < 128) {
/* one byte */
aBytes[nIdx++] = nChr;
}
else if (nChr < 0x800) {
/* two bytes */
aBytes[nIdx++] = 192 + (nChr >>> 6);
aBytes[nIdx++] = 128 + (nChr & 63);
}
else if (nChr < 0x10000) {
/* three bytes */
aBytes[nIdx++] = 224 + (nChr >>> 12);
aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);
aBytes[nIdx++] = 128 + (nChr & 63);
}
else if (nChr < 0x200000) {
/* four bytes */
aBytes[nIdx++] = 240 + (nChr >>> 18);
aBytes[nIdx++] = 128 + (nChr >>> 12 & 63);
aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);
aBytes[nIdx++] = 128 + (nChr & 63);
nChrIdx++;
}
else if (nChr < 0x4000000) {
/* five bytes */
aBytes[nIdx++] = 248 + (nChr >>> 24);
aBytes[nIdx++] = 128 + (nChr >>> 18 & 63);
aBytes[nIdx++] = 128 + (nChr >>> 12 & 63);
aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);
aBytes[nIdx++] = 128 + (nChr & 63);
nChrIdx++;
}
else /* if (nChr <= 0x7fffffff) */ {
/* six bytes */
aBytes[nIdx++] = 252 + (nChr >>> 30);
aBytes[nIdx++] = 128 + (nChr >>> 24 & 63);
aBytes[nIdx++] = 128 + (nChr >>> 18 & 63);
aBytes[nIdx++] = 128 + (nChr >>> 12 & 63);
aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);
aBytes[nIdx++] = 128 + (nChr & 63);
nChrIdx++;
}
}
return aBytes;
};
const wizardLogic = (screen) => {
const existing = document.querySelector('input[name="photonic-editor-shortcode"]').getAttribute('value');
const existingBlock = document.querySelector('input[name="photonic-editor-json"]').getAttribute('value');
if (screen === 1) {
if (existing === undefined || existing === null || existing === '') {
let shortcode = photonicShortcodeObjectEditor, attributes, type;
if (isEditor || isWidget || isMCE) {
if (typeof shortcode !== 'undefined' && shortcode !== null) {
let scParameter = photonicBase64EncArr(photonicStrToUTF8Arr(JSON.stringify(shortcode))); // To handle unicode in "more"; see https://developer.mozilla.org/en-US/docs/Glossary/Base64#solution_1_%E2%80%93_escaping_the_string_before_encoding_it
scParameter = scParameter.replace(/\n/g, '');
scParameter = scParameter.replace(/^=+|=+$/g, '');
attributes = shortcode.shortcode.attrs.named;
if (attributes['type'] !== undefined && photonicPermittedGalleries.indexOf(attributes['type']) !== -1) {
type = attributes['type'];
}
else if ((attributes['type'] === undefined && Photonic_Wizard_JS.shortcode !== 'gallery') || attributes['style'] !== undefined) {
type = 'wp';
}
if (type !== undefined) {
if (type === 'google') {
document.querySelector('.photonic-editor-info').innerHTML = '' + Photonic_Wizard_JS.info_editor_google_shortcode + '
';
}
else {
document.querySelector('[name="photonic-editor-shortcode-raw"]').value = scParameter;
document.querySelector('[name="photonic-editor-shortcode"]').value = photonicParentShortcode;
document.querySelector('[data-photonic-selection-id="' + type + '"]').click();
document.querySelector('.photonic-editor-info').innerHTML = '';
}
}
else {
document.querySelector('.photonic-editor-info').innerHTML = '' + Photonic_Wizard_JS.info_editor_not_shortcode + '
';
}
}
else if (photonicParentSelectionError !== undefined) {
document.querySelector('.photonic-editor-info').innerHTML = '' + Photonic_Wizard_JS.info_editor_not_shortcode + '
';
}
}
else if (isBlock) { // Gutenberg
document.querySelector('[name="photonic-gutenberg-active"]').value = 1;
if (photonicParentShortcode !== undefined && photonicParentShortcode !== '') {
shortcode = photonicParentShortcode;
attributes = JSON.parse(shortcode);
if (attributes.type !== undefined && photonicPermittedGalleries.indexOf(attributes.type) !== -1) {
type = attributes.type;
}
else if (attributes.style !== undefined) {
type = 'wp';
}
if (type !== undefined) {
document.querySelector('[name="photonic-editor-json"]').value = shortcode;
document.querySelector('[data-photonic-selection-id="' + type + '"]').click();
document.querySelector('.photonic-editor-info').replaceChildren();
}
}
else {
document.querySelector('.photonic-editor-info').innerHTML = '' + Photonic_Wizard_JS.info_editor_block_select + '
';
}
}
}
setWaitingVisibility(false);
}
if (screen === 6) {
if ((existing === undefined || existing === '') && (existingBlock === undefined || existingBlock === '')) {
document.getElementById('photonic-nav-next').innerHTML = Photonic_Wizard_JS.insert_gallery;
}
else {
document.getElementById('photonic-nav-next').innerHTML = Photonic_Wizard_JS.update_gallery;
}
}
else {
document.getElementById('photonic-nav-next').innerHTML = 'Next';
}
document.querySelectorAll('.photonic-flow-screen').forEach(screen => {
screen.style.display = 'none';
});
const activeScreen = document.querySelector('.photonic-flow-screen[data-screen="' + screen + '"]');
const fieldSequences = activeScreen.querySelectorAll('.photonic-flow-field[data-photonic-flow-sequence="1"]');
const displayType = activeScreen.querySelector('select[name="display_type"]');
const popupType = activeScreen.querySelector('select[name="popup"]');
fieldSequences.forEach(fieldSequence => {
const group = fieldSequence.getAttribute('data-photonic-flow-sequence-group');
document.querySelectorAll('.photonic-flow-field[data-photonic-flow-sequence-group="' + group + '"]').forEach((fieldContainer, idx) => {
let field = fieldContainer.querySelector('input, select');
let isRadio = false;
const fieldName = field.getAttribute('name');
let fieldSelection = document.querySelector('input[type="radio"][name="' + fieldName + '"]:checked') || document.querySelector('input[type="text"][name="' + fieldName + '"], select[name="' + fieldName + '"]');
const fieldValue = fieldSelection ? fieldSelection.value : undefined;
if (idx !== 0 && (fieldValue === '' || fieldValue === undefined)) {
fieldContainer.style.display = 'none';
}
// This has to happen after "fieldValue" is set
if (field.tagName === 'INPUT' && field.type === 'radio') {
field = field.closest('.photonic-flow-field-radio-group');
isRadio = true;
}
const siblings = fieldContainer.parentNode.children;
let sequence = parseInt(fieldContainer.getAttribute('data-photonic-flow-sequence'), 10);
field.addEventListener('change', () => {
if (isRadio) {
fieldSelection = document.querySelector('input[type="radio"][name="' + fieldName + '"]:checked');
}
const error = document.querySelector('.photonic-flow-error');
if (error) {
error.style.display = 'none';
}
if ((!isRadio && field.value !== '') || (isRadio && fieldSelection && fieldSelection.value !== undefined)) {
Array.from(siblings).forEach(sibling => {
let currSequence = parseInt(sibling.getAttribute('data-photonic-flow-sequence'), 10);
if (currSequence > sequence) {
if (sibling.getAttribute('data-photonic-condition')) {
const conditionMet = checkCondition(JSON.parse(sibling.getAttribute('data-photonic-condition')));
sibling.style.display = conditionMet ? 'block' : 'none';
}
else {
fadeIn(sibling);
}
showConditionalFieldValues(sibling);
}
});
}
else {
Array.from(siblings).forEach(sibling => {
let currSequence = parseInt(sibling.getAttribute('data-photonic-flow-sequence'), 10);
if (currSequence > sequence) {
fadeOut(sibling);
}
});
}
});
});
});
activeScreen.querySelectorAll('[data-photonic-condition] input, [data-photonic-condition] select').forEach(input => {
const fieldContainer = input.closest('.photonic-flow-field');
const sequences = input.closest('[data-photonic-flow-sequence]');
if (fieldContainer && !sequences) {
if (fieldContainer.getAttribute('data-photonic-condition') && fieldContainer.getAttribute('data-photonic-condition') !== '') {
const conditionMet = checkCondition(fieldContainer.getAttribute('data-photonic-condition'));
fieldContainer.style.display = conditionMet ? 'block' : 'none';
}
}
});
if (screen === 2) {
// One exception to the above ...
if (displayType && displayType.value !== '') {
const fieldContainer = document.querySelector('[name="for"]') ? document.querySelector('[name="for"]').closest('.photonic-flow-field') : undefined;
if (fieldContainer) {
showConditionalFieldValues(fieldContainer);
fadeIn(fieldContainer);
}
}
}
else if (screen === 5) {
// ... And another exception
if (popupType && popupType.value !== '' && popupType.value !== 'hide') {
const managedFields = document.querySelectorAll('[name="photo_count"], [name="photo_more"], [name="photo_layout"]');
managedFields.forEach(managedField => {
const fieldContainer = managedField.closest('.photonic-flow-field');
showConditionalFieldValues(fieldContainer);
fadeIn(fieldContainer);
});
}
}
activeScreen.style.display = 'block';
if (screen === 1) {
document.querySelector('.photonic-flow-navigation a.previous').classList.add('disabled');
}
else {
document.querySelector('.photonic-flow-navigation a.previous').classList.remove('disabled');
}
};
function fadeIn(el) {
if (!el.classList.contains('fade-in')) {
el.style.display = 'block';
el.style.visibility = 'visible';
el.classList.add('fade-in');
}
}
function fadeOut(el, duration) {
let s = el.style,
step = 25 / (duration || 500);
s.opacity = s.opacity || 1;
(function fade() {
s.opacity -= step;
if (s.opacity < 0) {
s.display = "none";
el.classList.remove('fade-in');
}
else {
setTimeout(fade, 25);
}
})();
}
function setWaitingVisibility(visible) {
const waiting = document.querySelector('.photonic-waiting');
waiting.style.display = visible ? 'block' : 'none';
}
document.querySelector('.photonic-flow-navigation a.disabled').addEventListener('click', (e) => {
e.preventDefault();
});
document.addEventListener('click', e => {
if (!(e.target instanceof Element) || !e.target.closest('.photonic-flow-navigation a')) {
return;
}
let clicked = e.target.closest('.photonic-flow-navigation a');
if (!clicked.classList.contains('disabled')) {
e.preventDefault();
setWaitingVisibility(true);
let activeScreen;
let flowScreens = document.querySelectorAll('.photonic-flow-screen');
flowScreens.forEach(f => {
if (f.checkVisibility()) {
activeScreen = parseInt(f.getAttribute('data-screen'), 10);
}
});
let nextScreen = activeScreen + 1;
let previousScreen = activeScreen - 1;
const form = document.getElementById('photonic-flow');
const formData = new FormData(form);
let formParameters = new URLSearchParams(formData).toString();
const activeScreenElement = document.querySelector('.photonic-flow-screen[data-screen="' + activeScreen + '"]');
if (clicked.classList.contains('next')) {
let shortcode = activeScreenElement.querySelector('#photonic_shortcode');
let submission = activeScreenElement.getAttribute('data-submitted');
let screenFormFields = new FormData();
activeScreenElement.querySelectorAll('input, select').forEach(input => {
// Only serialize fields with names that aren't disabled
if (input.name && !input.disabled) {
// Handle checkboxes and radios only if checked
if (['checkbox', 'radio'].includes(input.type)) {
if (input.checked) {
screenFormFields.append(input.name, input.value);
}
}
else {
screenFormFields.append(input.name, input.value);
}
}
});
let screenParameters = new URLSearchParams(screenFormFields).toString();
formParameters += ((formParameters === '') ? '' : '&') + 'action=photonic_wizard_next_screen&screen=' + activeScreen + '&_ajax_nonce=' + clicked.getAttribute('data-photonic-nonce');
// Make AJAX call if we are on the last screen, or if the current screen's parameters have changed since the last time.
// Otherwise just get the previously fetched screen. This saves a server call, and also helps preserve screen changes not sent to the back-end.
if (shortcode) {
if (isMCE) { // TinyMCE Editor
photonicIFramePort.postMessage({type: 'photonicUpdateGallery', html: shortcode.textContent});
}
else if (isBlock) { // Gutenberg
photonicIFramePort.postMessage({type: 'photonicUpdateGallery', props: shortcode.value});
}
else if (isWidget) {
photonicIFramePort.postMessage({type: 'photonicUpdateGallery', html: shortcode.textContent});
}
else {
photonicIFramePort.postMessage({type: 'photonicUpdateGallery', html: shortcode.textContent});
}
}
else if (activeScreen === 2
&& document.querySelector('input[name="provider"]') && document.querySelector('input[name="provider"]').value === 'wp'
&& document.querySelector('select[name="display_type"]') && document.querySelector('select[name="display_type"]').value === 'multi-photo') {
initializeWPMediaLibrary(activeScreen, nextScreen, activeScreenElement, screenParameters, clicked);
photonicIFramePort.postMessage({type: 'photonicOpenMediaLibrary'});
setWaitingVisibility(false);
}
else if (activeScreen === photonicLastActiveScreen || submission !== screenParameters || photonicMustPost) {
postFlowData(activeScreen, nextScreen, activeScreenElement, screenParameters, formParameters);
}
else {
wizardLogic(nextScreen);
setWaitingVisibility(false);
}
}
else if (clicked.classList.contains('previous')) {
let forceScreen = activeScreenElement.querySelector('input[name="force_previous_screen"]');
if (forceScreen && parseInt(forceScreen.value, 10) > -1) {
previousScreen = parseInt(forceScreen.value, 10);
}
wizardLogic(previousScreen);
setWaitingVisibility(false);
}
}
});
document.addEventListener('click', e => {
if (!(e.target instanceof Element) || !e.target.closest('.photonic-gallery a')) {
return;
}
e.preventDefault();
document.querySelectorAll('.photonic-gallery a').forEach(icon => {
icon.classList.remove('selected');
});
const clicked = e.target.closest('.photonic-gallery a');
clicked.classList.add('selected');
document.getElementById('provider').value = clicked.getAttribute('data-provider');
});
document.addEventListener('click', e => {
if (!(e.target instanceof Element) || !e.target.closest('.photonic-flow-selector')) {
return;
}
e.preventDefault();
const clicked = e.target.closest('.photonic-flow-selector');
const container = clicked.closest('.photonic-flow-selector-container');
const selectionMode = container.getAttribute('data-photonic-flow-selector-mode');
if (selectionMode === 'none') {
return;
}
else if (selectionMode === 'single' || selectionMode === 'single-no-plus') {
container.querySelectorAll('.photonic-flow-selector').forEach(selector => {
selector.classList.remove('selected');
});
container.querySelectorAll('.photonic-flow-selector .dashicons').forEach(selector => {
selector.remove();
});
if (container.getAttribute('data-photonic-flow-selector-for') === 'selected_data') {
const selectionPassworded = document.querySelector('input[name="selection_passworded"]');
if (clicked.classList.contains('passworded')) {
if (selectionPassworded.value === '') {
photonicMustPost = true;
}
selectionPassworded.value = '1';
}
else {
if (selectionPassworded.value === '1' || selectionPassworded.value === 1) {
photonicMustPost = true;
}
selectionPassworded.value = '';
}
}
}
if (selectionMode === 'multi') {
clicked.classList.add('selected');
addDashIcon(clicked);
}
else if (selectionMode === 'single-no-plus' || selectionMode === 'single') {
clicked.classList.add('selected');
}
updateSelection(clicked);
});
function addDashIcon(thumbnail) {
const icon = document.createElement("a");
icon.classList.add('dashicons', 'dashicons-plus');
icon.href = '#';
thumbnail.append(icon);
icon.addEventListener('click', ie => { // For some reason, doing this on document.addEventListener is unable to remove the dashicons.
ie.preventDefault();
ie.stopPropagation();
thumbnail.classList.remove('selected');
icon.remove();
updateSelection(thumbnail);
});
['mouseenter', 'mouseleave'].forEach(eventType => {
icon.addEventListener(eventType, me => {
me.preventDefault();
me.stopPropagation();
icon.classList.toggle('dashicons-plus');
icon.classList.toggle('dashicons-minus');
});
});
}
document.addEventListener('click', e => {
if (!(e.target instanceof Element) || !e.target.closest('.photonic-mark')) {
return;
}
e.preventDefault();
const clicked = e.target.closest('.photonic-mark');
const markFor = clicked.getAttribute('data-photonic-mark-for');
const thumbnails = document.querySelectorAll('.photonic-flow-selector-container[data-photonic-flow-selector-for="' + markFor + '"] .photonic-flow-selector');
let selection = '';
thumbnails.forEach(thumbnail => {
if (clicked.classList.contains('photonic-mark-all') && !thumbnail.classList.contains('selected')) {
thumbnail.classList.add('selected');
addDashIcon(thumbnail);
selection += thumbnail.querySelector('.photonic-flow-selector-inner').getAttribute('data-photonic-selection-id') + ',';
}
else if (clicked.classList.contains('photonic-mark-none')) {
thumbnail.classList.remove('selected');
if (thumbnail.querySelector('.dashicons')) {
thumbnail.querySelector('.dashicons').remove();
}
}
});
if (selection !== '') {
selection = selection.replace(/^,+|,+$/g, '');
}
document.querySelector('input[name="' + markFor + '"]').value = selection;
});
document.addEventListener('click', e => {
if (!(e.target instanceof Element) || !e.target.closest('a.photonic-add-date-filter')) {
return;
}
e.preventDefault();
const clicked = e.target.closest('a.photonic-add-date-filter');
const dateFilterField = clicked.getAttribute('data-photonic-add-date');
const list = document.querySelector('ol[data-photonic-date-filter="' + dateFilterField + '"]');
const dateFilterCount = parseInt(list.getAttribute('data-photonic-filter-count'), 10);
const currentCount = list.children.length;
const listItem = document.createElement("li");
const div = document.createElement('div');
div.classList.add('photonic-single-date');
const parts = ['Year', 'Month', 'Date'];
const texts = ['Year (0 - 9999)', 'Month (0 - 12)', 'Date (0 - 31)'];
parts.forEach((part, j) => {
div.insertAdjacentHTML('beforeend',
"" +
part.substring(0, 1) +
" " +
"" + texts[j] + "
" +
" "
);
});
listItem.append(div);
listItem.insertAdjacentHTML('beforeend', " ");
list.append(listItem);
if (list.children.length === dateFilterCount) {
clicked.style.display = 'none';
}
});
document.addEventListener('click', e => {
if (!(e.target instanceof Element) || !e.target.closest('a.photonic-add-date-range-filter')) {
return;
}
e.preventDefault();
const clicked = e.target.closest('a.photonic-add-date-range-filter');
const dateFilterField = clicked.getAttribute('data-photonic-add-date-range');
const list = document.querySelector('ol[data-photonic-date-range-filter="' + dateFilterField + '"]');
const dateFilterCount = parseInt(list.getAttribute('data-photonic-filter-count'), 10);
const currentCount = list.children.length;
const listItem = document.createElement('li');
const parts = ['Year', 'Month', 'Date'];
const range_parts = ['start', 'finish'];
const texts = ['Year (0 - 9999)', 'Month (0 - 12)', 'Date (0 - 31)'];
range_parts.forEach(range_part => {
const div = document.createElement('div');
div.classList.add('photonic-single-date');
parts.forEach((part, counter) => {
div.insertAdjacentHTML('beforeend',
"" +
part.substr(0, 1) +
" " +
"" + texts[counter] + "
" +
" "
);
});
listItem.append(div);
});
listItem.insertAdjacentHTML('beforeend', " ");
list.append(listItem);
if (list.children.length === dateFilterCount) {
clicked.style.display = 'none';
}
});
document.addEventListener('click', e => {
if (!(e.target instanceof Element) || !e.target.closest('a.photonic-remove-date-filter')) {
return;
}
e.preventDefault();
const clicked = e.target.closest('a.photonic-remove-date-filter');
const listItem = clicked.closest('li');
const list = listItem.parentElement;
const dateFilterField = list.getAttribute('data-photonic-date-filter');
const dateFilterCount = parseInt(list.getAttribute('data-photonic-filter-count'), 10);
let addButton = document.querySelector("a[data-photonic-add-date='" + dateFilterField + "']");
if (!addButton) {
addButton = document.createElement('a');
addButton.setAttribute('href', '#');
addButton.setAttribute('data-photonic-add-date', dateFilterField);
addButton.classList.add('photonic-add-date-filter');
addButton.insertAdjacentHTML('beforeend', " Add filter");
list.after(addButton);
addButton.style.display = 'none';
}
listItem.remove();
if (list.children.length < dateFilterCount) {
addButton.style.display = 'block';
}
});
document.addEventListener('click', e => {
if (!(e.target instanceof Element) || !e.target.closest('a.photonic-remove-date-range-filter')) {
return;
}
e.preventDefault();
const clicked = e.target.closest('a.photonic-remove-date-range-filter');
const listItem = clicked.closest('li');
const list = listItem.parentElement;
const dateFilterField = list.getAttribute('data-photonic-date-range-filter');
const dateFilterCount = parseInt(list.getAttribute('data-photonic-filter-count'), 10);
let addButton = document.querySelector("a[data-photonic-add-date-range='" + dateFilterField + "']");
if (!addButton) {
addButton = document.createElement('a');
addButton.setAttribute('href', '#');
addButton.setAttribute('data-photonic-add-date-range', dateFilterField);
addButton.classList.add('photonic-add-date-range-filter');
addButton.insertAdjacentHTML('beforeend', " Add filter");
list.after(addButton);
addButton.style.display = 'none';
}
listItem.remove();
if (list.children.length < dateFilterCount) {
addButton.style.display = 'block';
}
});
document.addEventListener('change', e => {
if (!(e.target instanceof Element) || !e.target.closest('input[class^=photonic-date-]')) {
return;
}
e.preventDefault();
const changed = e.target.closest('input[class^=photonic-date-]');
const container = changed.closest('ol');
if (container) {
const range = container.getAttribute('data-photonic-date-range-filter') !== undefined;
const dates = container.children;
let listMerge = [];
dates.forEach(date => {
let itemMerge = [];
const dateFields = date.querySelectorAll('input');
if (dateFields.length > 0) {
itemMerge[itemMerge.length] = [];
}
if (dateFields.length > 3) {
itemMerge[itemMerge.length] = [];
}
dateFields.forEach((d, i) => {
const mod = Math.floor(i / 3);
const div = i % 3;
itemMerge[mod][div] = d.value === '' ? 0 : d.value;
});
itemMerge.forEach((d, i) => {
itemMerge[i] = d.join('/');
});
listMerge.push(itemMerge.join('-'));
});
listMerge = listMerge.join();
if (range) {
document.querySelector('input[name="' + container.getAttribute('data-photonic-date-range-filter') + '"]').value = listMerge;
}
else {
document.querySelector('input[name="' + container.getAttribute('data-photonic-date-filter') + '"]').value = listMerge;
}
}
});
document.addEventListener('click', e => {
if (!(e.target instanceof Element) || !e.target.closest('a.photonic-flow-more')) {
return;
}
e.preventDefault();
const clicked = e.target.closest('a.photonic-flow-more');
const container = clicked.closest('.photonic-flow-selector-container');
const link = clicked.getAttribute('data-photonic-more-link');
const existing = document.querySelector('input[name="photonic-editor-shortcode"]') ? document.querySelector('input[name="photonic-editor-shortcode"]').value : undefined;
const existingBlock = document.querySelector('input[name="photonic-editor-json"]') ? document.querySelector('input[name="photonic-editor-json"]').value : undefined;
let shortcode, attributes, albumFilter;
if (existing && !isBlock) {
if (photonicShortcodeObjectEditor !== undefined) {
attributes = photonicShortcodeObjectEditor.shortcode.attrs.named;
if (attributes['filter']) {
albumFilter = attributes['filter'];
}
}
}
else if (existingBlock && isBlock) { // Gutenberg
if (photonicParentShortcode !== undefined && photonicParentShortcode !== '') {
shortcode = photonicParentShortcode;
attributes = JSON.parse(shortcode);
if (attributes.filter !== undefined) {
albumFilter = attributes.filter;
}
}
}
if (link !== undefined && link !== '') {
setWaitingVisibility(true);
let parameters = [];
parameters['action'] = 'photonic_wizard_more';
parameters['provider'] = clicked.getAttribute('data-photonic-provider');
parameters['display_type'] = clicked.getAttribute('data-photonic-display-type');
parameters['url'] = encodeURIComponent(clicked.getAttribute('data-photonic-more-link'));
if (albumFilter) {
albumFilter = '&filter=' + albumFilter;
}
else {
albumFilter = '';
}
parameters = 'action=photonic_wizard_more&provider=' + clicked.getAttribute('data-photonic-provider') + '&display_type=' + clicked.getAttribute('data-photonic-display-type') + '&url=' +
btoa(clicked.getAttribute('data-photonic-more-link')) + albumFilter + '&_ajax_nonce=' + clicked.getAttribute('data-photonic-nonce');
post(Photonic_Wizard_JS.ajaxurl, parameters, function (data) {
clicked.style.display = 'none';
if (clicked.closest('.photonic-more-wrapper')) {
clicked.closest('.photonic-more-wrapper').remove();
}
const currentSelectors = container.querySelectorAll('.photonic-flow-selector');
const lastItem = currentSelectors.item(currentSelectors.length - 1);
if (lastItem) {
lastItem.insertAdjacentHTML('afterend', data);
}
const search = document.getElementById('thumb-search');
search.focus();
search.blur();
updateSelection(document.querySelector('.photonic-flow-selector:last-child'));
setWaitingVisibility(false);
});
}
});
document.addEventListener('mouseover', e => {
if (!(e.target instanceof Element) || !e.target.closest('input, select')) {
return;
}
e.stopPropagation();
const item = e.target;
const tooltip = document.querySelector('#' + item.getAttribute('aria-describedby'));
if (tooltip) {
tooltip.setAttribute('aria-hidden', false);
tooltip.style.display = 'block';
fadeIn(tooltip);
}
});
document.addEventListener('mouseout', e => {
if (!(e.target instanceof Element) || !e.target.closest('input, select, .photonic-flow-hint')) {
return;
}
e.stopPropagation();
const item = e.target;
const tooltipId = item.classList.contains('photonic-flow-hint') ? item.getAttribute('id') : '#' + item.getAttribute('aria-describedby');
const tooltip = document.querySelector(tooltipId);
if (tooltip && !document.querySelector(tooltipId + ':hover')) {
tooltip.setAttribute('aria-hidden', true);
tooltip.style.display = 'none';
}
});
document.getElementById('photonic-flow').addEventListener('focusin', e => {
if (!e.target.matches('#thumb-search')) {
return;
}
const search = e.target;
const images = document.querySelectorAll('.photonic-flow-selector-container img');
const cache = [];
images.forEach((image) => {
cache.push({
element: image,
text: image.alt.trim().toLowerCase()
});
});
function filter(e) {
const query = e.target.value.trim().toLowerCase();
cache.forEach(image => {
let index = 0;
if (query) {
index = image.text.indexOf(query);
}
if (index === -1) {
image.element.closest('.photonic-flow-selector').style.display = 'none';
}
else {
image.element.closest('.photonic-flow-selector').style.display = 'inline-block';
}
});
}
search.addEventListener('input', filter);
search.addEventListener('keyup', filter);
});
document.addEventListener('change', e => {
if (!(e.target instanceof Element) || !e.target.matches('[name="selected_data"],[name="selection_passworded"]')) {
return;
}
photonicMustPost = true;
});
}
PhotonicWizard();
});