aleman 1.12.4 → 1.14.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/ChangeLog CHANGED
@@ -1,3 +1,13 @@
1
+ 2025.09.18, v1.14.0
2
+
3
+ feature:
4
+ - 9b7ceb5 aleman: beutify generated fixtues
5
+
6
+ 2025.09.17, v1.13.0
7
+
8
+ fix:
9
+ - 6c5e67c aleman: menu: select
10
+
1
11
  2025.09.16, v1.12.4
2
12
 
3
13
  fix:
@@ -1,4 +1,9 @@
1
1
  import {createVimParser} from './vim.js';
2
+ import {
3
+ emitBefore,
4
+ emitIf,
5
+ emitRun,
6
+ } from './emit.js';
2
7
 
3
8
  const queryElement = ({name}) => {
4
9
  return document.querySelector(`[data-name="${name}"]`);
@@ -65,34 +70,30 @@ export const addGlobalListeners = ({globalAddons, options, readState, writeState
65
70
 
66
71
  const createListener = ({options, addon, readState, writeState, parseVim = createVimParser()}) => (event) => {
67
72
  const {
68
- keys,
69
- listener,
70
73
  preventDefault,
71
74
  stopPropagation,
72
- filter,
73
75
  after,
74
76
  afterIf,
75
- commands,
76
77
  } = addon;
77
78
 
78
- if (keys && !keys.includes(event.key))
79
- return;
80
-
81
- const [command, count] = parseVim(event);
79
+ const [isEmitBefore, count] = emitBefore(addon, {
80
+ event,
81
+ parseVim,
82
+ });
82
83
 
83
- if (commands && !commands.includes(command))
84
- return;
84
+ if (!isEmitBefore)
85
+ return false;
85
86
 
86
87
  const state = readState();
87
88
 
88
- const is = filter?.({
89
+ const is = emitIf(addon, {
89
90
  event,
90
91
  state,
91
92
  options,
92
93
  });
93
94
 
94
- if (filter && !is)
95
- return false;
95
+ if (!is)
96
+ return;
96
97
 
97
98
  if (preventDefault)
98
99
  event.preventDefault();
@@ -100,12 +101,11 @@ const createListener = ({options, addon, readState, writeState, parseVim = creat
100
101
  if (stopPropagation)
101
102
  event.stopPropagation();
102
103
 
103
- const newState = listener({
104
+ const newState = emitRun(addon, {
104
105
  count,
105
106
  event,
106
107
  state,
107
108
  options,
108
- writeState,
109
109
  });
110
110
 
111
111
  writeState(newState);
package/aleman/emit.js ADDED
@@ -0,0 +1,52 @@
1
+ export const emit = (addon, {state, options, event, parseVim}) => {
2
+ const [isEmitBefore, count] = emitBefore(addon, {
3
+ event,
4
+ parseVim,
5
+ });
6
+
7
+ if (!isEmitBefore)
8
+ return false;
9
+
10
+ if (!emitIf(addon, {state, event}))
11
+ return state;
12
+
13
+ return emitRun(addon, {
14
+ event,
15
+ state,
16
+ options,
17
+ count,
18
+ });
19
+ };
20
+ export const emitIf = (addon, {state, event, options}) => {
21
+ if (!addon.filter)
22
+ return true;
23
+
24
+ return addon.filter({
25
+ state,
26
+ event,
27
+ options,
28
+ });
29
+ };
30
+
31
+ export const emitRun = (addon, {count, state, event, options}) => {
32
+ return addon.listener({
33
+ count,
34
+ event,
35
+ state,
36
+ options,
37
+ });
38
+ };
39
+
40
+ export const emitBefore = (addon, {event, parseVim}) => {
41
+ const {keys, commands} = addon;
42
+
43
+ if (keys && !keys.includes(event.key))
44
+ return [false];
45
+
46
+ const [command, count] = parseVim(event);
47
+
48
+ if (commands && !commands.includes(command))
49
+ return [false];
50
+
51
+ return [true, count];
52
+ };
package/aleman/render.js CHANGED
@@ -14,6 +14,7 @@ export const TRANSFORM = true;
14
14
  export const createRender = (html, {options, rules}) => {
15
15
  const {source} = branch(html)[0];
16
16
  const withDiv = `<template>${source}</template>`;
17
+
17
18
  const ast = parse(withDiv);
18
19
 
19
20
  return function render(state) {
@@ -33,7 +34,7 @@ export const createRender = (html, {options, rules}) => {
33
34
  });
34
35
 
35
36
  if (!places.length)
36
- return [SKIP];
37
+ return [SKIP, '', places];
37
38
 
38
39
  transform(ast, '', {
39
40
  rules: currentRules,
@@ -43,7 +44,7 @@ export const createRender = (html, {options, rules}) => {
43
44
  const code = print(ast, {
44
45
  printer: ['putout', {
45
46
  format: {
46
- newline: '',
47
+ newline: '\n',
47
48
  endOfFile: '',
48
49
  },
49
50
  }],
@@ -51,8 +52,14 @@ export const createRender = (html, {options, rules}) => {
51
52
 
52
53
  const prefix = '<template>';
53
54
  const suffix = '<\\template>\n';
55
+
54
56
  const result = merge('', [code]).slice(prefix.length, -suffix.length);
55
57
 
56
- return [TRANSFORM, result];
58
+ return [
59
+ TRANSFORM,
60
+ result,
61
+ places,
62
+ ];
57
63
  };
58
64
  };
65
+
@@ -5,10 +5,10 @@ import * as up from './up.js';
5
5
  import * as enter from './enter.js';
6
6
  import * as left from './left.js';
7
7
  import * as right from './right.js';
8
- import * as shiftG from './shift-g.js';
8
+ import * as shiftG from './shift-g/shift-g.js';
9
9
  import * as gg from './gg.js';
10
10
  import * as j from './j.js';
11
- import * as k from './k.js';
11
+ import * as k from './k/k.js';
12
12
 
13
13
  export const addons = [
14
14
  click,
@@ -0,0 +1,9 @@
1
+
2
+ <ul data-name="menu" class="menu menu-hidden" style="left: 0px; top: 20px;">
3
+ <li data-name="menu-item" data-menu-index="0" class="menu-item icon icon-view menu-item-selected">
4
+ <label data-menu-path="View">View</label>
5
+ </li>
6
+ <li data-name="menu-item" data-menu-index="1" class="menu-item icon icon-edit">
7
+ <label data-menu-path="Edit">Edit</label>
8
+ </li>
9
+ </ul>;
@@ -0,0 +1,8 @@
1
+ <ul data-name="menu" className="menu menu-hidden" style="left: 0px; top: 20px;">
2
+ <li data-name="menu-item" data-menu-index="0" className="menu-item icon icon-view">
3
+ <label data-menu-path="View">View</label>
4
+ </li>
5
+ <li data-name="menu-item" data-menu-index="1" className="menu-item icon icon-edit menu-item-selected">
6
+ <label data-menu-path="Edit">Edit</label>
7
+ </li>
8
+ </ul>;
@@ -0,0 +1,8 @@
1
+ <ul data-name="menu" class="menu menu-hidden" style="left: 0px; top: 20px;">
2
+ <li data-name="menu-item" data-menu-index="0" className="menu-item icon icon-view">
3
+ <label data-menu-path="View">View</label>
4
+ </li>
5
+ <li data-name="menu-item" data-menu-index="1" className="menu-item icon icon-edit menu-item-selected">
6
+ <label data-menu-path="Edit">Edit</label>
7
+ </li>
8
+ </ul>;
@@ -0,0 +1,9 @@
1
+
2
+ <ul data-name="menu" class="menu menu-hidden" style="left: 0px; top: 20px;">
3
+ <li data-name="menu-item" data-menu-index="0" class="menu-item icon icon-view">
4
+ <label data-menu-path="View">View</label>
5
+ </li>
6
+ <li data-name="menu-item" data-menu-index="1" class="menu-item icon icon-edit menu-item-selected">
7
+ <label data-menu-path="Edit">Edit</label>
8
+ </li>
9
+ </ul>;
@@ -0,0 +1,8 @@
1
+ <ul data-name="menu" class="menu menu-hidden">
2
+ <li data-name="menu-item" data-menu-index="0" class="menu-item icon icon-view menu-item-selected">
3
+ <label data-menu-path="View">View</label>
4
+ </li>
5
+ <li data-name="menu-item" data-menu-index="1" class="menu-item icon icon-edit">
6
+ <label data-menu-path="Edit">Edit</label>
7
+ </li>
8
+ </ul>;
@@ -1,6 +1,6 @@
1
- import * as down from './down.js';
1
+ import * as up from '../up.js';
2
2
 
3
- export const {filter} = down;
3
+ export const {filter} = up;
4
4
  export const commands = ['k'];
5
5
 
6
6
  export function listener({count, state, options}) {
@@ -10,8 +10,8 @@ export function listener({count, state, options}) {
10
10
  submenuIndex,
11
11
  } = state;
12
12
 
13
- let newIndex = insideSubmenu ? index : index - count - 1;
14
- let newSubmenuIndex = insideSubmenu ? submenuIndex - count - 1 : submenuIndex;
13
+ let newIndex = insideSubmenu ? index : index - count + 1;
14
+ let newSubmenuIndex = insideSubmenu ? submenuIndex - count + 1 : submenuIndex;
15
15
 
16
16
  if (newIndex < -1)
17
17
  newIndex = -1;
@@ -25,7 +25,7 @@ export function listener({count, state, options}) {
25
25
  submenuIndex: newSubmenuIndex,
26
26
  };
27
27
 
28
- return down.listener({
28
+ return up.listener({
29
29
  state: newState,
30
30
  options,
31
31
  });
@@ -0,0 +1,8 @@
1
+ <ul data-name="menu" className="menu menu-hidden" style="left: 0px; top: 20px;">
2
+ <li data-name="menu-item" data-menu-index="0" className="menu-item icon icon-view">
3
+ <label data-menu-path="View">View</label>
4
+ </li>
5
+ <li data-name="menu-item" data-menu-index="1" className="menu-item icon icon-edit menu-item-selected">
6
+ <label data-menu-path="Edit">Edit</label>
7
+ </li>
8
+ </ul>;
@@ -0,0 +1,9 @@
1
+
2
+ <ul data-name="menu" class="menu" style="left: 0px; top: 20px;">
3
+ <li data-name="menu-item" data-menu-index="0" class="menu-item icon icon-view">
4
+ <label data-menu-path="View">View</label>
5
+ </li>
6
+ <li data-name="menu-item" data-menu-index="1" class="menu-item icon icon-edit menu-item-selected">
7
+ <label data-menu-path="Edit">Edit</label>
8
+ </li>
9
+ </ul>;
@@ -0,0 +1,8 @@
1
+ <ul data-name="menu" className="menu menu-hidden" style="left: 0px; top: 20px;">
2
+ <li data-name="menu-item" data-menu-index="0" className="menu-item icon icon-view menu-item-selected">
3
+ <label data-menu-path="View">View</label>
4
+ </li>
5
+ <li data-name="menu-item" data-menu-index="1" className="menu-item icon icon-edit">
6
+ <label data-menu-path="Edit">Edit</label>
7
+ </li>
8
+ </ul>;
@@ -1,10 +1,12 @@
1
- import {getSubmenu} from './submenu/index.js';
1
+ import {getSubmenu} from '../submenu/index.js';
2
2
 
3
3
  export const keys = [
4
4
  'G',
5
5
  '$',
6
6
  ];
7
7
 
8
+ export const filter = ({state}) => state.command === 'show';
9
+
8
10
  export const preventDefault = true;
9
11
 
10
12
  export const listener = ({state, options}) => {
package/menu/addons/up.js CHANGED
@@ -3,6 +3,7 @@ import {getSubmenu} from './submenu/index.js';
3
3
  export const keys = ['ArrowUp'];
4
4
 
5
5
  export const preventDefault = true;
6
+ export const filter = ({state}) => state.command === 'show';
6
7
 
7
8
  export const listener = ({state, options}) => {
8
9
  const {menu} = options;
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.7.3',
3
+ 'putout': 'https://esm.sh/@putout/bundle@4.7.4',
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',
package/menu/menu.css CHANGED
@@ -28,7 +28,7 @@
28
28
  .menu-item {
29
29
  position: relative;
30
30
  padding: 3px 20px;
31
- white-space: pre;
31
+ white-space: nowrap;
32
32
  }
33
33
 
34
34
  .menu-item::after {
@@ -1 +1,8 @@
1
- <ul data-name="menu" class="menu menu-hidden"><li data-name="menu-item" data-menu-index="0" className="menu-item" data-menu-path="hello"><label data-menu-path="hello">hello</label></li><li data-name="menu-item" data-menu-index="1" className="menu-item" data-menu-path="world"><label data-menu-path="world">world</label></li></ul>;
1
+ <ul data-name="menu" class="menu menu-hidden">
2
+ <li data-name="menu-item" data-menu-index="0" className="menu-item" data-menu-path="hello">
3
+ <label data-menu-path="">hello</label>
4
+ </li>
5
+ <li data-name="menu-item" data-menu-index="1" className="menu-item" data-menu-path="world">
6
+ <label data-menu-path="">world</label>
7
+ </li>
8
+ </ul>;
@@ -1 +1,8 @@
1
- <ul data-name="menu" class="menu menu-hidden"><li data-name="menu-item" data-menu-index="0" className="menu-item icon icon-hello" data-menu-path="hello"><label data-menu-path="hello">hello</label></li><li data-name="menu-item" data-menu-index="1" className="menu-item icon icon-world" data-menu-path="world"><label data-menu-path="world">world</label></li></ul>;
1
+ <ul data-name="menu" class="menu menu-hidden">
2
+ <li data-name="menu-item" data-menu-index="0" className="menu-item icon icon-hello" data-menu-path="hello">
3
+ <label data-menu-path="">hello</label>
4
+ </li>
5
+ <li data-name="menu-item" data-menu-index="1" className="menu-item icon icon-world" data-menu-path="world">
6
+ <label data-menu-path="">world</label>
7
+ </li>
8
+ </ul>;
@@ -1 +1,9 @@
1
- <ul data-name="menu" class="menu menu-hidden"><li data-name="menu-item" data-menu-index="0" className="menu-item icon icon-hello menu-submenu" data-menu-path="hello"><label data-menu-path="hello">hello</label><ul data-name="menu" className="menu menu-hidden"><li data-name="menu-item" data-menu-index="0" className="menu-item icon icon-world" data-menu-path="hello.world"><label data-menu-path="hello.world">world</label></li></ul></li></ul>;
1
+ <ul data-name="menu" class="menu menu-hidden">
2
+ <li data-name="menu-item" data-menu-index="0" className="menu-item icon icon-hello menu-submenu" data-menu-path="hello">
3
+ <label data-menu-path="">hello</label>
4
+ <ul data-name="menu" className="menu menu-hidden">
5
+ <li data-name="menu-item" data-menu-index="0" className="menu-item icon icon-world" data-menu-path="hello.world">
6
+ <label data-menu-path="">world</label>
7
+ </li>
8
+ </ul></li>
9
+ </ul>;
@@ -1,5 +1,10 @@
1
- import {template, operator} from 'putout';
1
+ import {
2
+ template,
3
+ operator,
4
+ types,
5
+ } from 'putout';
2
6
 
7
+ const {jsxText} = types;
3
8
  const {
4
9
  setAttributeValue,
5
10
  hasDataName,
@@ -13,7 +18,9 @@ const isObject = (a) => a && typeof a === 'object';
13
18
  export const report = () => `Build menu`;
14
19
 
15
20
  const createMenuItem = template(`
16
- <li data-name="menu-item" data-menu-index="" className="menu-item" data-menu-path=""><label data-menu-path="">NAME</label></li>
21
+ <li data-name="menu-item" data-menu-index="" className="menu-item" data-menu-path="">
22
+ <label data-menu-path="">NAME</label>
23
+ </li>
17
24
  `);
18
25
 
19
26
  const createMenu = template(`
@@ -25,6 +32,9 @@ const DefaultMenu = {
25
32
  world: null,
26
33
  };
27
34
 
35
+ const NEWLINE = jsxText('\n');
36
+ const INDENT = jsxText(' ');
37
+
28
38
  export const fix = ({path, menu, icon, name = ''}) => {
29
39
  const {children} = path.node;
30
40
  let i = 0;
@@ -32,23 +42,22 @@ export const fix = ({path, menu, icon, name = ''}) => {
32
42
  for (const [key, value] of entries(menu)) {
33
43
  const menuItem = createMenuItem();
34
44
 
35
- menuItem.children[0].children[0].value = key;
45
+ menuItem.children[1].children[0].value = key;
36
46
 
37
47
  if (icon)
38
48
  setIcon(key, menuItem);
39
49
 
40
50
  setDataMenuIndex(i++, menuItem);
41
51
  setDataMenuPath(key, name, menuItem);
42
- setDataMenuPath(key, name, menuItem.children[0]);
43
-
44
- children.push(menuItem);
52
+ // setDataMenuPath(key, name, menuItem.children[3]);
53
+ children.push(INDENT, menuItem);
45
54
 
46
55
  if (isObject(value)) {
47
56
  setSubmenu(menuItem);
48
57
  menuItem.children.push(createMenu());
49
58
 
50
59
  const elementPath = path.get('children').at(-1)
51
- .get('children.1');
60
+ .get('children.3');
52
61
 
53
62
  fix({
54
63
  path: elementPath,
@@ -58,6 +67,8 @@ export const fix = ({path, menu, icon, name = ''}) => {
58
67
  });
59
68
  }
60
69
  }
70
+
71
+ children.push(NEWLINE);
61
72
  };
62
73
 
63
74
  export const traverse = ({options, push}) => ({
@@ -6,6 +6,8 @@ const {
6
6
  addClassName,
7
7
  hasDataName,
8
8
  removeClassName,
9
+ hasAttributeValue,
10
+ containsClassName,
9
11
  } = operator;
10
12
 
11
13
  const SELECTED = 'menu-item-selected';
@@ -31,6 +33,7 @@ export const traverse = ({options, push}) => ({
31
33
  name = 'menu',
32
34
  index = 1,
33
35
  showSubmenu,
36
+ insideSubmenu,
34
37
  } = options;
35
38
 
36
39
  if (!hasTagName(path, 'li'))
@@ -44,15 +47,18 @@ export const traverse = ({options, push}) => ({
44
47
  if (!hasDataName(parentPath, name))
45
48
  return;
46
49
 
50
+ if (!insideSubmenu && !hasAttributeValue(path, 'data-menu-index', String(index)))
51
+ return;
52
+
53
+ if (!insideSubmenu && containsClassName(path, 'menu-item-selected'))
54
+ return;
55
+
47
56
  const children = parentPath.get('children').filter(isJSXElement);
48
57
 
49
58
  const prev = children[index - 1];
50
59
  const current = children[index];
51
60
  const next = children[index + 1];
52
61
 
53
- if (!current)
54
- return;
55
-
56
62
  push({
57
63
  path: current,
58
64
  prev,
@@ -0,0 +1,8 @@
1
+ <ul data-name="menu" class="menu menu-hidden">
2
+ <li data-name="menu-item" className="menu-item icon icon-view menu-item-selected">
3
+ <label data-menu-path="View">View</label>
4
+ </li>
5
+ <li data-name="menu-item" className="menu-item icon icon-edit menu-item-selected">
6
+ <label data-menu-path="Edit">Edit</label>
7
+ </li>
8
+ </ul>;
@@ -18,7 +18,14 @@ export const fix = (path) => {
18
18
 
19
19
  export const traverse = ({push, options}) => ({
20
20
  JSXElement(path) {
21
- const {index, name = 'menu'} = options;
21
+ const {
22
+ index,
23
+ name = 'menu',
24
+ command,
25
+ } = options;
26
+
27
+ if (command === 'hide')
28
+ return;
22
29
 
23
30
  if (index !== -1)
24
31
  return;
@@ -0,0 +1,17 @@
1
+ // second selected
2
+ <ul data-name="menu" class="menu menu-hidden">
3
+ <li data-menu-path="Upload" data-name="menu-item" data-menu-index="0" className="menu-item icon icon-view menu-item-selected">
4
+ <label data-menu-path="Upload">Upload</label>
5
+ </li>
6
+ <li data-menu-path="New" data-name="menu-item" data-menu-index="1" 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" data-menu-index="0" className="menu-item icon icon-view menu-item-selected">
10
+ <label data-menu-path="Upload">Upload</label>
11
+ </li>
12
+ <li data-menu-path="Directory" data-name="menu-item" data-menu-index="1" className="menu-item icon icon-edit">
13
+ <label data-menu-path="New.Directory">New</label>
14
+ </li>
15
+ </ul>
16
+ </li>
17
+ </ul>;
@@ -15,7 +15,10 @@ export const fix = (path) => {
15
15
 
16
16
  export const traverse = ({push, options}) => ({
17
17
  JSXElement(path) {
18
- const {index = 1} = options;
18
+ const {index = 1, command} = options;
19
+
20
+ if (command === 'hide')
21
+ return;
19
22
 
20
23
  if (!hasTagName(path, 'li'))
21
24
  return;
package/menu/state.js CHANGED
@@ -1,19 +1,12 @@
1
- const {keys} = Object;
2
-
3
- export const initState = ({menu, name = 'menu'}) => {
4
- const count = keys(menu).length;
5
-
6
- return {
7
- name,
8
- command: 'hide',
9
- insideSubmenu: false,
10
- submenuIndex: 0,
11
- showSubmenu: false,
12
- index: -1,
13
- count,
14
- position: {
15
- x: 0,
16
- y: 20,
17
- },
18
- };
19
- };
1
+ export const initState = ({name = 'menu'}) => ({
2
+ name,
3
+ command: 'hide',
4
+ insideSubmenu: false,
5
+ submenuIndex: 0,
6
+ showSubmenu: false,
7
+ index: -1,
8
+ position: {
9
+ x: 0,
10
+ y: 20,
11
+ },
12
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aleman",
3
- "version": "1.12.4",
3
+ "version": "1.14.0",
4
4
  "type": "module",
5
5
  "author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
6
6
  "description": "🐊Putout-based framework for web",
@@ -23,6 +23,9 @@
23
23
  "coverage": "madrun coverage",
24
24
  "report": "madrun report"
25
25
  },
26
+ "imports": {
27
+ "#test": "./test/create-test.js"
28
+ },
26
29
  "dependencies": {
27
30
  "@putout/processor-html": "^14.0.2",
28
31
  "fullstore": "^3.0.0",