@8btc/mditor 0.0.25 → 0.0.27

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.
@@ -254591,6 +254591,32 @@
254591
254591
  });
254592
254592
  return md
254593
254593
  }
254594
+
254595
+ function __vditorPreprocessCustomTags(md) {
254596
+ if (!md || typeof md !== "string") return md;
254597
+
254598
+ // 第二步:处理自闭合标签 <tag attr="value" /> → <tag attr="value"></tag>
254599
+ // 匹配所有合法自定义标签(小写字母开头,含字母/数字/短横线)
254600
+ const selfClosingRegex = /<([a-z][a-z0-9-]*)\s+([^>]*?)\s*\/>/gi;
254601
+ md = md.replace(selfClosingRegex, function(match, tagName, attrs) {
254602
+ return `<${tagName} ${attrs}></${tagName}>`;
254603
+ });
254604
+
254605
+ // 第三步:处理纯开标签 <tag attr="value"> → <tag attr="value"></tag>
254606
+ // 修复:将标签外的空白字符(\s*)排除在匹配范围外,避免替换换行符
254607
+ const unclosedTagRegex = /<([a-z][a-z0-9-]*)\s+([^>]*?)>(?<!\/)(?!\s*<\/\1\s*>)/gi;
254608
+ md = md.replace(unclosedTagRegex, function(match, tagName, attrs) {
254609
+ // 兜底过滤:避免已闭合标签被重复处理
254610
+ if (match.includes('/>') || match.endsWith(`></${tagName}>`)) {
254611
+ return match;
254612
+ }
254613
+ // 只替换标签本身,保留原有换行符
254614
+ return `<${tagName} ${attrs}></${tagName}>`;
254615
+ });
254616
+
254617
+ return md;
254618
+ }
254619
+
254594
254620
  if (typeof window !== "undefined" && window.Lute && typeof window.Lute.New === "function") {
254595
254621
  var __origNew = window.Lute.New;
254596
254622
  window.Lute.New = function() {
@@ -254600,7 +254626,9 @@
254600
254626
  var orig = inst && inst[name];
254601
254627
  if (typeof orig === "function") {
254602
254628
  inst[name] = function(text) {
254603
- return orig.call(inst, __vditorPreprocessBackslashMath(text))
254629
+ text = __vditorPreprocessBackslashMath(text);
254630
+ text = __vditorPreprocessCustomTags(text);
254631
+ return orig.call(inst, text)
254604
254632
  }
254605
254633
  }
254606
254634
  }
package/dist/method.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vditor v0.0.25 - A markdown editor written in TypeScript.
2
+ * Vditor v0.0.27 - A markdown editor written in TypeScript.
3
3
  *
4
4
  * MIT License
5
5
  *
@@ -45,7 +45,7 @@ return /******/ (() => { // webpackBootstrap
45
45
  /* harmony export */ "g": () => (/* binding */ Constants)
46
46
  /* harmony export */ });
47
47
  /* unused harmony export VDITOR_VERSION */
48
- var _VDITOR_VERSION = (/* unused pure expression or super */ null && ("0.0.25"));
48
+ var _VDITOR_VERSION = (/* unused pure expression or super */ null && ("0.0.27"));
49
49
 
50
50
  var Constants = /** @class */ (function () {
51
51
  function Constants() {
@@ -347,7 +347,7 @@ var Constants = /** @class */ (function () {
347
347
  "c#",
348
348
  "bat",
349
349
  ];
350
- Constants.CDN = "https://webcdn.wujieai.com/vditor@".concat("0.0.25");
350
+ Constants.CDN = "https://webcdn.wujieai.com/vditor@".concat("0.0.27");
351
351
  Constants.MARKDOWN_OPTIONS = {
352
352
  autoSpace: false,
353
353
  gfmAutoLink: true,
@@ -4163,26 +4163,6 @@ var attachLineNumbersToBlocks = function (root, sourceMarkdown) {
4163
4163
  tableGroups: tableGroups,
4164
4164
  });
4165
4165
  }
4166
- console.log("[LineNumber][perf]", {
4167
- cached: !!cached,
4168
- times: {
4169
- normalize: Math.round((tNorm - t0) * 100) / 100,
4170
- index: Math.round((tIndexDone - tNorm) * 100) / 100,
4171
- blocks: Math.round((tBlockDone - tIndexDone) * 100) / 100,
4172
- ul: Math.round((tUlDone - tBlockDone) * 100) / 100,
4173
- ol: Math.round((tOlDone - tUlDone) * 100) / 100,
4174
- table: Math.round((tTableDone - tIndexDone) * 100) / 100,
4175
- apply: Math.round((tApplyDone - tTableDone) * 100) / 100,
4176
- total: Math.round((tApplyDone - t0) * 100) / 100,
4177
- },
4178
- counts: {
4179
- blocks: blocks.length,
4180
- ul: ulElements.length,
4181
- ol: olElements.length,
4182
- tables: tables.length,
4183
- updates: attrUpdates.length,
4184
- },
4185
- });
4186
4166
  };
4187
4167
  /**
4188
4168
  * 节流后的行号更新函数,避免频繁更新 data-linenumber
@@ -5136,6 +5116,147 @@ var speechRender = function (element, lang) {
5136
5116
  var selectionRender = __webpack_require__(616);
5137
5117
  // EXTERNAL MODULE: ./src/ts/util/mathSelection.ts
5138
5118
  var mathSelection = __webpack_require__(35);
5119
+ ;// CONCATENATED MODULE: ./src/ts/markdown/customRender.ts
5120
+ /**
5121
+ * 自定义组件渲染模块
5122
+ * 支持将 HTML 标签(如 <read-button label="文献解读">)转换为自定义 HTML
5123
+ */
5124
+ var __assign = (undefined && undefined.__assign) || function () {
5125
+ __assign = Object.assign || function(t) {
5126
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5127
+ s = arguments[i];
5128
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
5129
+ t[p] = s[p];
5130
+ }
5131
+ return t;
5132
+ };
5133
+ return __assign.apply(this, arguments);
5134
+ };
5135
+ /**
5136
+ * 解析 HTML 属性字符串
5137
+ * @param str 属性字符串,如 'label="文献解读" id="test"'
5138
+ * @returns 属性对象
5139
+ */
5140
+ function parseAttributes(str) {
5141
+ var attributes = {};
5142
+ if (!str)
5143
+ return attributes;
5144
+ var attrRegex = /(\w+)="([^"]*)"/g;
5145
+ var match;
5146
+ while ((match = attrRegex.exec(str)) !== null) {
5147
+ attributes[match[1]] = match[2];
5148
+ }
5149
+ return attributes;
5150
+ }
5151
+ /**
5152
+ * 从 HTML 字符串中提取自定义标签
5153
+ * @param html HTML 字符串
5154
+ * @param tagName 标签名称,如 'read-button'
5155
+ * @returns 匹配的标签信息数组
5156
+ */
5157
+ function extractCustomTags(html, tagName) {
5158
+ var results = [];
5159
+ // 匹配自闭合标签和非自闭合标签
5160
+ var selfClosingRegex = new RegExp("<".concat(tagName, "\\s+([^>]*)\\s*/>"), "g");
5161
+ var openCloseRegex = new RegExp("<".concat(tagName, "\\s+([^>]*)>([^<]*)</").concat(tagName, ">"), "g");
5162
+ var match;
5163
+ // 处理自闭合标签
5164
+ while ((match = selfClosingRegex.exec(html)) !== null) {
5165
+ results.push({
5166
+ fullTag: match[0],
5167
+ attributes: parseAttributes(match[1]),
5168
+ content: "",
5169
+ });
5170
+ }
5171
+ // 处理开闭合标签
5172
+ while ((match = openCloseRegex.exec(html)) !== null) {
5173
+ results.push({
5174
+ fullTag: match[0],
5175
+ attributes: parseAttributes(match[1]),
5176
+ content: match[2],
5177
+ });
5178
+ }
5179
+ return results;
5180
+ }
5181
+ /**
5182
+ * 使用 HTML 字符串渲染自定义标签
5183
+ * @param html HTML 字符串
5184
+ * @param tagName 标签名称
5185
+ * @param component 自定义组件配置
5186
+ * @returns 修改后的 HTML 字符串
5187
+ */
5188
+ function renderCustomComponentHTML(html, tagName, component) {
5189
+ var tags = extractCustomTags(html, tagName);
5190
+ var result = html;
5191
+ // 反向遍历以保持位置正确性
5192
+ for (var i = tags.length - 1; i >= 0; i--) {
5193
+ var tag = tags[i];
5194
+ var htmlString = component.renderHTML(tag.attributes);
5195
+ result = result.replace(tag.fullTag, htmlString);
5196
+ }
5197
+ return result;
5198
+ }
5199
+ /**
5200
+ * 在 DOM 元素中查找并渲染自定义组件
5201
+ * @param element DOM 元素
5202
+ * @param customComponents 自定义组件集合
5203
+ */
5204
+ function renderCustomComponents(element, customComponents) {
5205
+ Object.keys(customComponents).forEach(function (tagName) {
5206
+ var component = customComponents[tagName];
5207
+ var customElements = element.querySelectorAll(tagName);
5208
+ // 反向遍历以避免 DOM 修改时的索引问题
5209
+ Array.from(customElements)
5210
+ .reverse()
5211
+ .forEach(function (el) {
5212
+ var attributes = {};
5213
+ el.getAttributeNames().forEach(function (name) {
5214
+ attributes[name] = el.getAttribute(name) || "";
5215
+ });
5216
+ // 使用 innerHTML 保留内部 HTML 内容,而不仅仅是纯文本
5217
+ var content = el.innerHTML || "";
5218
+ // 使用 HTML 渲染
5219
+ var htmlString = component.renderHTML(__assign(__assign({}, attributes), { children: content }));
5220
+ el.outerHTML = htmlString;
5221
+ });
5222
+ });
5223
+ }
5224
+ /**
5225
+ * 批量处理自定义组件 - 用于预处理 HTML 字符串
5226
+ * @param html HTML 字符串
5227
+ * @param customComponents 自定义组件集合
5228
+ * @returns 处理后的 HTML 字符串
5229
+ */
5230
+ function processCustomComponents(html, customComponents) {
5231
+ var result = html;
5232
+ Object.keys(customComponents).forEach(function (tagName) {
5233
+ var component = customComponents[tagName];
5234
+ result = renderCustomComponentHTML(result, tagName, component);
5235
+ });
5236
+ return result;
5237
+ }
5238
+ /**
5239
+ * 处理 markdown 中的自定义组件
5240
+ * 将 markdown 中的自定义标签转换为对应的 HTML
5241
+ * @param markdown markdown 字符串
5242
+ * @param customComponents 自定义组件集合
5243
+ * @returns 处理后的 markdown 字符串
5244
+ */
5245
+ function processMarkdownCustomComponents(markdown, customComponents) {
5246
+ var result = markdown;
5247
+ Object.keys(customComponents).forEach(function (tagName) {
5248
+ var component = customComponents[tagName];
5249
+ result = renderCustomComponentHTML(result, tagName, component);
5250
+ });
5251
+ return result;
5252
+ }
5253
+ /**
5254
+ * 导出默认函数和其他公共 API
5255
+ */
5256
+ function customRender(element, customComponents) {
5257
+ renderCustomComponents(element, customComponents);
5258
+ }
5259
+
5139
5260
  ;// CONCATENATED MODULE: ./src/ts/markdown/previewRender.ts
