@microsoft/fast-html 1.0.0-alpha.14 → 1.0.0-alpha.16

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/README.md CHANGED
@@ -147,6 +147,8 @@ Attribute directives include:
147
147
  Example:
148
148
  ```html
149
149
  <slot f-slotted="{slottedNodes}"></slot>
150
+ <slot f-slotted="{slottedNodes filter elements()}"></slot>
151
+ <slot f-slotted="{slottedNodes filter elements(div, p)}"></slot>
150
152
  ```
151
153
 
152
154
  - **children**
@@ -257,4 +259,4 @@ If your template includes JavaScript specific logic that does not conform to tho
257
259
 
258
260
  ## Acknowledgements
259
261
 
260
- This project has been heavily inspired by [Handlebars](https://handlebarsjs.com/) and [Vue.js](https://vuejs.org/).
262
+ This project has been heavily inspired by [Handlebars](https://handlebarsjs.com/) and [Vue.js](https://vuejs.org/).
@@ -1,6 +1,10 @@
1
1
  import { FASTElement } from "@microsoft/fast-element";
2
2
  export declare abstract class RenderableFASTElement extends FASTElement {
3
3
  deferHydration: boolean;
4
- needsHydration: boolean;
5
4
  constructor();
5
+ /**
6
+ * A user defined function for determining if the element is ready to be hydrated.
7
+ * This function will get called if it has been defined after the template is connected.
8
+ */
9
+ private prepare;
6
10
  }
@@ -1,25 +1,20 @@
1
1
  import { __decorate, __metadata } from "tslib";
2
- import { attr, FASTElement, Observable } from "@microsoft/fast-element";
2
+ import { attr, FASTElement } from "@microsoft/fast-element";
3
3
  export class RenderableFASTElement extends FASTElement {
4
4
  constructor() {
5
5
  super();
6
6
  this.deferHydration = true;
7
- this.needsHydration = true;
8
- this.setAttribute("defer-hydration", "");
9
- this.setAttribute("needs-hydration", "");
10
- Observable.defineProperty(this.$fastController.definition, "shadowOptions");
11
- Observable.getNotifier(this.$fastController.definition).subscribe({
12
- handleChange: () => {
7
+ if (this.prepare) {
8
+ this.prepare().then(() => {
13
9
  this.deferHydration = false;
14
- },
15
- }, "shadowOptions");
10
+ });
11
+ }
12
+ else {
13
+ this.deferHydration = false;
14
+ }
16
15
  }
17
16
  }
18
17
  __decorate([
19
18
  attr({ mode: "boolean", attribute: "defer-hydration" }),
20
19
  __metadata("design:type", Boolean)
21
20
  ], RenderableFASTElement.prototype, "deferHydration", void 0);
22
- __decorate([
23
- attr({ mode: "boolean", attribute: "needs-hydration" }),
24
- __metadata("design:type", Boolean)
25
- ], RenderableFASTElement.prototype, "needsHydration", void 0);
@@ -1,5 +1,5 @@
1
1
  import { __awaiter, __decorate, __metadata } from "tslib";
2
- import { attr, FAST, FASTElement, fastElementRegistry, HydratableElementController, ViewTemplate, } from "@microsoft/fast-element";
2
+ import { attr, elements, FAST, FASTElement, FASTElementDefinition, fastElementRegistry, HydratableElementController, ViewTemplate, } from "@microsoft/fast-element";
3
3
  import "@microsoft/fast-element/install-hydratable-view-templates.js";
4
4
  import { getAllPartials, getExpressionChain, getNextBehavior, pathResolver, resolveWhen, transformInnerHTML, } from "./utilities.js";
5
5
  /**
@@ -38,9 +38,7 @@ class TemplateElement extends FASTElement {
38
38
  connectedCallback() {
39
39
  super.connectedCallback();
40
40
  if (this.name) {
41
- this.$fastController.definition.registry
42
- .whenDefined(this.name)
43
- .then((value) => __awaiter(this, void 0, void 0, function* () {
41
+ FASTElementDefinition.registerAsync(this.name).then((value) => __awaiter(this, void 0, void 0, function* () {
44
42
  var _a, _b;
45
43
  if (this.name && !!!((_a = TemplateElement.elementOptions) === null || _a === void 0 ? void 0 : _a[this.name])) {
46
44
  TemplateElement.setOptions(this.name);
@@ -53,8 +51,7 @@ class TemplateElement extends FASTElement {
53
51
  const { strings, values } = yield this.resolveStringsAndValues(innerHTML);
54
52
  if (registeredFastElement) {
55
53
  // all new elements will get the updated template
56
- registeredFastElement.template =
57
- this.resolveTemplateOrBehavior(strings, values);
54
+ registeredFastElement.template = this.resolveTemplateOrBehavior(strings, values);
58
55
  // set shadow options as defined by the f-template
59
56
  registeredFastElement.shadowOptions =
60
57
  (_b = TemplateElement.elementOptions[this.name]) === null || _b === void 0 ? void 0 : _b.shadowOptions;
@@ -151,7 +148,20 @@ class TemplateElement extends FASTElement {
151
148
  case "slotted":
152
149
  {
153
150
  const { slotted } = yield import("@microsoft/fast-element");
154
- externalValues.push(slotted(propName));
151
+ const parts = propName.trim().split(" filter ");
152
+ const slottedOption = {
153
+ property: parts[0],
154
+ };
155
+ if (parts[1]) {
156
+ if (parts[1].startsWith("elements(")) {
157
+ let params = parts[1].replace("elements(", "");
158
+ params = params.substring(0, params.lastIndexOf(")"));
159
+ Object.assign(slottedOption, {
160
+ filter: elements(params || undefined),
161
+ });
162
+ }
163
+ }
164
+ externalValues.push(slotted(slottedOption));
155
165
  }
156
166
  break;
157
167
  case "ref":
@@ -11,9 +11,9 @@ __decorate([
11
11
  attr,
12
12
  __metadata("design:type", String)
13
13
  ], TestElement.prototype, "type", void 0);
14
- TestElement.define({
14
+ TestElement.defineAsync({
15
15
  name: "test-element",
16
- shadowOptions: null,
16
+ templateOptions: "defer-and-hydrate",
17
17
  });
18
18
  TemplateElement.define({
19
19
  name: "f-template",
@@ -11,9 +11,9 @@ __decorate([
11
11
  attr,
12
12
  __metadata("design:type", String)
13
13
  ], TestElement.prototype, "text", void 0);
14
- TestElement.define({
14
+ TestElement.defineAsync({
15
15
  name: "test-element",
16
- shadowOptions: null,
16
+ templateOptions: "defer-and-hydrate",
17
17
  });
18
18
  class TestElementUnescaped extends RenderableFASTElement {
19
19
  constructor() {
@@ -21,9 +21,9 @@ class TestElementUnescaped extends RenderableFASTElement {
21
21
  this.html = `<p>Hello world</p>`;
22
22
  }
23
23
  }
24
- TestElementUnescaped.define({
24
+ TestElementUnescaped.defineAsync({
25
25
  name: "test-element-unescaped",
26
- shadowOptions: null,
26
+ templateOptions: "defer-and-hydrate",
27
27
  });
28
28
  TemplateElement.define({
29
29
  name: "f-template",
@@ -16,9 +16,9 @@ __decorate([
16
16
  observable,
17
17
  __metadata("design:type", Array)
18
18
  ], TestElement.prototype, "list", void 0);
19
- TestElement.define({
19
+ TestElement.defineAsync({
20
20
  name: "test-element",
21
- shadowOptions: null,
21
+ templateOptions: "defer-and-hydrate",
22
22
  });
23
23
  TemplateElement.define({
24
24
  name: "f-template",
@@ -7,9 +7,9 @@ class TestElement extends RenderableFASTElement {
7
7
  };
8
8
  }
9
9
  }
10
- TestElement.define({
10
+ TestElement.defineAsync({
11
11
  name: "test-element",
12
- shadowOptions: null,
12
+ templateOptions: "defer-and-hydrate",
13
13
  });
14
14
  TemplateElement.define({
15
15
  name: "f-template",
@@ -23,9 +23,9 @@ __decorate([
23
23
  attr,
24
24
  __metadata("design:type", String)
25
25
  ], TestElement.prototype, "foo", void 0);
26
- TestElement.define({
26
+ TestElement.defineAsync({
27
27
  name: "test-element",
28
- shadowOptions: null,
28
+ templateOptions: "defer-and-hydrate",
29
29
  });
30
30
  TemplateElement.define({
31
31
  name: "f-template",
@@ -1,6 +1,5 @@
1
- import { TemplateElement } from "@microsoft/fast-html";
2
- import { FASTElement } from "@microsoft/fast-element";
3
- class TestElement extends FASTElement {
1
+ import { RenderableFASTElement, TemplateElement } from "@microsoft/fast-html";
2
+ class TestElement extends RenderableFASTElement {
4
3
  constructor() {
5
4
  super(...arguments);
6
5
  this.items = [
@@ -23,9 +22,9 @@ class TestElement extends FASTElement {
23
22
  ];
24
23
  }
25
24
  }
26
- TestElement.define({
25
+ TestElement.defineAsync({
27
26
  name: "test-element",
28
- shadowOptions: null,
27
+ templateOptions: "defer-and-hydrate",
29
28
  });
30
29
  TemplateElement.define({
31
30
  name: "f-template",
@@ -5,9 +5,9 @@ class TestElement extends RenderableFASTElement {
5
5
  this.video = null;
6
6
  }
7
7
  }
8
- TestElement.define({
8
+ TestElement.defineAsync({
9
9
  name: "test-element",
10
- shadowOptions: null,
10
+ templateOptions: "defer-and-hydrate",
11
11
  });
12
12
  TemplateElement.define({
13
13
  name: "f-template",
@@ -3,11 +3,7 @@ import { expect, test } from "@playwright/test";
3
3
  test.describe("f-template", () => __awaiter(void 0, void 0, void 0, function* () {
4
4
  test("create a ref directive", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
5
5
  yield page.goto("/ref");
6
- const isVideo = yield page.evaluate(() => {
7
- var _a;
8
- const customElement = document.getElementsByTagName("test-element");
9
- return ((_a = customElement.item(0)) === null || _a === void 0 ? void 0 : _a.video) instanceof HTMLVideoElement;
10
- });
11
- expect(isVideo).toEqual(true);
6
+ const element = page.locator("test-element");
7
+ yield expect(element).toHaveJSProperty("video.nodeName", "VIDEO");
12
8
  }));
13
9
  }));
@@ -12,9 +12,9 @@ __decorate([
12
12
  observable,
13
13
  __metadata("design:type", Array)
14
14
  ], TestElement.prototype, "list", void 0);
15
- TestElement.define({
15
+ TestElement.defineAsync({
16
16
  name: "test-element",
17
- shadowOptions: null,
17
+ templateOptions: "defer-and-hydrate",
18
18
  });
19
19
  class TestElementInnerWhen extends RenderableFASTElement {
20
20
  constructor() {
@@ -35,9 +35,9 @@ __decorate([
35
35
  observable,
36
36
  __metadata("design:type", Array)
37
37
  ], TestElementInnerWhen.prototype, "list", void 0);
38
- TestElementInnerWhen.define({
38
+ TestElementInnerWhen.defineAsync({
39
39
  name: "test-element-inner-when",
40
- shadowOptions: null,
40
+ templateOptions: "defer-and-hydrate",
41
41
  });
42
42
  TemplateElement.define({
43
43
  name: "f-template",
@@ -5,18 +5,28 @@ class TestElement extends RenderableFASTElement {
5
5
  constructor() {
6
6
  super(...arguments);
7
7
  this.slottedNodes = [];
8
+ this.slottedFooNodes = [];
9
+ this.slottedBarNodes = [];
8
10
  }
9
- slottedNodesChanged() {
10
- this.classList.add(`class-${this.slottedNodes.length}`);
11
+ slottedFooNodesChanged() {
12
+ this.classList.add(`class-${this.slottedFooNodes.length}`);
11
13
  }
12
14
  }
13
15
  __decorate([
14
16
  observable,
15
17
  __metadata("design:type", Array)
16
18
  ], TestElement.prototype, "slottedNodes", void 0);
17
- TestElement.define({
19
+ __decorate([
20
+ observable,
21
+ __metadata("design:type", Array)
22
+ ], TestElement.prototype, "slottedFooNodes", void 0);
23
+ __decorate([
24
+ observable,
25
+ __metadata("design:type", Array)
26
+ ], TestElement.prototype, "slottedBarNodes", void 0);
27
+ TestElement.defineAsync({
18
28
  name: "test-element",
19
- shadowOptions: null,
29
+ templateOptions: "defer-and-hydrate",
20
30
  });
21
31
  TemplateElement.define({
22
32
  name: "f-template",
@@ -1,25 +1,24 @@
1
1
  import { __awaiter } from "tslib";
2
2
  import { expect, test } from "@playwright/test";
3
- test.describe("f-template", () => __awaiter(void 0, void 0, void 0, function* () {
4
- test("create a slotted directive", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
3
+ test.describe("f-template", () => {
4
+ let element;
5
+ test.beforeEach(({ page }) => __awaiter(void 0, void 0, void 0, function* () {
5
6
  yield page.goto("/slotted");
6
- const classCount1 = yield page.evaluate(() => {
7
- var _a;
8
- const customElement = document.getElementsByTagName("test-element");
9
- return (_a = customElement.item(0)) === null || _a === void 0 ? void 0 : _a.classList.length;
10
- });
11
- expect(classCount1).toEqual(2);
12
- yield page.evaluate(() => {
13
- var _a;
14
- const customElement = document.getElementsByTagName("test-element");
7
+ element = page.locator("test-element");
8
+ }));
9
+ test("create a slotted directive", () => __awaiter(void 0, void 0, void 0, function* () {
10
+ yield expect(element).toHaveJSProperty("classList.length", 2);
11
+ yield element.evaluate((node) => {
15
12
  const newElement = document.createElement("button");
16
- (_a = customElement.item(0)) === null || _a === void 0 ? void 0 : _a.append(newElement);
17
- });
18
- const classCount2 = yield page.evaluate(() => {
19
- var _a;
20
- const customElement = document.getElementsByTagName("test-element");
21
- return (_a = customElement.item(0)) === null || _a === void 0 ? void 0 : _a.classList.length;
13
+ newElement.slot = "foo";
14
+ node.append(newElement);
22
15
  });
23
- expect(classCount2).toEqual(3);
16
+ yield expect(element).toHaveJSProperty("classList.length", 3);
17
+ }));
18
+ test("slotted nodes are filtered by elements()", () => __awaiter(void 0, void 0, void 0, function* () {
19
+ yield expect(element).toHaveJSProperty("slottedNodes.length", 1);
20
+ }));
21
+ test("slotted nodes are filtered by elements() with query", () => __awaiter(void 0, void 0, void 0, function* () {
22
+ yield expect(element).toHaveJSProperty("slottedBarNodes.length", 1);
24
23
  }));
25
- }));
24
+ });
@@ -11,9 +11,9 @@ __decorate([
11
11
  attr({ mode: "boolean" }),
12
12
  __metadata("design:type", Boolean)
13
13
  ], TestElement.prototype, "show", void 0);
14
- TestElement.define({
14
+ TestElement.defineAsync({
15
15
  name: "test-element",
16
- shadowOptions: null,
16
+ templateOptions: "defer-and-hydrate",
17
17
  });
18
18
  class TestElementNot extends RenderableFASTElement {
19
19
  constructor() {
@@ -25,9 +25,9 @@ __decorate([
25
25
  attr({ mode: "boolean" }),
26
26
  __metadata("design:type", Boolean)
27
27
  ], TestElementNot.prototype, "hide", void 0);
28
- TestElementNot.define({
28
+ TestElementNot.defineAsync({
29
29
  name: "test-element-not",
30
- shadowOptions: null,
30
+ templateOptions: "defer-and-hydrate",
31
31
  });
32
32
  class TestElementEquals extends RenderableFASTElement {
33
33
  constructor() {
@@ -39,9 +39,9 @@ __decorate([
39
39
  attr({ attribute: "var-a" }),
40
40
  __metadata("design:type", Number)
41
41
  ], TestElementEquals.prototype, "varA", void 0);
42
- TestElementEquals.define({
42
+ TestElementEquals.defineAsync({
43
43
  name: "test-element-equals",
44
- shadowOptions: null,
44
+ templateOptions: "defer-and-hydrate",
45
45
  });
46
46
  class TestElementNotEquals extends RenderableFASTElement {
47
47
  constructor() {
@@ -53,9 +53,9 @@ __decorate([
53
53
  attr({ attribute: "var-a" }),
54
54
  __metadata("design:type", Number)
55
55
  ], TestElementNotEquals.prototype, "varA", void 0);
56
- TestElementNotEquals.define({
56
+ TestElementNotEquals.defineAsync({
57
57
  name: "test-element-not-equals",
58
- shadowOptions: null,
58
+ templateOptions: "defer-and-hydrate",
59
59
  });
60
60
  class TestElementGe extends RenderableFASTElement {
61
61
  constructor() {
@@ -67,9 +67,9 @@ __decorate([
67
67
  attr({ attribute: "var-a" }),
68
68
  __metadata("design:type", Number)
69
69
  ], TestElementGe.prototype, "varA", void 0);
70
- TestElementGe.define({
70
+ TestElementGe.defineAsync({
71
71
  name: "test-element-ge",
72
- shadowOptions: null,
72
+ templateOptions: "defer-and-hydrate",
73
73
  });
74
74
  class TestElementGt extends RenderableFASTElement {
75
75
  constructor() {
@@ -81,9 +81,9 @@ __decorate([
81
81
  attr({ attribute: "var-a" }),
82
82
  __metadata("design:type", Number)
83
83
  ], TestElementGt.prototype, "varA", void 0);
84
- TestElementGt.define({
84
+ TestElementGt.defineAsync({
85
85
  name: "test-element-gt",
86
- shadowOptions: null,
86
+ templateOptions: "defer-and-hydrate",
87
87
  });
88
88
  class TestElementLe extends RenderableFASTElement {
89
89
  constructor() {
@@ -95,9 +95,9 @@ __decorate([
95
95
  attr({ attribute: "var-a" }),
96
96
  __metadata("design:type", Number)
97
97
  ], TestElementLe.prototype, "varA", void 0);
98
- TestElementLe.define({
98
+ TestElementLe.defineAsync({
99
99
  name: "test-element-le",
100
- shadowOptions: null,
100
+ templateOptions: "defer-and-hydrate",
101
101
  });
102
102
  class TestElementLt extends RenderableFASTElement {
103
103
  constructor() {
@@ -109,9 +109,9 @@ __decorate([
109
109
  attr({ attribute: "var-a" }),
110
110
  __metadata("design:type", Number)
111
111
  ], TestElementLt.prototype, "varA", void 0);
112
- TestElementLt.define({
112
+ TestElementLt.defineAsync({
113
113
  name: "test-element-lt",
114
- shadowOptions: null,
114
+ templateOptions: "defer-and-hydrate",
115
115
  });
116
116
  class TestElementOr extends RenderableFASTElement {
117
117
  constructor() {
@@ -128,9 +128,9 @@ __decorate([
128
128
  attr({ attribute: "that-var", mode: "boolean" }),
129
129
  __metadata("design:type", Boolean)
130
130
  ], TestElementOr.prototype, "thatVar", void 0);
131
- TestElementOr.define({
131
+ TestElementOr.defineAsync({
132
132
  name: "test-element-or",
133
- shadowOptions: null,
133
+ templateOptions: "defer-and-hydrate",
134
134
  });
135
135
  class TestElementAnd extends RenderableFASTElement {
136
136
  constructor() {
@@ -147,9 +147,9 @@ __decorate([
147
147
  attr({ attribute: "that-var", mode: "boolean" }),
148
148
  __metadata("design:type", Boolean)
149
149
  ], TestElementAnd.prototype, "thatVar", void 0);
150
- TestElementAnd.define({
150
+ TestElementAnd.defineAsync({
151
151
  name: "test-element-and",
152
- shadowOptions: null,
152
+ templateOptions: "defer-and-hydrate",
153
153
  });
154
154
  TemplateElement.define({
155
155
  name: "f-template",