posthtml-component 1.0.0-beta.10 → 1.0.0-beta.11
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 +2 -2
- package/readme.md +48 -48
- package/src/index.js +18 -12
- package/src/{attributes.js → process-attributes.js} +4 -4
- package/src/{locals.js → process-props.js} +18 -17
- package/src/process-script.js +49 -0
- package/src/{slots.js → process-slots.js} +5 -5
- /package/src/{stacks.js → process-stacks.js} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "posthtml-component",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.11",
|
|
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",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"version": "conventional-changelog -i changelog.md -s -r 0 && git add changelog.md",
|
|
14
14
|
"test": "c8 ava",
|
|
15
15
|
"pretest": "clinton && xo",
|
|
16
|
-
"build
|
|
16
|
+
"build": "node ./docs-src"
|
|
17
17
|
},
|
|
18
18
|
"keywords": [
|
|
19
19
|
"posthtml",
|
package/readme.md
CHANGED
|
@@ -17,7 +17,7 @@ npm i -D posthtml-component
|
|
|
17
17
|
## Introduction
|
|
18
18
|
|
|
19
19
|
This PostHTML plugin provides an HTML-friendly syntax for write components in your templates.
|
|
20
|
-
If you are familiar with Blade, you will find similar syntax as this plugin
|
|
20
|
+
If you are familiar with Blade, you will find similar syntax as this plugin is inspired by it.
|
|
21
21
|
See below a basic example, as code is worth a thousand words.
|
|
22
22
|
|
|
23
23
|
> This plugin is still in early stage of development and the current API may change.
|
|
@@ -69,13 +69,11 @@ Result:
|
|
|
69
69
|
</html>
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
You may
|
|
72
|
+
You may notice that our `src/button.html` component has a `type` and `class` attribute, and when we use the component in `src/index.html` we add type and class attribute.
|
|
73
|
+
The result is that `type` is override, and `class` is merged.
|
|
73
74
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
First you may notice that our `src/button.html` component has a `type` and `class` attribute, and when we use the component in `src/index.html` we add type and class attribute. The result is that `type` is override, and `class` is merged.
|
|
77
|
-
|
|
78
|
-
By default `class` and `style` attributes are merged, while all others attribute are override. You can also override class and style attribute by prepending `override:` to the class attribute. Example:
|
|
75
|
+
By default `class` and `style` attributes are merged, while all others attribute are override.
|
|
76
|
+
You can also override class and style attribute by prepending `override:` to the class attribute. Example:
|
|
79
77
|
|
|
80
78
|
```html
|
|
81
79
|
<x-button override:class="btn-custom">Submit</x-button>
|
|
@@ -84,41 +82,43 @@ By default `class` and `style` attributes are merged, while all others attribute
|
|
|
84
82
|
<button type="button" class="btn-custom">Submit</button>
|
|
85
83
|
```
|
|
86
84
|
|
|
87
|
-
All attributes you pass to the component will be added to the first
|
|
88
|
-
|
|
89
|
-
Second you may notice a `<yield>` tag.
|
|
90
|
-
|
|
91
|
-
This is where your content will be injected.
|
|
85
|
+
All attributes you pass to the component will be added to the first node of your component or to the node with an attribute names `attributes`,
|
|
86
|
+
and only if they are not defined as `props` via `<script props>`. More details on this in [Attributes](#attributes) section.
|
|
92
87
|
|
|
93
|
-
|
|
88
|
+
The `<yield>` tag is where your content will be injected.
|
|
89
|
+
In next section you can find all available options and then examples for each features.
|
|
94
90
|
|
|
95
|
-
See also the `
|
|
91
|
+
See also the `docs-src` folder where you can find more examples. You can run `npm run build` to compile them.
|
|
96
92
|
|
|
97
93
|
## Options
|
|
98
94
|
|
|
99
|
-
|
|
|
100
|
-
|
|
101
|
-
|
|
|
102
|
-
|
|
|
103
|
-
|
|
|
104
|
-
|
|
|
105
|
-
|
|
|
106
|
-
|
|
|
107
|
-
|
|
|
108
|
-
|
|
|
109
|
-
|
|
|
110
|
-
|
|
|
111
|
-
|
|
|
112
|
-
|
|
|
113
|
-
|
|
|
114
|
-
|
|
|
115
|
-
|
|
|
116
|
-
|
|
|
117
|
-
|
|
|
118
|
-
| **
|
|
119
|
-
|
|
|
120
|
-
| **
|
|
121
|
-
|
|
|
95
|
+
| Option | Default | Description |
|
|
96
|
+
|:------------------------:|:--------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------|
|
|
97
|
+
| **root** | `'./'` | String value as root path for components lookup. |
|
|
98
|
+
| **folders** | `['']` | Array of additional multi folders path from `options.root` or any defined namespaces root, fallback or custom. |
|
|
99
|
+
| **tagPrefix** | `x-` | String for tag prefix. The plugin will use RegExp with this string. |
|
|
100
|
+
| **tag** | `false` | String or boolean value for component tag. Use this with `options.attribute`. Boolean only false. |
|
|
101
|
+
| **attribute** | `src` | String value for component attribute for set path. |
|
|
102
|
+
| **namespaces** | `[]` | Array of namespace's root path, fallback path and custom path for override. |
|
|
103
|
+
| **namespaceSeparator** | `::` | String value for namespace separator to be used with tag name. Example `<x-namespace::button>` |
|
|
104
|
+
| **fileExtension** | `html` | String value for file extension of the components used for retrieve x-tag file. |
|
|
105
|
+
| **yield** | `yield` | String value for `<yield>` tag name. Where main content of component is injected. |
|
|
106
|
+
| **slot** | `slot` | String value for `<slot>` tag name. Used with RegExp by appending `:` (example `<slot:slot-name>`). |
|
|
107
|
+
| **fill** | `fill` | String value for `<fill>` tag name. Used with RegExp by appending `:` (example `<fill:slot-name>`). |
|
|
108
|
+
| **slotSeparator** | `:` | String value used for separate `<slot>` and `<fill>` tag from their names. |
|
|
109
|
+
| **push** | `push` | String value for `<push>` tag name. |
|
|
110
|
+
| **stack** | `stack` | String value for `<stack>` tag name. |
|
|
111
|
+
| **propsScriptAttribute** | `props` | String value used as attribute in `<script props>` parsed by the plugin to retrieve props of the component. |
|
|
112
|
+
| **propsContext** | `props` | String value used as object name inside the script to process process before passed to the component. |
|
|
113
|
+
| **propsAttribute** | `props` | String value for props attribute to define props as JSON. |
|
|
114
|
+
| **propsSlot** | `props` | String value used to retrieve the props passed to slot via `$slots.slotName.props`. |
|
|
115
|
+
| **expressions** | `{}` | Object to configure `posthtml-expressions`. You can pre-set locals or customize the delimiters for example. |
|
|
116
|
+
| **plugins** | `[]` | PostHTML plugins to apply for every parsed components. |
|
|
117
|
+
| **matcher** | `[{tag: options.tagPrefix}]` | Array of object used to match the tags. |
|
|
118
|
+
| **attrsParserRules** | `{}` | Additional rules for attributes parser plugin. |
|
|
119
|
+
| **strict** | `true` | Boolean value for enable or disable throw an exception. |
|
|
120
|
+
| **mergeCustomizer** | `function` | Function callback passed to lodash `mergeWith` for merge `options.expressions.locals` and props passed via attribute `props`. |
|
|
121
|
+
| **utilities** | `{merge: _.mergeWith, template: _.template}` | Object of utilities methods to be passed to `<script props>`. By default lodash `mergeWith` and `template`. |
|
|
122
122
|
|
|
123
123
|
## Features
|
|
124
124
|
|
|
@@ -515,7 +515,7 @@ Create the component:
|
|
|
515
515
|
<!-- src/my-component.html -->
|
|
516
516
|
<script props>
|
|
517
517
|
module.exports = {
|
|
518
|
-
prop:
|
|
518
|
+
prop: props.prop || 'Default prop value'
|
|
519
519
|
}
|
|
520
520
|
</script>
|
|
521
521
|
<div>
|
|
@@ -556,7 +556,7 @@ The output will be:
|
|
|
556
556
|
If you don't add the props in `<script props>` inside your component, all props will be added as attributes to the first node of your component or to the node with attribute `attributes`.
|
|
557
557
|
More details on this in the next section.
|
|
558
558
|
|
|
559
|
-
So in the `<script props>` you have access to passed props via object `
|
|
559
|
+
So in the `<script props>` you have access to passed props via object `props`, and you can add any logic you need inside it.
|
|
560
560
|
|
|
561
561
|
Create the component:
|
|
562
562
|
|
|
@@ -564,9 +564,9 @@ Create the component:
|
|
|
564
564
|
<!-- src/modal.html -->
|
|
565
565
|
<script props>
|
|
566
566
|
module.exports = {
|
|
567
|
-
title:
|
|
568
|
-
size:
|
|
569
|
-
items: Array.isArray(
|
|
567
|
+
title: props.title || 'Default title',
|
|
568
|
+
size: props.size ? `modal-${props.size}` : '',
|
|
569
|
+
items: Array.isArray(props.items) ? props.items.concat(['first', 'second']) : ['first', 'second']
|
|
570
570
|
}
|
|
571
571
|
</script>
|
|
572
572
|
<div class="modal {{ size }}">
|
|
@@ -603,7 +603,7 @@ The output will be:
|
|
|
603
603
|
|
|
604
604
|
You can also notice how the `class` attribute is merged with `class` attribute of the first node. Let's see in next section more about this.
|
|
605
605
|
|
|
606
|
-
You can change how attributes are merged with global
|
|
606
|
+
You can change how attributes are merged with global props defined via options by passing a callback function used by lodash method [mergeWith](https://lodash.com/docs/4.17.15#mergeWith).
|
|
607
607
|
|
|
608
608
|
By default, all props are scoped to the component, and are not available to nested components. You can however change this accordingly to your need.
|
|
609
609
|
Let's see below example.
|
|
@@ -614,7 +614,7 @@ Create a component:
|
|
|
614
614
|
<!-- src/child.html -->
|
|
615
615
|
<script props>
|
|
616
616
|
module.exports = {
|
|
617
|
-
prop:
|
|
617
|
+
prop: props.prop || 'Default prop value'
|
|
618
618
|
}
|
|
619
619
|
</script>
|
|
620
620
|
<div>
|
|
@@ -629,7 +629,7 @@ Create another component that use the first one:
|
|
|
629
629
|
<!-- src/parent.html -->
|
|
630
630
|
<script props>
|
|
631
631
|
module.exports = {
|
|
632
|
-
prop:
|
|
632
|
+
prop: props.prop || 'Default prop value'
|
|
633
633
|
}
|
|
634
634
|
</script>
|
|
635
635
|
<div>
|
|
@@ -686,7 +686,7 @@ As already seen in basic example:
|
|
|
686
686
|
<!-- src/button.html -->
|
|
687
687
|
<script props>
|
|
688
688
|
module.exports = {
|
|
689
|
-
label:
|
|
689
|
+
label: props.label || 'A button'
|
|
690
690
|
}
|
|
691
691
|
</script>
|
|
692
692
|
<button type="button" class="btn">
|
|
@@ -760,7 +760,7 @@ You can add custom rules how attributes are parsed, as behind the scene it's use
|
|
|
760
760
|
## Examples
|
|
761
761
|
|
|
762
762
|
You can work with `<slot>` and `<fill>` or you can create component for each "block" of your component, and you can also support both of them.
|
|
763
|
-
You can find an example of this inside `
|
|
763
|
+
You can find an example of this inside `docs-src/components/modal`. Below is a short explanation about the both approach.
|
|
764
764
|
|
|
765
765
|
### Using slots
|
|
766
766
|
|
|
@@ -919,7 +919,7 @@ You can also combine both way, and then use them with slots or with small compon
|
|
|
919
919
|
</x-modal.body>
|
|
920
920
|
</if>
|
|
921
921
|
<if condition="$slots.footer?.filled">
|
|
922
|
-
<x-modal.footer close="{{ $slots.footer?.
|
|
922
|
+
<x-modal.footer close="{{ $slots.footer?.props.close }}">
|
|
923
923
|
<slot:footer></slot:footer>
|
|
924
924
|
</x-modal.footer>
|
|
925
925
|
</if>
|
package/src/index.js
CHANGED
|
@@ -6,10 +6,12 @@ const {parser} = require('posthtml-parser');
|
|
|
6
6
|
const {match} = require('posthtml/lib/api');
|
|
7
7
|
const expressions = require('posthtml-expressions');
|
|
8
8
|
const findPathFromTag = require('./find-path');
|
|
9
|
-
const
|
|
10
|
-
const processAttributes = require('./attributes');
|
|
11
|
-
const {processPushes, processStacks} = require('./stacks');
|
|
12
|
-
const {setFilledSlots, processSlotContent, processFillContent} = require('./slots');
|
|
9
|
+
const processProps = require('./process-props');
|
|
10
|
+
const processAttributes = require('./process-attributes');
|
|
11
|
+
const {processPushes, processStacks} = require('./process-stacks');
|
|
12
|
+
const {setFilledSlots, processSlotContent, processFillContent} = require('./process-slots');
|
|
13
|
+
const mergeWith = require('lodash/mergeWith');
|
|
14
|
+
const template = require('lodash/template');
|
|
13
15
|
|
|
14
16
|
// const {inspect} = require('util');
|
|
15
17
|
// const debug = true;
|
|
@@ -35,14 +37,18 @@ module.exports = (options = {}) => tree => {
|
|
|
35
37
|
options.slotSeparator = options.slotSeparator || ':';
|
|
36
38
|
options.push = options.push || 'push';
|
|
37
39
|
options.stack = options.stack || 'stack';
|
|
38
|
-
options.
|
|
40
|
+
options.propsScriptAttribute = options.propsScriptAttribute || 'props';
|
|
41
|
+
options.propsContext = options.propsContext || 'props';
|
|
42
|
+
options.propsAttribute = options.propsAttribute || 'props';
|
|
43
|
+
options.propsSlot = options.propsSlot || 'props';
|
|
39
44
|
options.expressions = options.expressions || {};
|
|
40
45
|
options.plugins = options.plugins || [];
|
|
41
46
|
options.attrsParserRules = options.attrsParserRules || {};
|
|
42
47
|
options.strict = typeof options.strict === 'undefined' ? true : options.strict;
|
|
48
|
+
options.utilities = options.utilities || {merge: mergeWith, template};
|
|
43
49
|
|
|
44
50
|
// Merge customizer callback passed to lodash mergeWith
|
|
45
|
-
// for merge attribute `
|
|
51
|
+
// for merge attribute `props` and all attributes starting with `merge:`
|
|
46
52
|
// @see https://lodash.com/docs/4.17.15#mergeWith
|
|
47
53
|
options.mergeCustomizer = options.mergeCustomizer || ((objectValue, sourceValue) => {
|
|
48
54
|
if (Array.isArray(objectValue)) {
|
|
@@ -86,7 +92,7 @@ module.exports = (options = {}) => tree => {
|
|
|
86
92
|
}
|
|
87
93
|
});
|
|
88
94
|
|
|
89
|
-
options.
|
|
95
|
+
options.props = {...options.expressions.locals};
|
|
90
96
|
options.aware = {};
|
|
91
97
|
|
|
92
98
|
const pushedContent = {};
|
|
@@ -140,10 +146,10 @@ function processTree(options) {
|
|
|
140
146
|
setFilledSlots(currentNode, filledSlots, options);
|
|
141
147
|
// setFilledSlots(nextNode, filledSlots, options);
|
|
142
148
|
|
|
143
|
-
// Reset
|
|
144
|
-
options.expressions.locals = {...options.
|
|
149
|
+
// Reset options.expressions.locals and keep aware locals
|
|
150
|
+
options.expressions.locals = {...options.props, ...options.aware};
|
|
145
151
|
|
|
146
|
-
const {attributes,
|
|
152
|
+
const {attributes, props} = processProps(currentNode, nextNode, filledSlots, options, componentPath);
|
|
147
153
|
|
|
148
154
|
options.expressions.locals = attributes;
|
|
149
155
|
options.expressions.locals.$slots = filledSlots;
|
|
@@ -172,11 +178,11 @@ function processTree(options) {
|
|
|
172
178
|
currentNode.tag = false;
|
|
173
179
|
currentNode.content = content;
|
|
174
180
|
|
|
175
|
-
processAttributes(currentNode, attributes,
|
|
181
|
+
processAttributes(currentNode, attributes, props, options);
|
|
176
182
|
|
|
177
183
|
// log(currentNode, 'currentNode', 'currentNode')
|
|
178
184
|
// currentNode.attrs.counter = processCounter;
|
|
179
|
-
// currentNode.attrs.data = JSON.stringify({ attributes,
|
|
185
|
+
// currentNode.attrs.data = JSON.stringify({ attributes, props });
|
|
180
186
|
|
|
181
187
|
// messages.push({
|
|
182
188
|
// type: 'dependency',
|
|
@@ -11,15 +11,15 @@ const has = require('lodash/has');
|
|
|
11
11
|
const extend = require('lodash/extend');
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* Map component attributes that it's not defined as
|
|
14
|
+
* Map component attributes that it's not defined as props to first element of node
|
|
15
15
|
*
|
|
16
16
|
* @param {Object} currentNode
|
|
17
17
|
* @param {Object} attributes
|
|
18
|
-
* @param {Object}
|
|
18
|
+
* @param {Object} props
|
|
19
19
|
* @param {Object} options
|
|
20
20
|
* @return {void}
|
|
21
21
|
*/
|
|
22
|
-
module.exports = (currentNode, attributes,
|
|
22
|
+
module.exports = (currentNode, attributes, props, options) => {
|
|
23
23
|
let mainNode;
|
|
24
24
|
match.call(currentNode, {attrs: {attributes: ''}}, node => {
|
|
25
25
|
delete node.attrs.attributes;
|
|
@@ -40,7 +40,7 @@ module.exports = (currentNode, attributes, locals, options) => {
|
|
|
40
40
|
|
|
41
41
|
const nodeAttrs = parseAttrs(mainNode.attrs, options.attrsParserRules);
|
|
42
42
|
|
|
43
|
-
const mainNodeAttributes = omit(attributes, union(keys(
|
|
43
|
+
const mainNodeAttributes = omit(attributes, union(keys(props), [options.attribute], keys(options.aware), keys(options.props), ['$slots']));
|
|
44
44
|
|
|
45
45
|
each(mainNodeAttributes, (value, key) => {
|
|
46
46
|
if (['class', 'style'].includes(key)) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const processScript = require('./process-script');
|
|
4
4
|
const pick = require('lodash/pick');
|
|
5
5
|
const each = require('lodash/each');
|
|
6
6
|
const assign = require('lodash/assign');
|
|
@@ -9,15 +9,16 @@ const mergeWith = require('lodash/mergeWith');
|
|
|
9
9
|
const attributeTypes = ['aware', 'merge'];
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* Parse
|
|
12
|
+
* Parse props from attributes, globals and via script
|
|
13
13
|
*
|
|
14
14
|
* @param {Object} currentNode - PostHTML tree
|
|
15
15
|
* @param {Array} nextNode - PostHTML tree
|
|
16
|
-
* @param {Object} filledSlots -
|
|
16
|
+
* @param {Object} filledSlots - Filled slots
|
|
17
17
|
* @param {Object} options - Plugin options
|
|
18
|
-
* @
|
|
18
|
+
* @param {string} componentPath - Component path
|
|
19
|
+
* @return {Object} - Attribute props and script props
|
|
19
20
|
*/
|
|
20
|
-
module.exports = (currentNode, nextNode, filledSlots, options) => {
|
|
21
|
+
module.exports = (currentNode, nextNode, filledSlots, options, componentPath) => {
|
|
21
22
|
let attributes = {...currentNode.attrs};
|
|
22
23
|
|
|
23
24
|
const attributesByTypeName = {};
|
|
@@ -47,26 +48,26 @@ module.exports = (currentNode, nextNode, filledSlots, options) => {
|
|
|
47
48
|
} catch {}
|
|
48
49
|
});
|
|
49
50
|
|
|
50
|
-
// Merge or extend attribute
|
|
51
|
-
if (attributes.
|
|
52
|
-
if (attributesByTypeName.merge.includes(
|
|
53
|
-
attributesByTypeName.merge.splice(attributesByTypeName.merge.indexOf(
|
|
54
|
-
mergeWith(attributes, attributes.
|
|
51
|
+
// Merge or extend attribute props
|
|
52
|
+
if (attributes[options.propsAttribute]) {
|
|
53
|
+
if (attributesByTypeName.merge.includes(options.propsAttribute)) {
|
|
54
|
+
attributesByTypeName.merge.splice(attributesByTypeName.merge.indexOf(options.propsAttribute), 1);
|
|
55
|
+
mergeWith(attributes, attributes[options.propsAttribute], options.mergeCustomizer);
|
|
55
56
|
} else {
|
|
56
|
-
assign(attributes, attributes.
|
|
57
|
+
assign(attributes, attributes[options.propsAttribute]);
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
delete attributes.
|
|
60
|
+
delete attributes[options.propsAttribute];
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
// Merge with global
|
|
63
64
|
attributes = mergeWith({}, options.expressions.locals, attributes, options.mergeCustomizer);
|
|
64
65
|
|
|
65
|
-
//
|
|
66
|
-
const {
|
|
66
|
+
// Process props from <script props>
|
|
67
|
+
const {props} = processScript(nextNode, {props: {...attributes}, $slots: filledSlots, propsScriptAttribute: options.propsScriptAttribute, propsContext: options.propsContext, utilities: options.utilities}, componentPath.replace(`.${options.fileExtension}`, '.js'));
|
|
67
68
|
|
|
68
|
-
if (
|
|
69
|
-
assign(attributes,
|
|
69
|
+
if (props) {
|
|
70
|
+
assign(attributes, props);
|
|
70
71
|
// if (attributesByTypeName.merge.length > 0) {
|
|
71
72
|
// assign(attributes, mergeWith(pick(locals, attributesByTypeName.merge), pick(attributes, attributesByTypeName.merge), options.mergeCustomizer));
|
|
72
73
|
// }
|
|
@@ -77,5 +78,5 @@ module.exports = (currentNode, nextNode, filledSlots, options) => {
|
|
|
77
78
|
options.aware = pick(attributes, attributesByTypeName.aware);
|
|
78
79
|
}
|
|
79
80
|
|
|
80
|
-
return {attributes,
|
|
81
|
+
return {attributes, props};
|
|
81
82
|
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const vm = require('vm');
|
|
4
|
+
const {existsSync, readFileSync} = require('fs');
|
|
5
|
+
const {render} = require('posthtml-render');
|
|
6
|
+
const {match} = require('posthtml/lib/api');
|
|
7
|
+
|
|
8
|
+
const ctx = vm.createContext({module, require});
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Get the script tag with props from a node list and return process props.
|
|
12
|
+
* Custom posthtml-expressions/lib/locals.
|
|
13
|
+
*
|
|
14
|
+
* @param {Array} tree Nodes
|
|
15
|
+
* @param {Object} options Options
|
|
16
|
+
* @param {string} scriptPath - Component path
|
|
17
|
+
* @return {Object} {} Locals
|
|
18
|
+
*/
|
|
19
|
+
module.exports = (tree, options, scriptPath) => {
|
|
20
|
+
const props = {};
|
|
21
|
+
const propsContext = options.props;
|
|
22
|
+
const utilities = {...options.utilities};
|
|
23
|
+
const context = {...utilities, ...ctx, [options.propsContext]: propsContext, $slots: options.$slots};
|
|
24
|
+
|
|
25
|
+
const runInContext = code => {
|
|
26
|
+
try {
|
|
27
|
+
const parsedContext = vm.createContext(context);
|
|
28
|
+
const parsedProps = vm.runInContext(code, parsedContext);
|
|
29
|
+
|
|
30
|
+
Object.assign(props, parsedProps);
|
|
31
|
+
} catch {}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
if (existsSync(scriptPath)) {
|
|
35
|
+
runInContext(readFileSync(scriptPath, 'utf8'));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
match.call(tree, {tag: 'script', attrs: {[options.propsScriptAttribute]: ''}}, node => {
|
|
39
|
+
if (node.content) {
|
|
40
|
+
runInContext(render(node.content));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return '';
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
props
|
|
48
|
+
};
|
|
49
|
+
};
|
|
@@ -14,7 +14,7 @@ const omit = require('lodash/omit');
|
|
|
14
14
|
* @param {String} slotSeparator Slot separator
|
|
15
15
|
* @return {void}
|
|
16
16
|
*/
|
|
17
|
-
function setFilledSlots(currentNode, filledSlots, {fill, slotSeparator}) {
|
|
17
|
+
function setFilledSlots(currentNode, filledSlots, {fill, slotSeparator, propsSlot}) {
|
|
18
18
|
match.call(currentNode, {tag: fill}, fillNode => {
|
|
19
19
|
if (!fillNode.attrs) {
|
|
20
20
|
fillNode.attrs = {};
|
|
@@ -22,10 +22,10 @@ function setFilledSlots(currentNode, filledSlots, {fill, slotSeparator}) {
|
|
|
22
22
|
|
|
23
23
|
const name = fillNode.tag.split(slotSeparator)[1];
|
|
24
24
|
|
|
25
|
-
const
|
|
25
|
+
const props = omit(fillNode.attrs, ['append', 'prepend', 'aware']);
|
|
26
26
|
|
|
27
|
-
if (
|
|
28
|
-
each(
|
|
27
|
+
if (props) {
|
|
28
|
+
each(props, (value, key, attrs) => {
|
|
29
29
|
try {
|
|
30
30
|
attrs[key] = JSON.parse(value);
|
|
31
31
|
} catch {}
|
|
@@ -39,7 +39,7 @@ function setFilledSlots(currentNode, filledSlots, {fill, slotSeparator}) {
|
|
|
39
39
|
attrs: fillNode.attrs,
|
|
40
40
|
content: fillNode.content,
|
|
41
41
|
source: render(fillNode.content),
|
|
42
|
-
|
|
42
|
+
[propsSlot]: props
|
|
43
43
|
};
|
|
44
44
|
|
|
45
45
|
return fillNode;
|
|
File without changes
|