5140
5261
  var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
5141
5262
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -5195,6 +5316,7 @@ var __generator = (undefined && undefined.__generator) || function (thisArg, bod
5195
5316
 
5196
5317
 
5197
5318
 
5319
+
5198
5320
 
5199
5321
 
5200
5322
  var mergeOptions = function (options) {
@@ -5335,6 +5457,7 @@ var previewRender = function (previewElement, markdown, options) { return __awai
5335
5457
  _a.sent();
5336
5458
  _a.label = 8;
5337
5459
  case 8:
5460
+ customRender(previewElement, mergedOptions.customComponents || {});
5338
5461
  (0,setContentTheme/* setContentTheme */.Z)(mergedOptions.theme.current, mergedOptions.theme.path);
5339
5462
  if (mergedOptions.anchor === 1) {
5340
5463
  previewElement.classList.add("vditor-reset--anchor");
@@ -5407,7 +5530,6 @@ var previewRender = function (previewElement, markdown, options) { return __awai
5407
5530
  .querySelectorAll(".language-math")
5408
5531
  .forEach(function (mathEl) {
5409
5532
  var mathSource = mathEl.getAttribute("data-math");
5410
- console.log(mathEl.tagName, "mathEl");
5411
5533
  if (mathSource) {
5412
5534
  if (mathEl.tagName === "SPAN") {
5413
5535
  var textNode = document.createTextNode("$".concat(mathSource, "$"));