ayasd
This commit is contained in:
@@ -206,6 +206,15 @@
|
|||||||
|| (component.view && component.view.el && component.view.el.innerHTML)
|
|| (component.view && component.view.el && component.view.el.innerHTML)
|
||||||
|| '';
|
|| '';
|
||||||
content.innerHTML = initialHtml;
|
content.innerHTML = initialHtml;
|
||||||
|
const existingStyle = component && component.get && component.get('style') ? component.get('style') : null;
|
||||||
|
if (existingStyle && typeof existingStyle === 'object') {
|
||||||
|
if (existingStyle.fontFamily) {
|
||||||
|
content.style.fontFamily = existingStyle.fontFamily;
|
||||||
|
}
|
||||||
|
if (existingStyle.fontSize) {
|
||||||
|
content.style.fontSize = existingStyle.fontSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let savedRange = null;
|
let savedRange = null;
|
||||||
const saveSelection = () => {
|
const saveSelection = () => {
|
||||||
@@ -235,29 +244,42 @@
|
|||||||
saveSelection();
|
saveSelection();
|
||||||
} catch {}
|
} catch {}
|
||||||
};
|
};
|
||||||
|
const getSelectionRange = () => {
|
||||||
|
try {
|
||||||
|
const docRef = content.ownerDocument || document;
|
||||||
|
const sel = docRef.getSelection();
|
||||||
|
if (!sel || sel.rangeCount === 0) return null;
|
||||||
|
const range = sel.getRangeAt(0);
|
||||||
|
if (!content.contains(range.commonAncestorContainer)) return null;
|
||||||
|
return range;
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
const applyInlineStyle = (styleProp, value) => {
|
const applyInlineStyle = (styleProp, value) => {
|
||||||
try {
|
try {
|
||||||
content.focus();
|
content.focus();
|
||||||
restoreSelection();
|
restoreSelection();
|
||||||
const docRef = content.ownerDocument || document;
|
const docRef = content.ownerDocument || document;
|
||||||
const sel = docRef.getSelection();
|
const range = getSelectionRange();
|
||||||
if (!sel || sel.rangeCount === 0) return;
|
if (!range || range.collapsed) return;
|
||||||
const range = sel.getRangeAt(0);
|
|
||||||
if (range.collapsed) return;
|
|
||||||
const wrapper = docRef.createElement('span');
|
const wrapper = docRef.createElement('span');
|
||||||
wrapper.style[styleProp] = value;
|
wrapper.style[styleProp] = value;
|
||||||
const fragment = range.extractContents();
|
const fragment = range.extractContents();
|
||||||
wrapper.appendChild(fragment);
|
wrapper.appendChild(fragment);
|
||||||
range.insertNode(wrapper);
|
range.insertNode(wrapper);
|
||||||
|
const sel = docRef.getSelection();
|
||||||
|
if (sel) {
|
||||||
sel.removeAllRanges();
|
sel.removeAllRanges();
|
||||||
const newRange = docRef.createRange();
|
const newRange = docRef.createRange();
|
||||||
newRange.selectNodeContents(wrapper);
|
newRange.selectNodeContents(wrapper);
|
||||||
sel.addRange(newRange);
|
sel.addRange(newRange);
|
||||||
|
}
|
||||||
saveSelection();
|
saveSelection();
|
||||||
} catch {}
|
} catch {}
|
||||||
};
|
};
|
||||||
|
|
||||||
const addButton = (labelHtml, title, cmd, valueGetter) => {
|
const addButton = (labelHtml, title, cmd, valueGetter, handler) => {
|
||||||
const btn = doc.createElement('button');
|
const btn = doc.createElement('button');
|
||||||
btn.type = 'button';
|
btn.type = 'button';
|
||||||
btn.innerHTML = labelHtml;
|
btn.innerHTML = labelHtml;
|
||||||
@@ -273,6 +295,10 @@
|
|||||||
saveSelection();
|
saveSelection();
|
||||||
});
|
});
|
||||||
btn.addEventListener('click', () => {
|
btn.addEventListener('click', () => {
|
||||||
|
if (typeof handler === 'function') {
|
||||||
|
handler();
|
||||||
|
return;
|
||||||
|
}
|
||||||
const value = typeof valueGetter === 'function' ? valueGetter() : valueGetter;
|
const value = typeof valueGetter === 'function' ? valueGetter() : valueGetter;
|
||||||
if (value === null || value === undefined) return;
|
if (value === null || value === undefined) return;
|
||||||
if (cmd === 'createLink' && !value) return;
|
if (cmd === 'createLink' && !value) return;
|
||||||
@@ -307,9 +333,27 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
const icon = (path) => `<svg viewBox="0 0 24 24" width="14" height="14" aria-hidden="true"><path d="${path}" fill="currentColor"/></svg>`;
|
const icon = (path) => `<svg viewBox="0 0 24 24" width="14" height="14" aria-hidden="true"><path d="${path}" fill="currentColor"/></svg>`;
|
||||||
addButton(icon('M6 4h5a3 3 0 0 1 0 6H6V4zm0 8h6a3 3 0 0 1 0 6H6v-6z'), 'Fett', 'bold');
|
addButton(
|
||||||
addButton(icon('M10 4h8v2h-3l-4 12h3v2H6v-2h3l4-12h-3V4z'), 'Kursiv', 'italic');
|
icon('M6 4h5a3 3 0 0 1 0 6H6V4zm0 8h6a3 3 0 0 1 0 6H6v-6z'),
|
||||||
addButton(icon('M5 4h14v2h-6v3h4a4 4 0 0 1 0 8H7v-2h10a2 2 0 0 0 0-4h-4V6H5V4z'), 'Unterstrichen', 'underline');
|
'Fett',
|
||||||
|
'bold',
|
||||||
|
null,
|
||||||
|
() => applyInlineStyle('fontWeight', '700')
|
||||||
|
);
|
||||||
|
addButton(
|
||||||
|
icon('M10 4h8v2h-3l-4 12h3v2H6v-2h3l4-12h-3V4z'),
|
||||||
|
'Kursiv',
|
||||||
|
'italic',
|
||||||
|
null,
|
||||||
|
() => applyInlineStyle('fontStyle', 'italic')
|
||||||
|
);
|
||||||
|
addButton(
|
||||||
|
icon('M5 4h14v2h-6v3h4a4 4 0 0 1 0 8H7v-2h10a2 2 0 0 0 0-4h-4V6H5V4z'),
|
||||||
|
'Unterstrichen',
|
||||||
|
'underline',
|
||||||
|
null,
|
||||||
|
() => applyInlineStyle('textDecoration', 'underline')
|
||||||
|
);
|
||||||
addButton(icon('M4 7h10v2H4zM4 11h16v2H4zM4 15h10v2H4z'), 'Liste (ungeordnet)', 'insertUnorderedList');
|
addButton(icon('M4 7h10v2H4zM4 11h16v2H4zM4 15h10v2H4z'), 'Liste (ungeordnet)', 'insertUnorderedList');
|
||||||
addButton(icon('M4 6h4v2H4V6zm0 4h4v2H4v-2zm0 4h4v2H4v-2zm6-8h10v2H10V6zm0 4h10v2H10v-2zm0 4h10v2H10v-2z'), 'Liste (geordnet)', 'insertOrderedList');
|
addButton(icon('M4 6h4v2H4V6zm0 4h4v2H4v-2zm0 4h4v2H4v-2zm6-8h10v2H10V6zm0 4h10v2H10v-2zm0 4h10v2H10v-2z'), 'Liste (geordnet)', 'insertOrderedList');
|
||||||
addButton(icon('M4 7h10v2H4zM4 11h16v2H4zM4 15h12v2H4z'), 'Linksbundig', 'justifyLeft');
|
addButton(icon('M4 7h10v2H4zM4 11h16v2H4zM4 15h12v2H4z'), 'Linksbundig', 'justifyLeft');
|
||||||
@@ -356,10 +400,15 @@
|
|||||||
} catch {}
|
} catch {}
|
||||||
};
|
};
|
||||||
|
|
||||||
addSelect([{ label: 'Schriftart', value: '' }, ...fontOptions], 'Schriftart', (value) => {
|
const pendingComponentStyle = {};
|
||||||
|
const fontSelect = addSelect([{ label: 'Schriftart', value: '' }, ...fontOptions], 'Schriftart', (value) => {
|
||||||
if (!value) return;
|
if (!value) return;
|
||||||
|
pendingComponentStyle.fontFamily = value;
|
||||||
applyComponentStyle({ fontFamily: value }, { preview: true });
|
applyComponentStyle({ fontFamily: value }, { preview: true });
|
||||||
});
|
});
|
||||||
|
if (existingStyle && existingStyle.fontFamily && fontSelect) {
|
||||||
|
fontSelect.value = existingStyle.fontFamily;
|
||||||
|
}
|
||||||
addSelect([
|
addSelect([
|
||||||
{ label: 'Groesse', value: '' },
|
{ label: 'Groesse', value: '' },
|
||||||
{ label: '10px', value: '10' },
|
{ label: '10px', value: '10' },
|
||||||
@@ -375,10 +424,22 @@
|
|||||||
const raw = prompt('Schriftgroesse in px', '14');
|
const raw = prompt('Schriftgroesse in px', '14');
|
||||||
const num = Number(raw || 0);
|
const num = Number(raw || 0);
|
||||||
if (!Number.isFinite(num) || num <= 0) return;
|
if (!Number.isFinite(num) || num <= 0) return;
|
||||||
|
const range = getSelectionRange();
|
||||||
|
if (range && !range.collapsed) {
|
||||||
applyInlineStyle('fontSize', `${num}px`);
|
applyInlineStyle('fontSize', `${num}px`);
|
||||||
|
} else {
|
||||||
|
pendingComponentStyle.fontSize = `${num}px`;
|
||||||
|
applyComponentStyle({ fontSize: `${num}px` }, { preview: true });
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const range = getSelectionRange();
|
||||||
|
if (range && !range.collapsed) {
|
||||||
applyInlineStyle('fontSize', `${value}px`);
|
applyInlineStyle('fontSize', `${value}px`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pendingComponentStyle.fontSize = `${value}px`;
|
||||||
|
applyComponentStyle({ fontSize: `${value}px` }, { preview: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
// Emoji-Picker entfernt (auf Wunsch) – kann spaeter als echter Picker wiederkommen.
|
// Emoji-Picker entfernt (auf Wunsch) – kann spaeter als echter Picker wiederkommen.
|
||||||
@@ -419,6 +480,9 @@
|
|||||||
component.__bridgeRteLastContent = html;
|
component.__bridgeRteLastContent = html;
|
||||||
logConsoleSnapshot(editor, component, 'before-save');
|
logConsoleSnapshot(editor, component, 'before-save');
|
||||||
const forceApply = () => {
|
const forceApply = () => {
|
||||||
|
if (Object.keys(pendingComponentStyle).length) {
|
||||||
|
applyComponentStyle(pendingComponentStyle);
|
||||||
|
}
|
||||||
applyContentToComponent(editor, component, html);
|
applyContentToComponent(editor, component, html);
|
||||||
logConsoleSnapshot(editor, component, 'after-save');
|
logConsoleSnapshot(editor, component, 'after-save');
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user