bridgerte 0.9.3 → 0.9.5
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 +892 -861
- package/dist/bridge.cjs.map +1 -1
- package/dist/bridge.d.ts +1 -3
- package/dist/bridge.js.map +1 -1
- package/dist/core.cjs +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.ts +9 -3
- package/dist/core.js +44 -54
- package/dist/core.js.map +1 -1
- package/dist/dom.cjs +1 -1
- package/dist/dom.d.ts +9 -3
- package/dist/dom.js +6 -5
- package/dist/index-BWi3d-Zp.js +314 -0
- package/dist/index-BWi3d-Zp.js.map +1 -0
- package/dist/index-B_g23O7q.cjs +4 -0
- package/dist/index-B_g23O7q.cjs.map +1 -0
- package/dist/index-CuNKUHed.js.map +1 -1
- package/dist/index-DF8OhKI4.cjs +2 -0
- package/dist/index-DF8OhKI4.cjs.map +1 -0
- package/dist/{index-BwZ0II4h.js → index-DyCMSFrm.js} +1135 -1141
- package/dist/index-DyCMSFrm.js.map +1 -0
- package/dist/index-GaS65GL0.cjs.map +1 -1
- package/dist/index-H5V0EMkq.cjs +36 -0
- package/dist/index-H5V0EMkq.cjs.map +1 -0
- package/dist/index-sbZNOcCB.js +54 -0
- package/dist/index-sbZNOcCB.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +17 -3
- package/dist/index.js +24 -21
- package/dist/index.js.map +1 -1
- package/dist/native-spec.cjs +1 -1
- package/dist/native-spec.cjs.map +1 -1
- package/dist/native-spec.d.ts +1 -3
- package/dist/native-spec.js +73 -119
- package/dist/native-spec.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/webview.cjs +1 -1
- package/dist/webview.d.ts +1 -3
- package/dist/webview.js +1 -1
- package/package.json +1 -1
- package/dist/index-BaOlPu8L.cjs +0 -4
- package/dist/index-BaOlPu8L.cjs.map +0 -1
- package/dist/index-BwZ0II4h.js.map +0 -1
- package/dist/index-bN5Hs6-3.js +0 -299
- package/dist/index-bN5Hs6-3.js.map +0 -1
- package/dist/index-hd9Zi2DV.cjs +0 -36
- package/dist/index-hd9Zi2DV.cjs.map +0 -1
package/dist/bridge.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.cjs","sources":["../../bridge/src/index.ts"],"sourcesContent":["import type { BridgeEventTiming, BridgeMessage } from './type';\n\nexport type * from './type';\n\n/**\n * bridge 高频事件的默认节流策略。\n *\n * 这里先固定协议默认值,真正的 WebView runtime 会在发送消息时使用这些数值。\n */\nexport const BRIDGE_CONTENT_CHANGE_DEBOUNCE_MS = 120;\nexport const BRIDGE_HEIGHT_CHANGE_THROTTLE_MS = 100;\n\nexport const defaultBridgeEventTiming: BridgeEventTiming = {\n contentChangeDebounceMs: BRIDGE_CONTENT_CHANGE_DEBOUNCE_MS,\n heightChangeThrottleMs: BRIDGE_HEIGHT_CHANGE_THROTTLE_MS,\n commandStateChangeDedupe: true\n};\n\n/**\n * bridge 当前支持的全部外层消息类型。\n *\n * `isBridgeMessage()` 只信任这个白名单,避免把未知 `editor.*` 消息误判为合法协议。\n */\nconst bridgeMessageTypes = new Set<BridgeMessage['type']>([\n 'editor.init',\n 'editor.executeCommand',\n 'editor.setContent',\n 'editor.setReadonly',\n 'editor.requestContent',\n 'editor.payloadPanelResolved',\n 'editor.payloadPanelCanceled',\n 'editor.uploadResolved',\n 'editor.uploadRejected',\n 'editor.ready',\n 'editor.content',\n 'editor.contentChange',\n 'editor.selectionChange',\n 'editor.commandStateChange',\n 'editor.payloadPanelRequest',\n 'editor.uploadRequest',\n 'editor.heightChange',\n 'editor.error'\n]);\n\n/**\n * bridge 消息的已知类型守卫。\n *\n * 这里只校验消息外层类型,深层 payload 校验留给具体消息处理器。\n * 这样能在轻量运行时判断和完整业务校验之间保持边界清楚。\n */\nexport function isBridgeMessage(value: unknown): value is BridgeMessage {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const candidate = value as { type?: unknown };\n return typeof candidate.type === 'string'\n && bridgeMessageTypes.has(candidate.type as BridgeMessage['type']);\n}\n"],"names":["BRIDGE_CONTENT_CHANGE_DEBOUNCE_MS","BRIDGE_HEIGHT_CHANGE_THROTTLE_MS","defaultBridgeEventTiming","bridgeMessageTypes","isBridgeMessage","value","candidate"],"mappings":"gFASO,MAAMA,EAAoC,IACpCC,EAAmC,IAEnCC,EAA8C,CACzD,wBAAyBF,EACzB,uBAAwBC,EACxB,yBAA0B,EAC5B,EAOME,MAAyB,IAA2B,CACxD,cACA,wBACA,oBACA,qBACA,wBACA,8BACA,8BACA,wBACA,wBACA,eACA,iBACA,uBACA,yBACA,4BACA,6BACA,uBACA,sBACA,cACF,CAAC,EAQM,SAASC,EAAgBC,EAAwC,CACtE,GAAI,OAAOA,GAAU,UAAYA,IAAU,KACzC,MAAO,GAGT,MAAMC,EAAYD,EAClB,OAAO,OAAOC,EAAU,MAAS,UAC5BH,EAAmB,IAAIG,EAAU,IAA6B,CACrE"}
|
|
1
|
+
{"version":3,"file":"bridge.cjs","sources":["../../bridge/src/index.ts"],"sourcesContent":["import type { BridgeEventTiming, BridgeMessage } from './type';\r\n\r\nexport type * from './type';\r\n\r\n/**\r\n * bridge 高频事件的默认节流策略。\r\n *\r\n * 这里先固定协议默认值,真正的 WebView runtime 会在发送消息时使用这些数值。\r\n */\r\nexport const BRIDGE_CONTENT_CHANGE_DEBOUNCE_MS = 120;\r\nexport const BRIDGE_HEIGHT_CHANGE_THROTTLE_MS = 100;\r\n\r\nexport const defaultBridgeEventTiming: BridgeEventTiming = {\r\n contentChangeDebounceMs: BRIDGE_CONTENT_CHANGE_DEBOUNCE_MS,\r\n heightChangeThrottleMs: BRIDGE_HEIGHT_CHANGE_THROTTLE_MS,\r\n commandStateChangeDedupe: true\r\n};\r\n\r\n/**\r\n * bridge 当前支持的全部外层消息类型。\r\n *\r\n * `isBridgeMessage()` 只信任这个白名单,避免把未知 `editor.*` 消息误判为合法协议。\r\n */\r\nconst bridgeMessageTypes = new Set<BridgeMessage['type']>([\r\n 'editor.init',\r\n 'editor.executeCommand',\r\n 'editor.setContent',\r\n 'editor.setReadonly',\r\n 'editor.requestContent',\r\n 'editor.payloadPanelResolved',\r\n 'editor.payloadPanelCanceled',\r\n 'editor.uploadResolved',\r\n 'editor.uploadRejected',\r\n 'editor.ready',\r\n 'editor.content',\r\n 'editor.contentChange',\r\n 'editor.selectionChange',\r\n 'editor.commandStateChange',\r\n 'editor.payloadPanelRequest',\r\n 'editor.uploadRequest',\r\n 'editor.heightChange',\r\n 'editor.error'\r\n]);\r\n\r\n/**\r\n * bridge 消息的已知类型守卫。\r\n *\r\n * 这里只校验消息外层类型,深层 payload 校验留给具体消息处理器。\r\n * 这样能在轻量运行时判断和完整业务校验之间保持边界清楚。\r\n */\r\nexport function isBridgeMessage(value: unknown): value is BridgeMessage {\r\n if (typeof value !== 'object' || value === null) {\r\n return false;\r\n }\r\n\r\n const candidate = value as { type?: unknown };\r\n return typeof candidate.type === 'string'\r\n && bridgeMessageTypes.has(candidate.type as BridgeMessage['type']);\r\n}\r\n"],"names":["BRIDGE_CONTENT_CHANGE_DEBOUNCE_MS","BRIDGE_HEIGHT_CHANGE_THROTTLE_MS","defaultBridgeEventTiming","bridgeMessageTypes","isBridgeMessage","value","candidate"],"mappings":"gFASO,MAAMA,EAAoC,IACpCC,EAAmC,IAEnCC,EAA8C,CACzD,wBAAyBF,EACzB,uBAAwBC,EACxB,yBAA0B,EAC5B,EAOME,MAAyB,IAA2B,CACxD,cACA,wBACA,oBACA,qBACA,wBACA,8BACA,8BACA,wBACA,wBACA,eACA,iBACA,uBACA,yBACA,4BACA,6BACA,uBACA,sBACA,cACF,CAAC,EAQM,SAASC,EAAgBC,EAAwC,CACtE,GAAI,OAAOA,GAAU,UAAYA,IAAU,KACzC,MAAO,GAGT,MAAMC,EAAYD,EAClB,OAAO,OAAOC,EAAU,MAAS,UAC5BH,EAAmB,IAAIG,EAAU,IAA6B,CACrE"}
|
package/dist/bridge.d.ts
CHANGED
|
@@ -182,7 +182,7 @@ export type ToolbarGroupConfig = {
|
|
|
182
182
|
/**
|
|
183
183
|
* toolbar JSON 配置项。
|
|
184
184
|
*
|
|
185
|
-
* 字符串使用 `MenuItem.id`;特殊字符串 `|`
|
|
185
|
+
* 字符串使用 `MenuItem.id`;特殊字符串 `|` 表示分割线,收纳菜单用对象配置显式声明。
|
|
186
186
|
*/
|
|
187
187
|
export type ToolbarKey = string | ToolbarGroupConfig;
|
|
188
188
|
/**
|
|
@@ -513,7 +513,6 @@ export type SlashCommandItem = {
|
|
|
513
513
|
icon?: string;
|
|
514
514
|
description?: string;
|
|
515
515
|
keywords?: string[];
|
|
516
|
-
group?: string;
|
|
517
516
|
requiresPayload?: boolean;
|
|
518
517
|
payloadPanel?: PayloadPanelSchema;
|
|
519
518
|
};
|
|
@@ -579,7 +578,6 @@ export type MenuItem = {
|
|
|
579
578
|
command: EditorCommand;
|
|
580
579
|
label: string;
|
|
581
580
|
icon: string;
|
|
582
|
-
group: 'text' | 'style' | 'block' | 'list' | 'align' | 'insert' | 'media' | 'table' | 'history' | 'view';
|
|
583
581
|
requiresPayload?: boolean;
|
|
584
582
|
payloadPanel?: PayloadPanelSchema;
|
|
585
583
|
children?: MenuItem[];
|
package/dist/bridge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.js","sources":["../../bridge/src/index.ts"],"sourcesContent":["import type { BridgeEventTiming, BridgeMessage } from './type';\n\nexport type * from './type';\n\n/**\n * bridge 高频事件的默认节流策略。\n *\n * 这里先固定协议默认值,真正的 WebView runtime 会在发送消息时使用这些数值。\n */\nexport const BRIDGE_CONTENT_CHANGE_DEBOUNCE_MS = 120;\nexport const BRIDGE_HEIGHT_CHANGE_THROTTLE_MS = 100;\n\nexport const defaultBridgeEventTiming: BridgeEventTiming = {\n contentChangeDebounceMs: BRIDGE_CONTENT_CHANGE_DEBOUNCE_MS,\n heightChangeThrottleMs: BRIDGE_HEIGHT_CHANGE_THROTTLE_MS,\n commandStateChangeDedupe: true\n};\n\n/**\n * bridge 当前支持的全部外层消息类型。\n *\n * `isBridgeMessage()` 只信任这个白名单,避免把未知 `editor.*` 消息误判为合法协议。\n */\nconst bridgeMessageTypes = new Set<BridgeMessage['type']>([\n 'editor.init',\n 'editor.executeCommand',\n 'editor.setContent',\n 'editor.setReadonly',\n 'editor.requestContent',\n 'editor.payloadPanelResolved',\n 'editor.payloadPanelCanceled',\n 'editor.uploadResolved',\n 'editor.uploadRejected',\n 'editor.ready',\n 'editor.content',\n 'editor.contentChange',\n 'editor.selectionChange',\n 'editor.commandStateChange',\n 'editor.payloadPanelRequest',\n 'editor.uploadRequest',\n 'editor.heightChange',\n 'editor.error'\n]);\n\n/**\n * bridge 消息的已知类型守卫。\n *\n * 这里只校验消息外层类型,深层 payload 校验留给具体消息处理器。\n * 这样能在轻量运行时判断和完整业务校验之间保持边界清楚。\n */\nexport function isBridgeMessage(value: unknown): value is BridgeMessage {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const candidate = value as { type?: unknown };\n return typeof candidate.type === 'string'\n && bridgeMessageTypes.has(candidate.type as BridgeMessage['type']);\n}\n"],"names":["BRIDGE_CONTENT_CHANGE_DEBOUNCE_MS","BRIDGE_HEIGHT_CHANGE_THROTTLE_MS","defaultBridgeEventTiming","bridgeMessageTypes","isBridgeMessage","value","candidate"],"mappings":"AASO,MAAMA,IAAoC,KACpCC,IAAmC,KAEnCC,IAA8C;AAAA,EACzD,yBAAyB;AAAA,EACzB,wBAAwB;AAAA,EACxB,0BAA0B;AAC5B,GAOMC,wBAAyB,IAA2B;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAQM,SAASC,EAAgBC,GAAwC;AACtE,MAAI,OAAOA,KAAU,YAAYA,MAAU;AACzC,WAAO;AAGT,QAAMC,IAAYD;AAClB,SAAO,OAAOC,EAAU,QAAS,YAC5BH,EAAmB,IAAIG,EAAU,IAA6B;AACrE;"}
|
|
1
|
+
{"version":3,"file":"bridge.js","sources":["../../bridge/src/index.ts"],"sourcesContent":["import type { BridgeEventTiming, BridgeMessage } from './type';\r\n\r\nexport type * from './type';\r\n\r\n/**\r\n * bridge 高频事件的默认节流策略。\r\n *\r\n * 这里先固定协议默认值,真正的 WebView runtime 会在发送消息时使用这些数值。\r\n */\r\nexport const BRIDGE_CONTENT_CHANGE_DEBOUNCE_MS = 120;\r\nexport const BRIDGE_HEIGHT_CHANGE_THROTTLE_MS = 100;\r\n\r\nexport const defaultBridgeEventTiming: BridgeEventTiming = {\r\n contentChangeDebounceMs: BRIDGE_CONTENT_CHANGE_DEBOUNCE_MS,\r\n heightChangeThrottleMs: BRIDGE_HEIGHT_CHANGE_THROTTLE_MS,\r\n commandStateChangeDedupe: true\r\n};\r\n\r\n/**\r\n * bridge 当前支持的全部外层消息类型。\r\n *\r\n * `isBridgeMessage()` 只信任这个白名单,避免把未知 `editor.*` 消息误判为合法协议。\r\n */\r\nconst bridgeMessageTypes = new Set<BridgeMessage['type']>([\r\n 'editor.init',\r\n 'editor.executeCommand',\r\n 'editor.setContent',\r\n 'editor.setReadonly',\r\n 'editor.requestContent',\r\n 'editor.payloadPanelResolved',\r\n 'editor.payloadPanelCanceled',\r\n 'editor.uploadResolved',\r\n 'editor.uploadRejected',\r\n 'editor.ready',\r\n 'editor.content',\r\n 'editor.contentChange',\r\n 'editor.selectionChange',\r\n 'editor.commandStateChange',\r\n 'editor.payloadPanelRequest',\r\n 'editor.uploadRequest',\r\n 'editor.heightChange',\r\n 'editor.error'\r\n]);\r\n\r\n/**\r\n * bridge 消息的已知类型守卫。\r\n *\r\n * 这里只校验消息外层类型,深层 payload 校验留给具体消息处理器。\r\n * 这样能在轻量运行时判断和完整业务校验之间保持边界清楚。\r\n */\r\nexport function isBridgeMessage(value: unknown): value is BridgeMessage {\r\n if (typeof value !== 'object' || value === null) {\r\n return false;\r\n }\r\n\r\n const candidate = value as { type?: unknown };\r\n return typeof candidate.type === 'string'\r\n && bridgeMessageTypes.has(candidate.type as BridgeMessage['type']);\r\n}\r\n"],"names":["BRIDGE_CONTENT_CHANGE_DEBOUNCE_MS","BRIDGE_HEIGHT_CHANGE_THROTTLE_MS","defaultBridgeEventTiming","bridgeMessageTypes","isBridgeMessage","value","candidate"],"mappings":"AASO,MAAMA,IAAoC,KACpCC,IAAmC,KAEnCC,IAA8C;AAAA,EACzD,yBAAyB;AAAA,EACzB,wBAAwB;AAAA,EACxB,0BAA0B;AAC5B,GAOMC,wBAAyB,IAA2B;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAQM,SAASC,EAAgBC,GAAwC;AACtE,MAAI,OAAOA,KAAU,YAAYA,MAAU;AACzC,WAAO;AAGT,QAAMC,IAAYD;AAClB,SAAO,OAAOC,EAAU,QAAS,YAC5BH,EAAmB,IAAIG,EAAU,IAA6B;AACrE;"}
|
package/dist/core.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./index-GaS65GL0.cjs"),l=require("./index-DF8OhKI4.cjs"),s=/[\u200B-\u200D\uFEFF]/g,o=/<[^>]*>/g,u=/&(?:nbsp|#160|#x0*a0);/gi,E=/&(?:[a-z\d]+|#\d+|#x[\da-f]+);/gi,m=["img","video","audio","iframe","table","pre","code","hr","figure","canvas","svg","math"],f=new Set(["bridgerte-divider","bridgerte-media","bridgerte-mention","code","horizontalrule","image","table","video"]),c=new RegExp(`<(${m.join("|")})(?=[\\s>/])`,"i"),n=e=>!!(e!=null&&e.replace(s,"").trim()),T=e=>{const t=e??"";if(!n(t))return!1;if(c.test(t))return!0;const r=t.replace(o," ").replace(u," ").replace(E,"x");return n(r)},i=e=>{var t;return e?n(e.text)||f.has(e.type)?!0:!!((t=e.children)!=null&&t.some(i)):!1},d=e=>{var t,r;return e?!(n(e.plainText)||(t=e.assets)!=null&&t.length||i((r=e.json)==null?void 0:r.root)||T(e.html)):!0};exports.BRIDGERTE_CONTENT_VERSION=a.BRIDGERTE_CONTENT_VERSION;exports.BRIDGERTE_TABLE_INSERT_MAX_COLS=a.BRIDGERTE_TABLE_INSERT_MAX_COLS;exports.BRIDGERTE_TABLE_INSERT_MAX_ROWS=a.BRIDGERTE_TABLE_INSERT_MAX_ROWS;exports.resolvePayloadPanelSchema=l.resolvePayloadPanelSchema;exports.isEditorContentEmpty=d;
|
|
2
2
|
//# sourceMappingURL=core.cjs.map
|
package/dist/core.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.cjs","sources":["../../core/src/
|
|
1
|
+
{"version":3,"file":"core.cjs","sources":["../../core/src/content/index.ts"],"sourcesContent":["import type { EditorContent, EditorContentNode } from './type';\n\nconst invisibleTextPattern = /[\\u200B-\\u200D\\uFEFF]/g;\nconst htmlTagPattern = /<[^>]*>/g;\nconst blankHtmlEntityPattern = /&(?:nbsp|#160|#x0*a0);/gi;\nconst htmlEntityPattern = /&(?:[a-z\\d]+|#\\d+|#x[\\da-f]+);/gi;\nconst meaningfulHtmlElementNames = [\n 'img',\n 'video',\n 'audio',\n 'iframe',\n 'table',\n 'pre',\n 'code',\n 'hr',\n 'figure',\n 'canvas',\n 'svg',\n 'math'\n];\n\n/*\n * 这些节点即使当前没有普通文本,也代表用户主动插入了结构内容。\n * 后续新增非文本内容节点时优先补进这张表;纯段落、列表容器这类结构继续靠子节点判断。\n */\nconst meaningfulStructuredNodeTypes = new Set([\n 'bridgerte-divider',\n 'bridgerte-media',\n 'bridgerte-mention',\n 'code',\n 'horizontalrule',\n 'image',\n 'table',\n 'video'\n]);\n\nconst meaningfulHtmlElementPattern = new RegExp(\n `<(${meaningfulHtmlElementNames.join('|')})(?=[\\\\s>/])`,\n 'i'\n);\n\nconst hasMeaningfulText = (text: string | undefined): boolean => (\n Boolean(text?.replace(invisibleTextPattern, '').trim())\n);\n\nconst hasMeaningfulHtmlFallback = (html: string | undefined): boolean => {\n const htmlValue = html ?? '';\n\n if (!hasMeaningfulText(htmlValue)) return false;\n if (meaningfulHtmlElementPattern.test(htmlValue)) return true;\n\n /*\n * core 不能依赖 DOMParser,这里只做轻量兜底:去掉标签和空白实体后,\n * 其余实体按可见字符处理。需要完整 HTML 语义时使用 DOM 包的解析工具。\n */\n const textLikeContent = htmlValue\n .replace(htmlTagPattern, ' ')\n .replace(blankHtmlEntityPattern, ' ')\n .replace(htmlEntityPattern, 'x');\n\n return hasMeaningfulText(textLikeContent);\n};\n\nconst hasMeaningfulContentNode = (node: EditorContentNode | undefined): boolean => {\n if (!node) return false;\n if (hasMeaningfulText(node.text)) return true;\n if (meaningfulStructuredNodeTypes.has(node.type)) return true;\n\n return Boolean(node.children?.some(hasMeaningfulContentNode));\n};\n\n/**\n * 判断 BridgeRTE 内容快照是否为空。\n *\n * 函数只读取已生成的 `EditorContent` 字段,不触发 DOM 解析或编辑器序列化;调用方应在保存、\n * 提交或离开确认这类低频动作里配合 `editor.getContent()` 使用。\n */\nexport const isEditorContentEmpty = (\n content: Partial<EditorContent> | null | undefined\n): boolean => {\n if (!content) return true;\n if (hasMeaningfulText(content.plainText)) return false;\n if (content.assets?.length) return false;\n if (hasMeaningfulContentNode(content.json?.root)) return false;\n if (hasMeaningfulHtmlFallback(content.html)) return false;\n\n return true;\n};\n"],"names":["invisibleTextPattern","htmlTagPattern","blankHtmlEntityPattern","htmlEntityPattern","meaningfulHtmlElementNames","meaningfulStructuredNodeTypes","meaningfulHtmlElementPattern","hasMeaningfulText","text","hasMeaningfulHtmlFallback","html","htmlValue","textLikeContent","hasMeaningfulContentNode","node","_a","isEditorContentEmpty","content","_b"],"mappings":"0JAEMA,EAAuB,yBACvBC,EAAiB,WACjBC,EAAyB,2BACzBC,EAAoB,mCACpBC,EAA6B,CACjC,MACA,QACA,QACA,SACA,QACA,MACA,OACA,KACA,SACA,SACA,MACA,MACF,EAMMC,MAAoC,IAAI,CAC5C,oBACA,kBACA,oBACA,OACA,iBACA,QACA,QACA,OACF,CAAC,EAEKC,EAA+B,IAAI,OACvC,KAAKF,EAA2B,KAAK,GAAG,CAAC,eACzC,GACF,EAEMG,EAAqBC,GACzB,GAAQA,GAAA,MAAAA,EAAM,QAAQR,EAAsB,IAAI,QAG5CS,EAA6BC,GAAsC,CACvE,MAAMC,EAAYD,GAAQ,GAE1B,GAAI,CAACH,EAAkBI,CAAS,EAAG,MAAO,GAC1C,GAAIL,EAA6B,KAAKK,CAAS,EAAG,MAAO,GAMzD,MAAMC,EAAkBD,EACrB,QAAQV,EAAgB,GAAG,EAC3B,QAAQC,EAAwB,GAAG,EACnC,QAAQC,EAAmB,GAAG,EAEjC,OAAOI,EAAkBK,CAAe,CAC1C,EAEMC,EAA4BC,GAAiD,OACjF,OAAKA,EACDP,EAAkBO,EAAK,IAAI,GAC3BT,EAA8B,IAAIS,EAAK,IAAI,EAAU,GAElD,IAAQC,EAAAD,EAAK,WAAL,MAAAC,EAAe,KAAKF,IAJjB,EAKpB,EAQaG,EACXC,GACY,SACZ,OAAKA,EACD,EAAAV,EAAkBU,EAAQ,SAAS,IACnCF,EAAAE,EAAQ,SAAR,MAAAF,EAAgB,QAChBF,GAAyBK,EAAAD,EAAQ,OAAR,YAAAC,EAAc,IAAI,GAC3CT,EAA0BQ,EAAQ,IAAI,GAJrB,EAOvB"}
|
package/dist/core.d.ts
CHANGED
|
@@ -182,7 +182,7 @@ export type ToolbarGroupConfig = {
|
|
|
182
182
|
/**
|
|
183
183
|
* toolbar JSON 配置项。
|
|
184
184
|
*
|
|
185
|
-
* 字符串使用 `MenuItem.id`;特殊字符串 `|`
|
|
185
|
+
* 字符串使用 `MenuItem.id`;特殊字符串 `|` 表示分割线,收纳菜单用对象配置显式声明。
|
|
186
186
|
*/
|
|
187
187
|
export type ToolbarKey = string | ToolbarGroupConfig;
|
|
188
188
|
/**
|
|
@@ -513,7 +513,6 @@ export type SlashCommandItem = {
|
|
|
513
513
|
icon?: string;
|
|
514
514
|
description?: string;
|
|
515
515
|
keywords?: string[];
|
|
516
|
-
group?: string;
|
|
517
516
|
requiresPayload?: boolean;
|
|
518
517
|
payloadPanel?: PayloadPanelSchema;
|
|
519
518
|
};
|
|
@@ -579,7 +578,6 @@ export type MenuItem = {
|
|
|
579
578
|
command: EditorCommand;
|
|
580
579
|
label: string;
|
|
581
580
|
icon: string;
|
|
582
|
-
group: 'text' | 'style' | 'block' | 'list' | 'align' | 'insert' | 'media' | 'table' | 'history' | 'view';
|
|
583
581
|
requiresPayload?: boolean;
|
|
584
582
|
payloadPanel?: PayloadPanelSchema;
|
|
585
583
|
children?: MenuItem[];
|
|
@@ -912,3 +910,11 @@ export declare const BRIDGERTE_CONTENT_VERSION = "0.1.0";
|
|
|
912
910
|
export declare const BRIDGERTE_TABLE_INSERT_MAX_ROWS = 20;
|
|
913
911
|
export declare const BRIDGERTE_TABLE_INSERT_MAX_COLS = 20;
|
|
914
912
|
|
|
913
|
+
/**
|
|
914
|
+
* 判断 BridgeRTE 内容快照是否为空。
|
|
915
|
+
*
|
|
916
|
+
* 函数只读取已生成的 `EditorContent` 字段,不触发 DOM 解析或编辑器序列化;调用方应在保存、
|
|
917
|
+
* 提交或离开确认这类低频动作里配合 `editor.getContent()` 使用。
|
|
918
|
+
*/
|
|
919
|
+
export declare const isEditorContentEmpty: (content: Partial<EditorContent> | null | undefined) => boolean;
|
|
920
|
+
|
package/dist/core.js
CHANGED
|
@@ -1,58 +1,48 @@
|
|
|
1
|
-
import { B as
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
},
|
|
38
|
-
|
|
39
|
-
return !
|
|
40
|
-
...e,
|
|
41
|
-
title: a.title ?? e.title,
|
|
42
|
-
description: a.description ?? e.description,
|
|
43
|
-
fields: e.fields.map((r) => {
|
|
44
|
-
var u;
|
|
45
|
-
return h(
|
|
46
|
-
r,
|
|
47
|
-
(u = a.fields) == null ? void 0 : u[r.name]
|
|
48
|
-
);
|
|
49
|
-
})
|
|
50
|
-
};
|
|
1
|
+
import { B as h, a as p, b as T } from "./index-CuNKUHed.js";
|
|
2
|
+
import { r as b } from "./index-sbZNOcCB.js";
|
|
3
|
+
const i = /[\u200B-\u200D\uFEFF]/g, l = /<[^>]*>/g, s = /&(?:nbsp|#160|#x0*a0);/gi, o = /&(?:[a-z\d]+|#\d+|#x[\da-f]+);/gi, u = [
|
|
4
|
+
"img",
|
|
5
|
+
"video",
|
|
6
|
+
"audio",
|
|
7
|
+
"iframe",
|
|
8
|
+
"table",
|
|
9
|
+
"pre",
|
|
10
|
+
"code",
|
|
11
|
+
"hr",
|
|
12
|
+
"figure",
|
|
13
|
+
"canvas",
|
|
14
|
+
"svg",
|
|
15
|
+
"math"
|
|
16
|
+
], f = /* @__PURE__ */ new Set([
|
|
17
|
+
"bridgerte-divider",
|
|
18
|
+
"bridgerte-media",
|
|
19
|
+
"bridgerte-mention",
|
|
20
|
+
"code",
|
|
21
|
+
"horizontalrule",
|
|
22
|
+
"image",
|
|
23
|
+
"table",
|
|
24
|
+
"video"
|
|
25
|
+
]), m = new RegExp(
|
|
26
|
+
`<(${u.join("|")})(?=[\\s>/])`,
|
|
27
|
+
"i"
|
|
28
|
+
), n = (e) => !!(e != null && e.replace(i, "").trim()), c = (e) => {
|
|
29
|
+
const t = e ?? "";
|
|
30
|
+
if (!n(t)) return !1;
|
|
31
|
+
if (m.test(t)) return !0;
|
|
32
|
+
const r = t.replace(l, " ").replace(s, " ").replace(o, "x");
|
|
33
|
+
return n(r);
|
|
34
|
+
}, a = (e) => {
|
|
35
|
+
var t;
|
|
36
|
+
return e ? n(e.text) || f.has(e.type) ? !0 : !!((t = e.children) != null && t.some(a)) : !1;
|
|
37
|
+
}, g = (e) => {
|
|
38
|
+
var t, r;
|
|
39
|
+
return e ? !(n(e.plainText) || (t = e.assets) != null && t.length || a((r = e.json) == null ? void 0 : r.root) || c(e.html)) : !0;
|
|
51
40
|
};
|
|
52
41
|
export {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
42
|
+
h as BRIDGERTE_CONTENT_VERSION,
|
|
43
|
+
p as BRIDGERTE_TABLE_INSERT_MAX_COLS,
|
|
44
|
+
T as BRIDGERTE_TABLE_INSERT_MAX_ROWS,
|
|
45
|
+
g as isEditorContentEmpty,
|
|
46
|
+
b as resolvePayloadPanelSchema
|
|
57
47
|
};
|
|
58
48
|
//# sourceMappingURL=core.js.map
|
package/dist/core.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.js","sources":["../../core/src/
|
|
1
|
+
{"version":3,"file":"core.js","sources":["../../core/src/content/index.ts"],"sourcesContent":["import type { EditorContent, EditorContentNode } from './type';\n\nconst invisibleTextPattern = /[\\u200B-\\u200D\\uFEFF]/g;\nconst htmlTagPattern = /<[^>]*>/g;\nconst blankHtmlEntityPattern = /&(?:nbsp|#160|#x0*a0);/gi;\nconst htmlEntityPattern = /&(?:[a-z\\d]+|#\\d+|#x[\\da-f]+);/gi;\nconst meaningfulHtmlElementNames = [\n 'img',\n 'video',\n 'audio',\n 'iframe',\n 'table',\n 'pre',\n 'code',\n 'hr',\n 'figure',\n 'canvas',\n 'svg',\n 'math'\n];\n\n/*\n * 这些节点即使当前没有普通文本,也代表用户主动插入了结构内容。\n * 后续新增非文本内容节点时优先补进这张表;纯段落、列表容器这类结构继续靠子节点判断。\n */\nconst meaningfulStructuredNodeTypes = new Set([\n 'bridgerte-divider',\n 'bridgerte-media',\n 'bridgerte-mention',\n 'code',\n 'horizontalrule',\n 'image',\n 'table',\n 'video'\n]);\n\nconst meaningfulHtmlElementPattern = new RegExp(\n `<(${meaningfulHtmlElementNames.join('|')})(?=[\\\\s>/])`,\n 'i'\n);\n\nconst hasMeaningfulText = (text: string | undefined): boolean => (\n Boolean(text?.replace(invisibleTextPattern, '').trim())\n);\n\nconst hasMeaningfulHtmlFallback = (html: string | undefined): boolean => {\n const htmlValue = html ?? '';\n\n if (!hasMeaningfulText(htmlValue)) return false;\n if (meaningfulHtmlElementPattern.test(htmlValue)) return true;\n\n /*\n * core 不能依赖 DOMParser,这里只做轻量兜底:去掉标签和空白实体后,\n * 其余实体按可见字符处理。需要完整 HTML 语义时使用 DOM 包的解析工具。\n */\n const textLikeContent = htmlValue\n .replace(htmlTagPattern, ' ')\n .replace(blankHtmlEntityPattern, ' ')\n .replace(htmlEntityPattern, 'x');\n\n return hasMeaningfulText(textLikeContent);\n};\n\nconst hasMeaningfulContentNode = (node: EditorContentNode | undefined): boolean => {\n if (!node) return false;\n if (hasMeaningfulText(node.text)) return true;\n if (meaningfulStructuredNodeTypes.has(node.type)) return true;\n\n return Boolean(node.children?.some(hasMeaningfulContentNode));\n};\n\n/**\n * 判断 BridgeRTE 内容快照是否为空。\n *\n * 函数只读取已生成的 `EditorContent` 字段,不触发 DOM 解析或编辑器序列化;调用方应在保存、\n * 提交或离开确认这类低频动作里配合 `editor.getContent()` 使用。\n */\nexport const isEditorContentEmpty = (\n content: Partial<EditorContent> | null | undefined\n): boolean => {\n if (!content) return true;\n if (hasMeaningfulText(content.plainText)) return false;\n if (content.assets?.length) return false;\n if (hasMeaningfulContentNode(content.json?.root)) return false;\n if (hasMeaningfulHtmlFallback(content.html)) return false;\n\n return true;\n};\n"],"names":["invisibleTextPattern","htmlTagPattern","blankHtmlEntityPattern","htmlEntityPattern","meaningfulHtmlElementNames","meaningfulStructuredNodeTypes","meaningfulHtmlElementPattern","hasMeaningfulText","text","hasMeaningfulHtmlFallback","html","htmlValue","textLikeContent","hasMeaningfulContentNode","node","_a","isEditorContentEmpty","content","_b"],"mappings":";;AAEA,MAAMA,IAAuB,0BACvBC,IAAiB,YACjBC,IAAyB,4BACzBC,IAAoB,oCACpBC,IAA6B;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMMC,wBAAoC,IAAI;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC,GAEKC,IAA+B,IAAI;AAAA,EACvC,KAAKF,EAA2B,KAAK,GAAG,CAAC;AAAA,EACzC;AACF,GAEMG,IAAoB,CAACC,MACzB,GAAQA,KAAA,QAAAA,EAAM,QAAQR,GAAsB,IAAI,SAG5CS,IAA4B,CAACC,MAAsC;AACvE,QAAMC,IAAYD,KAAQ;AAE1B,MAAI,CAACH,EAAkBI,CAAS,EAAG,QAAO;AAC1C,MAAIL,EAA6B,KAAKK,CAAS,EAAG,QAAO;AAMzD,QAAMC,IAAkBD,EACrB,QAAQV,GAAgB,GAAG,EAC3B,QAAQC,GAAwB,GAAG,EACnC,QAAQC,GAAmB,GAAG;AAEjC,SAAOI,EAAkBK,CAAe;AAC1C,GAEMC,IAA2B,CAACC,MAAiD;;AACjF,SAAKA,IACDP,EAAkBO,EAAK,IAAI,KAC3BT,EAA8B,IAAIS,EAAK,IAAI,IAAU,KAElD,IAAQC,IAAAD,EAAK,aAAL,QAAAC,EAAe,KAAKF,MAJjB;AAKpB,GAQaG,IAAuB,CAClCC,MACY;;AACZ,SAAKA,IACD,EAAAV,EAAkBU,EAAQ,SAAS,MACnCF,IAAAE,EAAQ,WAAR,QAAAF,EAAgB,UAChBF,GAAyBK,IAAAD,EAAQ,SAAR,gBAAAC,EAAc,IAAI,KAC3CT,EAA0BQ,EAAQ,IAAI,KAJrB;AAOvB;"}
|
package/dist/dom.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-B_g23O7q.cjs"),t=require("./index-H5V0EMkq.cjs");exports.createFloatingLayer=e.createFloatingLayer;exports.createRichTextEditor=e.createRichTextEditor;exports.createWebViewBridgeRuntime=e.createWebViewBridgeRuntime;exports.createRichTextToolbar=t.createRichTextToolbar;exports.hasMeaningfulHtmlContent=t.hasMeaningfulHtmlContent;
|
|
2
2
|
//# sourceMappingURL=dom.cjs.map
|
package/dist/dom.d.ts
CHANGED
|
@@ -182,7 +182,7 @@ export type ToolbarGroupConfig = {
|
|
|
182
182
|
/**
|
|
183
183
|
* toolbar JSON 配置项。
|
|
184
184
|
*
|
|
185
|
-
* 字符串使用 `MenuItem.id`;特殊字符串 `|`
|
|
185
|
+
* 字符串使用 `MenuItem.id`;特殊字符串 `|` 表示分割线,收纳菜单用对象配置显式声明。
|
|
186
186
|
*/
|
|
187
187
|
export type ToolbarKey = string | ToolbarGroupConfig;
|
|
188
188
|
/**
|
|
@@ -513,7 +513,6 @@ export type SlashCommandItem = {
|
|
|
513
513
|
icon?: string;
|
|
514
514
|
description?: string;
|
|
515
515
|
keywords?: string[];
|
|
516
|
-
group?: string;
|
|
517
516
|
requiresPayload?: boolean;
|
|
518
517
|
payloadPanel?: PayloadPanelSchema;
|
|
519
518
|
};
|
|
@@ -579,7 +578,6 @@ export type MenuItem = {
|
|
|
579
578
|
command: EditorCommand;
|
|
580
579
|
label: string;
|
|
581
580
|
icon: string;
|
|
582
|
-
group: 'text' | 'style' | 'block' | 'list' | 'align' | 'insert' | 'media' | 'table' | 'history' | 'view';
|
|
583
581
|
requiresPayload?: boolean;
|
|
584
582
|
payloadPanel?: PayloadPanelSchema;
|
|
585
583
|
children?: MenuItem[];
|
|
@@ -1018,3 +1016,11 @@ export declare function createFloatingLayer(reference: HTMLElement, floating: HT
|
|
|
1018
1016
|
*/
|
|
1019
1017
|
export declare function createRichTextEditor(container: HTMLElement, options?: RichTextEditorOptions): EditorAPI;
|
|
1020
1018
|
|
|
1019
|
+
/**
|
|
1020
|
+
* 判断一段 HTML 片段是否包含可保存的富文本内容。
|
|
1021
|
+
*
|
|
1022
|
+
* 这个工具会使用浏览器 template 解析 HTML,适合只拿到 HTML 字符串的业务表单;如果已经持有
|
|
1023
|
+
* `EditorContent`,优先使用 core 的 `isEditorContentEmpty()`,避免额外 DOM parse。
|
|
1024
|
+
*/
|
|
1025
|
+
export declare const hasMeaningfulHtmlContent: (html: string) => boolean;
|
|
1026
|
+
|
package/dist/dom.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { c as
|
|
2
|
-
import { c as i } from "./index-
|
|
1
|
+
import { c as t, a as r, b as o } from "./index-DyCMSFrm.js";
|
|
2
|
+
import { c as i, h as n } from "./index-BWi3d-Zp.js";
|
|
3
3
|
export {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
t as createFloatingLayer,
|
|
5
|
+
r as createRichTextEditor,
|
|
6
6
|
i as createRichTextToolbar,
|
|
7
|
-
|
|
7
|
+
o as createWebViewBridgeRuntime,
|
|
8
|
+
n as hasMeaningfulHtmlContent
|
|
8
9
|
};
|
|
9
10
|
//# sourceMappingURL=dom.js.map
|