@lobehub/editor 1.29.0 → 1.30.0
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/es/editor-kernel/kernel.js +2 -2
- package/es/editor-kernel/utils.d.ts +2 -1
- package/es/editor-kernel/utils.js +9 -2
- package/es/index.d.ts +1 -0
- package/es/index.js +1 -0
- package/es/plugins/code/plugin/index.js +24 -1
- package/es/plugins/codeblock/plugin/index.js +47 -3
- package/es/plugins/common/plugin/index.js +108 -3
- package/es/plugins/file/plugin/index.js +62 -16
- package/es/plugins/hr/plugin/index.js +25 -1
- package/es/plugins/image/node/basie-image-node.d.ts +2 -10
- package/es/plugins/image/node/basie-image-node.js +5 -30
- package/es/plugins/image/node/block-image-node.d.ts +1 -1
- package/es/plugins/image/node/block-image-node.js +3 -8
- package/es/plugins/image/node/image-node.d.ts +1 -1
- package/es/plugins/image/node/image-node.js +3 -8
- package/es/plugins/image/plugin/index.js +101 -17
- package/es/plugins/link/plugin/index.js +38 -4
- package/es/plugins/list/plugin/index.js +61 -0
- package/es/plugins/litexml/command/index.d.ts +16 -0
- package/es/plugins/litexml/command/index.js +91 -0
- package/es/plugins/litexml/data-source/litexml-data-source.d.ts +60 -0
- package/es/plugins/litexml/data-source/litexml-data-source.js +435 -0
- package/es/plugins/litexml/index.d.ts +7 -0
- package/es/plugins/litexml/index.js +5 -0
- package/es/plugins/litexml/plugin/index.d.ts +16 -0
- package/es/plugins/litexml/plugin/index.js +59 -0
- package/es/plugins/litexml/react/index.d.ts +3 -0
- package/es/plugins/litexml/react/index.js +22 -0
- package/es/plugins/litexml/service/litexml-service.d.ts +85 -0
- package/es/plugins/litexml/service/litexml-service.js +101 -0
- package/es/plugins/litexml/utils/index.d.ts +2 -0
- package/es/plugins/litexml/utils/index.js +33 -0
- package/es/plugins/math/plugin/index.js +40 -0
- package/es/plugins/mention/plugin/index.d.ts +1 -1
- package/es/plugins/mention/plugin/index.js +30 -4
- package/es/plugins/slash/react/ReactSlashPlugin.js +2 -1
- package/es/plugins/table/plugin/index.js +81 -0
- package/es/react/hooks/useEditorState/index.js +2 -1
- package/package.json +7 -6
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
2
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
3
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
4
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
5
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
6
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
7
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
8
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
9
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
10
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
11
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
12
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
13
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
14
|
+
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
|
|
15
|
+
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
|
16
|
+
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
|
17
|
+
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
|
|
18
|
+
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
|
19
|
+
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
|
20
|
+
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
|
21
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
22
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
23
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
24
|
+
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
|
|
25
|
+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
26
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
27
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
28
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
29
|
+
import { DOMParser } from '@xmldom/xmldom';
|
|
30
|
+
import { $getRoot, $getSelection, $isElementNode, $isRangeSelection } from 'lexical';
|
|
31
|
+
import { DataSource } from "../../../editor-kernel";
|
|
32
|
+
import { INodeHelper } from "../../../editor-kernel/inode/helper";
|
|
33
|
+
import { createDebugLogger } from "../../../utils/debug";
|
|
34
|
+
import { LitexmlService } from "../service/litexml-service";
|
|
35
|
+
var logger = createDebugLogger('plugin', 'litexml');
|
|
36
|
+
var IXmlWriterContext = /*#__PURE__*/function () {
|
|
37
|
+
function IXmlWriterContext() {
|
|
38
|
+
_classCallCheck(this, IXmlWriterContext);
|
|
39
|
+
}
|
|
40
|
+
_createClass(IXmlWriterContext, [{
|
|
41
|
+
key: "createXmlNode",
|
|
42
|
+
value: function createXmlNode(tagName, attributes, textContent) {
|
|
43
|
+
return {
|
|
44
|
+
attributes: attributes || {},
|
|
45
|
+
children: [],
|
|
46
|
+
tagName: tagName,
|
|
47
|
+
textContent: textContent
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}]);
|
|
51
|
+
return IXmlWriterContext;
|
|
52
|
+
}();
|
|
53
|
+
/**
|
|
54
|
+
* LitexmlDataSource - Handles conversion between Lexical editor state and XML format
|
|
55
|
+
* Provides read (parse XML to Lexical) and write (export Lexical to XML) capabilities
|
|
56
|
+
*/
|
|
57
|
+
var LitexmlDataSource = /*#__PURE__*/function (_DataSource) {
|
|
58
|
+
_inherits(LitexmlDataSource, _DataSource);
|
|
59
|
+
var _super = _createSuper(LitexmlDataSource);
|
|
60
|
+
function LitexmlDataSource() {
|
|
61
|
+
var _this;
|
|
62
|
+
var dataType = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'litexml';
|
|
63
|
+
var service = arguments.length > 1 ? arguments[1] : undefined;
|
|
64
|
+
_classCallCheck(this, LitexmlDataSource);
|
|
65
|
+
_this = _super.call(this, dataType);
|
|
66
|
+
_defineProperty(_assertThisInitialized(_this), "litexmlService", void 0);
|
|
67
|
+
_defineProperty(_assertThisInitialized(_this), "ctx", new IXmlWriterContext());
|
|
68
|
+
_this.dataType = dataType;
|
|
69
|
+
_this.litexmlService = service || new LitexmlService();
|
|
70
|
+
return _this;
|
|
71
|
+
}
|
|
72
|
+
_createClass(LitexmlDataSource, [{
|
|
73
|
+
key: "readLiteXMLToInode",
|
|
74
|
+
value: function readLiteXMLToInode(litexml) {
|
|
75
|
+
if (typeof litexml !== 'string') {
|
|
76
|
+
throw new Error('Invalid data type. Expected string, got ' + _typeof(litexml));
|
|
77
|
+
}
|
|
78
|
+
var xml = this.parseXMLString(litexml);
|
|
79
|
+
var inode = this.xmlToLexical(xml);
|
|
80
|
+
logger.debug('Parsed XML to Lexical State:', inode);
|
|
81
|
+
return inode;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Parse XML string and set it to the editor
|
|
86
|
+
* @param editor - The Lexical editor instance
|
|
87
|
+
* @param data - XML string to parse
|
|
88
|
+
*/
|
|
89
|
+
}, {
|
|
90
|
+
key: "read",
|
|
91
|
+
value: function read(editor, data) {
|
|
92
|
+
try {
|
|
93
|
+
var inode = this.readLiteXMLToInode(data);
|
|
94
|
+
editor.setEditorState(editor.parseEditorState(inode));
|
|
95
|
+
} catch (error) {
|
|
96
|
+
logger.error('Failed to parse XML:', error);
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Export editor content to XML format
|
|
103
|
+
* @param editor - The Lexical editor instance
|
|
104
|
+
* @param options - Write options (e.g., selection flag)
|
|
105
|
+
* @returns XML string representation of the editor content
|
|
106
|
+
*/
|
|
107
|
+
}, {
|
|
108
|
+
key: "write",
|
|
109
|
+
value: function write(editor, options) {
|
|
110
|
+
var _this2 = this;
|
|
111
|
+
try {
|
|
112
|
+
if (options !== null && options !== void 0 && options.selection) {
|
|
113
|
+
return editor.read(function () {
|
|
114
|
+
var selection = $getSelection();
|
|
115
|
+
if (!selection) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
if ($isRangeSelection(selection)) {
|
|
119
|
+
var selectedNodes = selection.getNodes();
|
|
120
|
+
var rootNode = INodeHelper.createRootNode();
|
|
121
|
+
|
|
122
|
+
// Wrap inline nodes in a paragraph
|
|
123
|
+
if (selectedNodes.some(function (node) {
|
|
124
|
+
return node.isInline();
|
|
125
|
+
})) {
|
|
126
|
+
var p = INodeHelper.createParagraph();
|
|
127
|
+
INodeHelper.appendChild.apply(INodeHelper, [p].concat(_toConsumableArray(selectedNodes.map(function (node) {
|
|
128
|
+
return node.exportJSON();
|
|
129
|
+
}))));
|
|
130
|
+
INodeHelper.appendChild(rootNode, p);
|
|
131
|
+
} else {
|
|
132
|
+
INodeHelper.appendChild.apply(INodeHelper, [rootNode].concat(_toConsumableArray(selectedNodes.map(function (node) {
|
|
133
|
+
return node.exportJSON();
|
|
134
|
+
}))));
|
|
135
|
+
}
|
|
136
|
+
var editorState = editor.parseEditorState({
|
|
137
|
+
root: rootNode
|
|
138
|
+
});
|
|
139
|
+
return editorState.read(function () {
|
|
140
|
+
var lexicalRootNode = $getRoot();
|
|
141
|
+
return _this2.lexicalToXML(lexicalRootNode);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
return null;
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
return editor.getEditorState().read(function () {
|
|
148
|
+
var rootNode = $getRoot();
|
|
149
|
+
return _this2.lexicalToXML(rootNode);
|
|
150
|
+
});
|
|
151
|
+
} catch (error) {
|
|
152
|
+
logger.error('Failed to export to XML:', error);
|
|
153
|
+
throw error;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Parse XML string using browser's built-in parser
|
|
159
|
+
*/
|
|
160
|
+
}, {
|
|
161
|
+
key: "parseXMLString",
|
|
162
|
+
value: function parseXMLString(xmlString) {
|
|
163
|
+
var parser = new DOMParser();
|
|
164
|
+
var doc = parser.parseFromString(xmlString, 'text/xml');
|
|
165
|
+
if (doc.getElementsByTagName('parsererror').length > 0) {
|
|
166
|
+
throw new Error('Invalid XML: ' + xmlString);
|
|
167
|
+
}
|
|
168
|
+
return doc;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Convert XML document to Lexical node structure
|
|
173
|
+
*/
|
|
174
|
+
}, {
|
|
175
|
+
key: "xmlToLexical",
|
|
176
|
+
value: function xmlToLexical(xml) {
|
|
177
|
+
var rootNode = INodeHelper.createRootNode();
|
|
178
|
+
|
|
179
|
+
// Process XML root element's children
|
|
180
|
+
var xmlRoot = xml.documentElement;
|
|
181
|
+
if (xmlRoot) {
|
|
182
|
+
this.processXMLElement(xmlRoot, rootNode);
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
root: rootNode
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Recursively process XML elements and convert to Lexical nodes
|
|
191
|
+
*/
|
|
192
|
+
}, {
|
|
193
|
+
key: "processXMLElement",
|
|
194
|
+
value: function processXMLElement(xmlElement, parentNode) {
|
|
195
|
+
var _this3 = this;
|
|
196
|
+
var tagName = xmlElement.tagName.toLowerCase();
|
|
197
|
+
var customReaders = this.litexmlService.getXMLReaders();
|
|
198
|
+
|
|
199
|
+
// Check if there's a custom reader for this tag
|
|
200
|
+
if (customReaders[tagName]) {
|
|
201
|
+
var readerOrReaders = customReaders[tagName];
|
|
202
|
+
var readers = Array.isArray(readerOrReaders) ? readerOrReaders : [readerOrReaders];
|
|
203
|
+
var _iterator = _createForOfIteratorHelper(readers),
|
|
204
|
+
_step;
|
|
205
|
+
try {
|
|
206
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
207
|
+
var reader = _step.value;
|
|
208
|
+
var children = [];
|
|
209
|
+
this.processXMLChildren(xmlElement, {
|
|
210
|
+
children: children
|
|
211
|
+
});
|
|
212
|
+
var result = reader(xmlElement, children);
|
|
213
|
+
if (result !== false) {
|
|
214
|
+
if (Array.isArray(result)) {
|
|
215
|
+
INodeHelper.appendChild.apply(INodeHelper, [parentNode].concat(_toConsumableArray(result)));
|
|
216
|
+
} else if (result) {
|
|
217
|
+
result.id = xmlElement.getAttribute('id') || undefined;
|
|
218
|
+
INodeHelper.appendChild(parentNode, result);
|
|
219
|
+
}
|
|
220
|
+
return; // Custom reader handled it
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
} catch (err) {
|
|
224
|
+
_iterator.e(err);
|
|
225
|
+
} finally {
|
|
226
|
+
_iterator.f();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Fall back to built-in handlers
|
|
231
|
+
switch (tagName) {
|
|
232
|
+
case 'p':
|
|
233
|
+
case 'paragraph':
|
|
234
|
+
{
|
|
235
|
+
var paragraph = INodeHelper.createParagraph();
|
|
236
|
+
this.processXMLChildren(xmlElement, paragraph);
|
|
237
|
+
INodeHelper.appendChild(parentNode, paragraph);
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
case 'h1':
|
|
241
|
+
case 'h2':
|
|
242
|
+
case 'h3':
|
|
243
|
+
case 'h4':
|
|
244
|
+
case 'h5':
|
|
245
|
+
case 'h6':
|
|
246
|
+
{
|
|
247
|
+
var level = parseInt(tagName.charAt(1));
|
|
248
|
+
var heading = INodeHelper.createElementNode('heading', {
|
|
249
|
+
children: [],
|
|
250
|
+
tag: "h".concat(level)
|
|
251
|
+
});
|
|
252
|
+
this.processXMLChildren(xmlElement, heading);
|
|
253
|
+
INodeHelper.appendChild(parentNode, heading);
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
case 'ul':
|
|
257
|
+
case 'ol':
|
|
258
|
+
{
|
|
259
|
+
xmlElement.querySelectorAll(':scope > li').forEach(function (li) {
|
|
260
|
+
var listItem = INodeHelper.createElementNode('listitem', {
|
|
261
|
+
children: [],
|
|
262
|
+
value: 1
|
|
263
|
+
});
|
|
264
|
+
_this3.processXMLChildren(li, listItem);
|
|
265
|
+
INodeHelper.appendChild(parentNode, listItem);
|
|
266
|
+
});
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
case 'blockquote':
|
|
270
|
+
{
|
|
271
|
+
var quote = INodeHelper.createElementNode('quote', {
|
|
272
|
+
children: []
|
|
273
|
+
});
|
|
274
|
+
this.processXMLChildren(xmlElement, quote);
|
|
275
|
+
INodeHelper.appendChild(parentNode, quote);
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
278
|
+
case 'code':
|
|
279
|
+
{
|
|
280
|
+
var codeNode = INodeHelper.createElementNode('codeInline', {
|
|
281
|
+
children: [INodeHelper.createTextNode(xmlElement.textContent || '')]
|
|
282
|
+
});
|
|
283
|
+
INodeHelper.appendChild(parentNode, codeNode);
|
|
284
|
+
break;
|
|
285
|
+
}
|
|
286
|
+
case 'text':
|
|
287
|
+
{
|
|
288
|
+
var textContent = xmlElement.textContent || '';
|
|
289
|
+
if (textContent) {
|
|
290
|
+
var textNode = INodeHelper.createTextNode(textContent);
|
|
291
|
+
INodeHelper.appendChild(parentNode, textNode);
|
|
292
|
+
}
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
default:
|
|
296
|
+
{
|
|
297
|
+
// Treat unknown tags as generic containers
|
|
298
|
+
this.processXMLChildren(xmlElement, parentNode);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Process XML element's children
|
|
305
|
+
*/
|
|
306
|
+
}, {
|
|
307
|
+
key: "processXMLChildren",
|
|
308
|
+
value: function processXMLChildren(xmlElement, parentNode) {
|
|
309
|
+
var _this4 = this;
|
|
310
|
+
Array.from(xmlElement.childNodes).forEach(function (child) {
|
|
311
|
+
if (child.nodeType === 1) {
|
|
312
|
+
// Element node
|
|
313
|
+
_this4.processXMLElement(child, parentNode);
|
|
314
|
+
} else if (child.nodeType === 3) {
|
|
315
|
+
// Text node
|
|
316
|
+
var text = child.textContent || '';
|
|
317
|
+
if (text.trim()) {
|
|
318
|
+
var textNode = INodeHelper.createTextNode(text);
|
|
319
|
+
INodeHelper.appendChild(parentNode, textNode);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Convert Lexical node structure to XML string
|
|
327
|
+
*/
|
|
328
|
+
}, {
|
|
329
|
+
key: "lexicalToXML",
|
|
330
|
+
value: function lexicalToXML(rootNode) {
|
|
331
|
+
var _this5 = this;
|
|
332
|
+
var xmlLines = ['<?xml version="1.0" encoding="UTF-8"?>'];
|
|
333
|
+
xmlLines.push('<root>');
|
|
334
|
+
var children = rootNode.getChildren();
|
|
335
|
+
children.forEach(function (child) {
|
|
336
|
+
_this5.nodesToXML(child, xmlLines);
|
|
337
|
+
});
|
|
338
|
+
xmlLines.push('</root>');
|
|
339
|
+
return xmlLines.join('\n');
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Recursively convert Lexical nodes to XML elements
|
|
344
|
+
*/
|
|
345
|
+
}, {
|
|
346
|
+
key: "nodesToXML",
|
|
347
|
+
value: function nodesToXML(node, lines) {
|
|
348
|
+
var _this6 = this;
|
|
349
|
+
var indent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
|
|
350
|
+
var indentStr = ' '.repeat(indent * 2);
|
|
351
|
+
var type = node.getType();
|
|
352
|
+
var customWriters = this.litexmlService.getXMLWriters();
|
|
353
|
+
var childLines = [];
|
|
354
|
+
|
|
355
|
+
// Check if there's a custom writer for this node type
|
|
356
|
+
if (customWriters[type]) {
|
|
357
|
+
var writerOrWriters = customWriters[type];
|
|
358
|
+
var writers = Array.isArray(writerOrWriters) ? writerOrWriters : [writerOrWriters];
|
|
359
|
+
var _iterator2 = _createForOfIteratorHelper(writers),
|
|
360
|
+
_step2;
|
|
361
|
+
try {
|
|
362
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
363
|
+
var writer = _step2.value;
|
|
364
|
+
var handled = writer(node, this.ctx, indent);
|
|
365
|
+
if (handled) {
|
|
366
|
+
var attrs = this.buildXMLAttributes(_objectSpread({
|
|
367
|
+
id: node.getKey()
|
|
368
|
+
}, handled.attributes));
|
|
369
|
+
var openTag = "".concat(indentStr, "<").concat(handled.tagName).concat(attrs, ">");
|
|
370
|
+
var closeTag = "</".concat(handled.tagName, ">");
|
|
371
|
+
if (handled.textContent) {
|
|
372
|
+
childLines.push(handled.textContent);
|
|
373
|
+
lines.push("".concat(openTag).concat(childLines.join('')).concat(closeTag));
|
|
374
|
+
} else if ($isElementNode(node)) {
|
|
375
|
+
var children = node.getChildren();
|
|
376
|
+
children.forEach(function (child) {
|
|
377
|
+
_this6.nodesToXML(child, childLines, indent + 1);
|
|
378
|
+
});
|
|
379
|
+
lines.push.apply(lines, [openTag].concat(childLines, ["".concat(indentStr).concat(closeTag)]));
|
|
380
|
+
} else {
|
|
381
|
+
lines.push(openTag, "".concat(indentStr).concat(closeTag));
|
|
382
|
+
}
|
|
383
|
+
return; // Custom writer handled it
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
} catch (err) {
|
|
387
|
+
_iterator2.e(err);
|
|
388
|
+
} finally {
|
|
389
|
+
_iterator2.f();
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
if ($isElementNode(node)) {
|
|
393
|
+
var _children = node.getChildren();
|
|
394
|
+
_children.forEach(function (child) {
|
|
395
|
+
_this6.nodesToXML(child, childLines, indent + 1);
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
lines.push.apply(lines, childLines);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Build XML attribute string from attributes object
|
|
403
|
+
*/
|
|
404
|
+
}, {
|
|
405
|
+
key: "buildXMLAttributes",
|
|
406
|
+
value: function buildXMLAttributes(attributes) {
|
|
407
|
+
var _this7 = this;
|
|
408
|
+
if (!attributes || _typeof(attributes) !== 'object') {
|
|
409
|
+
return '';
|
|
410
|
+
}
|
|
411
|
+
return Object.entries(attributes).filter(function (_ref) {
|
|
412
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
413
|
+
value = _ref2[1];
|
|
414
|
+
return value !== undefined && value !== null && value !== '';
|
|
415
|
+
}).map(function (_ref3) {
|
|
416
|
+
var _ref4 = _slicedToArray(_ref3, 2),
|
|
417
|
+
key = _ref4[0],
|
|
418
|
+
value = _ref4[1];
|
|
419
|
+
var escapedValue = _this7.escapeXML(String(value));
|
|
420
|
+
return " ".concat(key, "=\"").concat(escapedValue, "\"");
|
|
421
|
+
}).join('');
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Escape XML special characters
|
|
426
|
+
*/
|
|
427
|
+
}, {
|
|
428
|
+
key: "escapeXML",
|
|
429
|
+
value: function escapeXML(text) {
|
|
430
|
+
return text.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>').replaceAll('"', '"').replaceAll("'", ''');
|
|
431
|
+
}
|
|
432
|
+
}]);
|
|
433
|
+
return LitexmlDataSource;
|
|
434
|
+
}(DataSource);
|
|
435
|
+
export { LitexmlDataSource as default };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { LITEXML_APPLY_COMMAND, LITEXML_INSERT_COMMAND, LITEXML_REMOVE_COMMAND } from './command';
|
|
2
|
+
export { default as LitexmlDataSource } from './data-source/litexml-data-source';
|
|
3
|
+
export type { LitexmlPluginOptions } from './plugin';
|
|
4
|
+
export { LitexmlPlugin } from './plugin';
|
|
5
|
+
export { ReactLiteXmlPlugin } from './react';
|
|
6
|
+
export type { XMLReaderFunc, XMLReaderRecord, XMLWriterFunc, XMLWriterRecord, } from './service/litexml-service';
|
|
7
|
+
export { ILitexmlService, LitexmlService } from './service/litexml-service';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { LITEXML_APPLY_COMMAND, LITEXML_INSERT_COMMAND, LITEXML_REMOVE_COMMAND } from "./command";
|
|
2
|
+
export { default as LitexmlDataSource } from "./data-source/litexml-data-source";
|
|
3
|
+
export { LitexmlPlugin } from "./plugin";
|
|
4
|
+
export { ReactLiteXmlPlugin } from "./react";
|
|
5
|
+
export { ILitexmlService, LitexmlService } from "./service/litexml-service";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { IEditorPluginConstructor } from "../../../types";
|
|
2
|
+
/**
|
|
3
|
+
* LitexmlPluginOptions - Configuration options for the Litexml plugin
|
|
4
|
+
*/
|
|
5
|
+
export interface LitexmlPluginOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Enable or disable the litexml data source
|
|
8
|
+
* @default true
|
|
9
|
+
*/
|
|
10
|
+
enabled?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* LitexmlPlugin - A plugin that provides XML-based data source support
|
|
14
|
+
* Allows converting between Lexical editor state and XML format
|
|
15
|
+
*/
|
|
16
|
+
export declare const LitexmlPlugin: IEditorPluginConstructor<LitexmlPluginOptions>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
var _class;
|
|
2
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
3
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
4
|
+
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
|
|
5
|
+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
6
|
+
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
|
|
7
|
+
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
|
8
|
+
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
|
9
|
+
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
|
|
10
|
+
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
|
11
|
+
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
|
12
|
+
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
|
13
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
14
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
15
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
16
|
+
import { KernelPlugin } from "../../../editor-kernel/plugin";
|
|
17
|
+
import { registerLiteXMLCommand } from "../command";
|
|
18
|
+
import LitexmlDataSource from "../data-source/litexml-data-source";
|
|
19
|
+
import { ILitexmlService, LitexmlService } from "../service/litexml-service";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* LitexmlPluginOptions - Configuration options for the Litexml plugin
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* LitexmlPlugin - A plugin that provides XML-based data source support
|
|
27
|
+
* Allows converting between Lexical editor state and XML format
|
|
28
|
+
*/
|
|
29
|
+
export var LitexmlPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
30
|
+
_inherits(LitexmlPlugin, _KernelPlugin);
|
|
31
|
+
var _super = _createSuper(LitexmlPlugin);
|
|
32
|
+
function LitexmlPlugin(kernel, config) {
|
|
33
|
+
var _this;
|
|
34
|
+
_classCallCheck(this, LitexmlPlugin);
|
|
35
|
+
_this = _super.call(this);
|
|
36
|
+
|
|
37
|
+
// Create and register the Litexml service
|
|
38
|
+
_defineProperty(_assertThisInitialized(_this), "datasource", void 0);
|
|
39
|
+
_this.kernel = kernel;
|
|
40
|
+
_this.config = config;
|
|
41
|
+
var litexmlService = new LitexmlService();
|
|
42
|
+
kernel.registerService(ILitexmlService, litexmlService);
|
|
43
|
+
_this.datasource = new LitexmlDataSource('litexml', litexmlService);
|
|
44
|
+
|
|
45
|
+
// Register the litexml data source
|
|
46
|
+
if ((config === null || config === void 0 ? void 0 : config.enabled) !== false) {
|
|
47
|
+
kernel.registerDataSource(_this.datasource);
|
|
48
|
+
}
|
|
49
|
+
return _this;
|
|
50
|
+
}
|
|
51
|
+
_createClass(LitexmlPlugin, [{
|
|
52
|
+
key: "onInit",
|
|
53
|
+
value: function onInit(editor) {
|
|
54
|
+
// Plugin initialization logic can be added here if needed
|
|
55
|
+
registerLiteXMLCommand(editor, this.datasource);
|
|
56
|
+
}
|
|
57
|
+
}]);
|
|
58
|
+
return LitexmlPlugin;
|
|
59
|
+
}(KernelPlugin), _defineProperty(_class, "pluginName", 'LitexmlPlugin'), _class);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
4
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
5
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
6
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
7
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
8
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
9
|
+
import { useLayoutEffect } from 'react';
|
|
10
|
+
import { useLexicalComposerContext } from "../../../editor-kernel/react";
|
|
11
|
+
import { LitexmlPlugin } from "../plugin";
|
|
12
|
+
export var ReactLiteXmlPlugin = function ReactLiteXmlPlugin() {
|
|
13
|
+
var _useLexicalComposerCo = useLexicalComposerContext(),
|
|
14
|
+
_useLexicalComposerCo2 = _slicedToArray(_useLexicalComposerCo, 1),
|
|
15
|
+
editor = _useLexicalComposerCo2[0];
|
|
16
|
+
useLayoutEffect(function () {
|
|
17
|
+
editor.registerPlugin(LitexmlPlugin);
|
|
18
|
+
}, [editor]);
|
|
19
|
+
return null;
|
|
20
|
+
};
|
|
21
|
+
ReactLiteXmlPlugin.displayName = 'ReactLiteXmlPlugin';
|
|
22
|
+
export default ReactLiteXmlPlugin;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { LexicalNode } from 'lexical';
|
|
2
|
+
/**
|
|
3
|
+
* XML Reader function type - converts XML element to Lexical node
|
|
4
|
+
*/
|
|
5
|
+
export type XMLReaderFunc = (xmlElement: Element, children: any[]) => any | any[] | false;
|
|
6
|
+
/**
|
|
7
|
+
* XML Writer function type - converts Lexical node to XML string
|
|
8
|
+
*/
|
|
9
|
+
export type XMLWriterFunc = (node: LexicalNode, ctx: IWriterContext, indent: number) => IXmlNode | false;
|
|
10
|
+
/**
|
|
11
|
+
* Record of XML readers indexed by tag name
|
|
12
|
+
*/
|
|
13
|
+
export type XMLReaderRecord = {
|
|
14
|
+
[tagName: string]: XMLReaderFunc | XMLReaderFunc[];
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Record of XML writers indexed by node type
|
|
18
|
+
*/
|
|
19
|
+
export type XMLWriterRecord = {
|
|
20
|
+
[nodeType: string]: XMLWriterFunc | XMLWriterFunc[];
|
|
21
|
+
};
|
|
22
|
+
export interface IXmlNode {
|
|
23
|
+
attributes: {
|
|
24
|
+
[key: string]: string;
|
|
25
|
+
};
|
|
26
|
+
children?: IXmlNode[];
|
|
27
|
+
tagName: string;
|
|
28
|
+
textContent?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface IWriterContext {
|
|
31
|
+
createXmlNode(tagName: string, attributes?: {
|
|
32
|
+
[key: string]: string;
|
|
33
|
+
}, textContent?: string): IXmlNode;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* ILitexmlService - Service interface for extending Litexml plugin
|
|
37
|
+
* Allows other plugins to register custom XML readers and writers
|
|
38
|
+
*/
|
|
39
|
+
export interface ILitexmlService {
|
|
40
|
+
/**
|
|
41
|
+
* Get all registered XML readers
|
|
42
|
+
*/
|
|
43
|
+
getXMLReaders(): XMLReaderRecord;
|
|
44
|
+
/**
|
|
45
|
+
* Get all registered XML writers
|
|
46
|
+
*/
|
|
47
|
+
getXMLWriters(): XMLWriterRecord;
|
|
48
|
+
/**
|
|
49
|
+
* Check if a reader is registered for a tag
|
|
50
|
+
*/
|
|
51
|
+
hasXMLReader(tagName: string): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Check if a writer is registered for a node type
|
|
54
|
+
*/
|
|
55
|
+
hasXMLWriter(nodeType: string): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Register a custom XML reader for a specific tag name
|
|
58
|
+
* @param tagName - XML tag name to handle (case-insensitive)
|
|
59
|
+
* @param reader - Function that converts XML element to Lexical node
|
|
60
|
+
*/
|
|
61
|
+
registerXMLReader(tagName: string, reader: XMLReaderFunc): void;
|
|
62
|
+
/**
|
|
63
|
+
* Register a custom XML writer for a specific Lexical node type
|
|
64
|
+
* @param nodeType - Lexical node type to handle
|
|
65
|
+
* @param writer - Function that converts Lexical node to XML string
|
|
66
|
+
*/
|
|
67
|
+
registerXMLWriter(nodeType: string, writer: XMLWriterFunc): void;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Service ID for Litexml service
|
|
71
|
+
*/
|
|
72
|
+
export declare const ILitexmlService: import("../../../types").IServiceID<ILitexmlService>;
|
|
73
|
+
/**
|
|
74
|
+
* Default implementation of ILitexmlService
|
|
75
|
+
*/
|
|
76
|
+
export declare class LitexmlService implements ILitexmlService {
|
|
77
|
+
private readers;
|
|
78
|
+
private writers;
|
|
79
|
+
registerXMLReader(tagName: string, reader: XMLReaderFunc): void;
|
|
80
|
+
registerXMLWriter(nodeType: string, writer: XMLWriterFunc): void;
|
|
81
|
+
getXMLReaders(): XMLReaderRecord;
|
|
82
|
+
getXMLWriters(): XMLWriterRecord;
|
|
83
|
+
hasXMLReader(tagName: string): boolean;
|
|
84
|
+
hasXMLWriter(nodeType: string): boolean;
|
|
85
|
+
}
|