@webjourney/vite-plugins 1.2.7-1 → 1.2.7

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,wBAAgB,uBAAuB;;;oBAKnB,MAAM,MAAM,MAAM;;;;EA6KrC;AAED,wBAAgB,sBAAsB;;;6BAKT,MAAM;EAIlC;AAED,wBAAgB,iBAAiB;;;oBA1Lb,MAAM,MAAM,MAAM;;;;;;;6BAoLT,MAAM;KAUlC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,wBAAgB,uBAAuB;;;oBAKnB,MAAM,MAAM,MAAM;;;;EA0MrC;AAED,wBAAgB,sBAAsB;;;6BAKT,MAAM;EAIlC;AAED,wBAAgB,iBAAiB;;;oBAvNb,MAAM,MAAM,MAAM;;;;;;;6BAiNT,MAAM;KAUlC"}
package/dist/index.js CHANGED
@@ -34,70 +34,83 @@ export function webjourneyElementTagger() {
34
34
  traverse(ast, {
35
35
  JSXElement(path) {
36
36
  const openingElement = path.node.openingElement;
37
- // Skip wrapper spans we created (they have data-wj-text attribute)
38
- const isWrapperSpan = t.isJSXIdentifier(openingElement.name) &&
39
- openingElement.name.name === 'span' &&
40
- openingElement.attributes.some((attr) => t.isJSXAttribute(attr) &&
41
- t.isJSXIdentifier(attr.name) &&
42
- attr.name.name === 'data-wj-text');
43
- if (isWrapperSpan) {
44
- path.skip(); // Don't traverse into our wrapper spans
45
- return;
46
- }
47
- const lineNumber = openingElement.loc?.start.line ?? 0;
48
- // Process children to wrap text nodes
49
- const newChildren = [];
50
- let hasWrappedText = false;
51
- for (const child of path.node.children) {
52
- // Only wrap JSXText nodes that have non-whitespace content
53
- if (t.isJSXText(child) && child.value.trim() !== '') {
54
- // Generate unique ID for this text segment
55
- const textLineNumber = child.loc?.start.line ?? lineNumber;
56
- const elementId = `${relativePath}:${textLineNumber}`;
57
- // Create a span wrapper for the text node
58
- const wrapper = t.jsxElement(t.jsxOpeningElement(t.jsxIdentifier('span'), [
59
- t.jsxAttribute(t.jsxIdentifier('data-wj-text'), null),
60
- t.jsxAttribute(t.jsxIdentifier('data-wj-file'), t.stringLiteral(relativePath)),
61
- t.jsxAttribute(t.jsxIdentifier('data-wj-line'), t.stringLiteral(String(textLineNumber))),
62
- t.jsxAttribute(t.jsxIdentifier('data-wj-type'), t.stringLiteral('text')),
63
- t.jsxAttribute(t.jsxIdentifier('data-wj-id'), t.stringLiteral(elementId))
64
- ], false), t.jsxClosingElement(t.jsxIdentifier('span')), [child], false);
65
- newChildren.push(wrapper);
66
- hasWrappedText = true;
67
- modified = true;
68
- }
69
- else {
70
- // Keep other nodes as-is (elements, whitespace-only text, expressions, etc.)
71
- newChildren.push(child);
72
- }
73
- }
74
- // Replace children if we wrapped any text
75
- if (hasWrappedText) {
76
- path.node.children = newChildren;
77
- }
78
- // Handle img elements - add attributes to the img tag itself
79
37
  const elementName = openingElement.name;
80
- let tagName = '';
38
+ // Extract tag name - handle both regular tags and motion.* tags
39
+ let tagName;
81
40
  if (t.isJSXIdentifier(elementName)) {
82
41
  tagName = elementName.name;
83
42
  }
84
43
  else if (t.isJSXMemberExpression(elementName)) {
85
- // Handle motion.img
44
+ // Handle motion.div, motion.h1, etc.
86
45
  if (t.isJSXIdentifier(elementName.object) &&
87
46
  elementName.object.name === 'motion' &&
88
47
  t.isJSXIdentifier(elementName.property)) {
89
48
  tagName = elementName.property.name;
90
49
  }
50
+ else {
51
+ return;
52
+ }
91
53
  }
54
+ else {
55
+ return;
56
+ }
57
+ // Check if already has data-wj-file attribute
58
+ const hasDataWj = openingElement.attributes.some((attr) => t.isJSXAttribute(attr) &&
59
+ t.isJSXIdentifier(attr.name) &&
60
+ attr.name.name === 'data-wj-file');
61
+ if (hasDataWj)
62
+ return;
63
+ const lineNumber = openingElement.loc?.start.line ?? 0;
64
+ // Handle text elements
65
+ if (['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'span', 'div', 'button', 'a', 'label', 'li'].includes(tagName)) {
66
+ // Get all non-whitespace text nodes
67
+ const textNodes = path.node.children.filter((child) => t.isJSXText(child) && child.value.trim() !== '');
68
+ // Get all non-text children (elements, expressions, etc.)
69
+ const nonTextChildren = path.node.children.filter((child) => !t.isJSXText(child) || (t.isJSXText(child) && child.value.trim() === ''));
70
+ if (textNodes.length > 0) {
71
+ // Case 1: Single text node child (no other elements)
72
+ if (textNodes.length === 1 && nonTextChildren.length === 0) {
73
+ // Add data-wj-* attributes to the current element
74
+ const elementId = `${relativePath}:${lineNumber}`;
75
+ openingElement.attributes.push(t.jsxAttribute(t.jsxIdentifier('data-wj-file'), t.stringLiteral(relativePath)), t.jsxAttribute(t.jsxIdentifier('data-wj-line'), t.stringLiteral(String(lineNumber))), t.jsxAttribute(t.jsxIdentifier('data-wj-type'), t.stringLiteral('text')), t.jsxAttribute(t.jsxIdentifier('data-wj-id'), t.stringLiteral(elementId)));
76
+ modified = true;
77
+ }
78
+ // Case 2: Mixed children (text nodes + other elements)
79
+ else if (nonTextChildren.length > 0) {
80
+ // Wrap each text node in a span with data-wj-* attributes
81
+ const newChildren = [];
82
+ for (const child of path.node.children) {
83
+ if (t.isJSXText(child) && child.value.trim() !== '') {
84
+ // Generate unique ID for this text segment
85
+ const textLineNumber = child.loc?.start.line ?? lineNumber;
86
+ const elementId = `${relativePath}:${textLineNumber}`;
87
+ // Create a span wrapper
88
+ const wrapper = t.jsxElement(t.jsxOpeningElement(t.jsxIdentifier('span'), [
89
+ t.jsxAttribute(t.jsxIdentifier('data-wj-file'), t.stringLiteral(relativePath)),
90
+ t.jsxAttribute(t.jsxIdentifier('data-wj-line'), t.stringLiteral(String(textLineNumber))),
91
+ t.jsxAttribute(t.jsxIdentifier('data-wj-type'), t.stringLiteral('text')),
92
+ t.jsxAttribute(t.jsxIdentifier('data-wj-id'), t.stringLiteral(elementId))
93
+ ], false), t.jsxClosingElement(t.jsxIdentifier('span')), [child], false);
94
+ newChildren.push(wrapper);
95
+ }
96
+ else {
97
+ // Keep whitespace text nodes, elements, etc. as-is
98
+ newChildren.push(child);
99
+ }
100
+ }
101
+ path.node.children = newChildren;
102
+ modified = true;
103
+ }
104
+ }
105
+ }
106
+ // Handle img elements
92
107
  if (tagName === 'img') {
93
- // Check if img has src attribute and doesn't already have data-wj-file
108
+ // Check if img has src attribute
94
109
  const hasSrc = openingElement.attributes.some((attr) => t.isJSXAttribute(attr) &&
95
110
  t.isJSXIdentifier(attr.name) &&
96
111
  attr.name.name === 'src');
97
- const hasDataWj = openingElement.attributes.some((attr) => t.isJSXAttribute(attr) &&
98
- t.isJSXIdentifier(attr.name) &&
99
- attr.name.name === 'data-wj-file');
100
- if (hasSrc && !hasDataWj) {
112
+ if (hasSrc) {
113
+ // Generate unique ID: filename:line
101
114
  const elementId = `${relativePath}:${lineNumber}`;
102
115
  openingElement.attributes.push(t.jsxAttribute(t.jsxIdentifier('data-wj-file'), t.stringLiteral(relativePath)), t.jsxAttribute(t.jsxIdentifier('data-wj-line'), t.stringLiteral(String(lineNumber))), t.jsxAttribute(t.jsxIdentifier('data-wj-type'), t.stringLiteral('image')), t.jsxAttribute(t.jsxIdentifier('data-wj-id'), t.stringLiteral(elementId)));
103
116
  modified = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webjourney/vite-plugins",
3
- "version": "1.2.7-1",
3
+ "version": "1.2.7",
4
4
  "description": "Vite plugins for Webjourney WYSIWYG editing",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",