vsn 0.1.80 → 0.1.83

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vsn",
3
- "version": "0.1.80",
3
+ "version": "0.1.83",
4
4
  "description": "SEO Friendly Javascript/Typescript Framework",
5
5
  "keywords": [
6
6
  "framework",
@@ -18,6 +18,7 @@ export class ClassNode extends Node implements TreeNode {
18
18
  protected requiresPrep: boolean = true;
19
19
  public readonly classScope: Scope = new Scope();
20
20
  protected _fullSelector: string;
21
+ protected _parentSelector: string;
21
22
 
22
23
  constructor(
23
24
  public readonly selector: string,
@@ -45,6 +46,7 @@ export class ClassNode extends Node implements TreeNode {
45
46
  // Only prepare once during the initial prep, all subsequent prepares are on tag class blocks
46
47
  if (initial) {
47
48
  if (meta['ClassNodeSelector']) {
49
+ this._parentSelector = meta['ClassNodeSelector'] as string;
48
50
  ClassNode.classChildren[meta['ClassNodeSelector'] as string].push(this.selector);
49
51
  meta['ClassNodeSelector'] = `${meta['ClassNodeSelector']} ${this.selector}`;
50
52
  } else {
@@ -76,14 +78,17 @@ export class ClassNode extends Node implements TreeNode {
76
78
  }
77
79
  }
78
80
 
79
- public async findClassElements(dom) {
80
- for (const element of Array.from(dom.querySelectorAll(this._fullSelector))) {
81
- await ClassNode.addElementClass(this._fullSelector, element as HTMLElement, dom, element[Tag.TaggedVariable] || null);
81
+ public async findClassElements(dom: DOM, tag: Tag = null) {
82
+ const tags: Tag[] = [];
83
+ for (const element of Array.from(dom.querySelectorAll(this.selector, tag))) {
84
+ tags.push(await ClassNode.addElementClass(this._fullSelector, element as HTMLElement, dom, element[Tag.TaggedVariable] || null));
82
85
  }
83
86
  for (const childSelector of ClassNode.classChildren[this._fullSelector]) {
84
87
  const node = ClassNode.classes[`${this._fullSelector} ${childSelector}`];
85
88
  if (!node) continue;
86
- await node.findClassElements(dom);
89
+ for (const _tag of tags) {
90
+ await node.findClassElements(dom, _tag);
91
+ }
87
92
  }
88
93
  }
89
94
 
@@ -141,6 +146,16 @@ export class ClassNode extends Node implements TreeNode {
141
146
  return new ClassNode(selector, block);
142
147
  }
143
148
 
149
+ public getSelectorPath(): string[] {
150
+ const path: string[] = [this.selector];
151
+ let current = this._parentSelector;
152
+ while (current) {
153
+ path.push(ClassNode.classes[current].selector);
154
+ current = ClassNode.classes[current]._parentSelector;
155
+ }
156
+ return path.reverse();
157
+ }
158
+
144
159
  public static async checkForClassChanges(element: HTMLElement, dom: DOM, tag: Tag = null) {
145
160
  const localSelectors: string[] = [element.tagName.toLowerCase(), ...Array.from(element.classList).map(c => `.${c}`)];
146
161
  const fullSelectors: string[] = [...ClassNode.getClassesForElement(element)];
@@ -160,7 +175,8 @@ export class ClassNode extends Node implements TreeNode {
160
175
 
161
176
  for (const selector of fullSelectors) {
162
177
  const isPrepped = ClassNode.getClassesForElement(element).includes(selector);
163
- const elements = Array.from(dom.querySelectorAll(selector));
178
+ const path = ClassNode.classes[selector]?.getSelectorPath();
179
+ const elements = dom.querySelectPath(path);
164
180
  const inElements = elements.includes(element);
165
181
  let changed: boolean = false;
166
182
 
@@ -210,6 +226,8 @@ export class ClassNode extends Node implements TreeNode {
210
226
  if (classNode) {
211
227
  await classNode.constructTag(tag, dom);
212
228
  }
229
+
230
+ return tag;
213
231
  }
214
232
 
215
233
  public static async removeElementClass(selector: string, element: HTMLElement, dom: DOM, tag: Tag = null) {
package/src/Attribute.ts CHANGED
@@ -91,7 +91,7 @@ export abstract class Attribute extends EventDispatcher {
91
91
  }
92
92
  }
93
93
 
94
- private setState(state: AttributeState) {
94
+ protected setState(state: AttributeState) {
95
95
  const previousState = this._state;
96
96
  this._state = state;
97
97
  this.dispatch('state', {
package/src/DOM.ts CHANGED
@@ -102,6 +102,21 @@ export class DOM extends EventDispatcher {
102
102
  return tag.element.closest(q);
103
103
  }
104
104
 
105
+ public querySelectPath(path: string[], element: HTMLElement = null): HTMLElement[] {
106
+ const current = path.shift();
107
+ if (!current) return [];
108
+ const elements = Array.from(element ? this.querySelectorElement(element, current) : this.querySelectorAll(current));
109
+ if (path.length > 0) {
110
+ const result = [];
111
+ for (const _element of elements) {
112
+ result.push(...this.querySelectPath([...path], _element as HTMLElement));
113
+ }
114
+ return result;
115
+ }
116
+
117
+ return elements as HTMLElement[];
118
+ }
119
+
105
120
  public querySelectorAll(q: string, tag: Tag = null): NodeList | HTMLElement[] {
106
121
  const element: HTMLElement | Document = tag && !q.startsWith('#') ? tag.element : this.rootElement;
107
122
  return this.querySelectorElement(element, q);
@@ -128,7 +143,12 @@ export class DOM extends EventDispatcher {
128
143
  return this.querySelectorElement(element.parentElement, rest);
129
144
  }
130
145
  }
131
- return element.querySelectorAll(q);
146
+ let matches = element.querySelectorAll(q);
147
+
148
+ if (matches.length === 0 && (element as HTMLElement).shadowRoot) {
149
+ matches = (element as HTMLElement).shadowRoot.querySelectorAll(q);
150
+ }
151
+ return matches;
132
152
  }
133
153
 
134
154
  public querySelector(q: string): Element {
package/src/Tag.ts CHANGED
@@ -247,7 +247,14 @@ export class Tag extends DOMObject {
247
247
  break;
248
248
  }
249
249
 
250
- parentElement = parentElement.parentElement as HTMLElement;
250
+ if (parentElement.parentElement) {
251
+ parentElement = parentElement.parentElement as HTMLElement;
252
+ } else if (parentElement.assignedSlot) {
253
+ parentElement = parentElement.assignedSlot.parentElement as HTMLElement;
254
+ } else {
255
+ parentElement = null;
256
+ }
257
+
251
258
  }
252
259
 
253
260
  if (!foundParent && DOM.instance.root !== this)
@@ -10,7 +10,7 @@ export class Name extends Attribute {
10
10
  public async setup() {
11
11
  const parentScope: Scope = this.tag.scope.parentScope;
12
12
  if (parentScope) {
13
- parentScope.set(this.tag.parsedAttributes['vsn-name'][1], this.tag.scope);
13
+ parentScope.set(this.getAttributeValue(), this.tag.scope);
14
14
  }
15
15
  }
16
16
  }
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
- export const VERSION = '0.1.80';
1
+ export const VERSION = '0.1.83';
2
2
 
@@ -51,7 +51,6 @@ describe('ClassNode', () => {
51
51
  expect(t).toBeInstanceOf(TagList);
52
52
  expect(t.length).toBe(2);
53
53
  await t.all('.simple-construct.construct');
54
- console.log('####### hmm?', await dom.exec('?(.simple-construct).a'));
55
54
  expect(await dom.exec('?(.simple-construct).a')).toEqual([15, 15]);
56
55
  await dom.exec('?(.simple-construct).test()');
57
56
  expect(await dom.exec('?(.simple-construct).a')).toEqual([16, 16]);
@@ -85,7 +84,7 @@ describe('ClassNode', () => {
85
84
  it("properly define a simple class with a parent", async () => {
86
85
  document.body.innerHTML = `
87
86
  <script type="text/vsn" vsn-script>
88
- class .product-firearm-option {
87
+ class .option {
89
88
  func construct() {
90
89
  log('construct');
91
90
  }
@@ -132,20 +131,20 @@ class .product-firearm-option {
132
131
  }
133
132
  }
134
133
  </script>
135
- <div class="product-firearm-option">
136
- <input data-type="firearm-type" />
134
+ <div class="option">
135
+ <input data-type="normal" />
137
136
  <ul class="option-list">
138
- <li data-type="rifle">Rifle</li>
139
- <li data-type="pistol">Pistol</li>
140
- <li data-type="shotgun">Shotgun</li>
137
+ <li data-type="test">Foo</li>
138
+ <li data-type="test">Bar</li>
139
+ <li data-type="test">Baz</li>
141
140
  </ul>
142
141
  </div>
143
- <div class="product-firearm-option">
144
- <input data-type="model-type" />
142
+ <div class="option">
143
+ <input data-type="reverse" />
145
144
  <ul class="option-list">
146
- <li data-type="rifle">Glock</li>
147
- <li data-type="pistol">Springfield Armory</li>
148
- <li data-type="shotgun">Smith & Wesson</li>
145
+ <li data-type="tset">Oof</li>
146
+ <li data-type="tset">Rab</li>
147
+ <li data-type="tset">Zab</li>
149
148
  </ul>
150
149
  </div>
151
150
  `;