posthtml-component 1.0.0-beta.4 → 1.0.0-beta.5

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/changelog.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 1.0.0-beta.5 (2022-10-24)
2
+
3
+ * 100% coverage test
4
+ * Fix components with same slot name in the same node
5
+
1
6
  ## 1.0.0-beta.4 (2022-10-23)
2
7
 
3
8
  * Refactor with underscore.js
package/docs/demo.html ADDED
@@ -0,0 +1,117 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" class="h-100">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>PostHTML X Components</title>
7
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet">
8
+ <style>
9
+ .doc-shadow {
10
+ box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px,
11
+ rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0.1) 0px 1px 3px 0px,
12
+ rgba(0, 0, 0, 0.1) 0px 1px 2px -1px !important;
13
+ }
14
+ </style>
15
+ </head>
16
+ <body class="d-flex flex-column h-100 bg-light">
17
+ <header class="py-3 mb-4">
18
+ <div class="container-lg">
19
+ <div class="d-flex flex-wrap align-items-center justify-content-center justify-content-md-between">
20
+ <a href="index.html" class="d-flex align-items-center col-md-3 mb-2 mb-md-0 text-dark text-decoration-none h5">&lt;x-components/&gt;</a>
21
+ <ul class="nav col-12 col-md-auto mb-2 justify-content-center mb-md-0">
22
+ <li>
23
+ <a class="nav-link px-2 link-dark" href="index.html">Home</a>
24
+ </li>
25
+ <li>
26
+ <a class="nav-link px-2 link-dark" href="docs.html">Docs</a>
27
+ </li>
28
+ <li>
29
+ <a class="nav-link px-2 link-dark" href="https://github.com/posthtml" target="_blank">PostHTML</a>
30
+ </li>
31
+ <li>
32
+ <a class="nav-link px-2 link-dark d-block d-md-none" href="https://www.npmjs.com/package/posthtml-component" target="_blank">NPM</a>
33
+ </li>
34
+ <li>
35
+ <a class="nav-link px-2 link-dark d-block d-md-none" href="https://github.com/thewebartisan7/posthtml-components" target="_blank">GitHub</a>
36
+ </li>
37
+ </ul>
38
+ <div class="col-md-3 text-end d-none d-md-block">
39
+ <a class="btn btn-light bg-white doc-shadow border-white me-3" href="https://www.npmjs.com/package/posthtml-component" target="_blank">NPM</a>
40
+ <a class="btn btn-light bg-white doc-shadow border-white" href="https://github.com/thewebartisan7/posthtml-components" target="_blank">GitHub</a>
41
+ </div>
42
+ </div>
43
+ </div>
44
+ </header>
45
+ <main class="flex-shrink-0">
46
+ <div class="container-lg">
47
+ <div class="row">
48
+ <div class="col-lg-8">
49
+ <h1 class="display-1 fw-bold mb-4">Demo</h1>
50
+ </div>
51
+ </div>
52
+ </div>
53
+ </main>
54
+ <footer class="footer mt-auto py-3">
55
+ <div class="container-lg">
56
+ <div class="text-muted text-center">
57
+ Handcrafted with
58
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-heart-fill d-inline mx-1 text-danger" viewbox="0 0 16 16">
59
+ <path fill-rule="evenodd" d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314z"></path>
60
+ </svg>
61
+ and
62
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-cup-hot-fill d-inline mx-1 text-warning" viewbox="0 0 16 16">
63
+ <path fill-rule="evenodd" d="M.5 6a.5.5 0 0 0-.488.608l1.652 7.434A2.5 2.5 0 0 0 4.104 16h5.792a2.5 2.5 0 0 0 2.44-1.958l.131-.59a3 3 0 0 0 1.3-5.854l.221-.99A.5.5 0 0 0 13.5 6H.5ZM13 12.5a2.01 2.01 0 0 1-.316-.025l.867-3.898A2.001 2.001 0 0 1 13 12.5Z"></path>
64
+ <path d="m4.4.8-.003.004-.014.019a4.167 4.167 0 0 0-.204.31 2.327 2.327 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.593.593 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3.31 3.31 0 0 1-.202.388 5.444 5.444 0 0 1-.253.382l-.018.025-.005.008-.002.002A.5.5 0 0 1 3.6 4.2l.003-.004.014-.019a4.149 4.149 0 0 0 .204-.31 2.06 2.06 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.593.593 0 0 0-.09-.252A4.334 4.334 0 0 0 3.6 2.8l-.01-.012a5.099 5.099 0 0 1-.37-.543A1.53 1.53 0 0 1 3 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a5.446 5.446 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 4.4.8Zm3 0-.003.004-.014.019a4.167 4.167 0 0 0-.204.31 2.327 2.327 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.593.593 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3.31 3.31 0 0 1-.202.388 5.444 5.444 0 0 1-.253.382l-.018.025-.005.008-.002.002A.5.5 0 0 1 6.6 4.2l.003-.004.014-.019a4.149 4.149 0 0 0 .204-.31 2.06 2.06 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.593.593 0 0 0-.09-.252A4.334 4.334 0 0 0 6.6 2.8l-.01-.012a5.099 5.099 0 0 1-.37-.543A1.53 1.53 0 0 1 6 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a5.446 5.446 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 7.4.8Zm3 0-.003.004-.014.019a4.077 4.077 0 0 0-.204.31 2.337 2.337 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.593.593 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3.198 3.198 0 0 1-.202.388 5.385 5.385 0 0 1-.252.382l-.019.025-.005.008-.002.002A.5.5 0 0 1 9.6 4.2l.003-.004.014-.019a4.149 4.149 0 0 0 .204-.31 2.06 2.06 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.593.593 0 0 0-.09-.252A4.334 4.334 0 0 0 9.6 2.8l-.01-.012a5.099 5.099 0 0 1-.37-.543A1.53 1.53 0 0 1 9 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a5.446 5.446 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 10.4.8Z"></path>
65
+ </svg>
66
+ in Swiss Alp by
67
+ <a href="https://github.com/thewebartisan7" class="text-muted text-decoration-none fst-italic" target="_blank">@thewebartisan7</a>
68
+ </div>
69
+ </div>
70
+ </footer>
71
+ <div class="modal fade" id="modalWithComponents" data-bs-backdrop="true" data-bs-keyboard="true" aria-labelledby="modalWithComponents" tabindex="-1" aria-hidden="true" aria-modal="true" role="dialog">
72
+ <div class="modal-dialog modal-lg modal-fullscreen-lg-down modal-dialog-centered modal-dialog-custom">
73
+ <div class="modal-content modal-content-custom">
74
+ <div class="modal-header">
75
+ <h5 class="modal-title" id="modalWithComponentsLabel">Changelog</h5>
76
+ <button type="button" class="btn" override:class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
77
+ </div>
78
+ <!-- /.modal-header -->
79
+ <div class="modal-body">
80
+ <h3 id="1.0.0-beta.4-(2022-10-23)" tabindex="-1">
81
+ <a class="header-anchor" href="#1.0.0-beta.4-(2022-10-23)">#</a>
82
+ 1.0.0-beta.4 (2022-10-23)
83
+ </h3>
84
+ <ul>
85
+ <li>Refactor with underscore.js</li>
86
+ <li>Optionally set attributes to any nodes not only the first one</li>
87
+ <li>Added more docs</li>
88
+ </ul>
89
+ <h3 id="1.0.0-beta.3-(2022-10-21)" tabindex="-1">
90
+ <a class="header-anchor" href="#1.0.0-beta.3-(2022-10-21)">#</a>
91
+ 1.0.0-beta.3 (2022-10-21)
92
+ </h3>
93
+ <ul>
94
+ <li>Apply additional plugins to tree</li>
95
+ </ul>
96
+ <h3 id="1.0.0-beta.2-(2022-10-20)" tabindex="-1">
97
+ <a class="header-anchor" href="#1.0.0-beta.2-(2022-10-20)">#</a>
98
+ 1.0.0-beta.2 (2022-10-20)
99
+ </h3>
100
+ <ul>
101
+ <li>First beta release</li>
102
+ </ul>
103
+ </div>
104
+ <!-- /.modal-body -->
105
+ <div class="modal-footer">
106
+ <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
107
+ </div>
108
+ <!-- /.modal-footer -->
109
+ </div>
110
+ <!-- /.modal-content -->
111
+ </div>
112
+ <!-- /.modal-dialog -->
113
+ </div>
114
+ <!-- /.modal -->
115
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js"></script>
116
+ </body>
117
+ </html>
package/docs/docs.html CHANGED
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title>PostHTML UI</title>
6
+ <title>PostHTML X Components</title>
7
7
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet">
8
8
  <style>
