vsn 0.1.54 → 0.1.57

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.
Files changed (49) hide show
  1. package/demo/demo.html +184 -62
  2. package/demo/vsn.js +2 -1
  3. package/dist/AST/FunctionNode.d.ts +18 -0
  4. package/dist/AST/FunctionNode.js +87 -0
  5. package/dist/AST/FunctionNode.js.map +1 -1
  6. package/dist/DOM/DOMObject.d.ts +6 -1
  7. package/dist/DOM/DOMObject.js.map +1 -1
  8. package/dist/DOM.js +46 -76
  9. package/dist/DOM.js.map +1 -1
  10. package/dist/Tag.d.ts +4 -3
  11. package/dist/Tag.js +48 -19
  12. package/dist/Tag.js.map +1 -1
  13. package/dist/Types.js +1 -1
  14. package/dist/Types.js.map +1 -1
  15. package/dist/attributes/Bind.js.map +1 -1
  16. package/dist/attributes/KeyAbstract.js +1 -1
  17. package/dist/attributes/KeyAbstract.js.map +1 -1
  18. package/dist/attributes/KeyDown.js +1 -1
  19. package/dist/attributes/KeyDown.js.map +1 -1
  20. package/dist/attributes/KeyUp.js +1 -1
  21. package/dist/attributes/KeyUp.js.map +1 -1
  22. package/dist/attributes/LazyAttribute.js +2 -2
  23. package/dist/attributes/LazyAttribute.js.map +1 -1
  24. package/dist/attributes/List.js +13 -9
  25. package/dist/attributes/List.js.map +1 -1
  26. package/dist/attributes/On.js +1 -1
  27. package/dist/attributes/On.js.map +1 -1
  28. package/dist/attributes/ScopeAttribute.js +15 -5
  29. package/dist/attributes/ScopeAttribute.js.map +1 -1
  30. package/dist/vsn.d.ts +1 -1
  31. package/dist/vsn.js +2 -2
  32. package/dist/vsn.js.map +1 -1
  33. package/dist/vsn.min.js +2 -0
  34. package/package.json +3 -4
  35. package/src/AST/FunctionNode.ts +31 -0
  36. package/src/DOM/DOMObject.ts +7 -1
  37. package/src/DOM.ts +0 -20
  38. package/src/Tag.ts +41 -14
  39. package/src/Types.ts +1 -1
  40. package/src/attributes/Bind.ts +1 -2
  41. package/src/attributes/KeyAbstract.ts +1 -1
  42. package/src/attributes/KeyDown.ts +1 -1
  43. package/src/attributes/KeyUp.ts +1 -1
  44. package/src/attributes/LazyAttribute.ts +2 -2
  45. package/src/attributes/List.ts +2 -0
  46. package/src/attributes/On.ts +1 -1
  47. package/src/vsn.ts +2 -2
  48. package/test/attributes/ListItem.spec.ts +1 -0
  49. package/webpack.config.js +10 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vsn",
3
- "version": "0.1.54",
3
+ "version": "0.1.57",
4
4
  "description": "SEO Friendly Javascript/Typescript Framework",
