diff --git a/public/components/panels/settings/lib/customJavascript/component.js b/public/components/panels/settings/lib/customJavascript/component.js index 0a80c5cc2e..0deef700e5 100644 --- a/public/components/panels/settings/lib/customJavascript/component.js +++ b/public/components/panels/settings/lib/customJavascript/component.js @@ -3,6 +3,8 @@ import ScriptControl from './control' import HtmlEditor from './htmlEditor' import { getStorage, getService } from 'vc-cake' import Tooltip from '../../../../tooltip/tooltip' +import store from 'public/editor/stores/store' +import { notificationAdded } from 'public/editor/stores/notifications/slice' const dataManager = getService('dataManager') const roleManager = getService('roleManager') @@ -60,6 +62,15 @@ export default class CustomJavascript extends React.Component { } updateSettings (key, value) { + const regex = /document\.write\s*\(/ + if (regex.test(value)) { + store.dispatch(notificationAdded({ + text: CustomJavascript.localizations.documentWriteWarning, + html: true, + time: 15000 + })) + return false + } settingsStorage.state(key).set(value) this.setState({ [key]: value }) } diff --git a/public/components/wpVcSettings/dashboard.js b/public/components/wpVcSettings/dashboard.js index 8c7393c722..b95cad3e2a 100644 --- a/public/components/wpVcSettings/dashboard.js +++ b/public/components/wpVcSettings/dashboard.js @@ -8,6 +8,7 @@ window.ResizeSensor = ResizeSensorModule const dataManager = getService('dataManager') const localizations = dataManager.get('localizations') const unsavedChangesText = localizations && localizations.unsavedChangesText ? localizations.unsavedChangesText : 'Changes may not be saved.' +const documentWriteWarning = localizations && localizations.documentWriteWarningSettings ? localizations.documentWriteWarningSettings : 'Avoiding using document.write as per MDN documentation. This may result in editor not working properly.' export const dashboard = () => { const dashboardContainer = document.querySelector('.vcv-settings') @@ -108,6 +109,12 @@ export const dashboard = () => { } const submitButtonContainer = e.target.querySelector('.vcv-submit-button-container') const submitButton = e.target.querySelector('.vcv-dashboard-button--save') + if (submitButton.id === 'submit_btn-vcv-global-css-js') { + const isValid = isValidEditorsValue() + if (!isValid) { + alert(documentWriteWarning) + } + } // this will get all form fields and encode it as a string const data = Array.from( new window.FormData(e.target), @@ -156,6 +163,15 @@ export const dashboard = () => { window.jQuery(dataCollectionTableWrapper).slideToggle() } + const isValidEditorsValue = () => { + const regex = /document\.write\s*\(/ + const headerEditorValue = window.vcvGlobalJsHeadEditor.getValue().trim() + const footerEditorValue = window.vcvGlobalJsFooterEditor.getValue().trim() + const isValidHeadeEditor = headerEditorValue ? !regex.test(headerEditorValue) : true + const isValidFooterEditor = footerEditorValue ? !regex.test(footerEditorValue) : true + return isValidFooterEditor && isValidHeadeEditor + } + if (dataCollectionTableWrapper) { if (urlHash.indexOf(dataCollectionTableWrapper.id) !== -1) { dataCollectionTableWrapper.style.display = 'block' diff --git a/public/components/wpVcSettings/editors.js b/public/components/wpVcSettings/editors.js index 5ef6e7d39a..c742f649c3 100644 --- a/public/components/wpVcSettings/editors.js +++ b/public/components/wpVcSettings/editors.js @@ -50,16 +50,16 @@ export const initEditors = () => { */ const globalJsHead = document.querySelector('#vcv-settingsGlobalJsHead') if (globalJsHead !== null) { - const globalJsHeadEditor = codeEditor.getEditor(globalJsHead, 'text/html', globalJsHead.value) - globalJsHeadEditor.on('change', async () => { + window.vcvGlobalJsHeadEditor = codeEditor.getEditor(globalJsHead, 'text/html', globalJsHead.value) + window.vcvGlobalJsHeadEditor.on('change', async () => { setStatus('ready') }) } const globalJsFooter = document.querySelector('#vcv-settingsGlobalJsFooter') if (globalJsFooter !== null) { - const globalJsFooterEditor = codeEditor.getEditor(globalJsFooter, 'text/html', globalJsFooter.value) - globalJsFooterEditor.on('change', async () => { + window.vcvGlobalJsFooterEditor = codeEditor.getEditor(globalJsFooter, 'text/html', globalJsFooter.value) + window.vcvGlobalJsFooterEditor.on('change', async () => { setStatus('ready') }) } diff --git a/visualcomposer/Helpers/Localizations.php b/visualcomposer/Helpers/Localizations.php index 5d6b8b7c93..0ef90e501d 100644 --- a/visualcomposer/Helpers/Localizations.php +++ b/visualcomposer/Helpers/Localizations.php @@ -2291,6 +2291,14 @@ public function getLocalizations() 'Logo is not set. Please set a logo.', 'visualcomposer' ), + 'documentWriteWarning' => __( + 'Warning: Custom JavaScript won\'t be saved. Avoid using document.write() as it can break the editor. Please refer to the MDN documentation for more info.', + 'visualcomposer' + ), + 'documentWriteWarningSettings' => __( + 'Avoiding using document.write as per MDN documentation. This may result in editor not working properly.', + 'visualcomposer' + ), ]; return vcfilter('vcv:helpers:localizations:i18n', $locale);