@uniweb/semantic-parser 1.0.15 → 1.0.17
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/package.json +1 -1
- package/src/processors/groups.js +6 -1
- package/src/processors/sequence.js +30 -16
package/package.json
CHANGED
package/src/processors/groups.js
CHANGED
|
@@ -285,7 +285,12 @@ function processGroupContent(elements) {
|
|
|
285
285
|
break;
|
|
286
286
|
|
|
287
287
|
case "image":
|
|
288
|
-
|
|
288
|
+
// Check if this image is actually an icon (role="icon" from  syntax)
|
|
289
|
+
if (element.attrs?.role === "icon") {
|
|
290
|
+
body.icons.push(element.attrs);
|
|
291
|
+
} else {
|
|
292
|
+
body.imgs.push(preserveProps);
|
|
293
|
+
}
|
|
289
294
|
break;
|
|
290
295
|
|
|
291
296
|
case "video":
|
|
@@ -47,6 +47,14 @@ function getCodeBlockData(text, attrs) {
|
|
|
47
47
|
return text;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Check if an inline node is an icon.
|
|
52
|
+
* TipTap editor uses type "UniwebIcon"; markdown pipeline uses type "image" with role "icon".
|
|
53
|
+
*/
|
|
54
|
+
function isIconNode(node) {
|
|
55
|
+
return node.type === "UniwebIcon" || (node.type === "image" && node.attrs?.role === "icon");
|
|
56
|
+
}
|
|
57
|
+
|
|
50
58
|
/**
|
|
51
59
|
* Process a ProseMirror/TipTap document into a flat sequence
|
|
52
60
|
* @param {Object} doc ProseMirror document
|
|
@@ -364,7 +372,7 @@ function processInlineElements(content) {
|
|
|
364
372
|
const items = [];
|
|
365
373
|
|
|
366
374
|
for (const item of content) {
|
|
367
|
-
if (item
|
|
375
|
+
if (isIconNode(item)) {
|
|
368
376
|
items.push({
|
|
369
377
|
type: "icon",
|
|
370
378
|
attrs: parseUniwebIcon(item.attrs),
|
|
@@ -455,17 +463,23 @@ function parseDocumentBlock(itemAttrs) {
|
|
|
455
463
|
}
|
|
456
464
|
|
|
457
465
|
function parseUniwebIcon(itemAttrs) {
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
466
|
+
const { svg, url, size, color, preserveColors, href, target, library, name } = itemAttrs || {};
|
|
467
|
+
|
|
468
|
+
// Build object with only defined fields — icon source varies:
|
|
469
|
+
// TipTap editor: svg/url (resolved inline)
|
|
470
|
+
// Markdown pipeline: library + name (resolved at runtime via CDN)
|
|
471
|
+
const icon = {};
|
|
472
|
+
if (svg) icon.svg = svg;
|
|
473
|
+
if (url) icon.url = url;
|
|
474
|
+
if (size) icon.size = size;
|
|
475
|
+
if (color) icon.color = color;
|
|
476
|
+
if (preserveColors) icon.preserveColors = preserveColors;
|
|
477
|
+
if (href) icon.href = href;
|
|
478
|
+
if (target) icon.target = target;
|
|
479
|
+
if (library) icon.library = library;
|
|
480
|
+
if (name) icon.name = name;
|
|
481
|
+
|
|
482
|
+
return icon;
|
|
469
483
|
}
|
|
470
484
|
|
|
471
485
|
function parseIconBlock(itemAttrs) {
|
|
@@ -581,7 +595,7 @@ function isLink(item) {
|
|
|
581
595
|
|
|
582
596
|
// Filter out icons and whitespace to check for single link
|
|
583
597
|
const textContent = originalContent.filter((c) => {
|
|
584
|
-
if (c
|
|
598
|
+
if (isIconNode(c)) {
|
|
585
599
|
return false;
|
|
586
600
|
} else if (c.type === "text") {
|
|
587
601
|
return (c.text || "").trim() !== "";
|
|
@@ -607,7 +621,7 @@ function isLink(item) {
|
|
|
607
621
|
let iconAfter = null;
|
|
608
622
|
|
|
609
623
|
for (let i = 0; i < originalContent.length; i++) {
|
|
610
|
-
if (originalContent[i]
|
|
624
|
+
if (isIconNode(originalContent[i])) {
|
|
611
625
|
const iconAttrs = parseUniwebIcon(originalContent[i].attrs);
|
|
612
626
|
if (i < linkIndex) {
|
|
613
627
|
// Take the last icon before the link
|
|
@@ -657,7 +671,7 @@ function isOnlyLinks(item) {
|
|
|
657
671
|
|
|
658
672
|
// Filter to get only significant content (no icons, no whitespace)
|
|
659
673
|
const textContent = content.filter((c) => {
|
|
660
|
-
if (c
|
|
674
|
+
if (isIconNode(c)) return false;
|
|
661
675
|
if (c.type === "text" && !(c.text || "").trim()) return false;
|
|
662
676
|
return true;
|
|
663
677
|
});
|
|
@@ -698,7 +712,7 @@ function isStyledLink(item) {
|
|
|
698
712
|
if (!content.length) return false;
|
|
699
713
|
|
|
700
714
|
content = content.filter((c) => {
|
|
701
|
-
if (c
|
|
715
|
+
if (isIconNode(c)) {
|
|
702
716
|
return false;
|
|
703
717
|
}
|
|
704
718
|
|