@dooboostore/dom-render 1.0.99 → 1.0.102

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.
@@ -7,18 +7,77 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  var __metadata = (this && this.__metadata) || function (k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
+ import 'reflect-metadata';
11
+ import { ElementUtils } from '@dooboostore/core-web/element/ElementUtils';
10
12
  import { RawSet } from '../rawsets/RawSet';
11
13
  import { DomRenderNoProxy } from '../decorators/DomRenderNoProxy';
12
14
  import { ConvertUtils } from '@dooboostore/core/convert/ConvertUtils';
13
15
  import * as Render from '../rawsets/Render';
16
+ import { ReflectUtils } from '@dooboostore/core/reflect/ReflectUtils';
17
+ export const ATTRIBUTE_METADATA_KEY = Symbol('attribute');
18
+ export const QUERY_METADATA_KEY = Symbol('query');
19
+ export const EVENT_METADATA_KEY = Symbol('event');
20
+ export function attribute(options) {
21
+ return (target, propertyKey) => {
22
+ const attributes = ReflectUtils.getMetadata(ATTRIBUTE_METADATA_KEY, target.constructor) || [];
23
+ attributes.push({
24
+ propertyKey: propertyKey,
25
+ name: (options === null || options === void 0 ? void 0 : options.name) || propertyKey,
26
+ converter: options === null || options === void 0 ? void 0 : options.converter
27
+ });
28
+ ReflectUtils.defineMetadata(ATTRIBUTE_METADATA_KEY, attributes, target.constructor);
29
+ };
30
+ }
31
+ export function query(selector) {
32
+ return (target, propertyKey, descriptor) => {
33
+ const queries = ReflectUtils.getMetadata(QUERY_METADATA_KEY, target.constructor) || [];
34
+ queries.push({
35
+ selector: selector,
36
+ propertyKey: propertyKey,
37
+ isMethod: !!descriptor
38
+ });
39
+ ReflectUtils.defineMetadata(QUERY_METADATA_KEY, queries, target.constructor);
40
+ };
41
+ }
42
+ export function event(options) {
43
+ return (target, propertyKey, descriptor) => {
44
+ const events = ReflectUtils.getMetadata(EVENT_METADATA_KEY, target.constructor) || [];
45
+ events.push({
46
+ query: options.query,
47
+ eventName: options.name,
48
+ methodName: propertyKey
49
+ });
50
+ ReflectUtils.defineMetadata(EVENT_METADATA_KEY, events, target.constructor);
51
+ };
52
+ }
14
53
  export class ComponentBase {
15
- // private attributeData?: FieldUnionType<T, null>;
16
54
  get render() {
17
55
  return this._render;
18
56
  }
19
57
  get rawSet() {
20
58
  return this._rawSet;
21
59
  }
60
+ _queryElements(selector) {
61
+ var _a, _b, _c, _d;
62
+ const e = this.getElement();
63
+ if (e) {
64
+ return ElementUtils.querySelectorAll(e, selector);
65
+ }
66
+ else {
67
+ const startNode = (_b = (_a = this.rawSet) === null || _a === void 0 ? void 0 : _a.point) === null || _b === void 0 ? void 0 : _b.start;
68
+ const endNode = (_d = (_c = this.rawSet) === null || _c === void 0 ? void 0 : _c.point) === null || _d === void 0 ? void 0 : _d.end;
69
+ if (startNode && endNode) {
70
+ return ElementUtils.querySelectorAll({ start: startNode, end: endNode }, selector);
71
+ }
72
+ }
73
+ return [];
74
+ }
75
+ _cleanupEventListeners() {
76
+ for (const { element, eventName, listener } of this._boundEventListeners) {
77
+ element.removeEventListener(eventName, listener);
78
+ }
79
+ this._boundEventListeners = [];
80
+ }
22
81
  getAttribute(name, attribute = this._attribute) {
23
82
  const target = attribute;
24
83
  if (!target) {
@@ -47,35 +106,6 @@ export class ComponentBase {
47
106
  }
48
107
  return null;
49
108
  }
50
- // get attribute(): T | undefined {
51
- // const handler = {
52
- // get(target: any, prop: string) {
53
- // let p = prop;
54
- // if (p in target) {
55
- // return target[p];
56
- // }
57
- // p = ConvertUtils.snakeToCamelCase(prop);
58
- // if (p in target) {
59
- // return target[p];
60
- // }
61
- // p = ConvertUtils.camelToSnakeCase(prop);
62
- // if (p in target) {
63
- // return target[p];
64
- // }
65
- // p = prop.toUpperCase()
66
- // if (p in target) {
67
- // return target[p];
68
- // }
69
- // p = prop.toLowerCase()
70
- // if (p in target) {
71
- // return target[p];
72
- // }
73
- // return null;
74
- // }
75
- // };
76
- // const obj = new Proxy(this._attribute, handler);
77
- // return obj;
78
- // }
79
109
  hasAttribute(name) {
80
110
  return this.getAttribute(name) !== null;
81
111
  }
@@ -86,15 +116,6 @@ export class ComponentBase {
86
116
  n.toUpperCase() === name.toUpperCase() ||
87
117
  n.toLowerCase() === name.toLowerCase();
88
118
  }
89
- // attribute(name: keyof T, {attribute = this._attribute}: {equals?: (data: T[keyof T]) => void, notEquals?: () => void,attribute?: T} = {}) {
90
- // const data = this.getAttribute(name, attribute)
91
- // return n === name ||
92
- // ConvertUtils.snakeToCamelCase(n) === name ||
93
- // ConvertUtils.camelToSnakeCase(n) === name ||
94
- // n.toUpperCase() === (name as string).toUpperCase() ||
95
- // n.toLowerCase() === (name as string).toLowerCase()
96
- // ;
97
- // }
98
119
  get uuid() {
99
120
  var _a;
100
121
  return (_a = this._rawSet) === null || _a === void 0 ? void 0 : _a.uuid;
@@ -113,82 +134,115 @@ export class ComponentBase {
113
134
  var _a;
114
135
  return (_a = this.render) === null || _a === void 0 ? void 0 : _a.parentThis;
115
136
  }
116
- // 구현 시그니처 (오버로드 시그니처보다 더 일반적이어야 함)
117
137
  getChildren(typeOrTypes) {
118
138
  const targets = Array.isArray(typeOrTypes) ? typeOrTypes : [typeOrTypes];
119
- // filter의 결과는 항상 배열이므로 `?? []`는 필요 없습니다.
120
- // filter가 아무것도 찾지 못하면 빈 배열을 반환합니다.
121
139
  return this._children.filter(child => targets.some(targetConstructor => child instanceof targetConstructor));
122
140
  }
123
- // getChildren<T extends ConstructorType<any>[] | ConstructorType<any>>(
124
- // type: T
125
- // ): T extends (infer U)[] ? InstanceType<U>[] : T extends ConstructorType<infer V> ? V[] : never {
126
- // const target = Array.isArray(type) ? type : [type];
127
- // return this._children.filter(it => target.some(t => it instanceof t)) ?? [];
128
- // }
129
- // getChildren<T>(type: ConstructorType<T> | ConstructorType<T>[]): T[] {
130
- // const target = Array.isArray(type) ? type : [type];
131
- // return this._children.filter(it => target.some(t => it instanceof t)) ?? [];
132
- // }
133
- /*
134
- getChildren<T>(type: ConstructorType<T>): T[] {
135
- return this._children.filter(it => it instanceof type) ?? [];
136
- }
137
- */
138
141
  constructor(config) {
139
142
  this.config = config;
140
143
  this._children = [];
144
+ this._boundEventListeners = [];
145
+ }
146
+ setRawSet(rawSet) {
147
+ var _a, _b;
148
+ this._rawSet = rawSet;
149
+ if (this._rawSet) {
150
+ this.setAttribute((_b = (_a = this._rawSet.dataSet) === null || _a === void 0 ? void 0 : _a.render) === null || _b === void 0 ? void 0 : _b.attribute);
151
+ }
141
152
  }
142
153
  setAttribute(attribute) {
143
154
  this._attribute = attribute;
144
- // this.attributeData = this._attribute;
145
155
  }
146
156
  onCreatedThisChild(child, data) {
147
157
  this._children.push(child);
148
- // this._rawSet = data.render?.rawSet;
149
- // this._attribute = data.render?.attribute as T;
150
158
  }
151
159
  onCreateRenderData(data) {
152
- var _a, _b, _c, _d, _e, _f, _g;
153
- this._rawSet = (_a = data.render) === null || _a === void 0 ? void 0 : _a.rawSet;
154
- this.setAttribute((_b = data.render) === null || _b === void 0 ? void 0 : _b.attribute);
160
+ var _a, _b, _c, _d, _e, _f;
155
161
  this._render = data.render;
156
- if ((_c = this.config) === null || _c === void 0 ? void 0 : _c.onlyParentType) {
157
- const isOk = Array.isArray((_d = this.config) === null || _d === void 0 ? void 0 : _d.onlyParentType) ? (_e = this.config) === null || _e === void 0 ? void 0 : _e.onlyParentType : [(_f = this.config) === null || _f === void 0 ? void 0 : _f.onlyParentType].some(it => { var _a; return ((_a = data.render) === null || _a === void 0 ? void 0 : _a.parentThis) instanceof it; });
162
+ if ((_a = data.render) === null || _a === void 0 ? void 0 : _a.rawSet) {
163
+ this.setRawSet(data.render.rawSet);
164
+ }
165
+ if ((_b = this.config) === null || _b === void 0 ? void 0 : _b.onlyParentType) {
166
+ const isOk = Array.isArray((_c = this.config) === null || _c === void 0 ? void 0 : _c.onlyParentType) ? (_d = this.config) === null || _d === void 0 ? void 0 : _d.onlyParentType : [(_e = this.config) === null || _e === void 0 ? void 0 : _e.onlyParentType].some(it => { var _a; return ((_a = data.render) === null || _a === void 0 ? void 0 : _a.parentThis) instanceof it; });
158
167
  if (!isOk) {
159
- throw new Error('only my parentThis ' + ((_g = this.config) === null || _g === void 0 ? void 0 : _g.onlyParentType));
168
+ throw new Error('only my parentThis ' + ((_f = this.config) === null || _f === void 0 ? void 0 : _f.onlyParentType));
160
169
  }
161
170
  }
162
171
  }
163
172
  onChangeAttrRender(name, value, other) {
164
- var _a, _b;
165
173
  if (other.rawSet) {
166
- this._rawSet = other.rawSet;
167
- if (this._rawSet) {
168
- this.setAttribute((_b = (_a = this._rawSet.dataSet) === null || _a === void 0 ? void 0 : _a.render) === null || _b === void 0 ? void 0 : _b.attribute);
174
+ this.setRawSet(other.rawSet);
175
+ }
176
+ const attributes = ReflectUtils.getMetadata(ATTRIBUTE_METADATA_KEY, this.constructor);
177
+ if (attributes && Array.isArray(attributes)) {
178
+ for (const attrInfo of attributes) {
179
+ if (this.equalsAttributeName(name, attrInfo.name)) {
180
+ const finalValue = attrInfo.converter ? attrInfo.converter(value) : value;
181
+ this[attrInfo.propertyKey] = finalValue;
182
+ }
169
183
  }
170
184
  }
171
- // this.changeAttribute?.(this._attribute);
172
185
  }
173
186
  onInitRender(param, rawSet) {
174
- var _a, _b;
175
187
  if (rawSet) {
176
- this._rawSet = rawSet;
177
- if (this._rawSet) {
178
- this.setAttribute((_b = (_a = rawSet.dataSet) === null || _a === void 0 ? void 0 : _a.render) === null || _b === void 0 ? void 0 : _b.attribute);
179
- }
188
+ this.setRawSet(rawSet);
180
189
  const e = this.getElement();
181
190
  if (e) {
182
191
  e.component = this;
183
192
  }
193
+ // Handle @query decorators
194
+ const queries = ReflectUtils.getMetadata(QUERY_METADATA_KEY, this.constructor);
195
+ if (queries && Array.isArray(queries)) {
196
+ for (const queryInfo of queries) {
197
+ const { selector, propertyKey, isMethod } = queryInfo;
198
+ const elements = this._queryElements(selector);
199
+ if (isMethod) {
200
+ const method = this[propertyKey];
201
+ if (typeof method === 'function') {
202
+ const paramTypes = ReflectUtils.getParameterTypes(this, propertyKey);
203
+ if (paramTypes && paramTypes.length > 0 && paramTypes[0] === Array) {
204
+ method.call(this, elements);
205
+ }
206
+ else {
207
+ if (elements.length > 0) {
208
+ method.call(this, elements[0]);
209
+ }
210
+ }
211
+ }
212
+ }
213
+ else {
214
+ const propertyType = ReflectUtils.getType(this, propertyKey);
215
+ if (propertyType === Array) {
216
+ this[propertyKey] = elements;
217
+ }
218
+ else {
219
+ this[propertyKey] = elements[0] || null;
220
+ }
221
+ }
222
+ }
223
+ }
224
+ // Handle @event decorators
225
+ const events = ReflectUtils.getMetadata(EVENT_METADATA_KEY, this.constructor);
226
+ if (events && Array.isArray(events)) {
227
+ for (const eventInfo of events) {
228
+ const elements = this._queryElements(eventInfo.query);
229
+ elements.forEach(element => {
230
+ const listener = this[eventInfo.methodName].bind(this);
231
+ element.addEventListener(eventInfo.eventName, listener);
232
+ this._boundEventListeners.push({ element, eventName: eventInfo.eventName, listener });
233
+ });
234
+ }
235
+ }
184
236
  }
185
237
  }
186
238
  onDrThisBind() {
239
+ // Logic moved to onInitRender for robustness
187
240
  }
188
241
  onDrThisUnBind() {
242
+ this._cleanupEventListeners();
189
243
  }
190
244
  onDestroyRender(data) {
191
- // console.log('ComponentBase---onDestroyRender----')
245
+ this._cleanupEventListeners();
192
246
  }
193
247
  }
194
248
  __decorate([
@@ -207,4 +261,8 @@ __decorate([
207
261
  DomRenderNoProxy,
208
262
  __metadata("design:type", Object)
209
263
  ], ComponentBase.prototype, "_attribute", void 0);
264
+ __decorate([
265
+ DomRenderNoProxy,
266
+ __metadata("design:type", Array)
267
+ ], ComponentBase.prototype, "_boundEventListeners", void 0);
210
268
  //# sourceMappingURL=ComponentBase.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dooboostore/dom-render",
3
- "version": "1.0.99",
3
+ "version": "1.0.102",
4
4
  "license": "MIT",
5
5
  "description": "html view template engine",
6
6
  "keywords": [
@@ -44,7 +44,7 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "reflect-metadata": "^0.2.2",
47
- "@dooboostore/core": "1.0.7",
47
+ "@dooboostore/core": "1.0.8",
48
48
  "@dooboostore/core-web": "1.0.1",
49
49
  "@dooboostore/core-node": "1.0.1"
50
50
  },
@@ -66,7 +66,7 @@
66
66
  "ts-node-dev": "^2.0.0",
67
67
  "tslib": "^2.8.1",
68
68
  "@types/node": "^20",
69
- "typescript": "^5.8.2",
69
+ "typescript": "^5.9.2",
70
70
  "webpack": "^5.98.0",
71
71
  "webpack-cli": "^5.1.4",
72
72
  "webpack-dev-server": "^5.2.0"
package/rawsets/RawSet.js CHANGED
@@ -32,8 +32,7 @@ import { DestroyOptionType } from './DestroyOptionType';
32
32
  import { RawSetType } from './RawSetType';
33
33
  import { DrThisProperty } from '../operators/DrThisProperty';
34
34
  import { RawSetOperatorType } from './RawSetOperatorType';
35
- import cssParse from '../css/parse';
36
- import cssStringify from '../css/stringify';
35
+ import { CssParser, isStyleRule, isAtRule } from '@dooboostore/core/parser/css/CssParser';
37
36
  import { isOnCreateRenderData } from '../lifecycle/OnCreateRenderData';
38
37
  import { isOnCreateRender } from '../lifecycle/OnCreateRender';
39
38
  import { isOnChangeAttrRender } from '../lifecycle/OnChangeAttrRender';
@@ -390,7 +389,6 @@ export class RawSet {
390
389
  }
391
390
  }
392
391
  static generateStyleTransform(styleBody, componentKey, styleTagWrap = true) {
393
- var _a;
394
392
  // console.log('style!!!!!!!!!!!!!!!!1', styleBody, componentKey, styleTagWrap);
395
393
  if (Array.isArray(styleBody)) {
396
394
  styleBody = styleBody.join('\n');
@@ -400,37 +398,43 @@ export class RawSet {
400
398
  const end = `#${componentKey}-end`;
401
399
  // 이거뭐하는지 까먹었네 뭐였지??..
402
400
  // 동적으로 처리하는것같은데.. css 에서는 동적으로 처리하는걸 지향 해야될것같은데 이기능 deprecated 할지 고민중
403
- const before = StringUtils.regexExecArrayReplace(styleBody, /(\$\{.*?\}\$)/g, (data) => {
404
- // console.log('동적?', `var(--domrender-${data[0]})`)
405
- return `var(--domrender-${data[0]})`;
406
- });
401
+ // const before = StringUtils.regexExecArrayReplace(styleBody, /(\$\{.*?\}\$)/g, (data) => {
402
+ // // console.log('동적?', `var(--domrender-${data[0]})`)
403
+ // return `var(--domrender-${data[0]})`;
404
+ // });
407
405
  // const before = styleBody;
408
406
  // console.log('before@@@@@@@@@@@', before)
409
- const cssobject = cssParse(before);
410
- (_a = cssobject.stylesheet) === null || _a === void 0 ? void 0 : _a.rules.forEach((rule) => {
411
- var _a, _b, _c;
412
- // console.log('--------cssParse', rule)
413
- const isRoot = (_a = rule.selectors) === null || _a === void 0 ? void 0 : _a.find(it => it.startsWith(':root'));
414
- if (rule.type === 'rule' && !isRoot) { // && !!isRoot
415
- rule.selectors = (_b = rule.selectors) === null || _b === void 0 ? void 0 : _b.map(sit => {
416
- return this.generateRuleSelector(start, end, sit);
417
- });
407
+ const cssParser = new CssParser(styleBody);
408
+ const processRule = (rule) => {
409
+ if (isStyleRule(rule)) {
410
+ const isRoot = rule.selector.includes(':root');
411
+ if (!isRoot) {
412
+ // Handle comma-separated selectors
413
+ const selectors = rule.selector.split(',').map(s => s.trim());
414
+ const transformedSelectors = selectors.map(selector => this.generateRuleSelector(start, end, selector));
415
+ rule.selector = transformedSelectors.join(', ');
416
+ }
418
417
  }
419
- else if (rule.type === 'media' && !isRoot) {
420
- (_c = rule.rules) === null || _c === void 0 ? void 0 : _c.forEach((mediaRule) => {
421
- var _a;
422
- mediaRule.selectors = (_a = mediaRule.selectors) === null || _a === void 0 ? void 0 : _a.map(sit => {
423
- return this.generateRuleSelector(start, end, sit);
424
- });
425
- // console.log('--------', mediaRule, mediaRule.selectors)
426
- });
418
+ else if (isAtRule(rule)) {
419
+ if (rule.name === 'media') {
420
+ const hasRoot = rule.children.some(childRule => isStyleRule(childRule) && childRule.selector.includes(':root'));
421
+ if (!hasRoot) {
422
+ rule.children.forEach(childRule => {
423
+ if (isStyleRule(childRule)) {
424
+ const selectors = childRule.selector.split(',').map(s => s.trim());
425
+ const transformedSelectors = selectors.map(selector => this.generateRuleSelector(start, end, selector));
426
+ childRule.selector = transformedSelectors.join(', ');
427
+ }
428
+ });
429
+ }
430
+ }
427
431
  }
428
- });
429
- const stringify = cssStringify(cssobject);
432
+ };
433
+ cssParser.rules.forEach(processRule);
434
+ let after = cssParser.stringify();
430
435
  // let after = StringUtils.regexExecArrayReplace(stringify as string, /(var\(--domrender-(\$\{.*?\}\$)?\))/g, (data) => {
431
436
  // return data[2];
432
437
  // });
433
- let after = stringify;
434
438
  // console.log('after@@@@@@@@@@@', after)
435
439
  // 여기서 선언 selector 자체에도 처리가능하도록 한다 20250518
436
440
  after = after.replaceAll('/*$', '${');
@@ -1,49 +0,0 @@
1
- export interface Position {
2
- start: {
3
- line: number;
4
- column: number;
5
- };
6
- end: {
7
- line: number;
8
- column: number;
9
- };
10
- source?: string;
11
- content: string;
12
- }
13
- export interface ParseOptions {
14
- source?: string;
15
- silent?: boolean;
16
- }
17
- export interface StyleSheet {
18
- type: 'stylesheet';
19
- stylesheet: {
20
- source?: string;
21
- rules: Rule[];
22
- parsingErrors: Error[];
23
- };
24
- }
25
- export interface Rule {
26
- type: string;
27
- selectors?: string[];
28
- declarations?: Declaration[];
29
- values?: string[];
30
- name?: string;
31
- vendor?: string;
32
- keyframes?: Rule[];
33
- media?: string;
34
- rules?: Rule[];
35
- supports?: string;
36
- document?: string;
37
- comment?: string;
38
- position?: Position;
39
- [key: string]: any;
40
- }
41
- interface Declaration {
42
- type: 'declaration';
43
- property: string;
44
- value: string;
45
- position?: Position;
46
- }
47
- export default function parse(css: string, options?: ParseOptions): StyleSheet;
48
- export {};
49
- //# sourceMappingURL=index.d.ts.map