'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 "Copy Text" 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 = '' return '
' + container + '
'; } 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); } }); })();