5
5
  "keywords": [
6
6
  "framework",
@@ -15,11 +15,10 @@
15
15
  "scripts": {
16
16
  "build": "rm -rf ./dist/ && tsc",
17
17
  "build_dev": "rm -rf ./dist/ && webpack --env BUILD=development BENCHMARK=1",
18
- "demo": "rm -rf ./dist/ && webpack --env BUILD=production BENCHMARK=1 && cp ./dist/vsn.min.js ./demo/vsn.js",
19
- "clean": "rm -rf ./dist/",
18
+ "demo": "webpack --env BUILD=production BENCHMARK=1 && cp ./dist/vsn.min.js ./demo/vsn.js",
20
19
  "test": "karma start --single-run",
21
20
  "posttest": "codecov",
22
- "sample": "rm -rf sample/dist/ && tsc -p sample/ && node sample/dist/sample/index.js"
21
+ "clean": "rm -rf ./dist/"
23
22
  },
24
23
  "license": "MIT",
25
24
  "dependencies": {},
@@ -0,0 +1,31 @@
1
+ import {Scope} from "../Scope";
2
+ import {DOM} from "../DOM";
3
+ import {Tag} from "../Tag";
4
+ import {Token, TreeNode} from "../AST";
5
+ import {Node} from "./Node";
6
+ import {LiteralNode} from "./LiteralNode";
7
+ import {RootScopeMemberNode} from "./RootScopeMemberNode";
8
+ import {ScopeMemberNode} from "./ScopeMemberNode";
9
+
10
+ export class FunctionNode extends Node implements TreeNode {
11
+ constructor(
12
+ public readonly name: LiteralNode<string>,
13
+ public readonly variables: LiteralNode<string>[],
14
+ public readonly block: RootScopeMemberNode | ScopeMemberNode,
15
+ ) {
16
+ super();
17
+ }
18
+
19
+ protected _getChildNodes(): Node[] {
20
+ return [
21
+ this.block
22
+ ];
23
+ }
24
+
25
+ public async prepare(scope: Scope, dom: DOM, tag: Tag = null) {}
26
+ public async evaluate(scope: Scope, dom: DOM, tag: Tag = null) {}
27
+
28
+ public static parse(lastNode, token, tokens: Token[]): FunctionNode {
29
+ return new FunctionNode(null, null, null);
30
+ }
31
+ }
@@ -1,9 +1,15 @@
1
1
  import {Scope} from "../Scope";
2
2
  import {EventDispatcher} from "../EventDispatcher";
3
3
 
4
+ export interface IEventHandler {
5
+ event: string;
6
+ handler: (...args: any[]) => any;
7
+ context?: any;
8
+ }
9
+
4
10
  export abstract class DOMObject extends EventDispatcher {
5
11
  protected _scope: Scope;
6
- protected onEventHandlers: {[key:string]:any[]};
12
+ protected onEventHandlers: {[key:string]: IEventHandler[]};
7
13
  protected _uniqueScope: boolean = false;
8
14
 
9
15
  constructor(
package/src/DOM.ts CHANGED
@@ -177,26 +177,6 @@ export class DOM extends EventDispatcher {
177
177
  for (const tag of newTags)
178
178
  await tag.compileAttributes();
179
179
 
180
- for (const tag of newTags) {
181
- if (tag === this.root)
182
- continue;
183
-
184
- // Find the closest ancestor
185
- let parentElement: HTMLElement = tag.element.parentElement as HTMLElement;
186
- let foundParent = false;
187
- while (parentElement) {
188
- if (allElements.indexOf(parentElement) > -1) {
189
- foundParent = true;
190
- tag.parentTag = await this.getTagForElement(parentElement);
191
- break;
192
- }
193
-
194
- parentElement = parentElement.parentElement as HTMLElement;
195
- }
196
- if (!foundParent)
197
- console.error('Could not find parent for ', tag);
198
- }
199
-
200
180
  for (const tag of newTags)
201
181
  await tag.setupAttributes();
202
182
 
package/src/Tag.ts CHANGED
@@ -21,6 +21,8 @@ export enum TagState {
21
21
  Built,
22
22
  }
23
23
 
24
+ export const TaggedVariable:string = '_vsn_tag';
25
+
24
26
  export class Tag extends DOMObject {
25
27
  public readonly rawAttributes: { [key: string]: string; };
26
28
  public readonly parsedAttributes: { [key: string]: string[]; };
@@ -55,6 +57,7 @@ export class Tag extends DOMObject {
55
57
  ...props
56
58
  ) {
57
59
  super(element, props);
60
+ element[TaggedVariable] = this;
58
61
  this.rawAttributes = {};
59
62
  this.parsedAttributes = {};
60
63
  this.attributes = [];
@@ -232,6 +235,23 @@ export class Tag extends DOMObject {
232
235
  }
233
236
 
234
237
  public get parentTag(): Tag {
238
+ if (!this._parentTag) {
239
+ let parentElement: HTMLElement = this.element.parentElement as HTMLElement;
240
+ let foundParent = false;
241
+ while (parentElement) {
242
+ if (parentElement[TaggedVariable]) {
243
+ foundParent = true;
244
+ this.parentTag = parentElement[TaggedVariable];
245
+ break;
246
+ }
247
+
248
+ parentElement = parentElement.parentElement as HTMLElement;
249
+ }
250
+
251
+ if (!foundParent && DOM.instance.root !== this)
252
+ return DOM.instance.root;
253
+ }
254
+
235
255
  return this._parentTag;
236
256
  }
237
257
 
@@ -253,8 +273,8 @@ export class Tag extends DOMObject {
253
273
  if (this.uniqueScope)
254
274
  return this.createScope();
255
275
 
256
- if (!!this._parentTag)
257
- return this._parentTag.scope;
276
+ if (!!this.parentTag)
277
+ return this.parentTag.scope;
258
278
 
259
279
  return null;
260
280
  }
@@ -293,7 +313,7 @@ export class Tag extends DOMObject {
293
313
  }
294
314
 
295
315
  public addToParentElement() {
296
- this._parentTag.element.appendChild(this.element)
316
+ this.parentTag.element.appendChild(this.element)
297
317
  }
298
318
 
299
319
  public hide() {
@@ -307,7 +327,6 @@ export class Tag extends DOMObject {
307
327
  public findAncestorByAttribute(attr: string, includeSelf: boolean = false): Tag {
308
328
  if (includeSelf && this.hasAttribute(attr))
309
329
  return this;
310
-
311
330
  return this.parentTag ? this.parentTag.findAncestorByAttribute(attr, true) : null;
312
331
  }
313
332
 
@@ -472,7 +491,7 @@ export class Tag extends DOMObject {
472
491
 
473
492
  public async connectAttributes() {
474
493
  if (this.isInput) {
475
- this.addEventHandler('input', [], this.inputMutation.bind(this));
494
+ this.addEventHandler('input', [], this.inputMutation, this);
476
495
  }
477
496
 
478
497
  for (const attr of this.nonDeferredAttributes) {
@@ -496,9 +515,12 @@ export class Tag extends DOMObject {
496
515
  option.removeAttribute('selected');
497
516
  }
498
517
  }
499
- this.element.setAttribute('value', values.join(','));
518
+ //this.element.setAttribute('value', );
519
+ this.value = values.join(',');
500
520
  } else {
501
- this.element.setAttribute('value', e.target.value);
521
+ //this.element.setAttribute('value', e.target.value);
522
+ //(this.element as any).value = e.target.value;
523
+ this.value = e.target.value;
502
524
  }
503
525
  }
504
526
 
@@ -519,13 +541,14 @@ export class Tag extends DOMObject {
519
541
  protected handleEvent(eventType: string, e) {
520
542
  if (e)
521
543
  e.stopPropagation();
544
+
522
545
  if (!this.onEventHandlers[eventType])
523
546
  return;
524
547
 
525
548
  this.scope.set('$event', e);
526
549
  this.scope.set('$value', this.value);
527
550
  for (const handler of this.onEventHandlers[eventType]) {
528
- handler(e);
551
+ handler.handler.call(handler.context, e);
529
552
  }
530
553
  }
531
554
 
@@ -537,7 +560,7 @@ export class Tag extends DOMObject {
537
560
  return attribute.replace(`|${modifier}`, '');
538
561
  }
539
562
 
540
- public addEventHandler(eventType: string, modifiers: string[], handler) {
563
+ public addEventHandler(eventType: string, modifiers: string[], handler, context: any = null) {
541
564
  let passiveValue: boolean = null;
542
565
  if (modifiers.indexOf('active') > -1) {
543
566
  passiveValue = false;
@@ -555,16 +578,20 @@ export class Tag extends DOMObject {
555
578
  element.addEventListener(eventType, this.handleEvent.bind(this, eventType), opts);
556
579
  }
557
580
 
558
- this.onEventHandlers[eventType].push(handler);
581
+ this.onEventHandlers[eventType].push({
582
+ handler: handler,
583
+ event: eventType,
584
+ context: context,
585
+ });
559
586
  }
560
587
 
561
- public removeEventHandler(eventType: string, handler) {
588
+ public removeEventHandler(eventType: string, handler, context: any = null) {
562
589
  if (!this.onEventHandlers[eventType])
563
590
  return;
564
591
 
565
- const index = this.onEventHandlers[eventType].indexOf(handler);
566
- if (index > -1) {
567
- this.onEventHandlers[eventType].splice(index, 1);
592
+ const _handler = this.onEventHandlers[eventType].find(h => h.handler === handler && h.context === context);
593
+ if (_handler) {
594
+ this.onEventHandlers[eventType].splice(this.onEventHandlers[eventType].indexOf(_handler), 1);
568
595
  if (this.onEventHandlers[eventType].length === 0) {
569
596
  this.element.removeEventListener(eventType, this.handleEvent.bind(this, eventType));
570
597
  }
package/src/Types.ts CHANGED
@@ -18,7 +18,7 @@ export class Types {
18
18
 
19
19
  @Registry.type('float')
20
20
  public static float(value: string) {
21
- value = `${value}`.replace(/[^0-9.]+/, '');
21
+ value = `${value}`.replace(/[^\d.]+/, '');
22
22
  return parseFloat(value);
23
23
  }
24
24
 
@@ -44,7 +44,6 @@ export class Bind extends Attribute {
44
44
 
45
45
  this.key = await ref.getKey();
46
46
  this.boundScope = await ref.getScope();
47
-
48
47
  if (!!this.valueFromElement)
49
48
  this.updateFrom();
50
49
 
@@ -80,12 +79,12 @@ export class Bind extends Attribute {
80
79
 
81
80
  get valueFromElement(): string {
82
81
  let value;
82
+
83
83
  if (this.property) {
84
84
  value = this.tag.getElementAttribute(this.property);
85
85
  } else {
86
86
  value = this.tag.value;
87
87
  }
88
-
89
88
  return value;
90
89
  }
91
90
 
@@ -9,7 +9,7 @@ export abstract class KeyAbstract extends On {
9
9
  }
10
10
 
11
11
  public async connect() {
12
- this.tag.addEventHandler('keydown', this.getAttributeModifiers(), this.handleEvent.bind(this));
12
+ this.tag.addEventHandler('keydown', this.getAttributeModifiers(), this.handleEvent, this);
13
13
  await super.connect();
14
14
  }
15
15
 
@@ -4,7 +4,7 @@ import {Registry} from "../Registry";
4
4
  @Registry.attribute('vsn-key-down')
5
5
  export class KeyDown extends KeyAbstract {
6
6
  public async connect() {
7
- this.tag.addEventHandler('keydown', this.getAttributeModifiers(), this.handleEvent.bind(this));
7
+ this.tag.addEventHandler('keydown', this.getAttributeModifiers(), this.handleEvent, this);
8
8
  await super.connect();
9
9
  }
10
10
  }
@@ -4,7 +4,7 @@ import {Registry} from "../Registry";
4
4
  @Registry.attribute('vsn-key-up')
5
5
  export class KeyUp extends KeyAbstract {
6
6
  public async connect() {
7
- this.tag.addEventHandler('keyup', this.getAttributeModifiers(), this.handleEvent.bind(this));
7
+ this.tag.addEventHandler('keyup', this.getAttributeModifiers(), this.handleEvent, this);
8
8
  await super.connect();
9
9
  }
10
10
  }
@@ -12,7 +12,7 @@ export class LazyAttribute extends On {
12
12
  }
13
13
 
14
14
  public async connect() {
15
- this.tag.addEventHandler('scroll', ['passive'], this.handleEvent.bind(this));
15
+ this.tag.addEventHandler('scroll', ['passive'], this.handleEvent, this);
16
16
  await this.handleEvent();
17
17
  }
18
18
 
@@ -20,7 +20,7 @@ export class LazyAttribute extends On {
20
20
  if (!this.loaded && window.scrollY + window.outerHeight >= this.eleTop) {
21
21
  this.loaded = true;
22
22
  await this.handler.evaluate(this.tag.scope, this.tag.dom, this.tag);
23
- this.tag.removeEventHandler('scroll', this.handleEvent.bind(this));
23
+ this.tag.removeEventHandler('scroll', this.handleEvent, this);
24
24
  }
25
25
  }
26
26
  }
@@ -25,9 +25,11 @@ export class List extends Attribute {
25
25
  public async setup() {
26
26
  if (this.tag.element.children.length > 0) {
27
27
  const template = this.tag.element.children[0];
28
+ const templateTag: Tag = await this.tag.dom.getTagForElement(template);
28
29
 
29
30
  if (template) {
30
31
  if (template.hasAttribute('vsn-template')) {
32
+ templateTag.parentTag = this.tag; // Set parentTag before removing from DOM
31
33
  template.removeAttribute('vsn-template');
32
34
  this.tag.element.removeChild(template);
33
35
  this.template = template;
@@ -32,7 +32,7 @@ export abstract class On extends Attribute {
32
32
  }
33
33
 
34
34
  public async connect() {
35
- this.tag.addEventHandler(this.getAttributeBinding(), this.getAttributeModifiers(), this.handleEvent.bind(this));
35
+ this.tag.addEventHandler(this.getAttributeBinding(), this.getAttributeModifiers(), this.handleEvent, this);
36
36
  await super.connect();
37
37
  }
38
38
  }
package/src/vsn.ts CHANGED
@@ -43,7 +43,7 @@ export class Vision extends EventDispatcher {
43
43
  return this._dom;
44
44
  }
45
45
 
46
- public async eval(code: string) {
46
+ public async exec(code: string) {
47
47
  return await this._dom.exec(code);
48
48
  }
49
49
 
@@ -55,7 +55,7 @@ export class Vision extends EventDispatcher {
55
55
  await this._dom.buildFrom(document, true);
56
56
  const now = (new Date()).getTime();
57
57
  const setupTime = now - startTime;
58
- console.warn(`Took ${setupTime}ms to start up VisionJS. https://www.vsnjs.com/`);
58
+ console.warn(`Took ${setupTime}ms to start up VisionJS. https://www.vsnjs.com/`, window ? `v${window['VSN_VERSION']}` : null);
59
59
  }
60
60
 
61
61
  public static get instance() {
@@ -68,6 +68,7 @@ describe('ListItem', () => {
68
68
  </ul>
69
69
  </div>
70
70
  `;
71
+ console.log('########### test');
71
72
  const dom = new DOM(document);
72
73
  dom.once('built', async () => {
73
74
  const list = await dom.getTagForElement(document.getElementById('test'));
package/webpack.config.js CHANGED
@@ -1,5 +1,6 @@
1
1
  const path = require('path');
2
2
  const webpack = require("webpack");
3
+ const TerserPlugin = require("terser-webpack-plugin");
3
4
 
4
5
  const defaultConfiguration = {
5
6
  entry: './src/vsn.ts',
@@ -20,6 +21,15 @@ const defaultConfiguration = {
20
21
  filename: 'vsn.min.js',
21
22
  path: path.resolve(__dirname, 'dist'),
22
23
  },
24
+ optimization: {
25
+ minimizer: [new TerserPlugin({
26
+ terserOptions: {
27
+ format: {
28
+ preamble: `/* Copyright ${new Date().getUTCFullYear()}, VSNjs. ${require('./package.json').name} ${require('./package.json').version} (${new Date().toUTCString()}) */if (window) window['VSN_VERSION']='${require('./package.json').version}';`
29
+ }
30
+ }
31
+ })],
32
+ }
23
33
  };
24
34
 
25
35
  function buildConfig(env) {