|
@@ -836,7 +836,7 @@ export default {
|
|
|
const altMatch = attrs.match(/alt=["']([^"']*)["']/i);
|
|
const altMatch = attrs.match(/alt=["']([^"']*)["']/i);
|
|
|
const widthMatch = attrs.match(/width=["']?(\d+)["']?/i);
|
|
const widthMatch = attrs.match(/width=["']?(\d+)["']?/i);
|
|
|
const heightMatch = attrs.match(/height=["']?(\d+)["']?/i);
|
|
const heightMatch = attrs.match(/height=["']?(\d+)["']?/i);
|
|
|
- const styleMatch = attrs.match(/style=["']([^"']*)["']/i);
|
|
|
|
|
|
|
+ const styleValue = this.extractStyleAttr(attrs);
|
|
|
|
|
|
|
|
const containerStyleObj = {};
|
|
const containerStyleObj = {};
|
|
|
tagStack.forEach((tagItem) => {
|
|
tagStack.forEach((tagItem) => {
|
|
@@ -846,8 +846,8 @@ export default {
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
const imageStyleObj = {};
|
|
const imageStyleObj = {};
|
|
|
- if (styleMatch) {
|
|
|
|
|
- this.mergeStyleString(imageStyleObj, styleMatch[1]);
|
|
|
|
|
|
|
+ if (styleValue) {
|
|
|
|
|
+ this.mergeStyleString(imageStyleObj, styleValue);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
return {
|
|
@@ -974,8 +974,8 @@ export default {
|
|
|
const baseStyle = {};
|
|
const baseStyle = {};
|
|
|
baseStyle['font-size'] = styles ? styles.fontSize : '16px';
|
|
baseStyle['font-size'] = styles ? styles.fontSize : '16px';
|
|
|
baseStyle['--input-font-family'] = styles ? styles.fontFamily : '';
|
|
baseStyle['--input-font-family'] = styles ? styles.fontFamily : '';
|
|
|
- baseStyle['width'] = Math.max(40, words.value.length * 21.3) + 'px';
|
|
|
|
|
- baseStyle['height'] = styles && styles.fontSize ? styles.fontSize.replace('pt', '') * 1.5 + 'pt' : '24px';
|
|
|
|
|
|
|
+ baseStyle['width'] = `${Math.max(40, words.value.length * 21.3)}px`;
|
|
|
|
|
+ baseStyle['height'] = styles && styles.fontSize ? `${styles.fontSize.replace('pt', '') * 1.5}pt` : '24px';
|
|
|
|
|
|
|
|
return baseStyle;
|
|
return baseStyle;
|
|
|
},
|
|
},
|
|
@@ -987,10 +987,23 @@ export default {
|
|
|
}
|
|
}
|
|
|
return 'center';
|
|
return 'center';
|
|
|
},
|
|
},
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 提取标签属性中的 style 值。
|
|
|
|
|
+ * style 的属性值内部可能包含与包裹引号不同的引号(如 style="font-family: 'times new roman'"),
|
|
|
|
|
+ * 必须按包裹引号成对匹配,否则会在内层引号处提前截断,导致字体等样式丢失。
|
|
|
|
|
+ * @param {String} attrs 标签的属性字符串(不含标签名)
|
|
|
|
|
+ * @returns {String} style 属性值,未匹配到时返回空字符串
|
|
|
|
|
+ */
|
|
|
|
|
+ extractStyleAttr(attrs = '') {
|
|
|
|
|
+ const styleMatch = String(attrs).match(/\bstyle\s*=\s*(?:"([^"]*)"|'([^']*)')/i);
|
|
|
|
|
+ if (!styleMatch) return '';
|
|
|
|
|
+ const [, doubleQuotedStyle, singleQuotedStyle] = styleMatch;
|
|
|
|
|
+ if (doubleQuotedStyle === undefined) return singleQuotedStyle || '';
|
|
|
|
|
+ return doubleQuotedStyle;
|
|
|
|
|
+ },
|
|
|
// 提取标签信息(样式和类名)
|
|
// 提取标签信息(样式和类名)
|
|
|
extractTagInfo(attrs, tagName) {
|
|
extractTagInfo(attrs, tagName) {
|
|
|
- const styleMatch = attrs.match(/style=["']([^"']*)["']/);
|
|
|
|
|
- let style = styleMatch ? styleMatch[1] : null;
|
|
|
|
|
|
|
+ let style = this.extractStyleAttr(attrs) || null;
|
|
|
|
|
|
|
|
const classMatch = attrs.match(/class=["']([^"']*)["']/);
|
|
const classMatch = attrs.match(/class=["']([^"']*)["']/);
|
|
|
const className = classMatch ? classMatch[1] : '';
|
|
const className = classMatch ? classMatch[1] : '';
|
|
@@ -1033,7 +1046,7 @@ export default {
|
|
|
const posterMatch = attrs.match(/poster=["']([^"']*)["']/i);
|
|
const posterMatch = attrs.match(/poster=["']([^"']*)["']/i);
|
|
|
const widthMatch = attrs.match(/width=["']?(\d+)["']?/i);
|
|
const widthMatch = attrs.match(/width=["']?(\d+)["']?/i);
|
|
|
const heightMatch = attrs.match(/height=["']?(\d+)["']?/i);
|
|
const heightMatch = attrs.match(/height=["']?(\d+)["']?/i);
|
|
|
- const styleMatch = attrs.match(/style=["']([^"']*)["']/i);
|
|
|
|
|
|
|
+ const styleValue = this.extractStyleAttr(attrs);
|
|
|
|
|
|
|
|
// 直接从完整的文本中匹配 source
|
|
// 直接从完整的文本中匹配 source
|
|
|
const sourceMatch = item.text.match(/<source\s+([^>]*)\/?\s*>/i);
|
|
const sourceMatch = item.text.match(/<source\s+([^>]*)\/?\s*>/i);
|
|
@@ -1057,8 +1070,8 @@ export default {
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
const mediaStyleObj = {};
|
|
const mediaStyleObj = {};
|
|
|
- if (styleMatch) {
|
|
|
|
|
- this.mergeStyleString(mediaStyleObj, styleMatch[1]);
|
|
|
|
|
|
|
+ if (styleValue) {
|
|
|
|
|
+ this.mergeStyleString(mediaStyleObj, styleValue);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
return {
|
|
@@ -1080,7 +1093,7 @@ export default {
|
|
|
|
|
|
|
|
const attrs = audioMatch[1];
|
|
const attrs = audioMatch[1];
|
|
|
const srcMatch = attrs.match(/src=["']([^"']*)["']/i);
|
|
const srcMatch = attrs.match(/src=["']([^"']*)["']/i);
|
|
|
- const styleMatch = attrs.match(/style=["']([^"']*)["']/i);
|
|
|
|
|
|
|
+ const styleValue = this.extractStyleAttr(attrs);
|
|
|
|
|
|
|
|
const containerStyleObj = {};
|
|
const containerStyleObj = {};
|
|
|
tagStack.forEach((tagItem) => {
|
|
tagStack.forEach((tagItem) => {
|
|
@@ -1090,8 +1103,8 @@ export default {
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
const mediaStyleObj = {};
|
|
const mediaStyleObj = {};
|
|
|
- if (styleMatch) {
|
|
|
|
|
- this.mergeStyleString(mediaStyleObj, styleMatch[1]);
|
|
|
|
|
|
|
+ if (styleValue) {
|
|
|
|
|
+ this.mergeStyleString(mediaStyleObj, styleValue);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
return {
|