- Editor HTML aggiunto CSS e Script - Statistiche - CRISBalanceBar - Inizio Sync... (ma disattivato)
328 lines
8.9 KiB
TypeScript
Executable File
328 lines
8.9 KiB
TypeScript
Executable File
import { tools } from '@tools';
|
|
import { CTitleBanner } from '../CTitleBanner';
|
|
|
|
import { defineComponent, onMounted, onUnmounted, ref, toRef, watch } from 'vue';
|
|
import { useQuasar } from 'quasar';
|
|
import { useI18n } from 'vue-i18n';
|
|
|
|
export default defineComponent({
|
|
name: 'CMyEditor',
|
|
components: { CTitleBanner },
|
|
props: {
|
|
title: {
|
|
type: String,
|
|
required: false,
|
|
default: '',
|
|
},
|
|
value: {
|
|
type: String,
|
|
required: false,
|
|
default: '',
|
|
},
|
|
myclass: {
|
|
type: String,
|
|
required: false,
|
|
default: '',
|
|
},
|
|
customStyles: {
|
|
type: String,
|
|
required: false,
|
|
default: '',
|
|
},
|
|
showButtons: {
|
|
type: Boolean,
|
|
required: false,
|
|
default: true,
|
|
},
|
|
canModify: {
|
|
type: Boolean,
|
|
required: false,
|
|
default: false,
|
|
},
|
|
hideTools: {
|
|
type: Boolean,
|
|
required: false,
|
|
default: false,
|
|
},
|
|
maxlength: {
|
|
type: Number,
|
|
required: false,
|
|
default: 0,
|
|
},
|
|
startInCodeMode: {
|
|
type: Boolean,
|
|
required: false,
|
|
default: false,
|
|
},
|
|
},
|
|
setup(props, { emit }) {
|
|
const $q = useQuasar();
|
|
const { t } = useI18n();
|
|
|
|
const editorRef = ref(<any>null);
|
|
const editor = ref('');
|
|
const characterCount = ref(0);
|
|
|
|
//const myvalue = toRef(props, 'value')
|
|
const myvalue = ref('');
|
|
const mycolor = ref('');
|
|
|
|
const editorId = ref(
|
|
`editor-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
|
|
);
|
|
const styleElement = ref<HTMLStyleElement | null>(null);
|
|
|
|
// Watch per applicare stili personalizzati
|
|
watch(
|
|
() => props.customStyles,
|
|
(newStyles) => {
|
|
if (newStyles && editorRef.value) {
|
|
applyCustomStyles(newStyles);
|
|
}
|
|
}
|
|
);
|
|
|
|
const myfonts = ref({
|
|
arial: 'Arial',
|
|
arial_black: 'Arial Black',
|
|
AGaramondProRegular: 'AGaramondPro-Regular',
|
|
comic_sans: 'Comic Sans MS',
|
|
courier_new: 'Courier New',
|
|
impact: 'Impact',
|
|
lucida_grande: 'Lucida Grande',
|
|
times_new_roman: 'Times New Roman',
|
|
verdana: 'Verdana',
|
|
});
|
|
|
|
const showtools = ref(false);
|
|
|
|
const toolbarcomp = ref([
|
|
['left', 'center', 'right', 'justify'],
|
|
['bold', 'italic', 'underline', 'strike'],
|
|
['token', 'hr', 'link', 'custom_btn', 'print', 'fullscreen'],
|
|
[
|
|
{
|
|
label: $q.lang.editor.formatting,
|
|
icon: $q.iconSet.editor.formatting,
|
|
list: 'no-icons',
|
|
options: ['p', 'h4', 'h5', 'h6', 'code'],
|
|
},
|
|
{
|
|
label: $q.lang.editor.fontSize,
|
|
icon: $q.iconSet.editor.fontSize,
|
|
fixedLabel: true,
|
|
fixedIcon: true,
|
|
list: 'no-icons',
|
|
options: ['size-1', 'size-2', 'size-3', 'size-4', 'size-5', 'size-6', 'size-7'],
|
|
},
|
|
{
|
|
label: $q.lang.editor.defaultFont,
|
|
icon: $q.iconSet.editor.font,
|
|
fixedIcon: true,
|
|
list: 'no-icons',
|
|
options: [
|
|
'default_font',
|
|
'arial',
|
|
'arial_black',
|
|
'comic_sans',
|
|
'courier_new',
|
|
'impact',
|
|
'lucida_grande',
|
|
'times_new_roman',
|
|
'verdana',
|
|
],
|
|
},
|
|
'removeFormat',
|
|
],
|
|
['quote', 'unordered', 'ordered', 'outdent', 'indent'],
|
|
|
|
['undo', 'redo', 'viewsource'],
|
|
]);
|
|
|
|
watch(
|
|
() => props.value,
|
|
(newval, oldval) => {
|
|
if (props.value === undefined) myvalue.value = '';
|
|
else myvalue.value = props.value;
|
|
}
|
|
);
|
|
|
|
// Funzione per applicare stili custom
|
|
// ALTERNATIVA: Se vuoi applicare gli stili solo al contenuto dell'editor (più sicuro)
|
|
|
|
function applyCustomStyles(styles: string) {
|
|
// console.log('Applying custom styles:', styles);
|
|
|
|
// Rimuovi style precedente
|
|
if (styleElement.value && styleElement.value.parentNode) {
|
|
styleElement.value.parentNode.removeChild(styleElement.value);
|
|
}
|
|
|
|
if (!styles) return;
|
|
|
|
// Crea style element nel HEAD
|
|
styleElement.value = document.createElement('style');
|
|
styleElement.value.setAttribute('type', 'text/css');
|
|
styleElement.value.setAttribute('data-editor-styles', editorId.value);
|
|
|
|
// CSS con selettori super specifici usando l'ID univoco
|
|
const css = `
|
|
[data-editor-id="${editorId.value}"] .q-editor__content {
|
|
${styles}
|
|
}
|
|
|
|
[data-editor-id="${editorId.value}"] .q-editor__content * {
|
|
${styles}
|
|
}
|
|
|
|
/* Selettori per classi custom nel contenuto */
|
|
[data-editor-id="${editorId.value}"] .q-editor__content .prova1 {
|
|
color: red !important;
|
|
}
|
|
`;
|
|
|
|
styleElement.value.textContent = css;
|
|
document.head.appendChild(styleElement.value);
|
|
|
|
// console.log('Style injected:', css);
|
|
}
|
|
function getTextLength(html: string) {
|
|
// Crea un elemento temporaneo per convertire HTML in testo
|
|
const div = document.createElement('div');
|
|
div.innerHTML = html; // Imposta l'HTML
|
|
return div.innerText.length; // Restituisce la lunghezza del testo
|
|
}
|
|
|
|
function changeval(newval: any) {
|
|
// console.log('myEditor: changeval', newval)
|
|
characterCount.value = getTextLength(newval);
|
|
// newval = newval.replace(/ /g, ' ')
|
|
emit('update:value', newval);
|
|
}
|
|
|
|
function annulla() {
|
|
emit('annulla', true);
|
|
}
|
|
|
|
function saveval() {
|
|
// Converti i <b> in <strong>
|
|
myvalue.value = tools.convertinbspInSpazi(myvalue.value);
|
|
|
|
// myvalue.value = tools.convertiTagHTMLPerBOT(myvalue.value)
|
|
|
|
console.log('saveval', myvalue.value);
|
|
emit('showandsave', myvalue.value);
|
|
// emit('update:value', myvalue)
|
|
}
|
|
|
|
function setcolor() {
|
|
document.execCommand('foreColor', false, mycolor.value);
|
|
}
|
|
|
|
/**
|
|
* Capture the <CTL-V> paste event, only allow plain-text, no images.
|
|
*
|
|
* see: https://stackoverflow.com/a/28213320
|
|
*
|
|
* @param {object} evt - array of files
|
|
* @author Daniel Thompson-Yvetot
|
|
* @license MIT
|
|
*/
|
|
function pasteCapture(evt: any) {
|
|
// let text, onPasteStripFormattingIEPaste
|
|
// evt.preventDefault()
|
|
// if (evt.originalEvent && evt.originalEvent.clipboardData.getData) {
|
|
// text = evt.originalEvent.clipboardData.getData('text/plain')
|
|
// $refs.editor_ref.runCmd('insertText', text)
|
|
// }
|
|
// else if (evt.clipboardData && evt.clipboardData.getData) {
|
|
// text = evt.clipboardData.getData('text/plain')
|
|
// $refs.editor_ref.runCmd('insertText', text)
|
|
// }
|
|
// else if (window.clipboardData && window.clipboardData.getData) {
|
|
// if (!onPasteStripFormattingIEPaste) {
|
|
// onPasteStripFormattingIEPaste = true
|
|
// $refs.editor_ref.runCmd('ms-pasteTextOnly', text)
|
|
// }
|
|
// onPasteStripFormattingIEPaste = false
|
|
// }
|
|
}
|
|
|
|
function mounted() {
|
|
if (props.value === undefined) myvalue.value = '';
|
|
else myvalue.value = props.value;
|
|
|
|
showtools.value = tools.getCookie('showtools', '0') === '1';
|
|
|
|
characterCount.value = getTextLength(myvalue.value);
|
|
|
|
if (props.customStyles) {
|
|
setTimeout(() => {
|
|
applyCustomStyles(props.customStyles);
|
|
}, 300);
|
|
}
|
|
|
|
if (props.startInCodeMode) {
|
|
// Attiva modalità codice di default
|
|
setTimeout(() => {
|
|
if (editorRef.value) {
|
|
editorRef.value.runCmd('viewsource');
|
|
}
|
|
}, 100);
|
|
}
|
|
}
|
|
|
|
function onPaste(evt: any) {
|
|
// Let inputs do their thing, so we don't break pasting of links.
|
|
if (evt.target.nodeName === 'INPUT') return;
|
|
let text, onPasteStripFormattingIEPaste;
|
|
evt.preventDefault();
|
|
evt.stopPropagation();
|
|
if (evt.originalEvent && evt.originalEvent.clipboardData.getData) {
|
|
text = evt.originalEvent.clipboardData.getData('text/plain');
|
|
editorRef.value.runCmd('insertText', text);
|
|
} else if (evt.clipboardData && evt.clipboardData.getData) {
|
|
text = evt.clipboardData.getData('text/plain');
|
|
editorRef.value.runCmd('insertText', text);
|
|
}
|
|
/*else if (ClipboardEvent.clipboardData && ClipboardEvent.clipboardData.getData) {
|
|
if (!onPasteStripFormattingIEPaste) {
|
|
onPasteStripFormattingIEPaste = true
|
|
editorRef.value.runCmd('ms-pasteTextOnly', text)
|
|
}
|
|
onPasteStripFormattingIEPaste = false
|
|
}*/
|
|
}
|
|
|
|
onMounted(mounted);
|
|
|
|
// Cleanup quando componente viene distrutto
|
|
onUnmounted(() => {
|
|
if (styleElement.value && styleElement.value.parentNode) {
|
|
styleElement.value.parentNode.removeChild(styleElement.value);
|
|
}
|
|
});
|
|
|
|
return {
|
|
myfonts,
|
|
toolbarcomp,
|
|
editor,
|
|
myvalue,
|
|
mycolor,
|
|
changeval,
|
|
annulla,
|
|
saveval,
|
|
setcolor,
|
|
pasteCapture,
|
|
tools,
|
|
onPaste,
|
|
editorRef,
|
|
showtools,
|
|
characterCount,
|
|
t,
|
|
applyCustomStyles,
|
|
editorId,
|
|
};
|
|
},
|
|
});
|