9
9
  .doc-shadow {
@@ -32,28 +32,37 @@
32
32
  margin-bottom: 1.5rem;
33
33
  }
34
34
 
35
- .header-anchor {
36
- margin-left: -28px;
37
- line-height: 1;
35
+ .header-anchor,
36
+ h1 .header-anchor,
37
+ h2 .header-anchor,
38
+ h3 .header-anchor {
38
39
  color: inherit;
39
40
  text-decoration: none;
40
- visibility: hidden;
41
41
  }
42
42
 
43
- h1 .header-anchor {
44
- margin-left: -34px;
45
- }
43
+ @media only screen and (min-width: 1200px) {
44
+ .header-anchor {
45
+ margin-left: -28px;
46
+ line-height: 1;
47
+ color: inherit;
48
+ text-decoration: none;
49
+ visibility: hidden;
50
+ }
46
51
 
47
- h3 .header-anchor {
48
- margin-left: -24px;
49
- }
52
+ h1 .header-anchor {
53
+ margin-left: -34px;
54
+ }
50
55
 
51
- .header-anchor:hover,
52
- h1:hover .header-anchor,
53
- h2:hover .header-anchor,
54
- h3:hover .header-anchor{
55
- visibility: visible;
56
- color: inherit;
56
+ h3 .header-anchor {
57
+ margin-left: -24px;
58
+ }
59
+
60
+ .header-anchor:hover,
61
+ h1:hover .header-anchor,
62
+ h2:hover .header-anchor,
63
+ h3:hover .header-anchor {
64
+ visibility: visible;
65
+ }
57
66
  }
58
67
 
59
68
  #header-toc .nav-link {
@@ -80,11 +89,7 @@
80
89
  <header class="py-3 mb-4">
81
90
  <div class="container-lg">
82
91
  <div class="d-flex flex-wrap align-items-center justify-content-center justify-content-md-between">
83
- <a href="index.html" class="d-flex align-items-center col-md-3 mb-2 mb-md-0 text-dark text-decoration-none">
84
- <svg xmlns="http://www.w3.org/2000/svg" width="40" height="32" fill="currentColor" class="bi bi-code-slash me-2" viewbox="0 0 16 16">
85
- <path d="M10.478 1.647a.5.5 0 1 0-.956-.294l-4 13a.5.5 0 0 0 .956.294l4-13zM4.854 4.146a.5.5 0 0 1 0 .708L1.707 8l3.147 3.146a.5.5 0 0 1-.708.708l-3.5-3.5a.5.5 0 0 1 0-.708l3.5-3.5a.5.5 0 0 1 .708 0zm6.292 0a.5.5 0 0 0 0 .708L14.293 8l-3.147 3.146a.5.5 0 0 0 .708.708l3.5-3.5a.5.5 0 0 0 0-.708l-3.5-3.5a.5.5 0 0 0-.708 0z"></path>
86
- </svg>
87
- </a>
92
+ <a href="index.html" class="d-flex align-items-center col-md-3 mb-2 mb-md-0 text-dark text-decoration-none h5">&lt;x-components/&gt;</a>
88
93
  <ul class="nav col-12 col-md-auto mb-2 justify-content-center mb-md-0">
89
94
  <li>
90
95
  <a class="nav-link px-2 link-dark" href="index.html">Home</a>
@@ -110,7 +115,7 @@
110
115
  </div>
111
116
  </header>
112
117
  <main class="flex-shrink-0">
113
- <div class="container">
118
+ <div class="container-lg">
114
119
  <div class="row">
115
120
  <div class="col-12 col-xl-3 order-1 order-xl-2 toc">
116
121
  <div class="mt-3 mb-5 my-lg-0 ps-xl-3 mb-lg-5 text-muted">
package/docs/index.html CHANGED
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title>PostHTML UI</title>
6
+ <title>PostHTML X Components</title>
7
7
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet">
8
8
  <style>
9
9
  .doc-shadow {
@@ -17,11 +17,7 @@
17
17
  <header class="py-3 mb-4">
18
18
  <div class="container-lg">
19
19
  <div class="d-flex flex-wrap align-items-center justify-content-center justify-content-md-between">
20
- <a href="index.html" class="d-flex align-items-center col-md-3 mb-2 mb-md-0 text-dark text-decoration-none">
21
- <svg xmlns="http://www.w3.org/2000/svg" width="40" height="32" fill="currentColor" class="bi bi-code-slash me-2" viewbox="0 0 16 16">
22
- <path d="M10.478 1.647a.5.5 0 1 0-.956-.294l-4 13a.5.5 0 0 0 .956.294l4-13zM4.854 4.146a.5.5 0 0 1 0 .708L1.707 8l3.147 3.146a.5.5 0 0 1-.708.708l-3.5-3.5a.5.5 0 0 1 0-.708l3.5-3.5a.5.5 0 0 1 .708 0zm6.292 0a.5.5 0 0 0 0 .708L14.293 8l-3.147 3.146a.5.5 0 0 0 .708.708l3.5-3.5a.5.5 0 0 0 0-.708l-3.5-3.5a.5.5 0 0 0-.708 0z"></path>
23
- </svg>
24
- </a>
20
+ <a href="index.html" class="d-flex align-items-center col-md-3 mb-2 mb-md-0 text-dark text-decoration-none h5">&lt;x-components/&gt;</a>
25
21
  <ul class="nav col-12 col-md-auto mb-2 justify-content-center mb-md-0">
26
22
  <li>
27
23
  <a class="nav-link px-2 link-dark" href="index.html">Home</a>
@@ -47,14 +43,15 @@
47
43
  </div>
48
44
  </header>
49
45
  <main class="flex-shrink-0">
50
- <div class="container">
46
+ <div class="container-lg">
51
47
  <div class="row justify-content-center align-items-center">
52
48
  <div class="col-lg-8 text-center">
53
49
  <h1 class="display-1 fw-bold mb-4">Build the web with PostHTML</h1>
54
50
  <p class="lead mb-4">
55
- Quickly design and customize responsive mobile-first sites with Bootstrap, the world's most popular front-end
56
- open source toolkit, and with PostHTML, the simple, yet powerful tool for transforming HTML/XML with JS plugins.
57
- Powered with PostHTML Components plugin which give you additional superpowers!
51
+ Quickly design with PostHTML, the simple, yet powerful tool for transforming HTML/XML with JS plugins.
52
+ Fueled with
53
+ <strong>x-components</strong>
54
+ plugin which give you additional superpowers!
58
55
  </p>
59
56
  <div class="text-center mb-4">
60
57
  <a class="btn btn-light bg-white doc-shadow border-white btn-lg me-3" href="docs.html">Read the docs</a>
@@ -62,7 +59,7 @@
62
59
  </div>
63
60
  <p class="text-muted">
64
61
  Currently
65
- <strong>v1.0.0-beta.2</strong>
62
+ <strong>v1.0.0-beta.4</strong>
66
63
  <span class="px-1">·</span>
67
64
  <a href="#" class="link-secondary" data-bs-toggle="modal" data-bs-target="#modalWithComponents">Changelog</a>
68
65
  </p>
package/docs/test.html CHANGED
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title>PostHTML UI</title>
6
+ <title>PostHTML X Components</title>
7
7
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet">
8
8
  <style>
9
9
  .doc-shadow {
@@ -17,11 +17,7 @@
17
17
  <header class="py-3 mb-4">
18
18
  <div class="container-lg">
19
19
  <div class="d-flex flex-wrap align-items-center justify-content-center justify-content-md-between">
20
- <a href="index.html" class="d-flex align-items-center col-md-3 mb-2 mb-md-0 text-dark text-decoration-none">
21
- <svg xmlns="http://www.w3.org/2000/svg" width="40" height="32" fill="currentColor" class="bi bi-code-slash me-2" viewbox="0 0 16 16">
22
- <path d="M10.478 1.647a.5.5 0 1 0-.956-.294l-4 13a.5.5 0 0 0 .956.294l4-13zM4.854 4.146a.5.5 0 0 1 0 .708L1.707 8l3.147 3.146a.5.5 0 0 1-.708.708l-3.5-3.5a.5.5 0 0 1 0-.708l3.5-3.5a.5.5 0 0 1 .708 0zm6.292 0a.5.5 0 0 0 0 .708L14.293 8l-3.147 3.146a.5.5 0 0 0 .708.708l3.5-3.5a.5.5 0 0 0 0-.708l-3.5-3.5a.5.5 0 0 0-.708 0z"></path>
23
- </svg>
24
- </a>
20
+ <a href="index.html" class="d-flex align-items-center col-md-3 mb-2 mb-md-0 text-dark text-decoration-none h5">&lt;x-components/&gt;</a>
25
21
  <ul class="nav col-12 col-md-auto mb-2 justify-content-center mb-md-0">
26
22
  <li>
27
23
  <a class="nav-link px-2 link-dark" href="index.html">Home</a>
@@ -47,7 +43,7 @@
47
43
  </div>
48
44
  </header>
49
45
  <main class="flex-shrink-0">
50
- <div class="container">
46
+ <div class="container-lg">
51
47
  <div class="row">
52
48
  <div class="col-lg-8">
53
49
  <h1 class="display-1 fw-bold mb-4">Demo</h1>
@@ -93,7 +89,7 @@
93
89
  : Fourth merged item
94
90
  </p>
95
91
  <h1>aStringDefault</h1>
96
- <p></p>
92
+ <p>My default string</p>
97
93
  <h1>aStringOverride</h1>
98
94
  <p>My override string changed</p>
99
95
  <hr>
@@ -164,6 +160,37 @@
164
160
  Hello
165
161
  </div>
166
162
  </div>
163
+ <hr>
164
+ <div class="bg-secondary">
165
+ <h4>Parent</h4>
166
+ <h5>YIELD PARENT IN CHILD-PARENT.html</h5>
167
+ Test
168
+
169
+
170
+
171
+
172
+ SLOT PARENT INSIDE CHILD-PARENT.html
173
+ </div>
174
+ <div class="bg-warning">
175
+ <h4>Child</h4>
176
+ <h5>YIELD CHILD INSIDE CHILD-PARENT.html</h5>
177
+ SLOT CHILD INSIDE CHILD-PARENT.html
178
+ </div>
179
+ <div class="bg-secondary">
180
+ <h4>Parent</h4>
181
+ <h5>YIELD PARENT IN TEST.html</h5>
182
+ undefined
183
+
184
+
185
+
186
+
187
+ SLOT PARENT INSIDE TEST.html
188
+ </div>
189
+ <div class="bg-warning">
190
+ <h4>Child</h4>
191
+ <h5>YIELD CHILD INSIDE TEST.html</h5>
192
+ SLOT CHILD INSIDE TEST.html
193
+ </div>
167
194
  </div>
168
195
  </div>
169
196
  </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "posthtml-component",
3
- "version": "1.0.0-beta.4",
3
+ "version": "1.0.0-beta.5",
4
4
  "description": "PostHTML Components Blade-like with slots, attributes as props and custom tag",
5
5
  "license": "MIT",
6
6
  "repository": "thewebartisan7/posthtml-components",
package/readme.md CHANGED
@@ -5,7 +5,7 @@
5
5
  <div align="center">
6
6
  <img width="300" title="PostHTML" src="http://posthtml.github.io/posthtml/logo.svg">
7
7
  <h1>PostHTML Components </h1>
8
- <p>HTML-friendly syntax component with slots, attributes as locals and more!</p>
8
+ <p>A PostHTML plugin for create components with HTML-friendly syntax inspired by Laravel Blade. Slots, stack/push, props, custom tag and much more.</p>
9
9
  </div>
10
10
 
11
11
  ## Installation
package/src/index.js CHANGED
@@ -115,31 +115,19 @@ function processTree(options) {
115
115
  currentNode.attrs = {};
116
116
  }
117
117
 
118
- const componentFile = currentNode.attrs[options.attribute] || findPathFromTag(currentNode.tag, options);
118
+ const componentPath = getComponentPath(currentNode, options);
119
119
 
120
- if (!componentFile) {
120
+ if (!componentPath) {
121
121
  return currentNode;
122
122
  }
123
123
 
124
- const componentPath = path.isAbsolute(componentFile) && !currentNode.attrs[options.attribute] ?
125
- componentFile :
126
- path.join(options.root, componentFile);
127
-
128
- // Check if file exist only when not using x-tag
129
- if (currentNode.attrs[options.attribute] && !existsSync(componentPath)) {
130
- if (options.strict) {
131
- throw new Error(`[components] The component was not found in ${componentPath}.`);
132
- } else {
133
- return currentNode;
134
- }
135
- }
136
-
137
124
  // console.log(`${++processCounter}) Processing component ${componentPath}`);
138
125
 
139
126
  let nextNode = parser(readFileSync(componentPath, 'utf8'));
140
127
 
141
128
  // Set filled slots
142
129
  setFilledSlots(currentNode, filledSlots, options);
130
+ setFilledSlots(nextNode, filledSlots, options);
143
131
 
144
132
  // Reset previous locals with passed global and keep aware locals
145
133
  options.expressions.locals = {...options.locals, ...options.aware};
@@ -161,6 +149,8 @@ function processTree(options) {
161
149
  return currentNode.content || nextNode.content;
162
150
  });
163
151
 
152
+ nextNode = processTree(options)(nextNode);
153
+
164
154
  // Process <fill> tags
165
155
  processFillContent(nextNode, filledSlots, options);
166
156
 
@@ -190,6 +180,26 @@ function processTree(options) {
190
180
  };
191
181
  }
192
182
 
183
+ function getComponentPath(currentNode, options) {
184
+ const componentFile = currentNode.attrs[options.attribute];
185
+
186
+ if (componentFile) {
187
+ const componentPath = path.join(options.root, componentFile);
188
+
189
+ if (!existsSync(componentPath)) {
190
+ if (options.strict) {
191
+ throw new Error(`[components] The component was not found in ${componentPath}.`);
192
+ } else {
193
+ return false;
194
+ }
195
+ }
196
+
197
+ return componentPath;
198
+ }
199
+
200
+ return findPathFromTag(currentNode.tag, options);
201
+ }
202
+
193
203
  function applyPluginsToTree(tree, plugins) {
194
204
  return plugins.reduce((tree, plugin) => {
195
205
  tree = plugin(tree);
package/src/slots.js CHANGED
@@ -21,7 +21,7 @@ function setFilledSlots(currentNode, filledSlots, {fill, slotSeparator}) {
21
21
 
22
22
  const name = fillNode.tag.split(slotSeparator)[1];
23
23
 
24
- const locals = omit(fillNode.attrs, [name, 'type', 'append', 'prepend', 'aware']);
24
+ const locals = omit(fillNode.attrs, ['append', 'prepend', 'aware']);
25
25
 
26
26
  if (locals) {
27
27
  each(locals, (value, key, attrs) => {
@@ -58,10 +58,6 @@ function processFillContent(tree, filledSlots, {fill, slotSeparator}) {
58
58
  match.call(tree, {tag: fill}, fillNode => {
59
59
  const name = fillNode.tag.split(slotSeparator)[1];
60
60
 
61
- if (!filledSlots[name]) {
62
- filledSlots[name] = {};
63
- }
64
-
65
61
  filledSlots[name].tag = fillNode.tag;
66
62
  filledSlots[name].attrs = fillNode.attrs;
67
63
  filledSlots[name].content = fillNode.content;
@@ -90,17 +86,21 @@ function processSlotContent(tree, filledSlots, {slot, slotSeparator}) {
90
86
 
91
87
  slotNode.tag = false;
92
88
 
93
- if (filledSlots[name]?.rendered) {
89
+ if (!filledSlots[name]) {
90
+ return slotNode;
91
+ }
92
+
93
+ if (filledSlots[name].rendered) {
94
94
  slotNode.content = null;
95
- } else if (slotNode.content && filledSlots[name]?.attrs && (typeof filledSlots[name]?.attrs.append !== 'undefined' || typeof filledSlots[name]?.attrs.prepend !== 'undefined')) {
96
- slotNode.content = typeof filledSlots[name]?.attrs.append === 'undefined' ? filledSlots[name]?.content.concat(slotNode.content) : slotNode.content.concat(filledSlots[name]?.content);
95
+ } else if (slotNode.content && filledSlots[name].attrs && (typeof filledSlots[name].attrs.append !== 'undefined' || typeof filledSlots[name].attrs.prepend !== 'undefined')) {
96
+ slotNode.content = typeof filledSlots[name].attrs.append === 'undefined' ? filledSlots[name].content.concat(slotNode.content) : slotNode.content.concat(filledSlots[name].content);
97
97
  } else {
98
- slotNode.content = filledSlots[name]?.content;
98
+ slotNode.content = filledSlots[name].content;
99
99
  }
100
100
 
101
101
  // Set rendered to true so a slot can be output only once,
102
102
  // when not present "aware" attribute
103
- if (filledSlots[name] && (!filledSlots[name]?.attrs || typeof filledSlots[name].attrs.aware === 'undefined')) {
103
+ if (filledSlots[name] && (!filledSlots[name].attrs || typeof filledSlots[name].attrs.aware === 'undefined')) {
104
104
  filledSlots[name].rendered = true;
105
105
  }
106
106
 
@@ -0,0 +1 @@
1
+ <div><slot:name>{{ $slots.name.locals.mySlotLocal }}</slot:name></div>
@@ -1,5 +1,5 @@
1
1
  <html>
2
- <head><title>Base Layout</title></head>
2
+ <head><title>Base Layout</title><stack name="head"></stack></head>
3
3
  <body>
4
4
  <header><slot:header></slot:header></header>
5
5
  <main><yield></yield></main>
@@ -58,3 +58,9 @@ test('Must fail when component is not found in defined namespace with strict mod
58
58
 
59
59
  await t.throwsAsync(async () => posthtml([plugin({root: './test/templates', strict: true, namespaces: [{name: 'empty-namespace', root: './test/templates/empty-namespace'}]})]).process(actual).then(result => clean(result.html)));
60
60
  });
61
+
62
+ test('Must fail when push tag missing name', async t => {
63
+ const actual = `<div><push></push></div>`;
64
+
65
+ await t.throwsAsync(async () => posthtml([plugin({root: './test/templates', strict: true})]).process(actual).then(result => clean(result.html)));
66
+ });
@@ -72,3 +72,12 @@ test('Must process default, merged and override props', async t => {
72
72
 
73
73
  t.is(html, expected);
74
74
  });
75
+
76
+ test('Must process slot with locals', async t => {
77
+ const actual = `<component src="components/slot-with-locals.html"><fill:name mySlotLocal=" Via Slot" prepend>My Local</fill:name></component>`;
78
+ const expected = `<div>My Local Via Slot</div>`;
79
+
80
+ const html = await posthtml([plugin({root: './test/templates', tag: 'component'})]).process(actual).then(result => clean(result.html));
81
+
82
+ t.is(html, expected);
83
+ });
@@ -0,0 +1,24 @@
1
+ 'use strict';
2
+
3
+ const test = require('ava');
4
+ const plugin = require('../src');
5
+ const posthtml = require('posthtml');
6
+ const clean = html => html.replace(/(\n|\t)/g, '').trim();
7
+
8
+ test('Must process stacks and push', async t => {
9
+ const actual = `<component src="layouts/base.html"><div>Main content</div><push name="head"><meta name="pushed" content="Content pushed"></push></component>`;
10
+ const expected = `<html><head><title>Base Layout</title><meta name="pushed" content="Content pushed"></head><body><header></header><main><div>Main content</div></main><footer>footer content</footer></body></html>`;
11
+
12
+ const html = await posthtml([plugin({root: './test/templates', tag: 'component'})]).process(actual).then(result => clean(result.html));
13
+
14
+ t.is(html, expected);
15
+ });
16
+
17
+ test('Must prepend push on stack once', async t => {
18
+ const actual = `<component src="layouts/base.html"><div>Main content</div><push name="head" prepend once><meta name="pushed" content="Content pushed"></push><push name="head" prepend once><meta name="pushed" content="Content pushed"></push></component>`;
19
+ const expected = `<html><head><title>Base Layout</title><meta name="pushed" content="Content pushed"></head><body><header></header><main><div>Main content</div></main><footer>footer content</footer></body></html>`;
20
+
21
+ const html = await posthtml([plugin({root: './test/templates', tag: 'component'})]).process(actual).then(result => clean(result.html));
22
+
23
+ t.is(html, expected);
24
+ });