Add "Do not translate" functionality to TinyMCE editor
- Add a custom TinyMCE plugin to mark content with `translate="no"`. - Update WYSIWYG editor to support the "Do not translate" toggle button and menu item. - Highlight non-translatable content with custom styles in the editor. - Localize plugin strings for English and Russian.
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
return [
|
||||
'Do not translate' => 'Do not translate',
|
||||
'Mark as not to translate' => 'Mark as not to translate',
|
||||
];
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
return [
|
||||
'Do not translate' => 'Не переводить',
|
||||
'Mark as not to translate' => 'Пометить как не переводить',
|
||||
];
|
||||
@@ -95,14 +95,96 @@
|
||||
xhr.send(formData);
|
||||
});
|
||||
@endif
|
||||
|
||||
tinymce.PluginManager.add('translateNo', (editor) => {
|
||||
const ATTR = 'translate';
|
||||
const VALUE = 'no';
|
||||
|
||||
const isTranslateNo = (node) =>
|
||||
node && node.nodeType === 1 && node.getAttribute(ATTR) === VALUE;
|
||||
|
||||
const toggleTranslateNo = () => {
|
||||
const selectedNode = editor.selection.getNode();
|
||||
|
||||
if (isTranslateNo(selectedNode)) {
|
||||
// Remove translate="no", expand span
|
||||
if (selectedNode.tagName === 'SPAN') {
|
||||
editor.dom.remove(selectedNode, true); // true = сохранить детей
|
||||
} else {
|
||||
editor.dom.setAttrib(selectedNode, ATTR, null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If inside translate="no", remove the mark
|
||||
const wrapper = editor.dom.getParent(selectedNode, `[${ATTR}="${VALUE}"]`);
|
||||
if (wrapper) {
|
||||
if (wrapper.tagName === 'SPAN') {
|
||||
editor.dom.remove(wrapper, true);
|
||||
} else {
|
||||
editor.dom.setAttrib(wrapper, ATTR, null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, wrap the selection
|
||||
editor.formatter.register('translateNo', {
|
||||
inline: 'span',
|
||||
attributes: { [ATTR]: VALUE },
|
||||
remove: 'all'
|
||||
});
|
||||
editor.formatter.apply('translateNo');
|
||||
};
|
||||
|
||||
editor.ui.registry.addToggleButton('translateNo', {
|
||||
icon: 'translate',
|
||||
tooltip: '{{ __('editor.Do not translate') }}',
|
||||
onAction: toggleTranslateNo,
|
||||
onSetup: (api) => {
|
||||
const setActive = () => {
|
||||
const node = editor.selection.getNode();
|
||||
api.setActive(
|
||||
isTranslateNo(node) ||
|
||||
!!editor.dom.getParent(node, `[${ATTR}="${VALUE}"]`)
|
||||
);
|
||||
};
|
||||
editor.on('NodeChange', setActive);
|
||||
return () => editor.off('NodeChange', setActive);
|
||||
}
|
||||
});
|
||||
|
||||
editor.ui.registry.addMenuItem('translateNo', {
|
||||
text: '{{ __('editor.Mark as not to translate') }}',
|
||||
icon: 'translate',
|
||||
onAction: toggleTranslateNo
|
||||
});
|
||||
});
|
||||
|
||||
tinymce.init({
|
||||
content_style: `
|
||||
span[translate="no"] {
|
||||
background: rgba(255, 215, 0, 0.35);
|
||||
outline: 1px dashed #e0a800;
|
||||
position: relative;
|
||||
}
|
||||
span[translate="no"]:hover::before {
|
||||
position: absolute;
|
||||
content: "{{ __('editor.Do not translate') }}";
|
||||
left: 0;
|
||||
bottom: 100%;
|
||||
background: #e0a800;
|
||||
white-space: nowrap;
|
||||
padding: 0.25rem;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
`,
|
||||
selector: '#{{ $tinyId }}',
|
||||
@if(in_array(app()->getLocale(), ['ru'], true))
|
||||
language: '{{ app()->getLocale() }}',
|
||||
@endif
|
||||
license_key: '{{ $tinymceLicenseKey }}',
|
||||
plugins: 'advlist code emoticons link lists table codesample media my-image',
|
||||
toolbar: 'bold italic | bullist numlist | link image emoticons media codesample',
|
||||
plugins: 'advlist code emoticons link lists table codesample media my-image translateNo',
|
||||
toolbar: 'bold italic | bullist numlist | link image emoticons media codesample translateNo',
|
||||
referrer_policy: 'origin',
|
||||
@if($storageUpload !== null)
|
||||
images_upload_handler: imageUpload,
|
||||
|
||||
Reference in New Issue
Block a user