@esportsplus/template 0.19.5 → 0.19.7

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.
@@ -1,19 +1,17 @@
1
1
  import { effect } from '@esportsplus/reactivity';
2
- import { isArray, isObject, isString } from '@esportsplus/utilities';
2
+ import { isArray, isObject } from '@esportsplus/utilities';
3
3
  import { STATE_HYDRATING, STATE_NONE, STATE_WAITING } from './constants.js';
4
4
  import { className, removeAttribute, setAttribute } from './utilities/element.js';
5
5
  import { raf } from './utilities/queue.js';
6
6
  import q from '@esportsplus/queue';
7
7
  import event from './event.js';
8
- const EFFECT = Symbol();
9
8
  const STORE = Symbol();
10
- const UPDATES = Symbol();
11
9
  let delimiters = {
12
10
  class: ' ',
13
11
  style: ';'
14
12
  }, queue = q(64), scheduled = false;
15
- function attribute(element, name, value) {
16
- if (value === '' || value === false || value == null) {
13
+ function apply(element, name, value) {
14
+ if (value == null || value === false || value === '') {
17
15
  removeAttribute.call(element, name);
18
16
  }
19
17
  else if (name === 'class') {
@@ -26,61 +24,135 @@ function attribute(element, name, value) {
26
24
  element[name] = value;
27
25
  }
28
26
  }
29
- function schedule() {
27
+ function context(element) {
28
+ return (element[STORE] ??= { element });
29
+ }
30
+ function list(ctx, element, id, name, value, state) {
31
+ if (value == null || value === false || value === '') {
32
+ value = '';
33
+ }
34
+ let base = name + '.static', delimiter = delimiters[name], store = (ctx ??= context(element)).store ??= {}, dynamic = store[name], type = typeof value;
35
+ if (dynamic === undefined) {
36
+ let value = (element.getAttribute(name) || '').trim();
37
+ store[base] = value;
38
+ store[name] = dynamic = {};
39
+ }
40
+ if (id === null) {
41
+ if (value && type === 'string') {
42
+ store[base] += (store[base] ? delimiter : '') + value;
43
+ }
44
+ }
45
+ else {
46
+ let hot = {};
47
+ if (value && type === 'string') {
48
+ let part, parts = value.split(delimiter);
49
+ for (let i = 0, n = parts.length; i < n; i++) {
50
+ part = parts[i].trim();
51
+ if (part === '') {
52
+ continue;
53
+ }
54
+ dynamic[part] = null;
55
+ hot[part] = null;
56
+ }
57
+ }
58
+ let cold = store[id];
59
+ if (cold !== undefined) {
60
+ for (let part in cold) {
61
+ if (part in hot) {
62
+ continue;
63
+ }
64
+ delete dynamic[part];
65
+ }
66
+ }
67
+ store[id] = hot;
68
+ }
69
+ value = store[base];
70
+ for (let key in dynamic) {
71
+ value += (value ? delimiter : '') + key;
72
+ }
73
+ schedule(ctx, element, name, state, value);
74
+ }
75
+ function property(ctx, element, id, name, value, state) {
76
+ if (value == null || value === false || value === '') {
77
+ value = '';
78
+ }
79
+ if (id !== null) {
80
+ ctx ??= context(element);
81
+ if (ctx[name] === value) {
82
+ return;
83
+ }
84
+ ctx[name] = value;
85
+ }
86
+ schedule(ctx, element, name, state, value);
87
+ }
88
+ function schedule(ctx, element, name, state, value) {
89
+ if (state === STATE_HYDRATING) {
90
+ apply(element, name, value);
91
+ return;
92
+ }
93
+ ctx ??= context(element);
94
+ (ctx.updates ??= {})[name] = value;
95
+ if (state === STATE_NONE && !ctx.updating) {
96
+ ctx.updating = true;
97
+ queue.add(ctx);
98
+ }
30
99
  if (scheduled) {
31
100
  return;
32
101
  }
33
102
  scheduled = true;
34
103
  raf.add(task);
35
104
  }
36
- function set(context, name, value, state) {
37
- if (value === false || value == null) {
38
- value = '';
39
- }
40
- let type = typeof value;
105
+ function set(element, name, value, state) {
106
+ let fn = name === 'class' || name === 'style' ? list : property, type = typeof value;
41
107
  if (type === 'function') {
42
108
  if (name.startsWith('on')) {
43
- event(context.element, name, value);
109
+ event(element, name, value);
110
+ return;
44
111
  }
45
- else {
46
- context.store[EFFECT] ??= 0;
47
- let id = context.store[EFFECT]++;
48
- effect(() => {
49
- let v = value(context.element);
50
- if (isArray(v)) {
51
- let last = v.length - 1;
52
- for (let i = 0, n = v.length; i < n; i++) {
53
- update(context, id, name, v[i], state === STATE_HYDRATING
54
- ? state
55
- : i !== last ? STATE_WAITING : state);
56
- }
57
- }
58
- else {
59
- update(context, id, name, v, state);
112
+ let ctx = context(element);
113
+ ctx.effect ??= 0;
114
+ let id = ctx.effect++;
115
+ effect(() => {
116
+ let v = value(element);
117
+ if (v == null || typeof v !== 'object') {
118
+ fn(ctx, element, id, name, v, state);
119
+ }
120
+ else if (isArray(v)) {
121
+ let last = v.length - 1;
122
+ for (let i = 0, n = v.length; i < n; i++) {
123
+ fn(ctx, element, id, name, v[i], state === STATE_HYDRATING
124
+ ? state
125
+ : i !== last ? STATE_WAITING : state);
60
126
  }
61
- });
62
- state = STATE_NONE;
63
- }
127
+ }
128
+ });
129
+ state = STATE_NONE;
130
+ return;
131
+ }
132
+ if (type !== 'object') {
133
+ fn(null, element, null, name, value, state);
134
+ return;
64
135
  }
65
- else if (type === 'object') {
66
- if (isArray(value)) {
67
- for (let i = 0, n = value.length; i < n; i++) {
68
- set(context, name, value[i], state);
136
+ if (isArray(value)) {
137
+ for (let i = 0, n = value.length; i < n; i++) {
138
+ let v = value[i];
139
+ if (v == null || v === false || v === '') {
140
+ continue;
69
141
  }
142
+ set(element, name, v, state);
70
143
  }
144
+ return;
71
145
  }
72
- else {
73
- update(context, null, name, value, state);
74
- }
146
+ fn(null, element, null, name, value, state);
75
147
  }
76
148
  function task() {
77
149
  let context, n = queue.length;
78
150
  while ((context = queue.next()) && n--) {
79
151
  let { element, updates } = context;
80
152
  for (let name in updates) {
81
- attribute(element, name, updates[name]);
82
- delete updates[name];
153
+ apply(element, name, updates[name]);
83
154
  }
155
+ context.updates = {};
84
156
  context.updating = false;
85
157
  }
86
158
  if (queue.length) {
@@ -90,90 +162,19 @@ function task() {
90
162
  scheduled = false;
91
163
  }
92
164
  }
93
- function update(context, id, name, value, state) {
94
- if (value === false || value == null) {
95
- value = '';
96
- }
97
- let store = context.store;
98
- if (name in delimiters) {
99
- let cache = name + '.static', delimiter = delimiters[name], dynamic = store[name];
100
- if (dynamic === undefined) {
101
- let value = (context.element.getAttribute(name) || '').trim();
102
- store[cache] = value;
103
- store[name] = dynamic = {};
104
- }
105
- if (id === null) {
106
- if (value && isString(value)) {
107
- store[cache] += (store[cache] ? delimiter : '') + value;
108
- }
109
- }
110
- else {
111
- let hot = {};
112
- if (isString(value)) {
113
- let part, parts = value.split(delimiter);
114
- for (let i = 0, n = parts.length; i < n; i++) {
115
- part = parts[i].trim();
116
- if (part === '') {
117
- continue;
118
- }
119
- dynamic[part] = null;
120
- hot[part] = null;
121
- }
122
- }
123
- let cold = store[id];
124
- if (cold !== undefined) {
125
- for (let part in cold) {
126
- if (part in hot) {
127
- continue;
128
- }
129
- delete dynamic[part];
130
- }
131
- }
132
- store[id] = hot;
133
- }
134
- value = store[cache];
135
- for (let key in dynamic) {
136
- value += (value ? delimiter : '') + key;
137
- }
138
- }
139
- else if (id !== null) {
140
- if (store[name] === value) {
141
- return;
142
- }
143
- store[name] = value;
144
- }
145
- if (state === STATE_HYDRATING) {
146
- attribute(context.element, name, value);
147
- }
148
- else {
149
- context.updates[name] = value;
150
- if (state === STATE_NONE && !context.updating) {
151
- context.updating = true;
152
- queue.add(context);
153
- }
154
- if (!scheduled) {
155
- schedule();
156
- }
157
- }
158
- }
159
165
  const spread = function (element, value) {
160
- let cache = (element[STORE] ??= { [UPDATES]: {} }), context = {
161
- element,
162
- store: cache,
163
- updates: cache[UPDATES],
164
- updating: false
165
- };
166
166
  if (isObject(value)) {
167
167
  for (let name in value) {
168
- set(context, name, value[name], STATE_HYDRATING);
168
+ let v = value[name];
169
+ if (v == null || v === false || v === '') {
170
+ continue;
171
+ }
172
+ set(element, name, v, STATE_HYDRATING);
169
173
  }
170
174
  }
171
175
  else if (isArray(value)) {
172
176
  for (let i = 0, n = value.length; i < n; i++) {
173
- let v = value[i];
174
- for (let name in v) {
175
- set(context, name, v[name], STATE_HYDRATING);
176
- }
177
+ spread(element, value[i]);
177
178
  }
178
179
  }
179
180
  };
package/build/render.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  import { Renderable } from './types.js';
2
- declare const _default: (parent: HTMLElement, renderable: Renderable) => void;
2
+ declare const _default: <T>(parent: HTMLElement, renderable: Renderable<T>) => void;
3
3
  export default _default;
package/build/svg.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import html from './html/index.js';
2
2
  declare const svg: typeof html & {
3
- sprite: (symbol: string) => ReturnType<typeof html>;
3
+ sprite: (href: string) => ReturnType<typeof html>;
4
4
  };
5
5
  export default svg;
package/build/svg.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import html from './html/index.js';
2
2
  const svg = html.bind(null);
3
- svg.sprite = (symbol) => {
4
- if (symbol[0] !== '#') {
5
- symbol = '#' + symbol;
3
+ svg.sprite = (href) => {
4
+ if (href[0] !== '#') {
5
+ href = '#' + href;
6
6
  }
7
- return html `<svg><use xlink:href='${symbol}' /></svg>`;
7
+ return html `<svg><use ${{ ['href']: href }} /></svg>`;
8
8
  };
9
9
  export default svg;
package/package.json CHANGED
@@ -14,7 +14,7 @@
14
14
  "private": false,
15
15
  "type": "module",
16
16
  "types": "./build/index.d.ts",
17
- "version": "0.19.5",
17
+ "version": "0.19.7",
18
18
  "scripts": {
19
19
  "build": "tsc && tsc-alias",
20
20
  "-": "-"
package/src/attributes.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { effect } from '@esportsplus/reactivity';
2
- import { isArray, isObject, isString } from '@esportsplus/utilities';
2
+ import { isArray, isObject } from '@esportsplus/utilities';
3
3
  import { STATE_HYDRATING, STATE_NONE, STATE_WAITING } from './constants';
4
4
  import { Attributes, Element } from './types';
5
5
  import { className, removeAttribute, setAttribute } from './utilities/element';
@@ -8,22 +8,16 @@ import q from '@esportsplus/queue';
8
8
  import event from './event';
9
9
 
10
10
 
11
- // TODO: Refactor
12
-
13
-
14
- const EFFECT = Symbol();
15
-
16
11
  const STORE = Symbol();
17
12
 
18
- const UPDATES = Symbol();
19
-
20
13
 
21
14
  type Context = {
15
+ effect?: 0,
22
16
  element: Element;
23
- store: Record<PropertyKey, unknown>
24
- updates: Record<PropertyKey, unknown>;
25
- updating: boolean;
26
- };
17
+ store?: Record<string, unknown>;
18
+ updates?: Record<PropertyKey, unknown>;
19
+ updating?: boolean;
20
+ } & Record<PropertyKey, unknown>;
27
21
 
28
22
  type State = typeof STATE_HYDRATING | typeof STATE_NONE | typeof STATE_WAITING;
29
23
 
@@ -36,8 +30,8 @@ let delimiters: Record<string, string> = {
36
30
  scheduled = false;
37
31
 
38
32
 
39
- function attribute(element: Element, name: string, value: unknown) {
40
- if (value === '' || value === false || value == null) {
33
+ function apply(element: Element, name: string, value: unknown) {
34
+ if (value == null || value === false || value === '') {
41
35
  removeAttribute.call(element, name);
42
36
  }
43
37
  else if (name === 'class') {
@@ -51,209 +45,235 @@ function attribute(element: Element, name: string, value: unknown) {
51
45
  }
52
46
  }
53
47
 
54
- function schedule() {
55
- if (scheduled) {
56
- return;
57
- }
58
-
59
- scheduled = true;
60
- raf.add(task);
48
+ function context(element: Element) {
49
+ return (element[STORE] ??= { element }) as Context;
61
50
  }
62
51
 
63
- function set(context: Context, name: string, value: unknown, state: State) {
64
- if (value === false || value == null) {
52
+ function list(
53
+ ctx: Context | null,
54
+ element: Element,
55
+ id: null | number,
56
+ name: string,
57
+ value: unknown,
58
+ state: State
59
+ ) {
60
+ if (value == null || value === false || value === '') {
65
61
  value = '';
66
62
  }
67
63
 
68
- let type = typeof value;
64
+ let base = name + '.static',
65
+ delimiter = delimiters[name],
66
+ store = (ctx ??= context(element)).store ??= {},
67
+ dynamic = store[name] as Attributes | undefined,
68
+ type = typeof value;
69
69
 
70
- if (type === 'function') {
71
- if (name.startsWith('on')) {
72
- event(context.element, name as `on${string}`, value as Function);
73
- }
74
- else {
75
- context.store[EFFECT] ??= 0;
76
-
77
- let id = (context.store[EFFECT] as number)++;
78
-
79
- effect(() => {
80
- let v = (value as Function)(context.element);
81
-
82
- if (isArray(v)) {
83
- let last = v.length - 1;
84
-
85
- for (let i = 0, n = v.length; i < n; i++) {
86
- update(
87
- context,
88
- id,
89
- name,
90
- v[i],
91
- state === STATE_HYDRATING
92
- ? state
93
- : i !== last ? STATE_WAITING : state
94
- );
95
- }
96
- }
97
- else {
98
- update(context, id, name, v, state);
99
- }
100
- });
70
+ if (dynamic === undefined) {
71
+ let value = (element.getAttribute(name) || '').trim();
101
72
 
102
- state = STATE_NONE;
103
- }
73
+ store[base] = value;
74
+ store[name] = dynamic = {};
104
75
  }
105
- else if (type === 'object') {
106
- if (isArray(value)) {
107
- for (let i = 0, n = value.length; i < n; i++) {
108
- set(context, name, value[i], state);
109
- }
76
+
77
+ if (id === null) {
78
+ if (value && type === 'string') {
79
+ store[base] += (store[base] ? delimiter : '') + value;
110
80
  }
111
81
  }
112
82
  else {
113
- update(context, null, name, value, state);
114
- }
115
- }
83
+ let hot: Attributes = {};
116
84
 
117
- function task() {
118
- let context,
119
- n = queue.length;
85
+ if (value && type === 'string') {
86
+ let part: string,
87
+ parts = (value as string).split(delimiter);
120
88
 
121
- while ((context = queue.next()) && n--) {
122
- let { element, updates } = context;
89
+ for (let i = 0, n = parts.length; i < n; i++) {
90
+ part = parts[i].trim();
123
91
 
124
- for (let name in updates) {
125
- attribute(element, name, updates[name]);
126
- delete updates[name];
92
+ if (part === '') {
93
+ continue;
94
+ }
95
+
96
+ dynamic[part] = null;
97
+ hot[part] = null;
98
+ }
127
99
  }
128
100
 
129
- context.updating = false;
130
- }
101
+ let cold = store[id] as Attributes | undefined;
131
102
 
132
- if (queue.length) {
133
- raf.add(task);
103
+ if (cold !== undefined) {
104
+ for (let part in cold) {
105
+ if (part in hot) {
106
+ continue;
107
+ }
108
+
109
+ delete dynamic[part];
110
+ }
111
+ }
112
+
113
+ store[id] = hot;
134
114
  }
135
- else {
136
- scheduled = false;
115
+
116
+ value = store[base];
117
+
118
+ for (let key in dynamic) {
119
+ value += (value ? delimiter : '') + key;
137
120
  }
121
+
122
+ schedule(ctx, element, name, state, value);
138
123
  }
139
124
 
140
- function update(
141
- context: Context,
125
+ function property(
126
+ ctx: Context | null,
127
+ element: Element,
142
128
  id: null | number,
143
129
  name: string,
144
130
  value: unknown,
145
131
  state: State
146
132
  ) {
147
- if (value === false || value == null) {
133
+ if (value == null || value === false || value === '') {
148
134
  value = '';
149
135
  }
150
136
 
151
- let store = context.store;
137
+ if (id !== null) {
138
+ ctx ??= context(element);
152
139
 
153
- if (name in delimiters) {
154
- let cache = name + '.static',
155
- delimiter = delimiters[name],
156
- dynamic = store[name] as Attributes | undefined;
140
+ if (ctx[name] === value) {
141
+ return;
142
+ }
157
143
 
158
- if (dynamic === undefined) {
159
- let value = (context.element.getAttribute(name) || '').trim();
144
+ ctx[name] = value as string;
145
+ }
160
146
 
161
- store[cache] = value;
162
- store[name] = dynamic = {};
163
- }
147
+ schedule(ctx, element, name, state, value);
148
+ }
164
149
 
165
- if (id === null) {
166
- if (value && isString(value)) {
167
- store[cache] += (store[cache] ? delimiter : '') + value;
168
- }
150
+ function schedule(ctx: Context | null, element: Element, name: string, state: State, value: unknown) {
151
+ if (state === STATE_HYDRATING) {
152
+ apply(element, name, value);
153
+ return;
154
+ }
155
+
156
+ ctx ??= context(element);
157
+ (ctx.updates ??= {})[name] = value;
158
+
159
+ if (state === STATE_NONE && !ctx.updating) {
160
+ ctx.updating = true;
161
+ queue.add(ctx);
162
+ }
163
+
164
+ if (scheduled) {
165
+ return;
166
+ }
167
+
168
+ scheduled = true;
169
+ raf.add(task);
170
+ }
171
+
172
+ function set(element: Element, name: string, value: unknown, state: State) {
173
+ let fn = name === 'class' || name === 'style' ? list : property,
174
+ type = typeof value;
175
+
176
+ if (type === 'function') {
177
+ if (name.startsWith('on')) {
178
+ event(element, name as `on${string}`, value as Function);
179
+ return;
169
180
  }
170
- else {
171
- let hot: Attributes = {};
172
181
 
173
- if (isString(value)) {
174
- let part: string,
175
- parts = value.split(delimiter);
182
+ let ctx = context(element);
183
+
184
+ ctx.effect ??= 0;
176
185
 
177
- for (let i = 0, n = parts.length; i < n; i++) {
178
- part = parts[i].trim();
186
+ let id = (ctx.effect as number)++;
179
187
 
180
- if (part === '') {
181
- continue;
182
- }
188
+ effect(() => {
189
+ let v = (value as Function)(element);
183
190
 
184
- dynamic[part] = null;
185
- hot[part] = null;
191
+ if (v == null || typeof v !== 'object') {
192
+ fn(ctx, element, id, name, v, state);
193
+ }
194
+ else if (isArray(v)) {
195
+ let last = v.length - 1;
196
+
197
+ for (let i = 0, n = v.length; i < n; i++) {
198
+ fn(
199
+ ctx,
200
+ element,
201
+ id,
202
+ name,
203
+ v[i],
204
+ state === STATE_HYDRATING
205
+ ? state
206
+ : i !== last ? STATE_WAITING : state
207
+ );
186
208
  }
187
209
  }
210
+ });
188
211
 
189
- let cold = store[id] as Attributes | undefined;
212
+ state = STATE_NONE;
190
213
 
191
- if (cold !== undefined) {
192
- for (let part in cold) {
193
- if (part in hot) {
194
- continue;
195
- }
214
+ return;
215
+ }
196
216
 
197
- delete dynamic[part];
198
- }
199
- }
217
+ if (type !== 'object') {
218
+ fn(null, element, null, name, value, state);
219
+ return;
220
+ }
200
221
 
201
- store[id] = hot;
202
- }
222
+ if (isArray(value)) {
223
+ for (let i = 0, n = value.length; i < n; i++) {
224
+ let v = value[i];
203
225
 
204
- value = store[cache];
226
+ if (v == null || v === false || v === '') {
227
+ continue;
228
+ }
205
229
 
206
- for (let key in dynamic) {
207
- value += (value ? delimiter : '') + key;
230
+ set(element, name, v, state);
208
231
  }
232
+ return;
209
233
  }
210
- else if (id !== null) {
211
- if (store[name] === value) {
212
- return;
234
+
235
+ fn(null, element, null, name, value, state);
236
+ }
237
+
238
+ function task() {
239
+ let context,
240
+ n = queue.length;
241
+
242
+ while ((context = queue.next()) && n--) {
243
+ let { element, updates } = context;
244
+
245
+ for (let name in updates) {
246
+ apply(element, name, updates[name]);
213
247
  }
214
248
 
215
- store[name] = value as string;
249
+ context.updates = {};
250
+ context.updating = false;
216
251
  }
217
252
 
218
- if (state === STATE_HYDRATING) {
219
- attribute(context.element, name, value);
253
+ if (queue.length) {
254
+ raf.add(task);
220
255
  }
221
256
  else {
222
- context.updates[name] = value;
223
-
224
- if (state === STATE_NONE && !context.updating) {
225
- context.updating = true;
226
- queue.add(context);
227
- }
228
-
229
- if (!scheduled) {
230
- schedule();
231
- }
257
+ scheduled = false;
232
258
  }
233
259
  }
234
260
 
235
261
 
236
262
  const spread = function (element: Element, value: Attributes | Attributes[]) {
237
- let cache = (element[STORE] ??= { [UPDATES]: {} }) as Record<PropertyKey, unknown>,
238
- context = {
239
- element,
240
- store: cache,
241
- updates: cache[UPDATES] as Record<PropertyKey, unknown>,
242
- updating: false
243
- };
244
-
245
263
  if (isObject(value)) {
246
264
  for (let name in value) {
247
- set(context, name, value[name], STATE_HYDRATING);
265
+ let v = value[name];
266
+
267
+ if (v == null || v === false || v === '') {
268
+ continue;
269
+ }
270
+
271
+ set(element, name, v, STATE_HYDRATING);
248
272
  }
249
273
  }
250
274
  else if (isArray(value)) {
251
275
  for (let i = 0, n = value.length; i < n; i++) {
252
- let v = value[i];
253
-
254
- for (let name in v) {
255
- set(context, name, v[name], STATE_HYDRATING);
256
- }
276
+ spread(element, value[i]);
257
277
  }
258
278
  }
259
279
  };
package/src/html/index.ts CHANGED
@@ -13,42 +13,11 @@ const html = <T>(literals: TemplateStringsArray, ...values: (Values<T> | Values<
13
13
  clone = cloneNode.call(fragment, true);
14
14
 
15
15
  if (slots !== null) {
16
- let node, nodePath; // , parent, parentPath;
16
+ let node, nodePath;
17
17
 
18
- // TODO: when a new slot is added it breaks pathfinding for the next slot
19
- // for (let i = 0, n = slots.length; i < n; i++) {
20
18
  for (let i = slots.length - 1; i >= 0; i--) {
21
19
  let { fn, path, slot } = slots[i];
22
20
 
23
- // pp = path.parent,
24
- // pr = path.relative;
25
-
26
- // if (pp !== parentPath) {
27
- // if (pp === nodePath) {
28
- // parent = node;
29
- // parentPath = nodePath;
30
-
31
- // nodePath = undefined;
32
- // }
33
- // else {
34
- // parent = clone;
35
- // parentPath = pp;
36
-
37
- // for (let i = 0, n = pp.length; i < n; i++) {
38
- // parent = pp[i].call(parent);
39
- // }
40
- // }
41
- // }
42
-
43
- // if (pr !== nodePath) {
44
- // node = parent;
45
- // nodePath = path.absolute;
46
-
47
- // for (let i = 0, n = pr.length; i < n; i++) {
48
- // node = pr[i].call(node);
49
- // }
50
- // }
51
-
52
21
  if (nodePath !== path) {
53
22
  node = clone;
54
23
 
@@ -52,12 +52,6 @@ function build(literals: TemplateStringsArray) {
52
52
 
53
53
  if (attr) {
54
54
  let i = attr.indexOf(SLOT_MARKER);
55
- // @see ./index.ts comments
56
- // p = {
57
- // absolute: path,
58
- // parent: parent.path,
59
- // relative: path.slice(parent.path.length)
60
- // };
61
55
 
62
56
  while (i !== -1) {
63
57
  slots.push({
@@ -82,18 +76,10 @@ function build(literals: TemplateStringsArray) {
82
76
  parent.elements++;
83
77
  }
84
78
  else if (type === NODE_SLOT) {
85
- // @see ./index.ts comments
86
- // let relative = methods(parent.children, [], firstChild, nextSibling);
87
-
88
79
  buffer += parsed[slot] + SLOT_HTML;
89
80
  slots.push({
90
81
  fn: s,
91
82
  path: methods(parent.children, parent.path, firstChild, nextSibling),
92
- // path: {
93
- // absolute: [...parent.path, ...relative],
94
- // parent: parent.path,
95
- // relative
96
- // },
97
83
  slot: slot++
98
84
  });
99
85
  }
package/src/render.ts CHANGED
@@ -9,7 +9,7 @@ let anchor,
9
9
  marker = firstChild.call( fragment(SLOT_HTML) );
10
10
 
11
11
 
12
- export default (parent: HTMLElement, renderable: Renderable) => {
12
+ export default <T>(parent: HTMLElement, renderable: Renderable<T>) => {
13
13
  nodeValue.call(parent, '');
14
14
  parent.append(anchor = marker.cloneNode());
15
15
 
package/src/svg.ts CHANGED
@@ -2,15 +2,15 @@ import html from './html';
2
2
 
3
3
 
4
4
  const svg = html.bind(null) as typeof html & {
5
- sprite: (symbol: string) => ReturnType<typeof html>
5
+ sprite: (href: string) => ReturnType<typeof html>
6
6
  };
7
7
 
8
- svg.sprite = (symbol: string) => {
9
- if (symbol[0] !== '#') {
10
- symbol = '#' + symbol;
8
+ svg.sprite = (href: string) => {
9
+ if (href[0] !== '#') {
10
+ href = '#' + href;
11
11
  }
12
12
 
13
- return html`<svg><use xlink:href='${symbol}' /></svg>`;
13
+ return html`<svg><use ${{ ['href']: href }} /></svg>`;
14
14
  };
15
15
 
16
16
 
package/src/types.ts CHANGED
@@ -52,13 +52,7 @@ type Template = {
52
52
  literals: TemplateStringsArray;
53
53
  slots: {
54
54
  fn: typeof attributes.spread | typeof slot;
55
- // @see ./html/index.ts comments
56
55
  path: typeof firstChild[];
57
- // path: {
58
- // absolute: typeof firstChild[],
59
- // parent: typeof firstChild[],
60
- // relative: typeof firstChild[]
61
- // };
62
56
  slot: number;
63
57
  }[] | null;
64
58
  };