스키마 정의
글꼴 패밀리 마크 타입의 스키마 정의:
{
fontFamily: {
attrs: {
family: { default: 'Arial' }
},
style: 'font-family: ' + node.attrs.family
}, 0]
}
}모델 표현
모델 표현 예제:
{
type: 'text',
text: '고정폭 텍스트',
marks: [{
type: 'fontFamily',
attrs: { family: 'monospace' }
}]
}HTML 직렬화
모델을 HTML로 변환:
function serializeFontFamilyMark(text, mark) {
const family = mark.attrs?.family || 'Arial';
return '<span style="font-family: ' + escapeHtml(family) + '">' +
text + '</span>';
}HTML 역직렬화
HTML을 모델로 파싱:
function extractFontFamilyMark(element) {
if (element.tagName === 'SPAN' && element.style.fontFamily) {
const family = extractFontFamily(element.style.fontFamily);
return {
type: 'fontFamily',
attrs: { family }
};
}
return null;
}
function extractFontFamily(fontFamilyString) {
// font-family 문자열에서 첫 번째 글꼴 추출
// 예: "Arial, sans-serif" -> "Arial"
return fontFamilyString.split(',')[0].trim().replace(/['"]/g, '');
}뷰 연동
뷰 연동 노트: 이 노드 타입을 뷰 레이어에서 구현할 때 contenteditable 동작, 선택 처리, 이벤트 관리에 특히 주의하세요.
뷰 연동 코드:
// 글꼴 패밀리 설정
function setFontFamily(family) {
addMark({
type: 'fontFamily',
attrs: { family }
});
}
// 글꼴 패밀리 선택기
function showFontFamilyPicker() {
const families = ['Arial', 'Times New Roman', 'Courier New', 'monospace'];
// 글꼴 선택기 표시
}일반적인 문제
일반적인 함정: 이 노드 타입을 구현할 때 자주 발생하는 문제들입니다. 구현 전에 주의 깊게 검토하세요.
일반적인 문제 및 해결 방법:
// 문제: 따옴표가 있는 글꼴 패밀리
// 해결: 따옴표가 있는 글꼴 이름 처리
function normalizeFontFamily(family) {
return family.replace(/['"]/g, '');
}
// 문제: 글꼴 폴백 체인
// 해결: 폴백 체인에서 기본 글꼴 추출
function extractPrimaryFont(fontFamily) {
return fontFamily.split(',')[0].trim();
}
// 문제: 웹 안전 글꼴
// 해결: 글꼴 가용성 검증
function validateFontFamily(family) {
const webSafeFonts = [
'Arial', 'Times New Roman', 'Courier New',
'Verdana', 'Georgia', 'Palatino'
];
return webSafeFonts.includes(family) || family === 'monospace';
}구현
완전한 구현 예제:
class FontFamilyMark {
constructor(attrs) {
this.type = 'fontFamily';
this.attrs = { family: attrs?.family || 'Arial' };
}
toDOM() {
return ['span', {
style: 'font-family: ' + this.attrs.family
}, 0];
}
static fromDOM(element) {
if (element.tagName === 'SPAN' && element.style.fontFamily) {
return new FontFamilyMark({
family: extractFontFamily(element.style.fontFamily)
});
}
return null;
}
}