aleman 1.0.16 → 1.1.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/aleman/add-listeners.js +94 -0
- package/aleman/index.js +44 -0
- package/aleman/render.js +58 -0
- package/aleman/state.js +78 -0
- package/example/index.html +1 -0
- package/example/index.js +8 -0
- package/index-buttons.html +2 -2
- package/index.html +2 -3
- package/menu/addons/click.js +6 -0
- package/menu/addons/context-menu.js +13 -0
- package/menu/addons/down.js +16 -0
- package/menu/addons/enter.js +16 -0
- package/menu/addons/escape.js +6 -0
- package/menu/addons/f9.js +9 -0
- package/menu/addons/index.js +21 -0
- package/menu/addons/item-click.js +16 -0
- package/menu/addons/mouse-enter.js +5 -0
- package/menu/addons/up.js +12 -0
- package/menu/hydrate-menu.js +22 -0
- package/menu/importmap.json +9 -0
- package/menu/menu.js +40 -23
- package/{lib → menu}/rules/index.js +4 -10
- package/{lib → menu}/rules/select/fixture/select-fix.js +1 -1
- package/{lib → menu}/rules/select/index.js +29 -5
- package/menu/rules/set-position/fixture/no-style.js +2 -0
- package/menu/rules/set-position/fixture/set-position-fix.js +2 -0
- package/{lib → menu}/rules/set-position/index.js +29 -4
- package/{lib → menu}/rules/unselect-all/index.js +6 -1
- package/menu/state.js +15 -0
- package/package.json +3 -6
- package/lib/addons/additional/fixture/start-click-fix.html +0 -0
- package/lib/addons/additional/fixture/start-click.html +0 -1
- package/lib/addons/additional/fixture/stop-click-fix.html +0 -0
- package/lib/addons/additional/fixture/stop-click.html +0 -1
- package/lib/addons/additional/input-change.js +0 -39
- package/lib/addons/additional/start-click.js +0 -7
- package/lib/addons/additional/stop-click.js +0 -7
- package/lib/addons/menu-item-click.js +0 -27
- package/lib/addons/menu-mouse-over.js +0 -6
- package/lib/addons/show-menu-click.js +0 -12
- package/lib/aleman/add-listeners.js +0 -116
- package/lib/aleman/aleman.js +0 -47
- package/lib/aleman/load.js +0 -5
- package/lib/aleman/render.js +0 -107
- package/lib/globals/menu/click.js +0 -21
- package/lib/globals/menu/context-menu.js +0 -18
- package/lib/globals/menu/down.js +0 -21
- package/lib/globals/menu/enter.js +0 -33
- package/lib/globals/menu/escape.js +0 -19
- package/lib/globals/menu/f9.js +0 -27
- package/lib/globals/menu/menu.js +0 -34
- package/lib/globals/menu/up.js +0 -19
- package/lib/globals/menu.js +0 -17
- package/lib/main.js +0 -35
- package/lib/menu/menu.js +0 -4
- package/lib/rules/README.md +0 -10
- package/lib/rules/remove-button/fixture/remove-button-fix.js +0 -2
- package/lib/rules/remove-button/fixture/remove-button.js +0 -2
- package/lib/rules/remove-button/index.js +0 -27
- package/lib/rules/set-value/fixture/data-name.js +0 -1
- package/lib/rules/set-value/fixture/no-data-name.js +0 -1
- package/lib/rules/set-value/fixture/not-label.js +0 -1
- package/lib/rules/set-value/fixture/set-value-fix.js +0 -1
- package/lib/rules/set-value/fixture/set-value.js +0 -1
- package/lib/rules/set-value/index.js +0 -34
- package/lib/rules/unselect/fixture/no-data-name.js +0 -4
- package/lib/rules/unselect/fixture/no-parent.js +0 -2
- package/lib/rules/unselect/fixture/unselect-fix.js +0 -8
- package/lib/rules/unselect/fixture/unselect.js +0 -8
- package/lib/rules/unselect/index.js +0 -39
- package/menu/index.html +0 -4
- package/menu/main.js +0 -29
- /package/{lib → menu}/rules/build-menu/fixture/build-menu-fix.js +0 -0
- /package/{lib → menu}/rules/build-menu/fixture/build-menu.js +0 -0
- /package/{lib → menu}/rules/build-menu/fixture/built.js +0 -0
- /package/{lib → menu}/rules/build-menu/index.js +0 -0
- /package/{lib → menu}/rules/check-data-name.js +0 -0
- /package/{lib → menu}/rules/menu/fixture/hide-menu-fix.js +0 -0
- /package/{lib → menu}/rules/menu/fixture/hide-menu.js +0 -0
- /package/{lib → menu}/rules/menu/fixture/no-menu.js +0 -0
- /package/{lib → menu}/rules/menu/fixture/show-menu-fix.js +0 -0
- /package/{lib → menu}/rules/menu/fixture/show-menu.js +0 -0
- /package/{lib → menu}/rules/menu/index.js +0 -0
- /package/{lib → menu}/rules/select/fixture/no-data-name.js +0 -0
- /package/{lib → menu}/rules/select/fixture/no-next.js +0 -0
- /package/{lib → menu}/rules/select/fixture/no-parent.js +0 -0
- /package/{lib → menu}/rules/select/fixture/select.js +0 -0
- /package/{lib → menu}/rules/select/fixture/wrong-data-name.js +0 -0
- /package/{lib/rules/set-position/fixture/set-position-fix.js → menu/rules/set-position/fixture/no-style-fix.js} +0 -0
- /package/{lib → menu}/rules/set-position/fixture/not-menu.js +0 -0
- /package/{lib → menu}/rules/set-position/fixture/set-position.js +0 -0
- /package/{lib → menu}/rules/unselect-all/fixture/no-data-name.js +0 -0
- /package/{lib → menu}/rules/unselect-all/fixture/no-parent.js +0 -0
- /package/{lib → menu}/rules/unselect-all/fixture/unselect-all-fix.js +0 -0
- /package/{lib → menu}/rules/unselect-all/fixture/unselect-all.js +0 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
const queryElement = ({name}) => {
|
|
2
|
+
return document.querySelector(`[data-name="${name}"]`);
|
|
3
|
+
};
|
|
4
|
+
|
|
5
|
+
const maybeEvents = ({events}) => {
|
|
6
|
+
if (events)
|
|
7
|
+
return events;
|
|
8
|
+
|
|
9
|
+
return ['keydown'];
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const addListeners = ({namedAddons, options, readState, writeState}) => {
|
|
13
|
+
for (const addon of namedAddons) {
|
|
14
|
+
const element = queryElement(addon);
|
|
15
|
+
const events = maybeEvents(addon);
|
|
16
|
+
const {
|
|
17
|
+
key,
|
|
18
|
+
listener,
|
|
19
|
+
preventDefault,
|
|
20
|
+
} = addon;
|
|
21
|
+
|
|
22
|
+
for (const event of events) {
|
|
23
|
+
element.addEventListener(event, (event) => {
|
|
24
|
+
if (preventDefault)
|
|
25
|
+
event.preventDefault();
|
|
26
|
+
|
|
27
|
+
if (key && event.key !== key)
|
|
28
|
+
return;
|
|
29
|
+
|
|
30
|
+
const state = readState();
|
|
31
|
+
|
|
32
|
+
const newState = listener({
|
|
33
|
+
event,
|
|
34
|
+
state,
|
|
35
|
+
options,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
writeState(newState);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const hasName = ({name}) => name;
|
|
45
|
+
|
|
46
|
+
export const splitAddons = (addons) => {
|
|
47
|
+
const globalAddons = [];
|
|
48
|
+
const namedAddons = [];
|
|
49
|
+
|
|
50
|
+
for (const addon of addons) {
|
|
51
|
+
if (hasName(addon)) {
|
|
52
|
+
namedAddons.push(addon);
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
globalAddons.push(addon);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
globalAddons,
|
|
61
|
+
namedAddons,
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export const addGlobalListeners = ({globalAddons, options, readState, writeState}) => {
|
|
66
|
+
for (const addon of globalAddons) {
|
|
67
|
+
const events = maybeEvents(addon);
|
|
68
|
+
const {
|
|
69
|
+
key,
|
|
70
|
+
listener,
|
|
71
|
+
preventDefault,
|
|
72
|
+
} = addon;
|
|
73
|
+
|
|
74
|
+
for (const event of events) {
|
|
75
|
+
document.addEventListener(event, (event) => {
|
|
76
|
+
if (preventDefault)
|
|
77
|
+
event.preventDefault();
|
|
78
|
+
|
|
79
|
+
if (key && event.key !== key)
|
|
80
|
+
return;
|
|
81
|
+
|
|
82
|
+
const state = readState();
|
|
83
|
+
|
|
84
|
+
const newState = listener({
|
|
85
|
+
event,
|
|
86
|
+
state,
|
|
87
|
+
options,
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
writeState(newState);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
};
|
package/aleman/index.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import {createState} from './state.js';
|
|
2
|
+
import {
|
|
3
|
+
addGlobalListeners,
|
|
4
|
+
addListeners,
|
|
5
|
+
splitAddons,
|
|
6
|
+
} from './add-listeners.js';
|
|
7
|
+
import {createRender} from './render.js';
|
|
8
|
+
|
|
9
|
+
export const hydrate = (element, {addons, options, state, rules, stateName = 'aleman-state'}) => {
|
|
10
|
+
const render = createRender(element.innerHTML, {
|
|
11
|
+
options,
|
|
12
|
+
rules,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const {globalAddons, namedAddons} = splitAddons(addons);
|
|
16
|
+
|
|
17
|
+
const listener = () => {
|
|
18
|
+
const state = readState();
|
|
19
|
+
const [is, result] = render(state);
|
|
20
|
+
|
|
21
|
+
if (!is)
|
|
22
|
+
return;
|
|
23
|
+
|
|
24
|
+
element.innerHTML = result;
|
|
25
|
+
addListeners({
|
|
26
|
+
readState,
|
|
27
|
+
writeState,
|
|
28
|
+
namedAddons,
|
|
29
|
+
options,
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const {readState, writeState} = createState(state, {
|
|
34
|
+
stateName,
|
|
35
|
+
listener,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
addGlobalListeners({
|
|
39
|
+
readState,
|
|
40
|
+
writeState,
|
|
41
|
+
globalAddons,
|
|
42
|
+
options,
|
|
43
|
+
});
|
|
44
|
+
};
|
package/aleman/render.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import {
|
|
2
|
+
parse,
|
|
3
|
+
transform,
|
|
4
|
+
print,
|
|
5
|
+
findPlaces,
|
|
6
|
+
} from 'putout';
|
|
7
|
+
import {branch, merge} from '@putout/processor-html';
|
|
8
|
+
|
|
9
|
+
const {entries} = Object;
|
|
10
|
+
|
|
11
|
+
export const SKIP = false;
|
|
12
|
+
export const TRANSFORM = true;
|
|
13
|
+
|
|
14
|
+
export const createRender = (html, {options, rules}) => {
|
|
15
|
+
const {source} = branch(html)[0];
|
|
16
|
+
const withDiv = `<template>${source}</template>`;
|
|
17
|
+
const ast = parse(withDiv);
|
|
18
|
+
|
|
19
|
+
return function render(state) {
|
|
20
|
+
const currentRules = {};
|
|
21
|
+
const plugins = entries(rules);
|
|
22
|
+
|
|
23
|
+
for (const [name] of plugins) {
|
|
24
|
+
currentRules[name] = ['on', {
|
|
25
|
+
...state,
|
|
26
|
+
...options,
|
|
27
|
+
}];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const places = findPlaces(ast, source, {
|
|
31
|
+
rules: currentRules,
|
|
32
|
+
plugins,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
if (!places.length)
|
|
36
|
+
return [SKIP];
|
|
37
|
+
|
|
38
|
+
transform(ast, '', {
|
|
39
|
+
rules: currentRules,
|
|
40
|
+
plugins,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const code = print(ast, {
|
|
44
|
+
printer: ['putout', {
|
|
45
|
+
format: {
|
|
46
|
+
newline: '',
|
|
47
|
+
endOfFile: '',
|
|
48
|
+
},
|
|
49
|
+
}],
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const prefix = '<template>';
|
|
53
|
+
const suffix = '<\\template>\n';
|
|
54
|
+
const result = merge('', [code]).slice(prefix.length, -suffix.length);
|
|
55
|
+
|
|
56
|
+
return [TRANSFORM, result];
|
|
57
|
+
};
|
|
58
|
+
};
|
package/aleman/state.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import fullstore from 'fullstore';
|
|
2
|
+
|
|
3
|
+
const {assign} = Object;
|
|
4
|
+
const {stringify, parse} = JSON;
|
|
5
|
+
|
|
6
|
+
const wrap = (render, {prev, options, stateElement, readState, writeState}) => () => {
|
|
7
|
+
const {textContent} = stateElement;
|
|
8
|
+
|
|
9
|
+
if (stateElement.textContent === prev())
|
|
10
|
+
return;
|
|
11
|
+
|
|
12
|
+
const state = readState();
|
|
13
|
+
prev(textContent);
|
|
14
|
+
writeState(state);
|
|
15
|
+
|
|
16
|
+
render({
|
|
17
|
+
state,
|
|
18
|
+
options,
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const createState = (state, {options, listener, stateName = 'aleman-state'}) => {
|
|
23
|
+
const stateElement = document.querySelector(`[data-name="${stateName}"]`);
|
|
24
|
+
|
|
25
|
+
const prev = fullstore();
|
|
26
|
+
const readState = createReadState(stateElement);
|
|
27
|
+
const writeState = createWriteState(prev, stateElement);
|
|
28
|
+
|
|
29
|
+
const fn = wrap(listener, {
|
|
30
|
+
options,
|
|
31
|
+
prev,
|
|
32
|
+
stateElement,
|
|
33
|
+
readState,
|
|
34
|
+
writeState,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const observer = new MutationObserver(fn);
|
|
38
|
+
const str = stringify(state, null, 4);
|
|
39
|
+
|
|
40
|
+
history[str] = true;
|
|
41
|
+
stateElement.textContent = str;
|
|
42
|
+
|
|
43
|
+
document.addEventListener('keydown', ({key}) => {
|
|
44
|
+
if (key === '`')
|
|
45
|
+
fn();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
observer.observe(stateElement, {
|
|
49
|
+
attributes: true,
|
|
50
|
+
childList: true,
|
|
51
|
+
subtree: true,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
readState,
|
|
56
|
+
writeState,
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export const createReadState = (stateElement) => () => {
|
|
61
|
+
return parse(stateElement.textContent);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export const createWriteState = (prev, stateElement) => (newState) => {
|
|
65
|
+
const prevStateStr = stateElement.textContent;
|
|
66
|
+
const prevState = parse(stateElement.textContent);
|
|
67
|
+
|
|
68
|
+
assign(prevState, newState);
|
|
69
|
+
const str = stringify(prevState);
|
|
70
|
+
|
|
71
|
+
if (str === prevStateStr)
|
|
72
|
+
return;
|
|
73
|
+
|
|
74
|
+
stateElement.textContent = str;
|
|
75
|
+
setTimeout(() => {
|
|
76
|
+
prev(str);
|
|
77
|
+
});
|
|
78
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<script src="index.js" type="module"></script>
|
package/example/index.js
ADDED
package/index-buttons.html
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
|
-
<link href="menu/menu.css" rel="stylesheet">
|
|
2
|
+
<link href="menu-v1/menu.css" rel="stylesheet">
|
|
3
3
|
|
|
4
4
|
<section data-name="hydrate">
|
|
5
5
|
<button data-name="menu-toggler">Menu</button>
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
</section>
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
<script data-name="aleman" type="module" src="
|
|
17
|
+
<script data-name="aleman" type="module" src="menu-v1/aleman/load.js" data-main="lib/main.js"></script>
|
|
18
18
|
<script type="importmap">
|
|
19
19
|
{
|
|
20
20
|
"imports": {
|
package/index.html
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
|
-
<link href="menu/menu.css" rel="stylesheet">
|
|
2
|
+
<link href="menu-v1/menu.css" rel="stylesheet">
|
|
3
3
|
|
|
4
4
|
<section data-name="hydrate">
|
|
5
5
|
<ul data-name="menu" class="menu menu-hidden" style="left: 0; top: 20px;">
|
|
6
6
|
</ul>
|
|
7
7
|
</section>
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
<script data-name="aleman" type="module" src="lib/aleman/load.js"></script>
|
|
9
|
+
<script data-name="aleman" type="module" src="menu-v1/aleman/load.js"></script>
|
|
11
10
|
<script type="importmap">
|
|
12
11
|
{
|
|
13
12
|
"imports": {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const {keys} = Object;
|
|
2
|
+
|
|
3
|
+
export const key = 'ArrowDown';
|
|
4
|
+
|
|
5
|
+
export const listener = ({state, options}) => {
|
|
6
|
+
let {index} = state;
|
|
7
|
+
const {menu} = options;
|
|
8
|
+
const n = keys(menu).length - 1;
|
|
9
|
+
|
|
10
|
+
if (index < n)
|
|
11
|
+
++index;
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
index,
|
|
15
|
+
};
|
|
16
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const {values} = Object;
|
|
2
|
+
|
|
3
|
+
export const key = 'Enter';
|
|
4
|
+
|
|
5
|
+
export const listener = ({options, state}) => {
|
|
6
|
+
const {index} = state;
|
|
7
|
+
const {menu} = options;
|
|
8
|
+
|
|
9
|
+
const fn = values(menu)[index];
|
|
10
|
+
setTimeout(fn);
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
command: 'hide',
|
|
14
|
+
index: -1,
|
|
15
|
+
};
|
|
16
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as contextMenu from './context-menu.js';
|
|
2
|
+
import * as click from './click.js';
|
|
3
|
+
import * as escape from './escape.js';
|
|
4
|
+
import * as down from './down.js';
|
|
5
|
+
import * as up from './up.js';
|
|
6
|
+
import * as f9 from './f9.js';
|
|
7
|
+
import * as enter from './enter.js';
|
|
8
|
+
import * as mouseEnter from './mouse-enter.js';
|
|
9
|
+
import * as itemClick from './item-click.js';
|
|
10
|
+
|
|
11
|
+
export const addons = [
|
|
12
|
+
contextMenu,
|
|
13
|
+
click,
|
|
14
|
+
escape,
|
|
15
|
+
down,
|
|
16
|
+
up,
|
|
17
|
+
f9,
|
|
18
|
+
enter,
|
|
19
|
+
mouseEnter,
|
|
20
|
+
itemClick,
|
|
21
|
+
];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const name = 'menu';
|
|
2
|
+
export const events = ['click'];
|
|
3
|
+
|
|
4
|
+
export const listener = ({event, options}) => {
|
|
5
|
+
const menuItemElement = document.elementFromPoint(event.clientX, event.clientY);
|
|
6
|
+
const name = menuItemElement.textContent.trim();
|
|
7
|
+
const {menu} = options;
|
|
8
|
+
const fn = menu[name];
|
|
9
|
+
|
|
10
|
+
setTimeout(fn);
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
index: -1,
|
|
14
|
+
command: 'hide',
|
|
15
|
+
};
|
|
16
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {rules} from './rules/index.js';
|
|
2
|
+
import {hydrate} from '../aleman/index.js';
|
|
3
|
+
import {initState} from './state.js';
|
|
4
|
+
import {addons} from './addons/index.js';
|
|
5
|
+
|
|
6
|
+
const {assign} = Object;
|
|
7
|
+
|
|
8
|
+
export const hydrateMenu = (element, options, menu) => {
|
|
9
|
+
assign(options, {
|
|
10
|
+
menu,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const state = initState(options);
|
|
14
|
+
|
|
15
|
+
hydrate(element, {
|
|
16
|
+
options,
|
|
17
|
+
state,
|
|
18
|
+
addons,
|
|
19
|
+
rules,
|
|
20
|
+
stateName: 'aleman-state-menu',
|
|
21
|
+
});
|
|
22
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"imports": {
|
|
3
|
+
"putout": "https://esm.sh/@putout/bundle",
|
|
4
|
+
"@putout/processor-html": "https://esm.sh/@putout/processor-html@14.1.1",
|
|
5
|
+
"html-escaper": "https://esm.sh/html-escaper",
|
|
6
|
+
"once": "https://esm.sh/once",
|
|
7
|
+
"fullstore": "https://esm.sh/fullstore"
|
|
8
|
+
}
|
|
9
|
+
}
|
package/menu/menu.js
CHANGED
|
@@ -1,43 +1,60 @@
|
|
|
1
|
+
const {stringify} = JSON;
|
|
2
|
+
|
|
1
3
|
export const createMenu = async (element, options, menuData) => {
|
|
2
|
-
createHydrate();
|
|
3
|
-
|
|
4
|
+
const hydrateElement = createHydrate();
|
|
5
|
+
|
|
6
|
+
await createMap();
|
|
7
|
+
await createLink();
|
|
4
8
|
|
|
5
|
-
|
|
6
|
-
const {hydrateMenu} = await import('./
|
|
9
|
+
createStateElement();
|
|
10
|
+
const {hydrateMenu} = await import('./hydrate-menu.js');
|
|
7
11
|
|
|
8
|
-
hydrateMenu(
|
|
12
|
+
hydrateMenu(hydrateElement, options, menuData);
|
|
9
13
|
};
|
|
10
14
|
|
|
11
|
-
function createLink() {
|
|
12
|
-
const style = document.createElement('
|
|
15
|
+
async function createLink() {
|
|
16
|
+
const style = document.createElement('style');
|
|
17
|
+
const content = await import('./menu.css', {
|
|
18
|
+
with: {
|
|
19
|
+
type: 'css',
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
for (const rule of content.default.cssRules) {
|
|
24
|
+
style.innerHTML += rule.cssText;
|
|
25
|
+
}
|
|
13
26
|
|
|
14
|
-
style.rel = 'stylesheet';
|
|
15
|
-
style.href = 'https://esm.sh/aleman@1.0.15/menu/menu.css';
|
|
16
27
|
document.head.appendChild(style);
|
|
17
28
|
}
|
|
18
29
|
|
|
19
30
|
function createHydrate() {
|
|
20
31
|
const section = document.createElement('section');
|
|
21
32
|
|
|
22
|
-
section.dataset.name = 'hydrate';
|
|
23
|
-
section.innerHTML = `<ul data-name="menu" class="menu menu-hidden"
|
|
24
|
-
|
|
33
|
+
section.dataset.name = 'aleman-hydrate-menu';
|
|
34
|
+
section.innerHTML = `<ul data-name="menu" class="menu menu-hidden"></ul>`;
|
|
35
|
+
document.body.append(section);
|
|
36
|
+
|
|
37
|
+
return section;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function createStateElement() {
|
|
41
|
+
const section = document.createElement('section');
|
|
42
|
+
|
|
43
|
+
section.classList.add('menu-hidden');
|
|
44
|
+
section.dataset.name = 'aleman-state-menu';
|
|
25
45
|
document.body.append(section);
|
|
26
46
|
}
|
|
27
47
|
|
|
28
|
-
function createMap() {
|
|
48
|
+
async function createMap() {
|
|
49
|
+
const {default: importmap} = await import('./importmap.json', {
|
|
50
|
+
with: {
|
|
51
|
+
type: 'json',
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
|
|
29
55
|
const script = document.createElement('script');
|
|
30
56
|
|
|
31
57
|
script.type = 'importmap';
|
|
32
|
-
script.innerHTML =
|
|
33
|
-
{
|
|
34
|
-
"imports": {
|
|
35
|
-
"putout": "https://esm.sh/@putout/bundle",
|
|
36
|
-
"@putout/processor-html": "https://esm.sh/@putout/processor-html",
|
|
37
|
-
"html-escaper": "https://esm.sh/html-escaper",
|
|
38
|
-
"once": "https://esm.sh/once"
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
`;
|
|
58
|
+
script.innerHTML = stringify(importmap, null, 4);
|
|
42
59
|
document.body.append(script);
|
|
43
60
|
}
|
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
import * as setPosition from './set-position/index.js';
|
|
2
|
-
import * as unselectAll from './unselect-all/index.js';
|
|
3
2
|
import * as buildMenu from './build-menu/index.js';
|
|
4
|
-
import * as select from './select/index.js';
|
|
5
|
-
import * as unselect from './unselect/index.js';
|
|
6
3
|
import * as menu from './menu/index.js';
|
|
7
|
-
import * as
|
|
8
|
-
import * as
|
|
4
|
+
import * as select from './select/index.js';
|
|
5
|
+
import * as unselectAll from './unselect-all/index.js';
|
|
9
6
|
|
|
10
7
|
export const rules = {
|
|
11
|
-
'set-value': setValue,
|
|
12
|
-
'remove-button': removeButton,
|
|
13
8
|
'menu': menu,
|
|
14
|
-
'select': select,
|
|
15
9
|
'build-menu': buildMenu,
|
|
16
|
-
'unselect': unselect,
|
|
17
|
-
'unselect-all': unselectAll,
|
|
18
10
|
'set-position': setPosition,
|
|
11
|
+
'select': select,
|
|
12
|
+
'select-all': unselectAll,
|
|
19
13
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<ul data-name="menu" class="menu menu-hidden">
|
|
2
|
-
<li data-name="menu-item" className=
|
|
2
|
+
<li data-name="menu-item" className='menu-item icon icon-view'>
|
|
3
3
|
<label data-menu-path="View">View</label>
|
|
4
4
|
</li>
|
|
5
5
|
<li data-name="menu-item" className='menu-item icon icon-edit menu-item-selected'>
|
|
@@ -5,9 +5,12 @@ const {setLiteralValue} = operator;
|
|
|
5
5
|
|
|
6
6
|
export const report = () => `Select item`;
|
|
7
7
|
|
|
8
|
-
export const fix = (path) => {
|
|
8
|
+
export const fix = ({path, prev, next}) => {
|
|
9
9
|
const {value} = path.node;
|
|
10
10
|
setLiteralValue(value, `${value.value} menu-item-selected`);
|
|
11
|
+
|
|
12
|
+
unselect(prev);
|
|
13
|
+
unselect(next);
|
|
11
14
|
};
|
|
12
15
|
|
|
13
16
|
export const traverse = ({options, push}) => ({
|
|
@@ -28,19 +31,25 @@ export const traverse = ({options, push}) => ({
|
|
|
28
31
|
.get('children')
|
|
29
32
|
.filter(isJSXElement);
|
|
30
33
|
|
|
31
|
-
const
|
|
34
|
+
const prev = children[index - 1];
|
|
35
|
+
const current = children[index];
|
|
36
|
+
const next = children[index + 1];
|
|
32
37
|
|
|
33
|
-
if (!
|
|
38
|
+
if (!current)
|
|
34
39
|
return;
|
|
35
40
|
|
|
36
|
-
for (const attr of
|
|
41
|
+
for (const attr of current.get('openingElement.attributes')) {
|
|
37
42
|
const {name, value} = attr.node;
|
|
38
43
|
|
|
39
44
|
if (name.name !== 'className')
|
|
40
45
|
continue;
|
|
41
46
|
|
|
42
47
|
if (!value.value.includes('menu-item-selected')) {
|
|
43
|
-
push(
|
|
48
|
+
push({
|
|
49
|
+
path: attr,
|
|
50
|
+
prev,
|
|
51
|
+
next,
|
|
52
|
+
});
|
|
44
53
|
break;
|
|
45
54
|
}
|
|
46
55
|
}
|
|
@@ -59,3 +68,18 @@ function checkDataName(path) {
|
|
|
59
68
|
|
|
60
69
|
return false;
|
|
61
70
|
}
|
|
71
|
+
|
|
72
|
+
function unselect(path) {
|
|
73
|
+
if (!path)
|
|
74
|
+
return;
|
|
75
|
+
|
|
76
|
+
for (const attr of path.get('openingElement.attributes')) {
|
|
77
|
+
const {name, value} = attr.node;
|
|
78
|
+
|
|
79
|
+
if (name.name !== 'className')
|
|
80
|
+
continue;
|
|
81
|
+
|
|
82
|
+
if (value.value.includes('menu-item-selected'))
|
|
83
|
+
setLiteralValue(value, value.value.replace(' menu-item-selected', ''));
|
|
84
|
+
}
|
|
85
|
+
}
|