@htmlplus/element 0.7.2 → 0.7.4
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/client/decorators/host.d.ts +2 -0
- package/client/decorators/host.js +10 -0
- package/client/decorators/index.d.ts +3 -1
- package/client/decorators/index.js +3 -1
- package/client/decorators/query.d.ts +2 -0
- package/client/decorators/query.js +11 -0
- package/client/decorators/queryAll.d.ts +2 -0
- package/client/decorators/queryAll.js +11 -0
- package/client/helpers/index.d.ts +1 -9
- package/client/helpers/index.js +1 -9
- package/client/utils/attributes.d.ts +1 -0
- package/client/utils/attributes.js +31 -0
- package/client/{helpers → utils}/classes.js +1 -1
- package/client/utils/config.d.ts +5 -3
- package/client/{helpers → utils}/direction.js +1 -1
- package/client/utils/index.d.ts +8 -1
- package/client/utils/index.js +8 -1
- package/client/utils/request.js +3 -3
- package/client/{helpers → utils}/slots.js +1 -1
- package/client/{helpers → utils}/styles.js +1 -1
- package/client/utils/uhtml.d.ts +22 -0
- package/client/utils/uhtml.js +699 -0
- package/compiler/plugins/customElement.js +109 -45
- package/compiler/plugins/style.js +1 -2
- package/compiler/utils/addDependency.js +3 -0
- package/constants/index.d.ts +9 -3
- package/constants/index.js +9 -4
- package/package.json +1 -1
- package/client/decorators/attributes.d.ts +0 -2
- package/client/decorators/attributes.js +0 -12
- package/client/helpers/query.d.ts +0 -3
- package/client/helpers/query.js +0 -5
- package/client/helpers/queryAll.d.ts +0 -3
- package/client/helpers/queryAll.js +0 -5
- package/client/utils/syncAttributes.d.ts +0 -1
- package/client/utils/syncAttributes.js +0 -31
- /package/client/{helpers → utils}/classes.d.ts +0 -0
- /package/client/{helpers → utils}/direction.d.ts +0 -0
- /package/client/{helpers → utils}/isRTL.d.ts +0 -0
- /package/client/{helpers → utils}/isRTL.js +0 -0
- /package/client/{helpers → utils}/slots.d.ts +0 -0
- /package/client/{helpers → utils}/styles.d.ts +0 -0
- /package/client/{helpers → utils}/toUnit.d.ts +0 -0
- /package/client/{helpers → utils}/toUnit.js +0 -0
|
@@ -36,7 +36,7 @@ export const customElement = (options) => {
|
|
|
36
36
|
return;
|
|
37
37
|
if (value.type != 'JSXExpressionContainer')
|
|
38
38
|
return;
|
|
39
|
-
const { local } = addDependency(path, CONSTANTS.
|
|
39
|
+
const { local } = addDependency(path, CONSTANTS.UTILS_PATH, CONSTANTS.UTILS_STYLES_LOCAL, CONSTANTS.UTILS_STYLES_IMPORTED);
|
|
40
40
|
// TODO: remove 'local!'
|
|
41
41
|
path.replaceWith(t.jsxAttribute(t.jsxIdentifier('style'), t.jsxExpressionContainer(t.callExpression(t.identifier(local), [value.expression]))));
|
|
42
42
|
path.skip();
|
|
@@ -48,66 +48,130 @@ export const customElement = (options) => {
|
|
|
48
48
|
const { name, value } = path.node;
|
|
49
49
|
if (name.name != 'className')
|
|
50
50
|
return;
|
|
51
|
-
const hasClass = path.parentPath.node.attributes.some((attribute) => attribute.name.name == 'class');
|
|
51
|
+
const hasClass = path.parentPath.node.attributes.some((attribute) => { var _a; return ((_a = attribute.name) === null || _a === void 0 ? void 0 : _a.name) == 'class'; });
|
|
52
52
|
if (hasClass)
|
|
53
53
|
return path.remove();
|
|
54
54
|
path.replaceWith(t.jsxAttribute(t.jsxIdentifier('class'), value));
|
|
55
55
|
}
|
|
56
56
|
});
|
|
57
|
-
//
|
|
57
|
+
// TODO
|
|
58
58
|
visitor(ast, {
|
|
59
59
|
JSXAttribute(path) {
|
|
60
60
|
const { name, value } = path.node;
|
|
61
|
-
|
|
61
|
+
const key = ['tabIndex', 'viewBox'];
|
|
62
|
+
if (!key.includes(name.name))
|
|
62
63
|
return;
|
|
63
|
-
path.replaceWith(t.jsxAttribute(t.jsxIdentifier(
|
|
64
|
+
path.replaceWith(t.jsxAttribute(t.jsxIdentifier(name.name.toLowerCase()), value));
|
|
64
65
|
}
|
|
65
66
|
});
|
|
66
67
|
// converts 'jsx' to 'uhtml' syntax
|
|
67
68
|
visitor(ast, {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
69
|
+
enter(path) {
|
|
70
|
+
const { type } = path.node;
|
|
71
|
+
if (!['JSXElement', 'JSXFragment'].includes(type))
|
|
72
|
+
return;
|
|
73
|
+
const TODO = (node, attributes) => {
|
|
74
|
+
const { local } = addDependency(path, CONSTANTS.UTILS_PATH, CONSTANTS.UTILS_ATTRIBUTES_LOCAL, CONSTANTS.UTILS_ATTRIBUTES_IMPORTED);
|
|
75
|
+
return t.callExpression(t.identifier(local), [
|
|
76
|
+
node,
|
|
77
|
+
t.arrayExpression(attributes.map((attribute) => {
|
|
78
|
+
var _a;
|
|
79
|
+
switch (attribute.type) {
|
|
80
|
+
case 'JSXSpreadAttribute':
|
|
81
|
+
return attribute.argument;
|
|
82
|
+
default:
|
|
83
|
+
return t.objectExpression([
|
|
84
|
+
t.objectProperty(t.stringLiteral(attribute.name.name), ((_a = attribute.value) === null || _a === void 0 ? void 0 : _a.type) == 'JSXExpressionContainer'
|
|
85
|
+
? attribute.value.expression
|
|
86
|
+
: attribute.value || t.booleanLiteral(true))
|
|
87
|
+
]);
|
|
88
|
+
}
|
|
89
|
+
}))
|
|
90
|
+
]);
|
|
91
|
+
};
|
|
92
|
+
const render = (node) => {
|
|
93
|
+
switch (node.type) {
|
|
94
|
+
case 'JSXElement':
|
|
95
|
+
const attributes = node.openingElement.attributes;
|
|
96
|
+
const isHost = node.openingElement.name.name == 'host';
|
|
97
|
+
// TODO
|
|
98
|
+
if (isHost) {
|
|
99
|
+
const children = node.children.map(render).flat();
|
|
100
|
+
if (!attributes.length)
|
|
101
|
+
return children;
|
|
102
|
+
const { local } = addDependency(path, CONSTANTS.UTILS_PATH, CONSTANTS.UTILS_HOST_LOCAL, CONSTANTS.UTILS_HOST_IMPORTED);
|
|
103
|
+
const host = t.callExpression(t.identifier(local), [t.thisExpression()]);
|
|
104
|
+
return [TODO(host, attributes), ...children];
|
|
105
|
+
}
|
|
106
|
+
const name = node.openingElement.name.name;
|
|
107
|
+
const children = node.children.map(render).flat();
|
|
108
|
+
const parts = [];
|
|
109
|
+
parts.push('<', name);
|
|
110
|
+
const hasSpreadAttribute = attributes.some((attribute) => attribute.type == 'JSXSpreadAttribute');
|
|
111
|
+
if (hasSpreadAttribute) {
|
|
112
|
+
parts.push(' ', TODO(t.identifier('TODO'), attributes));
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
for (const attribute of attributes) {
|
|
116
|
+
switch (attribute.type) {
|
|
117
|
+
case 'JSXAttribute':
|
|
118
|
+
parts.push(' ', attribute.name.name);
|
|
119
|
+
if (!attribute.value)
|
|
120
|
+
continue;
|
|
121
|
+
parts.push('=');
|
|
122
|
+
switch (attribute.value.type) {
|
|
123
|
+
case 'JSXExpressionContainer':
|
|
124
|
+
parts.push(attribute.value.expression);
|
|
125
|
+
break;
|
|
126
|
+
default:
|
|
127
|
+
parts.push(attribute.value.extra.raw);
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
break;
|
|
131
|
+
default:
|
|
132
|
+
parts.push(' ', attribute);
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
parts.push(node.closingElement ? '>' : ' />');
|
|
138
|
+
parts.push(...children);
|
|
139
|
+
if (node.closingElement) {
|
|
140
|
+
parts.push('<', '/', name, '>');
|
|
141
|
+
}
|
|
142
|
+
return parts;
|
|
143
|
+
case 'JSXFragment':
|
|
144
|
+
return node.children.map(render).flat();
|
|
145
|
+
case 'JSXText':
|
|
146
|
+
return [node.extra.raw];
|
|
147
|
+
case 'JSXExpressionContainer':
|
|
148
|
+
if (node.expression.type == 'JSXEmptyExpression')
|
|
149
|
+
return [];
|
|
150
|
+
return [node.expression];
|
|
86
151
|
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
152
|
+
};
|
|
153
|
+
const transform = (parts) => {
|
|
154
|
+
const quasis = [];
|
|
155
|
+
const expressions = [];
|
|
156
|
+
let i = 0;
|
|
157
|
+
while (i < parts.length + 1) {
|
|
158
|
+
let quasi = '';
|
|
159
|
+
while (typeof parts[i] == 'string') {
|
|
160
|
+
quasi += parts[i].replace(/[\\`]/g, (s) => `\\${s}`);
|
|
161
|
+
i += 1;
|
|
162
|
+
}
|
|
163
|
+
quasis.push(t.templateElement({ raw: quasi }));
|
|
164
|
+
if (parts[i] != null)
|
|
165
|
+
expressions.push(parts[i]);
|
|
166
|
+
i += 1;
|
|
99
167
|
}
|
|
100
|
-
|
|
101
|
-
},
|
|
102
|
-
JSXSpreadAttribute: {
|
|
103
|
-
enter(path) {
|
|
168
|
+
const template = t.templateLiteral(quasis, expressions);
|
|
104
169
|
// TODO
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
t.addComment(node, 'leading', CONSTANTS.COMMENT_AUTO_ADDED_DEPENDENCY, true);
|
|
170
|
+
// if (!expressions.length) return template;
|
|
171
|
+
const { local } = addDependency(path, CONSTANTS.UTILS_PATH, CONSTANTS.UTILS_HTML_LOCAL, CONSTANTS.UTILS_HTML_IMPORTED);
|
|
172
|
+
return t.taggedTemplateExpression(t.identifier(local), template);
|
|
173
|
+
};
|
|
174
|
+
path.replaceWith(transform(render(path.node)));
|
|
111
175
|
}
|
|
112
176
|
});
|
|
113
177
|
// adds type to properties
|
|
@@ -30,8 +30,7 @@ export const style = (options) => {
|
|
|
30
30
|
}
|
|
31
31
|
if (!context.stylePath)
|
|
32
32
|
return;
|
|
33
|
-
const { local
|
|
34
|
-
t.addComment(node, 'leading', CONSTANTS.COMMENT_AUTO_ADDED_DEPENDENCY, true);
|
|
33
|
+
const { local } = addDependency(context.fileAST, context.stylePath, CONSTANTS.STYLE_IMPORTED);
|
|
35
34
|
// TODO: remove 'local!'
|
|
36
35
|
const property = t.classProperty(t.identifier(CONSTANTS.STATIC_STYLES), t.identifier(local), undefined, null, undefined, true);
|
|
37
36
|
t.addComment(property, 'leading', CONSTANTS.COMMENT_AUTO_ADDED_PROPERTY, true);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import t from '@babel/types';
|
|
2
|
+
import * as CONSTANTS from '../../constants/index.js';
|
|
2
3
|
import { visitor } from './visitor.js';
|
|
3
4
|
export function addDependency(path, source, local, imported) {
|
|
4
5
|
const isDefault = local && !imported;
|
|
@@ -52,6 +53,8 @@ export function addDependency(path, source, local, imported) {
|
|
|
52
53
|
declaration = t.importDeclaration(specifier ? [specifier] : [], t.stringLiteral(source));
|
|
53
54
|
// TODO
|
|
54
55
|
(file.program || file).body.unshift(declaration);
|
|
56
|
+
// TODO
|
|
57
|
+
t.addComment(declaration, 'leading', CONSTANTS.COMMENT_AUTO_ADDED_DEPENDENCY, true);
|
|
55
58
|
}
|
|
56
59
|
return {
|
|
57
60
|
local,
|
package/constants/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export declare const PACKAGE_NAME = "@htmlplus/element";
|
|
2
|
-
export declare const API_ATTRIBUTES_SYNCER: unique symbol;
|
|
3
2
|
export declare const API_CONNECTED: unique symbol;
|
|
4
3
|
export declare const API_HOST: unique symbol;
|
|
5
4
|
export declare const API_INSTANCE: unique symbol;
|
|
@@ -38,5 +37,12 @@ export declare const TYPE_NUMBER = 64;
|
|
|
38
37
|
export declare const TYPE_OBJECT = 128;
|
|
39
38
|
export declare const TYPE_STRING = 256;
|
|
40
39
|
export declare const TYPE_UNDEFINED = 512;
|
|
41
|
-
export declare const
|
|
42
|
-
export declare const
|
|
40
|
+
export declare const UTILS_ATTRIBUTES_IMPORTED = "attributes";
|
|
41
|
+
export declare const UTILS_ATTRIBUTES_LOCAL = "UTILS_ATTRIBUTES";
|
|
42
|
+
export declare const UTILS_HOST_IMPORTED = "host";
|
|
43
|
+
export declare const UTILS_HOST_LOCAL = "UTILS_HOST";
|
|
44
|
+
export declare const UTILS_HTML_IMPORTED = "html";
|
|
45
|
+
export declare const UTILS_HTML_LOCAL = "UTILS_HTML";
|
|
46
|
+
export declare const UTILS_STYLES_IMPORTED = "styles";
|
|
47
|
+
export declare const UTILS_STYLES_LOCAL = "UTILS_STYLES";
|
|
48
|
+
export declare const UTILS_PATH = "@htmlplus/element/client/utils/index.js";
|
package/constants/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export const PACKAGE_NAME = '@htmlplus/element';
|
|
2
2
|
// apis
|
|
3
|
-
export const API_ATTRIBUTES_SYNCER = Symbol();
|
|
4
3
|
export const API_CONNECTED = Symbol();
|
|
5
4
|
export const API_HOST = Symbol();
|
|
6
5
|
export const API_INSTANCE = Symbol();
|
|
@@ -47,6 +46,12 @@ export const TYPE_OBJECT = 128;
|
|
|
47
46
|
export const TYPE_STRING = 256;
|
|
48
47
|
export const TYPE_UNDEFINED = 512;
|
|
49
48
|
// utils
|
|
50
|
-
export const
|
|
51
|
-
|
|
52
|
-
export const
|
|
49
|
+
export const UTILS_ATTRIBUTES_IMPORTED = 'attributes';
|
|
50
|
+
export const UTILS_ATTRIBUTES_LOCAL = 'UTILS_ATTRIBUTES';
|
|
51
|
+
export const UTILS_HOST_IMPORTED = 'host';
|
|
52
|
+
export const UTILS_HOST_LOCAL = 'UTILS_HOST';
|
|
53
|
+
export const UTILS_HTML_IMPORTED = 'html';
|
|
54
|
+
export const UTILS_HTML_LOCAL = 'UTILS_HTML';
|
|
55
|
+
export const UTILS_STYLES_IMPORTED = 'styles';
|
|
56
|
+
export const UTILS_STYLES_LOCAL = 'UTILS_STYLES';
|
|
57
|
+
export const UTILS_PATH = '@htmlplus/element/client/utils/index.js';
|
package/package.json
CHANGED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import * as CONSTANTS from '../../constants/index.js';
|
|
2
|
-
import { appendToMethod, host, syncAttributes } from '../utils/index.js';
|
|
3
|
-
export function Attributes() {
|
|
4
|
-
return function (target, propertyKey) {
|
|
5
|
-
appendToMethod(target, CONSTANTS.LIFECYCLE_CONNECTED, function () {
|
|
6
|
-
this[CONSTANTS.API_ATTRIBUTES_SYNCER] = syncAttributes(host(this));
|
|
7
|
-
});
|
|
8
|
-
appendToMethod(target, CONSTANTS.LIFECYCLE_UPDATED, function () {
|
|
9
|
-
this[CONSTANTS.API_ATTRIBUTES_SYNCER](this[propertyKey]);
|
|
10
|
-
});
|
|
11
|
-
};
|
|
12
|
-
}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
export declare function query<K extends keyof HTMLElementTagNameMap>(target: any, selectors: K): HTMLElementTagNameMap[K] | null;
|
|
2
|
-
export declare function query<K extends keyof SVGElementTagNameMap>(target: any, selectors: K): SVGElementTagNameMap[K] | null;
|
|
3
|
-
export declare function query<E extends Element = Element>(target: any, selectors: string): E | null;
|
package/client/helpers/query.js
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
export declare function queryAll<K extends keyof HTMLElementTagNameMap>(target: any, selectors: K): NodeListOf<HTMLElementTagNameMap[K]>;
|
|
2
|
-
export declare function queryAll<K extends keyof SVGElementTagNameMap>(target: any, selectors: K): NodeListOf<SVGElementTagNameMap[K]>;
|
|
3
|
-
export declare function queryAll<E extends Element = Element>(target: any, selectors: string): NodeListOf<E>;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const syncAttributes: (node: HTMLElement) => (next?: any) => void;
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { off, on } from './event.js';
|
|
2
|
-
import { isEvent } from './isEvent.js';
|
|
3
|
-
import { toEvent } from './toEvent.js';
|
|
4
|
-
import { updateAttribute } from './updateAttribute.js';
|
|
5
|
-
export const syncAttributes = (node) => {
|
|
6
|
-
let prev = {};
|
|
7
|
-
return (next = {}) => {
|
|
8
|
-
const prevClass = (prev.class || '').split(' ');
|
|
9
|
-
const nextClass = (next.class || '').split(' ');
|
|
10
|
-
const newClass = node.className
|
|
11
|
-
.split(' ')
|
|
12
|
-
.filter((key) => !prevClass.includes(key) && !nextClass.includes(key))
|
|
13
|
-
.concat(nextClass)
|
|
14
|
-
.filter((key) => key)
|
|
15
|
-
.join(' ');
|
|
16
|
-
updateAttribute(node, 'class', newClass || undefined);
|
|
17
|
-
if (prev.style || next.style)
|
|
18
|
-
node.setAttribute('style', next.style || '');
|
|
19
|
-
for (const key in prev)
|
|
20
|
-
isEvent(key) && off(node, toEvent(key), prev[key]);
|
|
21
|
-
for (const key in next) {
|
|
22
|
-
if (['class', 'style'].includes(key))
|
|
23
|
-
continue;
|
|
24
|
-
if (isEvent(key))
|
|
25
|
-
on(node, toEvent(key), next[key]);
|
|
26
|
-
else
|
|
27
|
-
updateAttribute(node, key, next[key]);
|
|
28
|
-
}
|
|
29
|
-
prev = Object.assign({}, next);
|
|
30
|
-
};
|
|
31
|
-
};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|