Files
Jacek Pyziak cd264483f8 Add PSR HTTP Message Interfaces and Dependencies
- Implemented StreamInterface, UploadedFileInterface, and UriInterface as per PSR standards.
- Added getallheaders function to retrieve HTTP headers in a compatible manner.
- Included LICENSE files for ralouphie/getallheaders and symfony/deprecation-contracts.
- Introduced function for triggering deprecation notices in Symfony.
2025-12-28 12:44:00 +01:00

313 lines
14 KiB
JavaScript

'use strict';
(() => {
const { createBlock } = wp.blocks;
const { dispatch, select } = wp.data;
class atfpCreateNewBlock {
constructor() {
this.updateBlockStore = {};
this.loaderRemove = null;
this.loader = null;
this.replaceAttributes = null;
this.updateBlockId = new Array();
}
copyTranslateText = () => {
// Get the current selection object
const selection = window.getSelection();
// Create a new range object
const range = document.createRange();
// Select the contents of the copy text element
range.selectNodeContents(document.getElementById('atfp-copy-text'));
// Remove any existing selections
selection.removeAllRanges();
// Add the new range to the selection
selection.addRange(range);
// Execute the copy command
document.execCommand('copy');
// Clear the selection
selection.removeAllRanges();
}
noticeInitialize = () => {
dispatch("core/notices").createNotice('info', 'To enable translation, please include the Make This Content Available for Translation text in your block content. For help, watch the video and click <b>"Copy Text"</b> to use. Then, paste it into the section of your block you want automatically translated',
{
isDismissible : false,
id: 'atfp-notice-id',
actions: [
{
label: 'Watch Video.',
url: `${atfpAddBlockVars.atfp_demo_page_url}#custom-block-translate`,
},
],
__unstableHTML: true
}).then(()=>{
const targetAnchor=document.querySelector(`a[href^="${atfpAddBlockVars.atfp_demo_page_url}#custom-block-translate"]`);
if(targetAnchor){
targetAnchor.addEventListener('click', (e)=>{
e.preventDefault();
window.open(targetAnchor.href, '_blank');
})
}
});
}
copyBtnInitialize = () => { // Initialize the copy button
const copyBtn = document.createElement('div'); // Create a new div element for the copy button
copyBtn.id = 'atfp-copy-btn'; // Set the ID of the copy button
copyBtn.innerHTML = 'Copy Text'; // Set the inner HTML of the copy button
copyBtn.addEventListener('click', this.copyTranslateText); // Add click event listener to copy text
copyBtn.ariaLabel = 'Copy Text'; // Set the aria-label for accessibility
copyBtn.title = 'Click to copy the text "Make This Content Available for Translation"'; // Tooltip message
const copyText = document.createElement('div'); // Create a new div element for the copy text
copyText.id = 'atfp-copy-text'; // Set the ID of the copy text div
copyText.innerHTML = 'Make This Content Available for Translation'; // Set the inner HTML of the copy text div
document.body.appendChild(copyBtn); // Append the copy button to the document body
document.body.appendChild(copyText); // Append the copy text to the document body
}
addBlockInitialize = (newBlock) => {
this.newBlock = newBlock;
this.creteNewBlock();
this.skeletonLoader();
}
removeLoader = () => {
clearTimeout(this.loaderRemove);
this.loaderRemove = setTimeout(() => {
if (this.loader) {
this.loader.remove();
}
}, 2000);
}
creteNewBlock = () => {
const newBlock = createBlock(this.newBlock);
this.updateBlockData(newBlock);
}
updateBlockData = async (Block) => {
await dispatch('core/block-editor').insertBlocks([Block]);
setTimeout(() => {
const blockWrp = document.getElementById(`block-${Block.clientId}`);
if (blockWrp) {
blockWrp.appendChild(this.loader);
}
}, 100);
setTimeout(() => {
this.updateBlockContent(Block);
}, 400);
}
updateBlockContent = (Block) => {
const newBlock = document.getElementById(`block-${Block.clientId}`);
if (newBlock) {
this.updateContent(newBlock);
}
return;
}
updateContent = async (ele) => {
const element = ele;
let i = 1;
this.removeLoader();
if (element) {
if (element.contentEditable == 'true' && element.children.length < 2) {
element.innerHTML = 'Make This Content Available for Translation';
} else {
const innerElements = element.getElementsByTagName('*');
for (let innerElement of innerElements) {
if (i === innerElements.length) {
this.removeLoader();
setTimeout(() => {
this.updateBlockFromStore();
}, 500);
}
i++;
if (["SCRIPT", "STYLE", "META", "LINK", "TITLE", "NOSCRIPT", "STYLE", "SCRIPT", "NOSCRIPT", "STYLE", "SCRIPT", "NOSCRIPT", "STYLE", "SCRIPT", "NOSCRIPT"].includes(innerElement.tagName)) {
continue;
}
if (innerElement.childNodes.length > 0) {
innerElement.childNodes.forEach((child) => {
if (child.nodeType === Node.TEXT_NODE) {
this.updateBlockAttr(innerElement, child);
}
});
}
}
}
}
}
updateBlockAttr = (innerElement, child) => {
let blockId = false;
if (innerElement.classList.contains('wp-block')) {
blockId = innerElement.dataset.block;
} else {
const parentBlock = innerElement.closest('.wp-block');
if (parentBlock) {
blockId = parentBlock.dataset.block;
}
}
const blockAttributes = select('core/block-editor').getBlockAttributes(blockId);
let index = 0;
if (!this.updateBlockStore[blockId]) {
let attributes = JSON.parse(JSON.stringify(blockAttributes));
this.updateBlockStore[blockId] = { attributes: attributes };
this.updateBlockStore[blockId].updateBlockData = {};
}
const updateNestedAttributes = async (attributes, child) => {
const updateAttributes = async (key) => {
index++;
if (typeof attributes[key] === 'string' && attributes[key].trim() !== '' && (attributes[key].trim() === child.textContent.trim() || attributes[key] === child.textContent.trim())) {
const originalValue = attributes[key];
const newValue = 'Make This Content Available for Translation ' + index;
this.updateBlockStore[blockId].updateBlockData[newValue.replace(/\s+/g, '-')] = originalValue;
attributes[key] = newValue;
}
};
if (typeof attributes === 'object' && attributes !== null) {
for (const key of Object.keys(attributes)) {
await updateAttributes(key);
if (typeof attributes[key] === 'object' && attributes[key] !== null) {
await updateNestedAttributes(attributes[key], child); // Recursively update nested objects
}
}
}
};
const blockStoreAttributes = this.updateBlockStore[blockId].attributes;
updateNestedAttributes(blockStoreAttributes, child);
}
updateBlockFromStore = () => {
const blockStoreAttributes = this.updateBlockStore;
Object.keys(blockStoreAttributes).forEach((blockId) => {
const blockAttributes = blockStoreAttributes[blockId].attributes;
this.removeLoader();
dispatch('core/block-editor').updateBlockAttributes(blockId, blockAttributes).then(() => {
clearTimeout(this.replaceAttributes);
this.replaceAttributes = setTimeout(() => {
this.removeLoader();
const blockIds = Object.keys(this.updateBlockStore);
this.replaceBlockContent(blockIds[0]);
}, 500);
});
});
}
replaceBlockContent = (blockId) => {
const blockStoreAttributes = this.updateBlockStore;
const checkValidAttributes = (value = false, blockId) => {
const blockElement = document.querySelector(`#block-${blockId}`);
const regex = new RegExp(value, 'g'); // Create regex from the value parameter with global flag
const matchFound = regex.test(blockElement.innerText); // Check if the regex matches
return matchFound; // Return the result of the regex test directly
};
const blockAttributes = blockStoreAttributes[blockId].attributes;
const upateNestedAttributes = async (attributes) => {
const updateAttributes = async (key) => {
if (typeof attributes[key] === 'string' && attributes[key].includes('Make This Content Available for Translation')) {
try {
const keyWithDashes = attributes[key].replace(/\s+/g, '-');
const originalValue = this.updateBlockStore[blockId].updateBlockData[keyWithDashes];
const status = checkValidAttributes(attributes[key], blockId);
if (!status) {
attributes[key] = originalValue;
} else {
attributes[key] = 'Make This Content Available for Translation';
}
} catch (e) {
console.log(`${attributes[key]} is not valid JSON.`);
}
}
};
if (typeof attributes === 'object' && attributes !== null) {
for (const key of Object.keys(attributes)) {
await updateAttributes(key);
if (typeof attributes[key] === 'object' && attributes[key] !== null) {
await upateNestedAttributes(attributes[key]); // Recursively update nested objects
}
}
}
}
upateNestedAttributes(blockAttributes);
setTimeout(() => {
dispatch('core/block-editor').updateBlockAttributes(blockId, blockAttributes).then(() => {
const blockIds = Object.keys(this.updateBlockStore);
if (blockIds.length > 0) {
this.updateBlockId.push(blockId);
dispatch('core/block-editor').selectBlock(null);
this.removeLoader();
const firstBlockId = blockIds.find(id => !this.updateBlockId.includes(id));
if (firstBlockId) {
this.replaceBlockContent(firstBlockId);
}
}
});
}, 500);
}
skeletonLoader = () => {
const loader = document.createElement('div');
const loaderContainer = () => {
const container = '<style>.atfp-loader-wrapper{position:absolute;width:100%;height:100%;top:0;left:0;z-index:99999;}.atfp-loader-container{width:100%;height:100%;}.atfp-loader-skeleton{--skbg:hsl(227deg, 13%, 50%, 0.2);display:grid;gap:20px;width:100%;height:100%;background:#ffffff;padding:15px;border-radius:8px;box-shadow:0 4px 12px rgba(0, 0, 0, 0.1);transition:transform 0.3s ease;transform:scale(1.02);}.atfp-loader-shimmer{display:flex;aspect-ratio:2/1;width:100%;height:100%;background:var(--skbg);border-radius:4px;overflow:hidden;position:relative;}.atfp-loader-shimmer::before{content:"";position:absolute;width:100%;height:100%;background-image:linear-gradient(-90deg,transparent 8%,rgba(255,255,255,0.28) 18%,transparent 33%);background-size:200%;animation:shimerAnimate 1.5s ease-in-out infinite;}@keyframes shimerAnimate{0%{background-position:100% 0;}100%{background-position:-100% 0;}}</style>'
return '<div class="atfp-loader-container">' + container + '<div class="atfp-loader-skeleton"><span class="atfp-loader-shimmer"></span></div></div>';
}
loader.className = 'atfp-loader-wrapper'; // Add the atfp class to the loader
loader.innerHTML = loaderContainer();
this.loader = loader;
}
}
window.addEventListener('load', () => {
const atfpCreateBlockObj = new atfpCreateNewBlock();
atfpCreateBlockObj.copyBtnInitialize();
atfpCreateBlockObj.noticeInitialize();
const urlParams = new URLSearchParams(window.location.search);
let newBlock = '';
if (urlParams.has('atfp_new_block') && '' !== urlParams.get('atfp_new_block').trim()) {
newBlock = urlParams.get('atfp_new_block');
atfpCreateBlockObj.addBlockInitialize(newBlock);
}
});
})();