@mnykj/alleditor-dual 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -58,10 +58,10 @@ const html = ref('<p>hello</p>')
58
58
  ## HTML 协议
59
59
 
60
60
  ```html
61
- <div class="alleditor-root" data-alleditor-engine="ue">…</div>
61
+ <div class="alleditor-root" data-alleditor-engine="wang|ue">…</div>
62
62
  ```
63
63
 
64
- 兼容旧注释 `<!--yunkee-editor:ue-html-->`。
64
+ wang / ue 保存时都会包外层;兼容旧注释 `<!--yunkee-editor:ue-html-->`。
65
65
 
66
66
  ## 开发(monorepo)
67
67
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mnykj/alleditor-dual",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "AllEditor dual-engine (wang + UE HTML) Vue3 components, with bundled UEditor static assets",
5
5
  "author": "mnykj",
6
6
  "license": "MIT",
@@ -37,7 +37,7 @@
37
37
  "registry": "https://registry.npmjs.org/"
38
38
  },
39
39
  "peerDependencies": {
40
- "@mnykj/alleditor": "^1.1.0",
40
+ "@mnykj/alleditor": "^1.1.1",
41
41
  "@mnykj/alleditor-for-vue": "^1.1.0",
42
42
  "vue": "^3.0.5",
43
43
  "vite": ">=4",
@@ -31,8 +31,8 @@ const props = defineProps({
31
31
  editorConfig: { type: Object, default: () => ({}) },
32
32
  /** wang 占位正文(UE 模式下避免把高保真 HTML 喂进 Slate) */
33
33
  wangPlaceholder: { type: String, default: '<p><br></p>' },
34
- /** 仅当引擎为 ue 时才写外层 div(推荐;wang 正文保持干净) */
35
- wrapOnlyWhenUe: { type: Boolean, default: true },
34
+ /** 为 true 时仅 ue 写外层 div;默认 false,wang/ue 都包 data-alleditor-engine */
35
+ wrapOnlyWhenUe: { type: Boolean, default: false },
36
36
  toolbarSelector: {
37
37
  type: String,
38
38
  default: '.alleditor-dual .w-e-toolbar, .alleditor-dual .editor-toolbar',
@@ -95,6 +95,29 @@ function syncDisabled() {
95
95
  }
96
96
  }
97
97
 
98
+ /**
99
+ * 清理公众号/Slate 残留:
100
+ * - <span leaf=""> 包住的 img 易让 UEditor 图片缩放框错位,挡住正文无法编辑
101
+ * - 去掉无意义的 leaf 属性
102
+ */
103
+ function sanitizeUeHtml(html) {
104
+ return String(html ?? '')
105
+ .replace(/<span\b[^>]*\bleaf(?:\s*=\s*(?:""|''|[^>\s]+))?\s*[^>]*>\s*(<img\b[^>]*>)\s*<\/span>/gi, '$1')
106
+ .replace(/\sleaf(?:\s*=\s*(?:""|''|"[^"]*"|'[^']*'|[^\s>]+))?/gi, '')
107
+ }
108
+
109
+ function hideImageScaleUi(ue) {
110
+ try {
111
+ const uiRoot = ue?.ui?.getDom?.()
112
+ if (!uiRoot) return
113
+ uiRoot.querySelectorAll('.edui-editor-imagescale, [id$="_imagescale"], [id$="_imagescale_cover"]').forEach((el) => {
114
+ el.style.display = 'none'
115
+ })
116
+ } catch {
117
+ /* ignore */
118
+ }
119
+ }
120
+
98
121
  function getContent() {
99
122
  const ue = instance.value
100
123
  if (!ue || !ready) {
@@ -109,7 +132,7 @@ function getContent() {
109
132
  }
110
133
 
111
134
  function setContent(html) {
112
- const next = html || ''
135
+ const next = sanitizeUeHtml(html || '')
113
136
  const ue = instance.value
114
137
  if (!ue || !ready) {
115
138
  pendingHtml = next
@@ -121,6 +144,7 @@ function setContent(html) {
121
144
  } finally {
122
145
  applying = false
123
146
  }
147
+ hideImageScaleUi(ue)
124
148
  requestAnimationFrame(() => fitEditorHeight(ue))
125
149
  }
126
150
 
@@ -251,6 +275,10 @@ onMounted(async () => {
251
275
  initialFrameHeight: height,
252
276
  initialFrameWidth: '100%',
253
277
  autoHeightEnabled: false,
278
+ // 关闭图片八爪缩放框:编辑区在 iframe 内时缩放层常错位/关不掉,正文点不动
279
+ imageScaleEnabled: false,
280
+ imagePopup: false,
281
+ scaleEnabled: false,
254
282
  serverUrl: '',
255
283
  enableAutoSave: false,
256
284
  elementPathEnabled: false,
@@ -269,12 +297,15 @@ onMounted(async () => {
269
297
  emit('update:modelValue', html)
270
298
  emit('change', html)
271
299
  })
300
+ // 即便外部配置被覆盖,缩放层弹出时立刻隐藏,避免挡住编辑
301
+ ue.addListener('afterscaleshow', () => hideImageScaleUi(ue))
272
302
 
273
303
  ue.ready(() => {
274
304
  if (destroyed) return
275
305
  ready = true
276
- const initial =
306
+ const initial = sanitizeUeHtml(
277
307
  pendingHtml !== undefined ? pendingHtml : props.modelValue || ''
308
+ )
278
309
  pendingHtml = undefined
279
310
  applying = true
280
311
  try {
@@ -283,6 +314,7 @@ onMounted(async () => {
283
314
  applying = false
284
315
  }
285
316
  injectReadableBodyStyle(ue)
317
+ hideImageScaleUi(ue)
286
318
  fitEditorHeight(ue)
287
319
  bindResize(ue)
288
320
  requestAnimationFrame(() => fitEditorHeight(ue))
@@ -300,7 +332,7 @@ watch(
300
332
  () => props.modelValue,
301
333
  (html) => {
302
334
  if (destroyed) return
303
- const next = html || ''
335
+ const next = sanitizeUeHtml(html || '')
304
336
  if (!ready || applying) {
305
337
  pendingHtml = next
306
338
  return
@@ -382,4 +414,12 @@ defineExpose({
382
414
  border: none !important;
383
415
  background: #fff !important;
384
416
  }
417
+
418
+ /* 兜底隐藏图片缩放框(错位时会盖住正文) */
419
+ .alleditor-ue-engine :deep(.edui-editor-imagescale),
420
+ .alleditor-ue-engine :deep([id$='_imagescale']),
421
+ .alleditor-ue-engine :deep([id$='_imagescale_cover']) {
422
+ display: none !important;
423
+ pointer-events: none !important;
424
+ }
385
425
  </style>