|
|
@@ -96,7 +96,12 @@
|
|
|
</span>
|
|
|
</span>
|
|
|
<template v-else-if="word.type === 'input'">
|
|
|
- <span v-if="data.property.pinyin_position === 'top'" class="pinyin"> </span>
|
|
|
+ <span
|
|
|
+ v-if="data.property.pinyin_position === 'top'"
|
|
|
+ class="pinyin"
|
|
|
+ :style="getPinyinStyle(word)"
|
|
|
+ > </span
|
|
|
+ >
|
|
|
<template v-if="data.property.fill_type === fillTypeList[0].value">
|
|
|
<el-input
|
|
|
:key="index"
|
|
|
@@ -153,7 +158,12 @@
|
|
|
@handleWav="handleMiniWav($event, word)"
|
|
|
/>
|
|
|
</template>
|
|
|
- <span v-if="data.property.pinyin_position === 'bottom'" class="pinyin"> </span>
|
|
|
+ <span
|
|
|
+ v-if="data.property.pinyin_position === 'bottom'"
|
|
|
+ class="pinyin"
|
|
|
+ :style="getPinyinStyle(word)"
|
|
|
+ > </span
|
|
|
+ >
|
|
|
</template>
|
|
|
</span>
|
|
|
</span>
|
|
|
@@ -222,86 +232,239 @@
|
|
|
</template>
|
|
|
</template>
|
|
|
<template v-else>
|
|
|
- <div v-for="(item, index) in col.model_essay" :key="index" :style="[tdStyle]">
|
|
|
- <span
|
|
|
- v-if="item.type === 'text'"
|
|
|
+ <template v-if="col.rich_text_list && col.rich_text_list.length !== 0">
|
|
|
+ <div
|
|
|
+ v-for="(item, index) in col.rich_text_list"
|
|
|
:key="index"
|
|
|
- :style="{
|
|
|
- fontSize:
|
|
|
- data.unified_attrib && data.unified_attrib.font_size ? data.unified_attrib.font_size : '',
|
|
|
- fontFamily: data.unified_attrib && data.unified_attrib.font ? data.unified_attrib.font : '',
|
|
|
- }"
|
|
|
- v-html="convertText(sanitizeHTML(item.value))"
|
|
|
- ></span>
|
|
|
- <template v-if="item.type === 'input'">
|
|
|
- <template v-if="data.property.fill_type === fillTypeList[0].value">
|
|
|
- <el-input
|
|
|
- :key="index"
|
|
|
- v-model="item.value"
|
|
|
- :disabled="disabled"
|
|
|
- :class="[...computedAnswerClass(item, i, j)]"
|
|
|
- :style="[
|
|
|
- {
|
|
|
- width: Math.max(40, item.value.length * 21.3) + 'px',
|
|
|
- fontSize:
|
|
|
- data.unified_attrib && data.unified_attrib.font_size
|
|
|
- ? data.unified_attrib.font_size
|
|
|
- : '',
|
|
|
- fontFamily:
|
|
|
- data.unified_attrib && data.unified_attrib.font ? data.unified_attrib.font : '',
|
|
|
- },
|
|
|
- ]"
|
|
|
- />
|
|
|
- </template>
|
|
|
- <template v-else-if="data.property.fill_type === fillTypeList[1].value">
|
|
|
- <el-popover :key="index" placement="top" trigger="click">
|
|
|
- <div class="word-list">
|
|
|
+ class="pinyin-text pinyin-text-sentence"
|
|
|
+ :class="[
|
|
|
+ index === 0 ? 'pinyin-text-left' : '',
|
|
|
+ item.type === 'audio' ? 'pinyin-text-audio' : '',
|
|
|
+ ]"
|
|
|
+ >
|
|
|
+ <!-- 文字块:包含 word_list -->
|
|
|
+ <span
|
|
|
+ v-if="item.type === 'text'"
|
|
|
+ :key="'text-' + index"
|
|
|
+ class="pinyin-sentence"
|
|
|
+ :style="[
|
|
|
+ { 'align-items': data.property.pinyin_position === 'top' ? 'flex-end' : 'flex-start' },
|
|
|
+ ]"
|
|
|
+ >
|
|
|
+ <span
|
|
|
+ v-for="(word, wIndex) in item.word_list"
|
|
|
+ :key="wIndex"
|
|
|
+ class="pinyin-text"
|
|
|
+ :style="item.styleObj"
|
|
|
+ >
|
|
|
+ <span v-if="word.type === 'text'">
|
|
|
<span
|
|
|
- v-for="{ content, mark } in data.word_list"
|
|
|
- :key="mark"
|
|
|
- class="word-item"
|
|
|
- @click="handleSelectWord(content, mark, item)"
|
|
|
+ :style="{
|
|
|
+ flexDirection:
|
|
|
+ data.property.pinyin_position === 'top' ? 'column' : 'column-reverse',
|
|
|
+ 'align-items': getWordAlignItems(word, item),
|
|
|
+ }"
|
|
|
>
|
|
|
- {{ convertText(content) }}
|
|
|
+ <span class="py-char" :style="getCharStyle(word, item)">{{
|
|
|
+ convertText(word.text)
|
|
|
+ }}</span>
|
|
|
</span>
|
|
|
- </div>
|
|
|
+ </span>
|
|
|
+ <template v-else-if="word.type === 'input'">
|
|
|
+ <template v-if="data.property.fill_type === fillTypeList[0].value">
|
|
|
+ <el-input
|
|
|
+ :key="index"
|
|
|
+ v-model="word.value"
|
|
|
+ :disabled="disabled"
|
|
|
+ :class="[...computedAnswerClass(word, i, j)]"
|
|
|
+ :style="getInputStyle(item.styleObj, word)"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ <template v-else-if="data.property.fill_type === fillTypeList[1].value">
|
|
|
+ <el-popover :key="index" placement="top" trigger="click">
|
|
|
+ <div class="word-list">
|
|
|
+ <span
|
|
|
+ v-for="{ content, mark } in data.word_list"
|
|
|
+ :key="mark"
|
|
|
+ class="word-item"
|
|
|
+ @click="handleSelectWord(content, mark, word)"
|
|
|
+ >
|
|
|
+ {{ convertText(content) }}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <el-input
|
|
|
+ slot="reference"
|
|
|
+ v-model="word.value"
|
|
|
+ :readonly="true"
|
|
|
+ :class="[...computedAnswerClass(word, i, j)]"
|
|
|
+ :style="getInputStyle(item.styleObj, word)"
|
|
|
+ />
|
|
|
+ </el-popover>
|
|
|
+ </template>
|
|
|
|
|
|
+ <template v-else-if="data.property.fill_type === fillTypeList[2].value">
|
|
|
+ <span :key="j" class="write-click" @click="handleWriteClick(word)">
|
|
|
+ <img
|
|
|
+ v-show="word.write_base64"
|
|
|
+ style="background-color: #f4f4f4"
|
|
|
+ :src="word.write_base64"
|
|
|
+ alt="write-show"
|
|
|
+ />
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template v-else-if="data.property.fill_type === fillTypeList[3].value">
|
|
|
+ <SoundRecordBox
|
|
|
+ ref="record"
|
|
|
+ :key="j"
|
|
|
+ type="mini"
|
|
|
+ :many-times="false"
|
|
|
+ class="record-box"
|
|
|
+ :answer-record-list="data.audio_answer_list"
|
|
|
+ :task-model="isJudgingRightWrong ? 'ANSWER' : ''"
|
|
|
+ :attrib="data.unified_attrib"
|
|
|
+ @handleWav="handleMiniWav($event, word)"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ </span>
|
|
|
+ </span>
|
|
|
+ <!-- 图片块 -->
|
|
|
+ <div
|
|
|
+ v-else-if="item.type === 'image'"
|
|
|
+ :key="'image-' + index"
|
|
|
+ :style="item.containerStyle"
|
|
|
+ class="image-container"
|
|
|
+ >
|
|
|
+ <img
|
|
|
+ :src="item.src"
|
|
|
+ :alt="item.alt"
|
|
|
+ :width="item.width"
|
|
|
+ :height="item.height"
|
|
|
+ :style="item.imageStyle"
|
|
|
+ class="inline-image"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <!-- 视频块 -->
|
|
|
+ <div
|
|
|
+ v-else-if="item.type === 'video'"
|
|
|
+ :key="'video-' + index"
|
|
|
+ :style="item.containerStyle"
|
|
|
+ class="video-container"
|
|
|
+ >
|
|
|
+ <video
|
|
|
+ :poster="item.poster"
|
|
|
+ :width="item.width"
|
|
|
+ :height="item.height"
|
|
|
+ :style="item.mediaStyle"
|
|
|
+ controls
|
|
|
+ class="inline-video"
|
|
|
+ >
|
|
|
+ <source :src="item.src" :type="item.videoType" />
|
|
|
+ 您的浏览器不支持视频播放
|
|
|
+ </video>
|
|
|
+ </div>
|
|
|
+ <!-- 音频块 -->
|
|
|
+ <div
|
|
|
+ v-else-if="item.type === 'audio'"
|
|
|
+ :key="'audio-' + index"
|
|
|
+ :style="item.containerStyle"
|
|
|
+ class="audio-container"
|
|
|
+ >
|
|
|
+ <audio :src="item.src" :style="item.mediaStyle" controls class="inline-audio">
|
|
|
+ 您的浏览器不支持音频播放
|
|
|
+ </audio>
|
|
|
+ </div>
|
|
|
+ <!-- 换行符 -->
|
|
|
+ <br v-else-if="item.type === 'newline'" :key="'newline-' + index" />
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <div v-for="(item, index) in col.model_essay" :key="index" :style="[tdStyle]">
|
|
|
+ <span
|
|
|
+ v-if="item.type === 'text'"
|
|
|
+ :key="index"
|
|
|
+ :style="{
|
|
|
+ fontSize:
|
|
|
+ data.unified_attrib && data.unified_attrib.font_size
|
|
|
+ ? data.unified_attrib.font_size
|
|
|
+ : '',
|
|
|
+ fontFamily:
|
|
|
+ data.unified_attrib && data.unified_attrib.font ? data.unified_attrib.font : '',
|
|
|
+ }"
|
|
|
+ v-html="convertText(sanitizeHTML(item.value))"
|
|
|
+ ></span>
|
|
|
+ <template v-if="item.type === 'input'">
|
|
|
+ <template v-if="data.property.fill_type === fillTypeList[0].value">
|
|
|
<el-input
|
|
|
- slot="reference"
|
|
|
+ :key="index"
|
|
|
v-model="item.value"
|
|
|
- :readonly="true"
|
|
|
+ :disabled="disabled"
|
|
|
:class="[...computedAnswerClass(item, i, j)]"
|
|
|
- :style="[{ width: Math.max(40, item.value.length * 21.3) + 'px' }]"
|
|
|
+ :style="[
|
|
|
+ {
|
|
|
+ width: Math.max(40, item.value.length * 21.3) + 'px',
|
|
|
+ fontSize:
|
|
|
+ data.unified_attrib && data.unified_attrib.font_size
|
|
|
+ ? data.unified_attrib.font_size
|
|
|
+ : '',
|
|
|
+ fontFamily:
|
|
|
+ data.unified_attrib && data.unified_attrib.font ? data.unified_attrib.font : '',
|
|
|
+ },
|
|
|
+ ]"
|
|
|
/>
|
|
|
- </el-popover>
|
|
|
- </template>
|
|
|
-
|
|
|
- <template v-else-if="data.property.fill_type === fillTypeList[2].value">
|
|
|
- <span :key="j" class="write-click" @click="handleWriteClick(item)">
|
|
|
- <img
|
|
|
- v-show="item.write_base64"
|
|
|
- style="background-color: #f4f4f4"
|
|
|
- :src="item.write_base64"
|
|
|
- alt="write-show"
|
|
|
+ </template>
|
|
|
+ <template v-else-if="data.property.fill_type === fillTypeList[1].value">
|
|
|
+ <el-popover :key="index" placement="top" trigger="click">
|
|
|
+ <div class="word-list">
|
|
|
+ <span
|
|
|
+ v-for="{ content, mark } in data.word_list"
|
|
|
+ :key="mark"
|
|
|
+ class="word-item"
|
|
|
+ @click="handleSelectWord(content, mark, item)"
|
|
|
+ >
|
|
|
+ {{ convertText(content) }}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <el-input
|
|
|
+ slot="reference"
|
|
|
+ v-model="item.value"
|
|
|
+ :readonly="true"
|
|
|
+ :class="[...computedAnswerClass(item, i, j)]"
|
|
|
+ :style="[{ width: Math.max(40, item.value.length * 21.3) + 'px' }]"
|
|
|
+ />
|
|
|
+ </el-popover>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template v-else-if="data.property.fill_type === fillTypeList[2].value">
|
|
|
+ <span :key="j" class="write-click" @click="handleWriteClick(item)">
|
|
|
+ <img
|
|
|
+ v-show="item.write_base64"
|
|
|
+ style="background-color: #f4f4f4"
|
|
|
+ :src="item.write_base64"
|
|
|
+ alt="write-show"
|
|
|
+ />
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template v-else-if="data.property.fill_type === fillTypeList[3].value">
|
|
|
+ <SoundRecordBox
|
|
|
+ ref="record"
|
|
|
+ :key="j"
|
|
|
+ type="mini"
|
|
|
+ :many-times="false"
|
|
|
+ class="record-box"
|
|
|
+ :answer-record-list="data.audio_answer_list"
|
|
|
+ :task-model="isJudgingRightWrong ? 'ANSWER' : ''"
|
|
|
+ :attrib="data.unified_attrib"
|
|
|
+ @handleWav="handleMiniWav($event, item)"
|
|
|
/>
|
|
|
- </span>
|
|
|
+ </template>
|
|
|
</template>
|
|
|
-
|
|
|
- <template v-else-if="data.property.fill_type === fillTypeList[3].value">
|
|
|
- <SoundRecordBox
|
|
|
- ref="record"
|
|
|
- :key="j"
|
|
|
- type="mini"
|
|
|
- :many-times="false"
|
|
|
- class="record-box"
|
|
|
- :answer-record-list="data.audio_answer_list"
|
|
|
- :task-model="isJudgingRightWrong ? 'ANSWER' : ''"
|
|
|
- :attrib="data.unified_attrib"
|
|
|
- @handleWav="handleMiniWav($event, item)"
|
|
|
- />
|
|
|
- </template>
|
|
|
- </template>
|
|
|
- </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
</template>
|
|
|
</div>
|
|
|
|
|
|
@@ -511,22 +674,123 @@
|
|
|
</template>
|
|
|
</template>
|
|
|
<template v-else>
|
|
|
- <div v-for="(item, index) in col.model_essay" :key="index" :style="[tdStyle]">
|
|
|
- <span
|
|
|
- v-if="item.type === 'text'"
|
|
|
+ <template v-if="col.rich_text_list && col.rich_text_list.length !== 0">
|
|
|
+ <div
|
|
|
+ v-for="(item, index) in col.rich_text_list"
|
|
|
:key="index"
|
|
|
- :style="{
|
|
|
- fontSize:
|
|
|
- data.unified_attrib && data.unified_attrib.font_size
|
|
|
- ? data.unified_attrib.font_size
|
|
|
- : '',
|
|
|
- fontFamily:
|
|
|
- data.unified_attrib && data.unified_attrib.font ? data.unified_attrib.font : '',
|
|
|
- }"
|
|
|
- v-html="convertText(sanitizeHTML(item.value))"
|
|
|
- ></span>
|
|
|
- <template v-if="item.type === 'input'">
|
|
|
- <!-- <template v-if="data.property.fill_type === fillTypeList[0].value">
|
|
|
+ class="pinyin-text pinyin-text-sentence"
|
|
|
+ :class="[
|
|
|
+ index === 0 ? 'pinyin-text-left' : '',
|
|
|
+ item.type === 'audio' ? 'pinyin-text-audio' : '',
|
|
|
+ ]"
|
|
|
+ >
|
|
|
+ <!-- 文字块:包含 word_list -->
|
|
|
+ <span
|
|
|
+ v-if="item.type === 'text'"
|
|
|
+ :key="'text-' + index"
|
|
|
+ class="pinyin-sentence"
|
|
|
+ :style="[
|
|
|
+ { 'align-items': data.property.pinyin_position === 'top' ? 'flex-end' : 'flex-start' },
|
|
|
+ ]"
|
|
|
+ >
|
|
|
+ <span
|
|
|
+ v-for="(word, wIndex) in item.word_list"
|
|
|
+ :key="wIndex"
|
|
|
+ class="pinyin-text"
|
|
|
+ :style="item.styleObj"
|
|
|
+ >
|
|
|
+ <span v-if="word.type === 'text'">
|
|
|
+ <span
|
|
|
+ :style="{
|
|
|
+ flexDirection:
|
|
|
+ data.property.pinyin_position === 'top' ? 'column' : 'column-reverse',
|
|
|
+ 'align-items': getWordAlignItems(word, item),
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ <span class="py-char" :style="getCharStyle(word, item)">{{
|
|
|
+ convertText(word.text)
|
|
|
+ }}</span>
|
|
|
+ </span>
|
|
|
+ </span>
|
|
|
+ <template v-else-if="word.type === 'input'">
|
|
|
+ <span
|
|
|
+ v-show="computedAnswerText(word, i, j).length > 0"
|
|
|
+ :key="`answer-${j}`"
|
|
|
+ class="right-answer"
|
|
|
+ >
|
|
|
+ {{ convertText(computedAnswerText(word, i, j)) }}
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </span>
|
|
|
+ </span>
|
|
|
+ <!-- 图片块 -->
|
|
|
+ <div
|
|
|
+ v-else-if="item.type === 'image'"
|
|
|
+ :key="'image-' + index"
|
|
|
+ :style="item.containerStyle"
|
|
|
+ class="image-container"
|
|
|
+ >
|
|
|
+ <img
|
|
|
+ :src="item.src"
|
|
|
+ :alt="item.alt"
|
|
|
+ :width="item.width"
|
|
|
+ :height="item.height"
|
|
|
+ :style="item.imageStyle"
|
|
|
+ class="inline-image"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <!-- 视频块 -->
|
|
|
+ <div
|
|
|
+ v-else-if="item.type === 'video'"
|
|
|
+ :key="'video-' + index"
|
|
|
+ :style="item.containerStyle"
|
|
|
+ class="video-container"
|
|
|
+ >
|
|
|
+ <video
|
|
|
+ :poster="item.poster"
|
|
|
+ :width="item.width"
|
|
|
+ :height="item.height"
|
|
|
+ :style="item.mediaStyle"
|
|
|
+ controls
|
|
|
+ class="inline-video"
|
|
|
+ >
|
|
|
+ <source :src="item.src" :type="item.videoType" />
|
|
|
+ 您的浏览器不支持视频播放
|
|
|
+ </video>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 音频块 -->
|
|
|
+ <div
|
|
|
+ v-else-if="item.type === 'audio'"
|
|
|
+ :key="'audio-' + index"
|
|
|
+ :style="item.containerStyle"
|
|
|
+ class="audio-container"
|
|
|
+ >
|
|
|
+ <audio :src="item.src" :style="item.mediaStyle" controls class="inline-audio">
|
|
|
+ 您的浏览器不支持音频播放
|
|
|
+ </audio>
|
|
|
+ </div>
|
|
|
+ <!-- 换行符 -->
|
|
|
+ <br v-else-if="item.type === 'newline'" :key="'newline-' + index" />
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <div v-for="(item, index) in col.model_essay" :key="index" :style="[tdStyle]">
|
|
|
+ <span
|
|
|
+ v-if="item.type === 'text'"
|
|
|
+ :key="index"
|
|
|
+ :style="{
|
|
|
+ fontSize:
|
|
|
+ data.unified_attrib && data.unified_attrib.font_size
|
|
|
+ ? data.unified_attrib.font_size
|
|
|
+ : '',
|
|
|
+ fontFamily:
|
|
|
+ data.unified_attrib && data.unified_attrib.font ? data.unified_attrib.font : '',
|
|
|
+ }"
|
|
|
+ v-html="convertText(sanitizeHTML(item.value))"
|
|
|
+ ></span>
|
|
|
+ <template v-if="item.type === 'input'">
|
|
|
+ <!-- <template v-if="data.property.fill_type === fillTypeList[0].value">
|
|
|
<el-input
|
|
|
:key="index"
|
|
|
v-model="item.value"
|
|
|
@@ -583,15 +847,16 @@
|
|
|
/>
|
|
|
</template> -->
|
|
|
|
|
|
- <span
|
|
|
- v-show="computedAnswerText(item, i, j).length > 0"
|
|
|
- :key="`answer-${j}`"
|
|
|
- class="right-answer"
|
|
|
- >
|
|
|
- {{ convertText(computedAnswerText(item, i, j)) }}
|
|
|
- </span>
|
|
|
- </template>
|
|
|
- </div>
|
|
|
+ <span
|
|
|
+ v-show="computedAnswerText(item, i, j).length > 0"
|
|
|
+ :key="`answer-${j}`"
|
|
|
+ class="right-answer"
|
|
|
+ >
|
|
|
+ {{ convertText(computedAnswerText(item, i, j)) }}
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
</template>
|
|
|
</div>
|
|
|
<i
|
|
|
@@ -836,7 +1101,7 @@ export default {
|
|
|
const altMatch = attrs.match(/alt=["']([^"']*)["']/i);
|
|
|
const widthMatch = attrs.match(/width=["']?(\d+)["']?/i);
|
|
|
const heightMatch = attrs.match(/height=["']?(\d+)["']?/i);
|
|
|
- const styleMatch = attrs.match(/style=["']([^"']*)["']/i);
|
|
|
+ const styleValue = this.extractStyleAttr(attrs);
|
|
|
|
|
|
const containerStyleObj = {};
|
|
|
tagStack.forEach((tagItem) => {
|
|
|
@@ -846,8 +1111,8 @@ export default {
|
|
|
});
|
|
|
|
|
|
const imageStyleObj = {};
|
|
|
- if (styleMatch) {
|
|
|
- this.mergeStyleString(imageStyleObj, styleMatch[1]);
|
|
|
+ if (styleValue) {
|
|
|
+ this.mergeStyleString(imageStyleObj, styleValue);
|
|
|
}
|
|
|
|
|
|
return {
|
|
|
@@ -974,8 +1239,8 @@ export default {
|
|
|
const baseStyle = {};
|
|
|
baseStyle['font-size'] = styles ? styles.fontSize : '16px';
|
|
|
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;
|
|
|
},
|
|
|
@@ -987,10 +1252,23 @@ export default {
|
|
|
}
|
|
|
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) {
|
|
|
- const styleMatch = attrs.match(/style=["']([^"']*)["']/);
|
|
|
- let style = styleMatch ? styleMatch[1] : null;
|
|
|
+ let style = this.extractStyleAttr(attrs) || null;
|
|
|
|
|
|
const classMatch = attrs.match(/class=["']([^"']*)["']/);
|
|
|
const className = classMatch ? classMatch[1] : '';
|
|
|
@@ -1033,7 +1311,7 @@ export default {
|
|
|
const posterMatch = attrs.match(/poster=["']([^"']*)["']/i);
|
|
|
const widthMatch = attrs.match(/width=["']?(\d+)["']?/i);
|
|
|
const heightMatch = attrs.match(/height=["']?(\d+)["']?/i);
|
|
|
- const styleMatch = attrs.match(/style=["']([^"']*)["']/i);
|
|
|
+ const styleValue = this.extractStyleAttr(attrs);
|
|
|
|
|
|
// 直接从完整的文本中匹配 source
|
|
|
const sourceMatch = item.text.match(/<source\s+([^>]*)\/?\s*>/i);
|
|
|
@@ -1057,8 +1335,8 @@ export default {
|
|
|
});
|
|
|
|
|
|
const mediaStyleObj = {};
|
|
|
- if (styleMatch) {
|
|
|
- this.mergeStyleString(mediaStyleObj, styleMatch[1]);
|
|
|
+ if (styleValue) {
|
|
|
+ this.mergeStyleString(mediaStyleObj, styleValue);
|
|
|
}
|
|
|
|
|
|
return {
|
|
|
@@ -1080,7 +1358,7 @@ export default {
|
|
|
|
|
|
const attrs = audioMatch[1];
|
|
|
const srcMatch = attrs.match(/src=["']([^"']*)["']/i);
|
|
|
- const styleMatch = attrs.match(/style=["']([^"']*)["']/i);
|
|
|
+ const styleValue = this.extractStyleAttr(attrs);
|
|
|
|
|
|
const containerStyleObj = {};
|
|
|
tagStack.forEach((tagItem) => {
|
|
|
@@ -1090,8 +1368,8 @@ export default {
|
|
|
});
|
|
|
|
|
|
const mediaStyleObj = {};
|
|
|
- if (styleMatch) {
|
|
|
- this.mergeStyleString(mediaStyleObj, styleMatch[1]);
|
|
|
+ if (styleValue) {
|
|
|
+ this.mergeStyleString(mediaStyleObj, styleValue);
|
|
|
}
|
|
|
|
|
|
return {
|
|
|
@@ -1471,8 +1749,10 @@ $border-color: #e6e6e6;
|
|
|
}
|
|
|
|
|
|
:deep input.el-input__inner {
|
|
|
+ height: 100%;
|
|
|
padding: 0;
|
|
|
font-family: var(--input-font-family);
|
|
|
+ line-height: 1;
|
|
|
|
|
|
// font-size: 16pt;
|
|
|
color: $font-color;
|