aleman 1.4.3 → 1.4.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/ChangeLog CHANGED
@@ -1,3 +1,14 @@
1
+ 2025.09.09, v1.4.5
2
+
3
+ feature:
4
+ - 3adffdf aleman: menu: use getAttributePath from operator
5
+ - 92d48da jsx-operator: simplify
6
+
7
+ 2025.09.08, v1.4.4
8
+
9
+ feature:
10
+ - c69b6da aleman: menu: simplify
11
+
1
12
  2025.09.07, v1.4.3
2
13
 
3
14
  feature:
@@ -30,4 +30,3 @@ function getMenuPath(event) {
30
30
 
31
31
  return menuItemElement.dataset.menuPath;
32
32
  }
33
-
package/menu/importmap.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export const importmap = {
2
2
  imports: {
3
- 'putout': 'https://esm.sh/@putout/bundle@4.6.0't add .,
3
+ 'putout': 'https://esm.sh/@putout/bundle@4.6.2',
4
4
  '@putout/processor-html': 'https://esm.sh/@putout/processor-html',
5
5
  'fullstore': 'https://esm.sh/fullstore',
6
6
  'jessy': 'https://esm.sh/jessy',
@@ -1,6 +1,6 @@
1
1
  import {template} from 'putout';
2
2
  import {
3
- appendAttributeValue,
3
+ addAttributeValue,
4
4
  hasDataName,
5
5
  setAttributeValue,
6
6
  } from '../jsx-operator.js';
@@ -45,9 +45,7 @@ export const fix = ({path, menu, icon, name = ''}) => {
45
45
  setSubmenu(menuItem);
46
46
  menuItem.children.push(createMenu());
47
47
 
48
- const elementPath = path
49
- .get('children')
50
- .at(-1)
48
+ const elementPath = path.get('children').at(-1)
51
49
  .get('children.1');
52
50
 
53
51
  fix({
@@ -83,7 +81,7 @@ export const traverse = ({options, push}) => ({
83
81
  });
84
82
 
85
83
  function setSubmenu(menuItem) {
86
- appendAttributeValue(menuItem, 'className', 'menu-submenu');
84
+ addAttributeValue(menuItem, 'className', 'menu-submenu');
87
85
  }
88
86
 
89
87
  function setDataMenuPath(key, name, menuItem) {
@@ -92,7 +90,7 @@ function setDataMenuPath(key, name, menuItem) {
92
90
  }
93
91
 
94
92
  function setIcon(name, menuItem) {
95
- appendAttributeValue(menuItem, 'className', `icon ${getIconName(name)}`);
93
+ addAttributeValue(menuItem, 'className', `icon ${getIconName(name)}`);
96
94
  }
97
95
 
98
96
  function getIconName(name) {
@@ -0,0 +1,18 @@
1
+ // second selected
2
+ <ul data-name="menu" className="menu menu-hidden">
3
+ <li data-menu-path="Upload" data-name="menu-item" className="menu-item icon icon-view">
4
+ <label data-menu-path="Upload">Upload</label>
5
+ </li>
6
+ <li data-menu-path="New" data-name="menu-item" className="menu-item icon icon-edit menu-item-selected menu-submenu-show">
7
+ <label data-menu-path="New">New</label>
8
+ <ul data-name="menu" className="menu menu-hidden">
9
+ <li data-menu-path="New.File" data-name="menu-item" className="menu-item icon icon-view">
10
+ <label data-menu-path="New.File">File</label>
11
+ </li>
12
+ <li data-menu-path="New.Directory" data-name="menu-item" className="menu-item icon icon-edit">
13
+ <label data-menu-path="New.Directory">Directory</label>
14
+ </li>
15
+ </ul>
16
+ </li>
17
+ </ul>;
18
+
@@ -16,7 +16,7 @@ export const fix = (path) => {
16
16
 
17
17
  export const traverse = ({push, options}) => ({
18
18
  JSXElement(path) {
19
- const {name, showSubmenu} = options;
19
+ const {name = 'menu', showSubmenu} = options;
20
20
  const {parentPath} = path;
21
21
 
22
22
  if (showSubmenu)
@@ -32,4 +32,3 @@ export const traverse = ({push, options}) => ({
32
32
  push(path);
33
33
  },
34
34
  });
35
-
@@ -4,21 +4,18 @@ const {isJSXElement} = types;
4
4
  const {setLiteralValue} = operator;
5
5
 
6
6
  export function getAttributeValue(path, attributeName) {
7
- if (isJSXElement(path))
8
- path = path.get('openingElement');
7
+ const attribute = getAttributeNode(path, attributeName);
9
8
 
10
- const {attributes} = path.node;
9
+ if (!attribute)
10
+ return '';
11
11
 
12
- for (const {name, value} of attributes) {
13
- if (name.name === attributeName)
14
- return value.value;
15
- }
16
-
17
- return '';
12
+ return attribute.value.value;
18
13
  }
19
14
 
20
- export function getAttributeNode(node, name) {
15
+ export function getAttributeNode(path, name) {
21
16
  let result = null;
17
+
18
+ const node = path.node || path;
22
19
  const {attributes} = node.openingElement;
23
20
 
24
21
  for (const attr of attributes) {
@@ -31,24 +28,7 @@ export function getAttributeNode(node, name) {
31
28
  return result;
32
29
  }
33
30
 
34
- export function getAttributePath(path, name) {
35
- if (isJSXElement(path))
36
- path = path.get('openingElement');
37
-
38
- let result = null;
39
- const attributes = path.get('attributes');
40
-
41
- for (const attr of attributes) {
42
- if (attr.node.name.name === name) {
43
- result = attr;
44
- break;
45
- }
46
- }
47
-
48
- return result;
49
- }
50
-
51
- export function appendAttributeValue(path, name, value) {
31
+ export function addAttributeValue(path, name, value) {
52
32
  const node = path.node || path;
53
33
  const attributeNode = getAttributeNode(node, name);
54
34
 
@@ -68,7 +48,11 @@ export function setAttributeValue(node, name, value) {
68
48
  }
69
49
 
70
50
  export function addClassName(path, name) {
71
- appendAttributeValue(path, 'className', name);
51
+ addAttributeValue(path, 'className', name);
52
+ }
53
+
54
+ export function getClassName(path) {
55
+ return getAttributeValue(path, 'className');
72
56
  }
73
57
 
74
58
  export function removeClassName(path, name) {
@@ -76,7 +60,7 @@ export function removeClassName(path, name) {
76
60
  }
77
61
 
78
62
  export function containsClassName(path, className) {
79
- const classNameValue = getAttributeValue(path, 'className');
63
+ const classNameValue = getClassName(path);
80
64
  return classNameValue.includes(className);
81
65
  }
82
66
 
@@ -93,8 +77,8 @@ export function removeAttributeValue(path, name, attributeValue) {
93
77
  setLiteralValue(classAttribute.value, value.replace(RegExp(`\\s?${attributeValue}`), ''));
94
78
  }
95
79
 
96
- export function hasDataName(path, value = 'menu') {
80
+ export function hasDataName(path, value = '') {
97
81
  const attribute = getAttributeValue(path, 'data-name');
98
-
99
82
  return attribute === value;
100
83
  }
84
+
@@ -1,26 +1,22 @@
1
1
  import {operator, types} from 'putout';
2
2
  import {
3
- appendAttributeValue,
4
- getAttributePath,
3
+ addClassName,
5
4
  hasDataName,
6
- removeAttributeValue,
5
+ removeClassName,
7
6
  } from '../jsx-operator.js';
8
7
 
8
+ const {hasTagName} = operator;
9
9
  const {isJSXElement} = types;
10
- const {setLiteralValue} = operator;
10
+ const SELECTED = 'menu-item-selected';
11
+ const SHOW = 'menu-submenu-show';
11
12
 
12
13
  export const report = () => `Select item`;
13
14
 
14
- export const fix = ({path, current, prev, next, showSubmenu}) => {
15
- const {value} = path.node;
16
-
17
- if (!value.value.includes('menu-item-selected'))
18
- setLiteralValue(value, `${value.value} menu-item-selected`);
19
-
20
- addShowSubmenu(current, {
15
+ export const fix = ({path, prev, next, showSubmenu}) => {
16
+ addClassName(path, SELECTED);
17
+ addShowSubmenu(path, {
21
18
  showSubmenu,
22
19
  });
23
-
24
20
  unselect(prev);
25
21
  unselect(next);
26
22
  removeShowSubmenu(next);
@@ -28,25 +24,25 @@ export const fix = ({path, current, prev, next, showSubmenu}) => {
28
24
  };
29
25
 
30
26
  export const traverse = ({options, push}) => ({
31
- JSXOpeningElement(path) {
27
+ JSXElement(path) {
32
28
  const {
33
29
  name = 'menu',
34
30
  index = 1,
35
31
  showSubmenu,
36
32
  } = options;
37
33
 
38
- if (path.node.name.name !== 'li')
34
+ if (!hasTagName(path, 'li'))
39
35
  return;
40
36
 
41
- const parentParentPath = path.parentPath.parentPath;
37
+ const {parentPath} = path;
42
38
 
43
- if (!isJSXElement(parentParentPath))
39
+ if (!isJSXElement(parentPath))
44
40
  return;
45
41
 
46
- if (!hasDataName(parentParentPath, name))
42
+ if (!hasDataName(parentPath, name))
47
43
  return;
48
44
 
49
- const children = parentParentPath.get('children').filter(isJSXElement);
45
+ const children = parentPath.get('children').filter(isJSXElement);
50
46
 
51
47
  const prev = children[index - 1];
52
48
  const current = children[index];
@@ -55,11 +51,8 @@ export const traverse = ({options, push}) => ({
55
51
  if (!current)
56
52
  return;
57
53
 
58
- const attributePath = getAttributePath(current, 'className');
59
-
60
54
  push({
61
- path: attributePath,
62
- current,
55
+ path: current,
63
56
  prev,
64
57
  next,
65
58
  showSubmenu,
@@ -68,14 +61,14 @@ export const traverse = ({options, push}) => ({
68
61
  });
69
62
 
70
63
  function unselect(path) {
71
- removeAttributeValue(path, 'className', 'menu-item-selected');
64
+ removeClassName(path, SELECTED);
72
65
  }
73
66
 
74
67
  function addShowSubmenu(path, {showSubmenu}) {
75
68
  if (showSubmenu)
76
- return appendAttributeValue(path, 'className', 'menu-submenu-show');
69
+ return addClassName(path, SHOW);
77
70
  }
78
71
 
79
72
  function removeShowSubmenu(path) {
80
- removeAttributeValue(path, 'className', 'menu-submenu-show');
73
+ removeClassName(path, SHOW);
81
74
  }
@@ -1,11 +1,12 @@
1
- import {types} from 'putout';
1
+ import {types, operator} from 'putout';
2
2
  import {
3
- getAttributePath,
4
3
  getAttributeValue,
5
4
  hasDataName,
6
5
  setAttributeValue,
7
6
  } from '../jsx-operator.js';
8
7
 
8
+ const {getAttributePath} = operator;
9
+
9
10
  const {
10
11
  stringLiteral,
11
12
  jsxIdentifier,
@@ -73,3 +74,4 @@ function parsePosition(str) {
73
74
  Number(y),
74
75
  ];
75
76
  }
77
+
@@ -45,7 +45,7 @@
45
45
  <li data-menu-path="New.File" data-name="menu-item" className='menu-item icon icon-view'>
46
46
  <label data-menu-path="New.File">File</label>
47
47
  </li>
48
- <li data-menu-path="New.Directory" data-name="menu-item" className='menu-item icon icon-edit'>
48
+ <li data-menu-path="New.Directory" data-name="menu-item" className="menu-item icon icon-edit">
49
49
  <label data-menu-path="New.Directory">Directory</label>
50
50
  </li>
51
51
  </ul>
@@ -0,0 +1,54 @@
1
+ // second selected
2
+ <ul data-name="menu" class="menu menu-hidden">
3
+ <li data-menu-path="Upload" data-name="menu-item" className="menu-item icon icon-view">
4
+ <label data-menu-path="Upload">Upload</label>
5
+ </li>
6
+ <li data-menu-path="New" data-name="menu-item" className="menu-item icon icon-edit menu-item-selected">
7
+ <label data-menu-path="New">New</label>
8
+ <ul data-name="menu" class="menu menu-hidden">
9
+ <li data-menu-path="New.File" data-name="menu-item" className="menu-item icon icon-view">
10
+ <label data-menu-path="New.File">File</label>
11
+ </li>
12
+ <li data-menu-path="New.Directory" data-name="menu-item" className="menu-item icon icon-edit">
13
+ <label data-menu-path="New.Directory">Directory</label>
14
+ </li>
15
+ </ul>
16
+ </li>
17
+ </ul>;
18
+
19
+
20
+ // first selected
21
+ <ul data-name="menu" class="menu menu-hidden">
22
+ <li data-menu-path="Upload" data-name="menu-item" className="menu-item icon icon-view menu-item-selected">
23
+ <label data-menu-path="Upload">Upload</label>
24
+ </li>
25
+ <li data-menu-path="New" data-name="menu-item" className="menu-item icon icon-edit">
26
+ <label data-menu-path="New">New</label>
27
+ <ul data-name="menu" class="menu menu-hidden">
28
+ <li data-menu-path="New.File" data-name="menu-item" className="menu-item icon icon-view">
29
+ <label data-menu-path="New.File">File</label>
30
+ </li>
31
+ <li data-menu-path="New.Directory" data-name="menu-item" className="menu-item icon icon-edit">
32
+ <label data-menu-path="New.Directory">Directory</label>
33
+ </li>
34
+ </ul>
35
+ </li>
36
+ </ul>;
37
+
38
+ // second selected, submenu first selected
39
+ <ul data-name="menu" class="menu menu-hidden">
40
+ <li data-menu-path="Upload" data-name="menu-item" className="menu-item icon icon-view">
41
+ <label data-menu-path="Upload">Upload</label>
42
+ </li>
43
+ <li data-menu-path="New" data-name="menu-item" className="menu-item icon icon-edit menu-item-selected">
44
+ <label data-menu-path="New">New</label>
45
+ <ul data-name="menu" class="menu menu-hidden">
46
+ <li data-menu-path="New.File" data-name="menu-item" className="menu-item icon icon-view menu-item-selected">
47
+ <label data-menu-path="New.File">File</label>
48
+ </li>
49
+ <li data-menu-path="New.Directory" data-name="menu-item" className="menu-item icon icon-edit">
50
+ <label data-menu-path="New.Directory">Directory</label>
51
+ </li>
52
+ </ul>
53
+ </li>
54
+ </ul>;
@@ -1,40 +1,36 @@
1
1
  import {operator, types} from 'putout';
2
2
  import {
3
- getAttributePath,
3
+ addClassName,
4
4
  getAttributeValue,
5
5
  hasDataName,
6
6
  removeAttributeValue,
7
+ removeClassName,
7
8
  } from '../jsx-operator.js';
8
9
 
10
+ const {hasTagName} = operator;
11
+
9
12
  const {isJSXElement} = types;
10
- const {setLiteralValue} = operator;
11
13
 
12
14
  export const report = ({insideSubmenu}) => `${insideSubmenu ? 'Show' : 'Hide'} submenu`;
13
15
 
14
16
  export const fix = ({path, prev, next, insideSubmenu}) => {
15
- const {value} = path.node;
16
17
  unselect(prev);
17
18
  unselect(next);
18
19
 
19
20
  if (!insideSubmenu) {
20
- const newValue = value.value.replace(/\s?menu-item-selected/, '');
21
- setLiteralValue(value, newValue);
22
-
21
+ removeClassName(path, 'menu-item-selected');
23
22
  return;
24
23
  }
25
24
 
26
- if (!value.value.includes('menu-item-selected')) {
27
- const newValue = `${value.value} menu-item-selected`;
28
- setLiteralValue(value, newValue);
29
- }
25
+ addClassName(path, 'menu-item-selected');
30
26
  };
31
27
 
32
28
  export const traverse = ({options, push}) => ({
33
- JSXOpeningElement(path) {
34
- if (path.node.name.name !== 'li')
29
+ JSXElement(path) {
30
+ if (!hasTagName(path, 'li'))
35
31
  return;
36
32
 
37
- if (!isJSXElement(path.parentPath.parentPath))
33
+ if (!isJSXElement(path.parentPath))
38
34
  return;
39
35
 
40
36
  const {insideSubmenu = true, submenuIndex = 1} = options;
@@ -43,16 +39,13 @@ export const traverse = ({options, push}) => ({
43
39
  if (!isJSXElement(parentMenu))
44
40
  return;
45
41
 
46
- if (!isParentSelected(parentMenu))
42
+ if (!isParentSelected(path.parentPath.parentPath))
47
43
  return;
48
44
 
49
- const openingElementPath = path.parentPath.parentPath.get('openingElement');
50
-
51
- if (!hasDataName(openingElementPath))
45
+ if (!hasDataName(path.parentPath, 'menu'))
52
46
  return;
53
47
 
54
48
  const children = path.parentPath
55
- .parentPath
56
49
  .get('children')
57
50
  .filter(isJSXElement);
58
51
 
@@ -63,11 +56,8 @@ export const traverse = ({options, push}) => ({
63
56
  if (!current)
64
57
  return;
65
58
 
66
- const currentOpeningElementPath = current.get('openingElement');
67
- const currentClassPath = getAttributePath(currentOpeningElementPath, 'className');
68
-
69
59
  push({
70
- path: currentClassPath,
60
+ path: current,
71
61
  insideSubmenu,
72
62
  prev,
73
63
  next,
@@ -76,9 +66,7 @@ export const traverse = ({options, push}) => ({
76
66
  });
77
67
 
78
68
  function isParentSelected(path) {
79
- const openingElement = path.get('openingElement');
80
- const classAttributeValue = getAttributeValue(openingElement, 'className');
81
-
69
+ const classAttributeValue = getAttributeValue(path, 'className');
82
70
  return classAttributeValue.includes('menu-item-selected');
83
71
  }
84
72
 
@@ -1,53 +1,45 @@
1
1
  import {operator, types} from 'putout';
2
- import {hasDataName} from '../jsx-operator.js';
2
+ import {
3
+ containsClassName,
4
+ hasDataName,
5
+ removeClassName,
6
+ } from '../jsx-operator.js';
3
7
 
8
+ const {hasTagName} = operator;
4
9
  const {isJSXElement} = types;
5
- const {setLiteralValue} = operator;
10
+ const SELECTED = 'menu-item-selected';
6
11
 
7
12
  export const report = () => `Unselect all`;
8
13
 
9
14
  export const fix = ({path}) => {
10
- const {value} = path.node;
11
- const newValue = value.value.replace(/\s?menu-item-selected/, '');
12
-
13
- setLiteralValue(value, newValue);
15
+ removeClassName(path, SELECTED);
14
16
  };
15
17
 
16
18
  export const traverse = ({push, options}) => ({
17
- JSXOpeningElement(path) {
18
- const {index, name} = options;
19
+ JSXElement(path) {
20
+ const {index, name = 'menu'} = options;
19
21
 
20
22
  if (index !== -1)
21
23
  return;
22
24
 
23
- if (path.node.name.name !== 'li')
25
+ if (!hasTagName(path, 'li'))
24
26
  return;
25
27
 
26
- if (!isJSXElement(path.parentPath.parentPath))
28
+ if (!isJSXElement(path.parentPath))
27
29
  return;
28
30
 
29
- const openingElementPath = path.parentPath.parentPath.get('openingElement');
30
-
31
- if (!hasDataName(openingElementPath, name))
31
+ if (!hasDataName(path.parentPath, name))
32
32
  return;
33
33
 
34
34
  const children = path.parentPath
35
- .parentPath
36
35
  .get('children')
37
36
  .filter(isJSXElement);
38
37
 
39
38
  for (const child of children) {
40
- for (const attr of child.get('openingElement.attributes')) {
41
- const {name, value} = attr.node;
42
-
43
- if (name.name !== 'className')
44
- continue;
45
-
46
- if (value.value.includes('menu-item-selected'))
47
- push({
48
- path: attr,
49
- });
50
- }
39
+ if (containsClassName(child, SELECTED))
40
+ push({
41
+ path: child,
42
+ });
51
43
  }
52
44
  },
53
45
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aleman",
3
- "version": "1.4.3",
3
+ "version": "1.4.5",
4
4
  "type": "module",
5
5
  "author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
6
6
  "description": "🐊Putout-based framework for web",