vsn 0.1.93 → 0.1.96

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/dist/version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VERSION = void 0;
4
- exports.VERSION = '0.1.93';
4
+ exports.VERSION = '0.1.96';
5
5
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vsn",
3
- "version": "0.1.93",
3
+ "version": "0.1.96",
4
4
  "description": "SEO Friendly Javascript/Typescript Framework",
5
5
  "keywords": [
6
6
  "framework",
@@ -226,6 +226,11 @@ export class ClassNode extends Node implements TreeNode {
226
226
  tag = await dom.getTagForElement(element, true);
227
227
  }
228
228
 
229
+ if (!tag) {
230
+ console.error('no tag found for element', element);
231
+ return;
232
+ }
233
+
229
234
  const classNode: ClassNode = Registry.instance.classes.getSynchronous(selector);
230
235
  if (classNode) {
231
236
  await classNode.constructTag(tag, dom);
package/src/DOM.ts CHANGED
@@ -189,16 +189,8 @@ export class DOM extends EventDispatcher {
189
189
  }
190
190
  }
191
191
 
192
- async buildFrom(ele: any, isRoot: boolean = false, forComponent: boolean = false) {
193
- if (isRoot) {
194
- document.body.setAttribute('vsn-root', '');
195
- document.ondragover = (e) => e.cancelable && e.preventDefault(); // Allow dragging over document
196
- }
197
-
198
- // Create tags for each html element with a v-attribute
199
- const newTags: Tag[] = [];
200
- const toBuild: HTMLElement[] = [];
201
-
192
+ async discover(ele: HTMLElement, forComponent: boolean = false): Promise<HTMLElement[]> {
193
+ const discovered: HTMLElement[] = [];
202
194
  const checkElement = (e: HTMLElement): boolean => {
203
195
  if (ElementHelper.hasVisionAttribute(e)) {
204
196
  if (
@@ -206,7 +198,7 @@ export class DOM extends EventDispatcher {
206
198
  ) return false;
207
199
  if (this.queued.indexOf(e) > -1) return false;
208
200
  this.queued.push(e);
209
- toBuild.push(e);
201
+ discovered.push(e);
210
202
  }
211
203
 
212
204
  return true;
@@ -221,38 +213,39 @@ export class DOM extends EventDispatcher {
221
213
  checkElement(ele);
222
214
  scanChildren(ele);
223
215
 
224
- for (const element of toBuild) {
225
- if (element[Tag.TaggedVariable]) continue;
226
- const tag: Tag = new Tag(element, this);
227
- this.tags.push(tag);
228
- newTags.push(tag);
229
- }
216
+ return discovered;
217
+ }
230
218
 
231
- if (isRoot)
232
- this._root = await this.getTagForElement(document.body);
219
+ async buildTag(element: HTMLElement, returnExisting: boolean = false): Promise<Tag> {
220
+ if (element[Tag.TaggedVariable]) return returnExisting ? element[Tag.TaggedVariable] : null;
221
+ const tag: Tag = new Tag(element, this);
222
+ this.tags.push(tag);
223
+ return tag;
224
+ }
233
225
 
234
- // Configure, setup & execute attributes
235
- for (const tag of newTags)
226
+ async setupTags(tags: Tag[]) {
227
+ // Configure, setup & execute attributes
228
+ for (const tag of tags)
236
229
  await tag.buildAttributes();
237
230
 
238
- for (const tag of newTags)
231
+ for (const tag of tags)
239
232
  await tag.compileAttributes();
240
233
 
241
- for (const tag of newTags)
234
+ for (const tag of tags)
242
235
  await tag.setupAttributes();
243
236
 
244
- for (const tag of newTags)
237
+ for (const tag of tags)
245
238
  await tag.extractAttributes();
246
239
 
247
- for (const tag of newTags)
240
+ for (const tag of tags)
248
241
  await tag.connectAttributes();
249
242
 
250
- for (const tag of newTags) {
243
+ for (const tag of tags) {
251
244
  await tag.finalize();
252
245
  this.queued.splice(this.queued.indexOf(tag.element), 1);
253
246
  }
254
247
 
255
- for (const tag of newTags) {
248
+ for (const tag of tags) {
256
249
  this.observer.observe(tag.element, {
257
250
  attributes: true,
258
251
  characterData: true,
@@ -260,6 +253,28 @@ export class DOM extends EventDispatcher {
260
253
  subtree: true
261
254
  });
262
255
  }
256
+ }
257
+
258
+ async buildFrom(ele: any, isRoot: boolean = false, forComponent: boolean = false) {
259
+ if (isRoot) {
260
+ document.body.setAttribute('vsn-root', '');
261
+ document.ondragover = (e) => e.cancelable && e.preventDefault(); // Allow dragging over document
262
+ }
263
+
264
+ // Create tags for each html element with a vsn-attribute
265
+ const newTags: Tag[] = [];
266
+ const toBuild: HTMLElement[] = await this.discover(ele, forComponent);
267
+
268
+ for (const element of toBuild) {
269
+ const tag = await this.buildTag(element);
270
+ if (tag)
271
+ newTags.push(tag);
272
+ }
273
+
274
+ if (isRoot)
275
+ this._root = await this.getTagForElement(document.body);
276
+
277
+ await this.setupTags(newTags);
263
278
 
264
279
  if (isRoot) {
265
280
  this._built = true;
@@ -113,11 +113,11 @@ export class List extends Attribute {
113
113
  }
114
114
 
115
115
  public get listItemName(): string {
116
- return this.tag.getRawAttributeValue('vsn-list-item-name', 'item');
116
+ return this.tag.getRawAttributeValue('list-item-name', 'item');
117
117
  }
118
118
 
119
119
  public get listItemModel(): string {
120
- return this.tag.getRawAttributeValue('vsn-list-item-model');
120
+ return this.tag.getRawAttributeValue('list-item-model');
121
121
  }
122
122
 
123
123
  public remove(item: any) {
@@ -135,6 +135,7 @@ export class List extends Attribute {
135
135
  }
136
136
 
137
137
  protected async add(obj) {
138
+ // Setup new HTML element
138
139
  const clone = this.template.cloneNode(true);
139
140
  let element: HTMLElement;
140
141
  if (clone instanceof DocumentFragment) {
@@ -144,20 +145,36 @@ export class List extends Attribute {
144
145
  }
145
146
  delete element[Tag.TaggedVariable];
146
147
 
147
- this.tag.element.appendChild(element);
148
+ // Setup new tag
149
+ const tag = await this.tag.dom.buildTag(element, true);
150
+
151
+ await this.setupTag(tag, obj);
148
152
 
153
+ // Add to DOM & build
154
+ this.tag.element.appendChild(element);
149
155
  await this.tag.dom.buildFrom(this.tag.element);
150
- const tag: Tag = await this.tag.dom.getTagForElement(element);
151
156
  this.tags.push(tag);
157
+ this.tag.dispatch('add', obj);
158
+ }
152
159
 
153
- if (obj) {
154
- if (tag.scope.wrapped) {
155
- tag.scope.data.setData(obj);
156
- } else {
157
- tag.wrap(obj);
158
- }
160
+ async setupTag(tag: Tag, obj: any) {
161
+ tag.createScope(true);
162
+
163
+ // Setup new scope & class, if defined
164
+ const modelName: string = this.listItemModel;
165
+ let cls;
166
+ if (modelName)
167
+ cls = await Registry.instance.models.get(modelName);
168
+
169
+ if (cls) {
170
+ if (!obj || !(obj instanceof cls))
171
+ obj = new cls(obj);
159
172
  }
160
173
 
161
- this.tag.dispatch('add', obj);
174
+ // Check if the class is set up already
175
+ if (!cls || (!(tag.scope.data instanceof cls) && !(tag.scope.wrapped instanceof cls)))
176
+ tag.wrap(obj);
177
+
178
+ tag.scope.set(this.listItemName, tag.scope);
162
179
  }
163
180
  }
@@ -18,30 +18,13 @@ export class ListItem extends Attribute {
18
18
  this._list = this.tag.findAncestorByAttribute('vsn-list');
19
19
  if (!this._list)
20
20
  throw Error(ListItem.ERROR_NO_PARENT);
21
- const modelName: string = (await this.getList()).listItemModel;
22
- if (modelName) {
23
- const cls = await Registry.instance.models.get(modelName);
24
- if (
25
- !(this.tag.scope.data instanceof cls) &&
26
- !(this.tag.scope.wrapped instanceof cls)
27
- ) {
28
- this.instantiateModel(cls);
29
- }
30
21
 
31
- }
32
- this.tag.scope.set(this.listItemName, this.tag.scope);
22
+ const listAttr = await this.getListAttribute();
23
+ await listAttr.setupTag(this.tag, {});
33
24
  await super.setup();
34
25
  }
35
26
 
36
- public get listItemName(): string {
37
- return this.getAttributeBinding('item');
38
- }
39
-
40
- public async getList(): Promise<List> {
27
+ public async getListAttribute(): Promise<List> {
41
28
  return await this._list.getAttribute<List>('vsn-list');
42
29
  }
43
-
44
- private instantiateModel(model: any) {
45
- this.tag.wrap(model, false, true);
46
- }
47
30
  }
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
- export const VERSION = '0.1.93';
1
+ export const VERSION = '0.1.96';
2
2
 
@@ -41,7 +41,7 @@ describe('ListItem', () => {
41
41
 
42
42
  it("vsn-list-item should find it's parent list", (done) => {
43
43
  document.body.innerHTML = `
44
- <ul vsn-list:list vsn-list-item-model="ListItemSpecTestItem" id="test"><li vsn-list-item:item id="test-item"></li></ul>
44
+ <ul vsn-list:list list-item-model="ListItemSpecTestItem" id="test"><li vsn-list-item id="test-item"></li></ul>
45
45
  `;
46
46
 
47
47
  const dom = new DOM(document);
@@ -58,7 +58,7 @@ describe('ListItem', () => {
58
58
  it("should properly wrap list item class", (done) => {
59
59
  document.body.innerHTML = `
60
60
  <div vsn-controller:controller="ListItemController">
61
- <ul vsn-list:controller.items vsn-list-item-model="ListItemSpecTestItem" id="test">
61
+ <ul vsn-list:controller.items list-item-model="ListItemSpecTestItem" id="test">
62
62
  <li vsn-template vsn-list-item:item></li>
63
63
  </ul>
64
64
  </div>
@@ -89,15 +89,12 @@ describe('ListItem', () => {
89
89
 
90
90
  it("vsn-list-item should work with vsn-set", (done) => {
91
91
  document.body.innerHTML = `
92
- <ul vsn-list:list vsn-list-item-model="ListItemSpecTestItem" id="test"><li vsn-list-item:item id="test-item" vsn-set:item.testing|integer="1"></li></ul>
92
+ <ul vsn-list:list list-item-model="ListItemSpecTestItem" id="test"><li vsn-list-item id="test-item" vsn-set:item.testing|integer="1"></li></ul>
93
93
  `;
94
94
 
95
95
  const dom = new DOM(document);
96
96
  dom.once('built', async () => {
97
- const list = await dom.getTagForElement(document.getElementById('test'));
98
97
  const listItem = await dom.getTagForElement(document.getElementById('test-item'));
99
- const listItemAttr: ListItem = await listItem.getAttribute('vsn-list-item') as ListItem;
100
-
101
98
  expect(listItem.scope.get('testing')).toBe(1);
102
99
  done();
103
100
  });
@@ -105,14 +102,15 @@ describe('ListItem', () => {
105
102
 
106
103
  it("vsn-list-item should work with vsn-exec", (done) => {
107
104
  document.body.innerHTML = `
108
- <ul vsn-list:list vsn-list-item-model="ListItemSpecTestItem" id="test"><li vsn-list-item:item id="test-item" vsn-exec="item.test = 1"></li></ul>
105
+ <ul vsn-list:list list-item-model="ListItemSpecTestItem" id="test">
106
+ <li vsn-list-item id="test-item" vsn-exec="item.test = 1"></li>
107
+ </ul>
109
108
  `;
110
109
 
110
+ console.log('################# building dom');
111
111
  const dom = new DOM(document);
112
112
  dom.once('built', async () => {
113
- const list = await dom.getTagForElement(document.getElementById('test'));
114
113
  const listItem = await dom.getTagForElement(document.getElementById('test-item'));
115
- const listItemAttr: ListItem = await listItem.getAttribute('vsn-list-item') as ListItem;
116
114
  console.log('test keys', listItem.scope.keys);
117
115
  expect(listItem.scope.get('test')).toBe(1);
118
116
  done();