|
@@ -115,7 +115,16 @@ const listItem: NodeSpec = {
|
|
|
paddingRight: { default: '' },
|
|
paddingRight: { default: '' },
|
|
|
paddingBottom: { default: '' },
|
|
paddingBottom: { default: '' },
|
|
|
paddingLeft: { default: '' },
|
|
paddingLeft: { default: '' },
|
|
|
- whiteSpace: { default: 'normal' }, // 新增 white-space 属性
|
|
|
|
|
|
|
+ whiteSpace: { default: 'normal' },
|
|
|
|
|
+ writingMode: { default: '' },
|
|
|
|
|
+ // 新增字体相关属性
|
|
|
|
|
+ fontWeight: { default: '' },
|
|
|
|
|
+ fontStyle: { default: '' },
|
|
|
|
|
+ textDecoration: { default: '' },
|
|
|
|
|
+ textDecorationLine: { default: '' },
|
|
|
|
|
+ verticalAlign: { default: '' },
|
|
|
|
|
+ letterSpacing: { default: '' },
|
|
|
|
|
+ textShadow: { default: '' },
|
|
|
},
|
|
},
|
|
|
content: 'paragraph block*',
|
|
content: 'paragraph block*',
|
|
|
group: 'block',
|
|
group: 'block',
|
|
@@ -138,7 +147,17 @@ const listItem: NodeSpec = {
|
|
|
const paddingRight = style.paddingRight || '';
|
|
const paddingRight = style.paddingRight || '';
|
|
|
const paddingBottom = style.paddingBottom || '';
|
|
const paddingBottom = style.paddingBottom || '';
|
|
|
const paddingLeft = style.paddingLeft || '';
|
|
const paddingLeft = style.paddingLeft || '';
|
|
|
- const whiteSpace = style.whiteSpace || 'normal'; // 读取 white-space
|
|
|
|
|
|
|
+ const whiteSpace = style.whiteSpace || 'normal';
|
|
|
|
|
+ const writingMode = style.writingMode || '';
|
|
|
|
|
+
|
|
|
|
|
+ // 读取新增属性
|
|
|
|
|
+ const fontWeight = style.fontWeight || '';
|
|
|
|
|
+ const fontStyle = style.fontStyle || '';
|
|
|
|
|
+ const textDecoration = style.textDecoration || '';
|
|
|
|
|
+ const textDecorationLine = style.textDecorationLine || '';
|
|
|
|
|
+ const verticalAlign = style.verticalAlign || '';
|
|
|
|
|
+ const letterSpacing = style.letterSpacing || '';
|
|
|
|
|
+ const textShadow = style.textShadow || '';
|
|
|
|
|
|
|
|
return {
|
|
return {
|
|
|
textAlign,
|
|
textAlign,
|
|
@@ -153,7 +172,15 @@ const listItem: NodeSpec = {
|
|
|
paddingRight,
|
|
paddingRight,
|
|
|
paddingBottom,
|
|
paddingBottom,
|
|
|
paddingLeft,
|
|
paddingLeft,
|
|
|
- whiteSpace, // 返回 whiteSpace
|
|
|
|
|
|
|
+ whiteSpace,
|
|
|
|
|
+ writingMode,
|
|
|
|
|
+ fontWeight,
|
|
|
|
|
+ fontStyle,
|
|
|
|
|
+ textDecoration,
|
|
|
|
|
+ textDecorationLine,
|
|
|
|
|
+ verticalAlign,
|
|
|
|
|
+ letterSpacing,
|
|
|
|
|
+ textShadow,
|
|
|
};
|
|
};
|
|
|
},
|
|
},
|
|
|
},
|
|
},
|
|
@@ -172,7 +199,15 @@ const listItem: NodeSpec = {
|
|
|
paddingRight,
|
|
paddingRight,
|
|
|
paddingBottom,
|
|
paddingBottom,
|
|
|
paddingLeft,
|
|
paddingLeft,
|
|
|
- whiteSpace, // 获取 whiteSpace
|
|
|
|
|
|
|
+ whiteSpace,
|
|
|
|
|
+ writingMode,
|
|
|
|
|
+ fontWeight,
|
|
|
|
|
+ fontStyle,
|
|
|
|
|
+ textDecoration,
|
|
|
|
|
+ textDecorationLine,
|
|
|
|
|
+ verticalAlign,
|
|
|
|
|
+ letterSpacing,
|
|
|
|
|
+ textShadow,
|
|
|
} = node.attrs;
|
|
} = node.attrs;
|
|
|
|
|
|
|
|
let style = '';
|
|
let style = '';
|
|
@@ -189,13 +224,12 @@ const listItem: NodeSpec = {
|
|
|
if (marginTop) style += `margin-top: ${marginTop};`;
|
|
if (marginTop) style += `margin-top: ${marginTop};`;
|
|
|
if (marginBottom) style += `margin-bottom: ${marginBottom};`;
|
|
if (marginBottom) style += `margin-bottom: ${marginBottom};`;
|
|
|
if (marginLeft) {
|
|
if (marginLeft) {
|
|
|
- // 解析数值和单位
|
|
|
|
|
const str = String(marginLeft).trim();
|
|
const str = String(marginLeft).trim();
|
|
|
const match = str.match(/^([+-]?\d*\.?\d+)(px|pt|em|rem|%|vw|vh)?$/i);
|
|
const match = str.match(/^([+-]?\d*\.?\d+)(px|pt|em|rem|%|vw|vh)?$/i);
|
|
|
if (match) {
|
|
if (match) {
|
|
|
let num = parseFloat(match[1]);
|
|
let num = parseFloat(match[1]);
|
|
|
const unit = match[2] || 'px';
|
|
const unit = match[2] || 'px';
|
|
|
- const absNum = Math.abs(num); // 负数转正
|
|
|
|
|
|
|
+ const absNum = Math.abs(num);
|
|
|
const val = absNum + unit;
|
|
const val = absNum + unit;
|
|
|
style += `margin-left: max(min(0px, 100% - ${val}), 0px);`;
|
|
style += `margin-left: max(min(0px, 100% - ${val}), 0px);`;
|
|
|
} else {
|
|
} else {
|
|
@@ -206,35 +240,43 @@ const listItem: NodeSpec = {
|
|
|
if (lineHeight) {
|
|
if (lineHeight) {
|
|
|
let finalValue;
|
|
let finalValue;
|
|
|
const str = String(lineHeight).trim();
|
|
const str = String(lineHeight).trim();
|
|
|
- // 匹配纯数字(整数或小数,可带负号)
|
|
|
|
|
if (/^-?\d+(\.\d+)?$/.test(str)) {
|
|
if (/^-?\d+(\.\d+)?$/.test(str)) {
|
|
|
finalValue = parseFloat(str) * 1.2;
|
|
finalValue = parseFloat(str) * 1.2;
|
|
|
} else {
|
|
} else {
|
|
|
- // 带单位或其他非纯数字内容,直接使用原值
|
|
|
|
|
finalValue = lineHeight;
|
|
finalValue = lineHeight;
|
|
|
}
|
|
}
|
|
|
style += `line-height: ${finalValue};`;
|
|
style += `line-height: ${finalValue};`;
|
|
|
}
|
|
}
|
|
|
|
|
+ else{
|
|
|
|
|
+ style += `line-height: 1.2;`;
|
|
|
|
|
+ }
|
|
|
if (paddingTop) style += `padding-top: ${paddingTop};`;
|
|
if (paddingTop) style += `padding-top: ${paddingTop};`;
|
|
|
if (paddingRight) style += `padding-right: ${paddingRight};`;
|
|
if (paddingRight) style += `padding-right: ${paddingRight};`;
|
|
|
if (paddingBottom) style += `padding-bottom: ${paddingBottom};`;
|
|
if (paddingBottom) style += `padding-bottom: ${paddingBottom};`;
|
|
|
if (paddingLeft) style += `padding-left: ${paddingLeft};`;
|
|
if (paddingLeft) style += `padding-left: ${paddingLeft};`;
|
|
|
if (whiteSpace && whiteSpace !== 'normal') {
|
|
if (whiteSpace && whiteSpace !== 'normal') {
|
|
|
- style += `white-space: ${whiteSpace};`; // 添加 white-space
|
|
|
|
|
|
|
+ style += `white-space: ${whiteSpace};`;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (writingMode) {
|
|
|
|
|
+ style += `writing-mode: ${writingMode};`;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- //const attrs: { style?: string } = {};
|
|
|
|
|
- //if (style) attrs.style = style;
|
|
|
|
|
|
|
+ // 新增字体相关样式输出
|
|
|
|
|
+ if (fontWeight) style += `font-weight: ${fontWeight};`;
|
|
|
|
|
+ if (fontStyle) style += `font-style: ${fontStyle};`;
|
|
|
|
|
+ if (textDecoration) style += `text-decoration: ${textDecoration};`;
|
|
|
|
|
+ if (textDecorationLine) style += `text-decoration-line: ${textDecorationLine};`;
|
|
|
|
|
+ if (verticalAlign) style += `vertical-align: ${verticalAlign};`;
|
|
|
|
|
+ if (letterSpacing) style += `letter-spacing: ${letterSpacing};`;
|
|
|
|
|
+ if (textShadow) style += `text-shadow: ${textShadow};`;
|
|
|
|
|
|
|
|
let isEmpty = false;
|
|
let isEmpty = false;
|
|
|
const firstChild = node.content.firstChild;
|
|
const firstChild = node.content.firstChild;
|
|
|
if (firstChild && firstChild.type.name === 'paragraph') {
|
|
if (firstChild && firstChild.type.name === 'paragraph') {
|
|
|
- // 段落无任何子节点(包括 text 和 inline 节点)
|
|
|
|
|
if (firstChild.content.size === 0) {
|
|
if (firstChild.content.size === 0) {
|
|
|
isEmpty = true;
|
|
isEmpty = true;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- // 如果整个 li 的内容长度为 0 也可以作为判断
|
|
|
|
|
if (node.content.size === 0) isEmpty = true;
|
|
if (node.content.size === 0) isEmpty = true;
|
|
|
|
|
|
|
|
const attrs: { style?: string; class?: string } = {};
|
|
const attrs: { style?: string; class?: string } = {};
|
|
@@ -246,7 +288,7 @@ const listItem: NodeSpec = {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const paragraph: NodeSpec = {
|
|
const paragraph: NodeSpec = {
|
|
|
- whitespace: "pre", // 此属性控制 ProseMirror 内部空格处理,与 CSS white-space 无关,保留不变
|
|
|
|
|
|
|
+ whitespace: "pre",
|
|
|
attrs: {
|
|
attrs: {
|
|
|
textAlign: { default: '' },
|
|
textAlign: { default: '' },
|
|
|
textAlignLast: { default: '' },
|
|
textAlignLast: { default: '' },
|
|
@@ -261,7 +303,16 @@ const paragraph: NodeSpec = {
|
|
|
paddingRight: { default: '' },
|
|
paddingRight: { default: '' },
|
|
|
paddingBottom: { default: '' },
|
|
paddingBottom: { default: '' },
|
|
|
paddingLeft: { default: '' },
|
|
paddingLeft: { default: '' },
|
|
|
- whiteSpace: { default: 'normal' }, // 新增 white-space 属性
|
|
|
|
|
|
|
+ whiteSpace: { default: 'normal' },
|
|
|
|
|
+ writingMode: { default: '' },
|
|
|
|
|
+ // 新增字体相关属性
|
|
|
|
|
+ fontWeight: { default: '' },
|
|
|
|
|
+ fontStyle: { default: '' },
|
|
|
|
|
+ textDecoration: { default: '' },
|
|
|
|
|
+ textDecorationLine: { default: '' },
|
|
|
|
|
+ verticalAlign: { default: '' },
|
|
|
|
|
+ letterSpacing: { default: '' },
|
|
|
|
|
+ textShadow: { default: '' },
|
|
|
},
|
|
},
|
|
|
content: 'inline*',
|
|
content: 'inline*',
|
|
|
group: 'block',
|
|
group: 'block',
|
|
@@ -284,7 +335,17 @@ const paragraph: NodeSpec = {
|
|
|
const paddingRight = style.paddingRight || '';
|
|
const paddingRight = style.paddingRight || '';
|
|
|
const paddingBottom = style.paddingBottom || '';
|
|
const paddingBottom = style.paddingBottom || '';
|
|
|
const paddingLeft = style.paddingLeft || '';
|
|
const paddingLeft = style.paddingLeft || '';
|
|
|
- const whiteSpace = style.whiteSpace || 'normal'; // 读取 white-space
|
|
|
|
|
|
|
+ const whiteSpace = style.whiteSpace || 'normal';
|
|
|
|
|
+ const writingMode = style.writingMode || '';
|
|
|
|
|
+
|
|
|
|
|
+ // 读取新增属性
|
|
|
|
|
+ const fontWeight = style.fontWeight || '';
|
|
|
|
|
+ const fontStyle = style.fontStyle || '';
|
|
|
|
|
+ const textDecoration = style.textDecoration || '';
|
|
|
|
|
+ const textDecorationLine = style.textDecorationLine || '';
|
|
|
|
|
+ const verticalAlign = style.verticalAlign || '';
|
|
|
|
|
+ const letterSpacing = style.letterSpacing || '';
|
|
|
|
|
+ const textShadow = style.textShadow || '';
|
|
|
|
|
|
|
|
return {
|
|
return {
|
|
|
textAlign,
|
|
textAlign,
|
|
@@ -299,7 +360,15 @@ const paragraph: NodeSpec = {
|
|
|
paddingRight,
|
|
paddingRight,
|
|
|
paddingBottom,
|
|
paddingBottom,
|
|
|
paddingLeft,
|
|
paddingLeft,
|
|
|
- whiteSpace, // 返回 whiteSpace
|
|
|
|
|
|
|
+ whiteSpace,
|
|
|
|
|
+ writingMode,
|
|
|
|
|
+ fontWeight,
|
|
|
|
|
+ fontStyle,
|
|
|
|
|
+ textDecoration,
|
|
|
|
|
+ textDecorationLine,
|
|
|
|
|
+ verticalAlign,
|
|
|
|
|
+ letterSpacing,
|
|
|
|
|
+ textShadow,
|
|
|
};
|
|
};
|
|
|
},
|
|
},
|
|
|
},
|
|
},
|
|
@@ -326,7 +395,15 @@ const paragraph: NodeSpec = {
|
|
|
paddingRight,
|
|
paddingRight,
|
|
|
paddingBottom,
|
|
paddingBottom,
|
|
|
paddingLeft,
|
|
paddingLeft,
|
|
|
- whiteSpace, // 获取 whiteSpace
|
|
|
|
|
|
|
+ whiteSpace,
|
|
|
|
|
+ writingMode,
|
|
|
|
|
+ fontWeight,
|
|
|
|
|
+ fontStyle,
|
|
|
|
|
+ textDecoration,
|
|
|
|
|
+ textDecorationLine,
|
|
|
|
|
+ verticalAlign,
|
|
|
|
|
+ letterSpacing,
|
|
|
|
|
+ textShadow,
|
|
|
} = node.attrs;
|
|
} = node.attrs;
|
|
|
|
|
|
|
|
let style = '';
|
|
let style = '';
|
|
@@ -342,60 +419,42 @@ const paragraph: NodeSpec = {
|
|
|
}
|
|
}
|
|
|
if (marginTop) style += `margin-top: ${marginTop};`;
|
|
if (marginTop) style += `margin-top: ${marginTop};`;
|
|
|
if (marginBottom) style += `margin-bottom: ${marginBottom};`;
|
|
if (marginBottom) style += `margin-bottom: ${marginBottom};`;
|
|
|
- /*
|
|
|
|
|
- if (marginLeft) {
|
|
|
|
|
- // 解析数值和单位
|
|
|
|
|
- const str = String(marginLeft).trim();
|
|
|
|
|
- const match = str.match(/^([+-]?\d*\.?\d+)(px|pt|em|rem|%|vw|vh)?$/i);
|
|
|
|
|
- if (match) {
|
|
|
|
|
- let num = parseFloat(match[1]);
|
|
|
|
|
- const unit = match[2] || 'px';
|
|
|
|
|
- const absNum = Math.abs(num); // 负数转正
|
|
|
|
|
- const val = absNum + unit;
|
|
|
|
|
- style += `margin-left: max(min(0px, 100% - ${val}), 0px);`;
|
|
|
|
|
- } else {
|
|
|
|
|
- style += `margin-left: ${marginLeft};`;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- */
|
|
|
|
|
if (marginLeft) style += `margin-left: ${marginLeft};`;
|
|
if (marginLeft) style += `margin-left: ${marginLeft};`;
|
|
|
if (marginRight) style += `margin-right: ${marginRight};`;
|
|
if (marginRight) style += `margin-right: ${marginRight};`;
|
|
|
if (lineHeight) {
|
|
if (lineHeight) {
|
|
|
let finalValue;
|
|
let finalValue;
|
|
|
const str = String(lineHeight).trim();
|
|
const str = String(lineHeight).trim();
|
|
|
- // 匹配纯数字(整数或小数,可带负号)
|
|
|
|
|
if (/^-?\d+(\.\d+)?$/.test(str)) {
|
|
if (/^-?\d+(\.\d+)?$/.test(str)) {
|
|
|
finalValue = parseFloat(str) * 1.2;
|
|
finalValue = parseFloat(str) * 1.2;
|
|
|
} else {
|
|
} else {
|
|
|
- // 带单位或其他非纯数字内容,直接使用原值
|
|
|
|
|
finalValue = lineHeight;
|
|
finalValue = lineHeight;
|
|
|
}
|
|
}
|
|
|
style += `line-height: ${finalValue};`;
|
|
style += `line-height: ${finalValue};`;
|
|
|
}
|
|
}
|
|
|
|
|
+ else{
|
|
|
|
|
+ style += `line-height: 1.2;`;
|
|
|
|
|
+ }
|
|
|
if (paddingTop) style += `padding-top: ${paddingTop};`;
|
|
if (paddingTop) style += `padding-top: ${paddingTop};`;
|
|
|
if (paddingRight) style += `padding-right: ${paddingRight};`;
|
|
if (paddingRight) style += `padding-right: ${paddingRight};`;
|
|
|
if (paddingBottom) style += `padding-bottom: ${paddingBottom};`;
|
|
if (paddingBottom) style += `padding-bottom: ${paddingBottom};`;
|
|
|
if (paddingLeft) style += `padding-left: ${paddingLeft};`;
|
|
if (paddingLeft) style += `padding-left: ${paddingLeft};`;
|
|
|
if (whiteSpace && whiteSpace !== 'normal') {
|
|
if (whiteSpace && whiteSpace !== 'normal') {
|
|
|
- style += `white-space: ${whiteSpace};`; // 添加 white-space
|
|
|
|
|
|
|
+ style += `white-space: ${whiteSpace};`;
|
|
|
}
|
|
}
|
|
|
|
|
+ if (writingMode) {
|
|
|
|
|
+ style += `writing-mode: ${writingMode};`;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 新增字体相关样式输出
|
|
|
|
|
+ if (fontWeight) style += `font-weight: ${fontWeight};`;
|
|
|
|
|
+ if (fontStyle) style += `font-style: ${fontStyle};`;
|
|
|
|
|
+ if (textDecoration) style += `text-decoration: ${textDecoration};`;
|
|
|
|
|
+ if (textDecorationLine) style += `text-decoration-line: ${textDecorationLine};`;
|
|
|
|
|
+ if (verticalAlign) style += `vertical-align: ${verticalAlign};`;
|
|
|
|
|
+ if (letterSpacing) style += `letter-spacing: ${letterSpacing};`;
|
|
|
|
|
+ if (textShadow) style += `text-shadow: ${textShadow};`;
|
|
|
|
|
|
|
|
const attrs: { style?: string; class?: string } = {};
|
|
const attrs: { style?: string; class?: string } = {};
|
|
|
-/*
|
|
|
|
|
- let isEmpty = false;
|
|
|
|
|
- const firstChild = node.content.firstChild;
|
|
|
|
|
- if (firstChild) {
|
|
|
|
|
- // 段落无任何子节点(包括 text 和 inline 节点)
|
|
|
|
|
- if (firstChild.content.size === 0) {
|
|
|
|
|
- isEmpty = true;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 如果整个 li 的内容长度为 0 也可以作为判断
|
|
|
|
|
- if (node.content.size === 0) isEmpty = true;
|
|
|
|
|
- if (style) attrs.style = style;
|
|
|
|
|
- //if (isEmpty) attrs.class = 'empty';
|
|
|
|
|
-*/
|
|
|
|
|
if (style) attrs.style = style;
|
|
if (style) attrs.style = style;
|
|
|
return ['p', attrs, 0];
|
|
return ['p', attrs, 0];
|
|
|
},
|
|
},
|