flex-html-render 1.1.0 → 1.1.2
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 +36 -6
- package/dist/flex-html-render.cjs.js +6 -6
- package/dist/flex-html-render.es.js +143 -124
- package/dist/flex-html-render.umd.js +5 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -34,8 +34,17 @@ const htmlString = `
|
|
|
34
34
|
|
|
35
35
|
const flexMessage = convertHtmlToFlexMessage(htmlString);
|
|
36
36
|
console.log(JSON.stringify(flexMessage, null, 2));
|
|
37
|
+
|
|
38
|
+
// 將產生的 JSON 放入 LINE Messaging API 的訊息結構中
|
|
39
|
+
const message = {
|
|
40
|
+
type: 'flex',
|
|
41
|
+
altText: 'Flex Message',
|
|
42
|
+
contents: flexMessage[0] // 因為 convertHtmlToFlexMessage 回傳陣列,取第一個元素
|
|
43
|
+
};
|
|
37
44
|
```
|
|
38
45
|
|
|
46
|
+
**注意**:此套件產生的 JSON 物件應放置在 LINE Messaging API 中 `type` 為 `flex` 的訊息物件的 `contents` 區塊內。詳細請參考 [LINE Flex Message 官方文件](https://developers.line.biz/en/reference/messaging-api/#flex-message)。
|
|
47
|
+
|
|
39
48
|
## API
|
|
40
49
|
|
|
41
50
|
### `convertHtmlToFlexMessage(htmlString)`
|
|
@@ -98,6 +107,7 @@ console.log(JSON.stringify(flexMessage, null, 2));
|
|
|
98
107
|
### 特殊功能標籤
|
|
99
108
|
- `<action>` - 動作設定標籤,必須放在需要添加動作的元件內(如 `<button>`、`<box>`、`<image>` 等)
|
|
100
109
|
- `<background>` - 背景設定標籤,只能放在 Box 相關標籤內(`<box>`、`<baseline>`、`<row>`、`<vertical>`)
|
|
110
|
+
- `<style>` - 樣式設定標籤,只能放在 top-level 區塊標籤內(`<header>`、`<hero>`、`<body>`、`<footer>`)
|
|
101
111
|
|
|
102
112
|
## 特殊標籤使用規則
|
|
103
113
|
|
|
@@ -171,7 +181,26 @@ console.log(JSON.stringify(flexMessage, null, 2));
|
|
|
171
181
|
</text>
|
|
172
182
|
```
|
|
173
183
|
|
|
174
|
-
### 4. `<
|
|
184
|
+
### 4. `<style>` 使用規則
|
|
185
|
+
`<style>` 標籤只能放在 top-level 區塊標籤內(`<header>`、`<hero>`、`<body>`、`<footer>`),用於設定該區塊的樣式屬性,如背景色等。各區塊標籤只能有一個 `<style>` 子元素。最終會整合為一個 styles 屬性到 bubble 的 JSON 結構中。
|
|
186
|
+
|
|
187
|
+
```xml
|
|
188
|
+
<!-- ✅ 正確 - 在 header 內使用 -->
|
|
189
|
+
<header>
|
|
190
|
+
<style backgroundColor="#ff0000" />
|
|
191
|
+
<box layout="vertical">
|
|
192
|
+
<text>有背景色的標題</text>
|
|
193
|
+
</box>
|
|
194
|
+
</header>
|
|
195
|
+
|
|
196
|
+
<!-- ❌ 錯誤 - 不能在 box 內使用 -->
|
|
197
|
+
<box layout="vertical">
|
|
198
|
+
<style backgroundColor="#ff0000" />
|
|
199
|
+
<text>文字</text>
|
|
200
|
+
</box>
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### 5. `<strong>` 使用方式
|
|
175
204
|
`<strong>` 標籤會自動轉換為 `<text weight="bold">`,用於顯示粗體文字。
|
|
176
205
|
|
|
177
206
|
```html
|
|
@@ -181,7 +210,7 @@ console.log(JSON.stringify(flexMessage, null, 2));
|
|
|
181
210
|
</box>
|
|
182
211
|
```
|
|
183
212
|
|
|
184
|
-
###
|
|
213
|
+
### 6. `<space>` 使用方式
|
|
185
214
|
`<space>` 標籤用於在文字中插入空格,可透過 `size` 屬性指定空格數量。
|
|
186
215
|
|
|
187
216
|
```html
|
|
@@ -192,7 +221,7 @@ console.log(JSON.stringify(flexMessage, null, 2));
|
|
|
192
221
|
</text>
|
|
193
222
|
```
|
|
194
223
|
|
|
195
|
-
###
|
|
224
|
+
### 7. 便捷 Box 標籤(`<baseline>`、`<row>`、`<vertical>`)
|
|
196
225
|
這些標籤是 `<box>` 的簡寫形式,省去了 `layout` 屬性的設定。
|
|
197
226
|
|
|
198
227
|
```html
|
|
@@ -215,7 +244,7 @@ console.log(JSON.stringify(flexMessage, null, 2));
|
|
|
215
244
|
</vertical>
|
|
216
245
|
```
|
|
217
246
|
|
|
218
|
-
###
|
|
247
|
+
### 8. `<carousel>` 使用規則
|
|
219
248
|
`<carousel>` 只能包含 `<bubble>` 子元素,且最多 12 個。
|
|
220
249
|
|
|
221
250
|
```html
|
|
@@ -237,7 +266,7 @@ console.log(JSON.stringify(flexMessage, null, 2));
|
|
|
237
266
|
</carousel>
|
|
238
267
|
```
|
|
239
268
|
|
|
240
|
-
###
|
|
269
|
+
### 9. `<video>` 使用規則
|
|
241
270
|
`<video>` 必須包含一個 `<box>` 或 `<image>` 作為 altContent(影片無法播放時的替代內容)。
|
|
242
271
|
|
|
243
272
|
```html
|
|
@@ -248,9 +277,10 @@ console.log(JSON.stringify(flexMessage, null, 2));
|
|
|
248
277
|
|
|
249
278
|
## 完整範例
|
|
250
279
|
|
|
251
|
-
```
|
|
280
|
+
```xml
|
|
252
281
|
<bubble>
|
|
253
282
|
<header>
|
|
283
|
+
<style backgroundColor="#f0f0f0" />
|
|
254
284
|
<vertical>
|
|
255
285
|
<background type="linearGradient" angle="90deg" startColor="#667eea" endColor="#764ba2" />
|
|
256
286
|
<strong>商品資訊</strong>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const
|
|
2
|
-
`).map(
|
|
3
|
-
`):
|
|
4
|
-
`);return` <${t}${
|
|
5
|
-
${
|
|
6
|
-
</${t}>`}},createText:t=>t};function
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const _=require("htmlparser2"),E={ELEMENT:"element",TEXT:"text"},e={CAROUSEL:"carousel",BUBBLE:"bubble",HEADER:"header",HERO:"hero",BODY:"body",FOOTER:"footer",BOX:"box",TEXT:"text",SPAN:"span",IMAGE:"image",VIDEO:"video",ICON:"icon",SEPARATOR:"separator",BUTTON:"button",FILLER:"filler",SPACE:"space",STRONG:"strong",BASELINE:"baseline",ROW:"row",VERTICAL:"vertical",DIV:"div",ARTICLE:"article",ACTION:"action",BACKGROUND:"background",STYLE:"style"},D=[e.HEADER,e.HERO,e.BODY,e.FOOTER],Q=[e.BOX,e.VERTICAL,e.ROW,e.BASELINE,e.DIV,e.ARTICLE],Z=[e.TEXT,e.STRONG];function tt(t){const r=Number(t);return isNaN(r)?t:r}function et(t){return t==="true"?!0:t==="false"?!1:t}function rt(t){return[tt,et].reduce((n,c)=>c(n),t)}function at(t){const r={type:"root",children:[]},n=[r],c=new _.Parser({onopentag(o,a){const i={type:E.ELEMENT,tagName:o,attributes:Object.fromEntries(Object.entries(a).map(([s,b])=>[s,rt(b)])),children:[]};n[n.length-1].children.push(i),n.push(i)},ontext(o){const a=n[n.length-1];if(a.tagName==="span"){a.children.push({type:E.TEXT,content:o});return}o.trim()&&a.children.push({type:E.TEXT,content:o.replace(/\n/g,"").trim()})},onclosetag(){n.pop()},onerror(o){console.error("解析錯誤:",o)}},{xmlMode:!0,lowerCaseTags:!1,lowerCaseAttributeNames:!1});return c.write(t),c.end(),r.children}const h=t=>{throw Error(`[Flex Html Render]: ${t}`)},l={carousel:t=>({type:"carousel",contents:t}),bubble:(t={})=>({type:"bubble",...t}),box:(t,r={})=>({type:"box",contents:t,...r}),text:(t,r={})=>({type:"text",...typeof t=="string"?{text:t}:{contents:t},...r}),span:(t,r={})=>({type:"span",text:t,...r}),image:(t={})=>({type:"image",...t}),video:(t={})=>({type:"video",...t}),icon:(t={})=>({type:"icon",...t}),button:(t={})=>({type:"button",...t}),separator:(t={color:"#E0E3EA"})=>({type:"separator",...t}),filler:(t={})=>({type:"filler",...t}),uri:(t={})=>({type:"uri",altUri:t.altUri?{desktop:t.altUri}:void 0,...t}),postback:(t={})=>({type:"postback",...t}),message:(t={})=>({type:"message",...t}),datetimepicker:(t={})=>({type:"datetimepicker",...t}),camera:(t={})=>({type:"camera",...t}),cameraRoll:(t={})=>({type:"cameraRoll",...t}),location:(t={})=>({type:"location",...t}),richmenuswitch:(t={})=>({type:"richmenuswitch",...t}),clipboard:(t={})=>({type:"clipboard",...t})};function nt(t){if(t.tagName!==e.BACKGROUND&&t.children&&t.children.length>0){const r=t.children.filter(n=>n.tagName===e.BACKGROUND);return r.length>1&&h("A box node can only allowed with one background node inside"),t.children=t.children.filter(n=>n.tagName!==e.BACKGROUND),r[0]}return null}function it(t){if(t.tagName!==e.ACTION&&t.children&&t.children.length>0){const r=t.children.filter(n=>n.tagName===e.ACTION);return r.length>1&&h("A node can only allowed with one action node inside"),t.children=t.children.filter(n=>n.tagName!==e.ACTION),r[0]}return null}function ct(t){![...Z,e.SPAN].includes(t.tagName)&&t.children?.some(a=>a.type===E.TEXT)&&h("Span component only allowed inside Text component"),t.tagName===e.VIDEO&&t.children?.some(a=>![e.BOX,e.IMAGE].includes(a.tagName))&&h("Video component only allowed Box or Image as altContent child"),!Q.includes(t.tagName)&&t.children?.some(a=>a.tagName===e.BACKGROUND)&&h("Only Box component allowed to have Background child"),!D.includes(t.tagName)&&t.children?.filter(a=>a.tagName===e.STYLE).length>=1&&h("Only top-level section(header, hero, body, footer) can have Style child")}function O(t){if(t){const r=t.children.find(n=>n.tagName===e.STYLE);if(r)return t.children=t.children.filter(n=>n.tagName!==e.STYLE),r.attributes}}function u(t){t.attributes=t.attributes||{},ct(t);const r=it(t);r&&(t.attributes.action=u(r));const n=nt(t);if(n&&(t.attributes.background=u(n)),t.type===E.TEXT)return l.span(t.content,t.attributes);if(t.tagName===e.BUBBLE){const c=t.children.find(s=>s.tagName===e.HEADER),o=t.children.find(s=>s.tagName===e.HERO),a=t.children.find(s=>s.tagName===e.BODY),i=t.children.find(s=>s.tagName===e.FOOTER),p={header:O(c),hero:O(o),body:O(a),footer:O(i)};return l.bubble({...t.attributes,header:c?u(c):void 0,hero:o?u(o):void 0,body:a?u(a):void 0,footer:i?u(i):void 0,styles:Object.values(p).some(s=>s!==void 0)?p:void 0})}if(t.tagName===e.CAROUSEL)return t.children.some(c=>c.tagName!==e.BUBBLE)&&h("Carousel can only have Bubble as children"),t.children.length>12&&h("Carousel can have maximum 12 bubbles"),l.carousel(t.children.map(u));if(D.includes(t.tagName))return t.children.length!==1&&h(`${t.tagName} should have exactly one child node`),u(t.children[0]);if(t.tagName===e.BUTTON)return t.attributes.action||h("Button component should contain an action node"),l.button(t.attributes);if(t.tagName===e.SPAN){t.children.length>1&&h("Span component can only have one text child");const c=t.children[0];if(c&&c.type===E.TEXT)return l.span(c.content,t.attributes);h(c?"Span component only allowed text child":"Span component can not be empty")}if(t.tagName===e.TEXT)return l.text(t.children.map(u),t.attributes);if(t.tagName===e.SEPARATOR)return l.separator(t.attributes);if(t.tagName===e.IMAGE)return l.image(t.attributes);if(t.tagName===e.VIDEO)return t.children.length!==1&&h("Video component should only has one Box or Image as altContent"),t.attributes.altContent=u(t.children[0]),l.video(t.attributes);if(t.tagName===e.ICON)return l.icon(t.attributes);if(t.tagName===e.FILLER)return l.filler(t.attributes);if(t.tagName===e.BOX||t.tagName===e.DIV||t.tagName===e.ARTICLE)return t.attributes.layout||(t.attributes.layout="vertical"),l.box(t.children.map(u),t.attributes);if(t.tagName===e.SPACE)return l.span(" ".repeat(t.attributes.size||1));if(t.tagName===e.STRONG)return t.tagName=e.TEXT,t.attributes.weight="bold",u(t);if(t.tagName===e.BASELINE)return t.tagName=e.BOX,t.attributes.layout="baseline",u(t);if(t.tagName===e.ROW)return t.tagName=e.BOX,t.attributes.layout="horizontal",u(t);if(t.tagName===e.VERTICAL)return t.tagName=e.BOX,t.attributes.layout="vertical",u(t);if(t.tagName===e.ACTION){const c=t.attributes.type;switch(c){case"uri":return l.uri(t.attributes);case"postback":return l.postback(t.attributes);case"message":return l.message(t.attributes);case"datetimepicker":return l.datetimepicker(t.attributes);case"camera":return l.camera(t.attributes);case"cameraRoll":return l.cameraRoll(t.attributes);case"location":return l.location(t.attributes);case"richmenuswitch":return l.richmenuswitch(t.attributes);case"clipboard":return l.clipboard(t.attributes);default:h(`Unsupported action type: ${c}`)}}if(t.tagName===e.BACKGROUND)return t.attributes}const m={createElement:(t,r={},n=[],c=0)=>{const a=Object.entries(r).filter(([p,s])=>s!=null).map(([p,s])=>typeof s=="object"?`${p}="${JSON.stringify(s).replace(/"/g,""")}"`:`${p}="${s}"`).join(" "),i=a?` ${a}`:"";if(n.length===0)return` <${t}${i} />`;{const p=n.map(s=>typeof s=="string"?s.split(`
|
|
2
|
+
`).map(b=>b?" "+b:"").join(`
|
|
3
|
+
`):s).join(`
|
|
4
|
+
`);return` <${t}${i}>
|
|
5
|
+
${p}
|
|
6
|
+
</${t}>`}},createText:t=>t},d=(t,r,n,c)=>{const o=[f(r,c+1)];return n&&Object.keys(n).length>0&&o.unshift(f(k("style",n),c+1)),m.createElement(t,{},o,c)},k=(t,r)=>({...r,type:t});function f(t,r=0){if(!t||typeof t!="object")return"";const{type:n,...c}=t,{action:o,...a}=c,i=o?f(o,r+1):"";switch(n){case"carousel":const{contents:p,...s}=a,b=p.map(N=>f(N,r+1));return i&&b.unshift(i),m.createElement(e.CAROUSEL,s,b,r);case"bubble":const{header:R,hero:B,body:S,footer:x,styles:T={},...X}=a,g=[];return i&&g.push(i),R&&g.push(d(e.HEADER,R,T.header,r+1)),B&&g.push(d(e.HERO,B,T.hero,r+1)),S&&g.push(d(e.BODY,S,T.body,r+1)),x&&g.push(d(e.FOOTER,x,T.footer,r+1)),m.createElement(e.BUBBLE,X,g,r);case"box":const{contents:$,background:v,...A}=a;A.layout||(A.layout="vertical");const y=[];return i&&y.push(i),v&&y.push(f(k("background",v),r+1)),y.push(...($||[]).map(N=>f(N,r+1))),m.createElement(e.BOX,A,y,r);case"text":const{text:H,contents:C,...G}=a,I=C&&C.length>0?C.map(N=>f(N,r+1)):[H||""];return i&&I.unshift(i),m.createElement(e.TEXT,G,I,r);case"span":const{text:M,...F}=a,L=[M||""];return i&&L.unshift(i),m.createElement(e.SPAN,F,L,r);case"image":const{...P}=a,V=i?[i]:[];return m.createElement(e.IMAGE,P,V,r);case"video":const{altContent:w,...j}=a,U=w?[f(w,r+1)]:[];return i&&U.unshift(i),m.createElement(e.VIDEO,j,U,r);case"icon":const{...Y}=a,K=i?[i]:[];return m.createElement(e.ICON,Y,K,r);case"button":const{...J}=a,W=i?[i]:[];return m.createElement(e.BUTTON,J,W,r);case"separator":const q=i?[i]:[];return m.createElement(e.SEPARATOR,a,q,r);case"filler":const z=i?[i]:[];return m.createElement(e.FILLER,a,z,r);case"uri":case"message":case"postback":case"datetimepicker":case"camera":case"cameraRoll":case"location":case"richmenuswitch":case"clipboard":return m.createElement(e.ACTION,{type:n,...a},[],r);case"background":return m.createElement(e.BACKGROUND,a,[],r);case"style":return m.createElement(e.STYLE,a,[],r);default:return""}}function st(t){try{return at(t).map(u)}catch(r){throw console.error("Error converting HTML to Flex Message:",r),r}}exports.convertJsonToHtml=f;exports.default=st;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Parser as
|
|
1
|
+
import { Parser as Q } from "htmlparser2";
|
|
2
2
|
const E = {
|
|
3
3
|
ELEMENT: "element",
|
|
4
4
|
TEXT: "text"
|
|
@@ -32,69 +32,70 @@ const E = {
|
|
|
32
32
|
ARTICLE: "article",
|
|
33
33
|
// custom utils tags
|
|
34
34
|
ACTION: "action",
|
|
35
|
-
BACKGROUND: "background"
|
|
36
|
-
|
|
35
|
+
BACKGROUND: "background",
|
|
36
|
+
STYLE: "style"
|
|
37
|
+
}, D = [
|
|
37
38
|
e.HEADER,
|
|
38
39
|
e.HERO,
|
|
39
40
|
e.BODY,
|
|
40
41
|
e.FOOTER
|
|
41
|
-
],
|
|
42
|
+
], Z = [
|
|
42
43
|
e.BOX,
|
|
43
44
|
e.VERTICAL,
|
|
44
45
|
e.ROW,
|
|
45
46
|
e.BASELINE,
|
|
46
47
|
e.DIV,
|
|
47
48
|
e.ARTICLE
|
|
48
|
-
],
|
|
49
|
+
], _ = [
|
|
49
50
|
e.TEXT,
|
|
50
51
|
e.STRONG
|
|
51
52
|
];
|
|
52
|
-
function
|
|
53
|
+
function tt(t) {
|
|
53
54
|
const r = Number(t);
|
|
54
55
|
return isNaN(r) ? t : r;
|
|
55
56
|
}
|
|
56
|
-
function
|
|
57
|
+
function et(t) {
|
|
57
58
|
return t === "true" ? !0 : t === "false" ? !1 : t;
|
|
58
59
|
}
|
|
59
|
-
function
|
|
60
|
+
function rt(t) {
|
|
60
61
|
return [
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
].reduce((n,
|
|
62
|
+
tt,
|
|
63
|
+
et
|
|
64
|
+
].reduce((n, c) => c(n), t);
|
|
64
65
|
}
|
|
65
|
-
function
|
|
66
|
-
const r = { type: "root", children: [] }, n = [r],
|
|
66
|
+
function at(t) {
|
|
67
|
+
const r = { type: "root", children: [] }, n = [r], c = new Q(
|
|
67
68
|
{
|
|
68
|
-
onopentag(
|
|
69
|
-
const
|
|
69
|
+
onopentag(o, a) {
|
|
70
|
+
const i = {
|
|
70
71
|
type: E.ELEMENT,
|
|
71
|
-
tagName:
|
|
72
|
+
tagName: o,
|
|
72
73
|
attributes: Object.fromEntries(
|
|
73
|
-
Object.entries(
|
|
74
|
+
Object.entries(a).map(([s, b]) => [s, rt(b)])
|
|
74
75
|
),
|
|
75
76
|
children: []
|
|
76
77
|
};
|
|
77
|
-
n[n.length - 1].children.push(
|
|
78
|
+
n[n.length - 1].children.push(i), n.push(i);
|
|
78
79
|
},
|
|
79
|
-
ontext(
|
|
80
|
-
const
|
|
81
|
-
if (
|
|
82
|
-
|
|
80
|
+
ontext(o) {
|
|
81
|
+
const a = n[n.length - 1];
|
|
82
|
+
if (a.tagName === "span") {
|
|
83
|
+
a.children.push({
|
|
83
84
|
type: E.TEXT,
|
|
84
|
-
content:
|
|
85
|
+
content: o
|
|
85
86
|
});
|
|
86
87
|
return;
|
|
87
88
|
}
|
|
88
|
-
|
|
89
|
+
o.trim() && a.children.push({
|
|
89
90
|
type: E.TEXT,
|
|
90
|
-
content:
|
|
91
|
+
content: o.replace(/\n/g, "").trim()
|
|
91
92
|
});
|
|
92
93
|
},
|
|
93
94
|
onclosetag() {
|
|
94
95
|
n.pop();
|
|
95
96
|
},
|
|
96
|
-
onerror(
|
|
97
|
-
console.error("解析錯誤:",
|
|
97
|
+
onerror(o) {
|
|
98
|
+
console.error("解析錯誤:", o);
|
|
98
99
|
}
|
|
99
100
|
},
|
|
100
101
|
{
|
|
@@ -105,11 +106,11 @@ function _(t) {
|
|
|
105
106
|
lowerCaseAttributeNames: !1
|
|
106
107
|
}
|
|
107
108
|
);
|
|
108
|
-
return
|
|
109
|
+
return c.write(t), c.end(), r.children;
|
|
109
110
|
}
|
|
110
111
|
const h = (t) => {
|
|
111
112
|
throw Error(`[Flex Html Render]: ${t}`);
|
|
112
|
-
},
|
|
113
|
+
}, l = {
|
|
113
114
|
carousel: (t) => ({
|
|
114
115
|
type: "carousel",
|
|
115
116
|
contents: t
|
|
@@ -199,173 +200,189 @@ const h = (t) => {
|
|
|
199
200
|
...t
|
|
200
201
|
})
|
|
201
202
|
};
|
|
202
|
-
function
|
|
203
|
+
function nt(t) {
|
|
203
204
|
if (t.tagName !== e.BACKGROUND && t.children && t.children.length > 0) {
|
|
204
205
|
const r = t.children.filter((n) => n.tagName === e.BACKGROUND);
|
|
205
206
|
return r.length > 1 && h("A box node can only allowed with one background node inside"), t.children = t.children.filter((n) => n.tagName !== e.BACKGROUND), r[0];
|
|
206
207
|
}
|
|
207
208
|
return null;
|
|
208
209
|
}
|
|
209
|
-
function
|
|
210
|
+
function it(t) {
|
|
210
211
|
if (t.tagName !== e.ACTION && t.children && t.children.length > 0) {
|
|
211
212
|
const r = t.children.filter((n) => n.tagName === e.ACTION);
|
|
212
213
|
return r.length > 1 && h("A node can only allowed with one action node inside"), t.children = t.children.filter((n) => n.tagName !== e.ACTION), r[0];
|
|
213
214
|
}
|
|
214
215
|
return null;
|
|
215
216
|
}
|
|
216
|
-
function
|
|
217
|
-
![...
|
|
217
|
+
function ct(t) {
|
|
218
|
+
![..._, e.SPAN].includes(t.tagName) && t.children?.some((a) => a.type === E.TEXT) && h("Span component only allowed inside Text component"), t.tagName === e.VIDEO && t.children?.some((a) => ![e.BOX, e.IMAGE].includes(a.tagName)) && h("Video component only allowed Box or Image as altContent child"), !Z.includes(t.tagName) && t.children?.some((a) => a.tagName === e.BACKGROUND) && h("Only Box component allowed to have Background child"), !D.includes(t.tagName) && t.children?.filter((a) => a.tagName === e.STYLE).length >= 1 && h("Only top-level section(header, hero, body, footer) can have Style child");
|
|
219
|
+
}
|
|
220
|
+
function O(t) {
|
|
221
|
+
if (t) {
|
|
222
|
+
const r = t.children.find((n) => n.tagName === e.STYLE);
|
|
223
|
+
if (r)
|
|
224
|
+
return t.children = t.children.filter((n) => n.tagName !== e.STYLE), r.attributes;
|
|
225
|
+
}
|
|
218
226
|
}
|
|
219
|
-
function
|
|
220
|
-
t.attributes = t.attributes || {},
|
|
221
|
-
const r =
|
|
222
|
-
r && (t.attributes.action =
|
|
223
|
-
const n =
|
|
224
|
-
if (n && (t.attributes.background =
|
|
225
|
-
return
|
|
227
|
+
function u(t) {
|
|
228
|
+
t.attributes = t.attributes || {}, ct(t);
|
|
229
|
+
const r = it(t);
|
|
230
|
+
r && (t.attributes.action = u(r));
|
|
231
|
+
const n = nt(t);
|
|
232
|
+
if (n && (t.attributes.background = u(n)), t.type === E.TEXT)
|
|
233
|
+
return l.span(t.content, t.attributes);
|
|
226
234
|
if (t.tagName === e.BUBBLE) {
|
|
227
|
-
const
|
|
228
|
-
|
|
235
|
+
const c = t.children.find((s) => s.tagName === e.HEADER), o = t.children.find((s) => s.tagName === e.HERO), a = t.children.find((s) => s.tagName === e.BODY), i = t.children.find((s) => s.tagName === e.FOOTER), p = {
|
|
236
|
+
header: O(c),
|
|
237
|
+
hero: O(o),
|
|
238
|
+
body: O(a),
|
|
239
|
+
footer: O(i)
|
|
240
|
+
};
|
|
241
|
+
return l.bubble({
|
|
229
242
|
...t.attributes,
|
|
230
|
-
header:
|
|
231
|
-
hero:
|
|
232
|
-
body:
|
|
233
|
-
footer:
|
|
243
|
+
header: c ? u(c) : void 0,
|
|
244
|
+
hero: o ? u(o) : void 0,
|
|
245
|
+
body: a ? u(a) : void 0,
|
|
246
|
+
footer: i ? u(i) : void 0,
|
|
247
|
+
styles: Object.values(p).some((s) => s !== void 0) ? p : void 0
|
|
234
248
|
});
|
|
235
249
|
}
|
|
236
250
|
if (t.tagName === e.CAROUSEL)
|
|
237
|
-
return t.children.some((
|
|
238
|
-
t.children.map(
|
|
251
|
+
return t.children.some((c) => c.tagName !== e.BUBBLE) && h("Carousel can only have Bubble as children"), t.children.length > 12 && h("Carousel can have maximum 12 bubbles"), l.carousel(
|
|
252
|
+
t.children.map(u)
|
|
239
253
|
);
|
|
240
|
-
if (
|
|
241
|
-
return t.children.length !== 1 && h(`${t.tagName} should have exactly one child node`),
|
|
254
|
+
if (D.includes(t.tagName))
|
|
255
|
+
return t.children.length !== 1 && h(`${t.tagName} should have exactly one child node`), u(t.children[0]);
|
|
242
256
|
if (t.tagName === e.BUTTON)
|
|
243
|
-
return t.attributes.action || h("Button component should contain an action node"),
|
|
257
|
+
return t.attributes.action || h("Button component should contain an action node"), l.button(t.attributes);
|
|
244
258
|
if (t.tagName === e.SPAN) {
|
|
245
259
|
t.children.length > 1 && h("Span component can only have one text child");
|
|
246
|
-
const
|
|
247
|
-
if (
|
|
248
|
-
return
|
|
249
|
-
|
|
260
|
+
const c = t.children[0];
|
|
261
|
+
if (c && c.type === E.TEXT)
|
|
262
|
+
return l.span(
|
|
263
|
+
c.content,
|
|
250
264
|
t.attributes
|
|
251
265
|
);
|
|
252
|
-
h(
|
|
266
|
+
h(c ? "Span component only allowed text child" : "Span component can not be empty");
|
|
253
267
|
}
|
|
254
268
|
if (t.tagName === e.TEXT)
|
|
255
|
-
return
|
|
256
|
-
t.children.map(
|
|
269
|
+
return l.text(
|
|
270
|
+
t.children.map(u),
|
|
257
271
|
t.attributes
|
|
258
272
|
);
|
|
259
273
|
if (t.tagName === e.SEPARATOR)
|
|
260
|
-
return
|
|
274
|
+
return l.separator(t.attributes);
|
|
261
275
|
if (t.tagName === e.IMAGE)
|
|
262
|
-
return
|
|
276
|
+
return l.image(t.attributes);
|
|
263
277
|
if (t.tagName === e.VIDEO)
|
|
264
|
-
return t.children.length !== 1 && h("Video component should only has one Box or Image as altContent"), t.attributes.altContent =
|
|
278
|
+
return t.children.length !== 1 && h("Video component should only has one Box or Image as altContent"), t.attributes.altContent = u(t.children[0]), l.video(t.attributes);
|
|
265
279
|
if (t.tagName === e.ICON)
|
|
266
|
-
return
|
|
280
|
+
return l.icon(t.attributes);
|
|
267
281
|
if (t.tagName === e.FILLER)
|
|
268
|
-
return
|
|
282
|
+
return l.filler(t.attributes);
|
|
269
283
|
if (t.tagName === e.BOX || t.tagName === e.DIV || t.tagName === e.ARTICLE)
|
|
270
|
-
return t.attributes.layout || (t.attributes.layout = "vertical"),
|
|
271
|
-
t.children.map(
|
|
284
|
+
return t.attributes.layout || (t.attributes.layout = "vertical"), l.box(
|
|
285
|
+
t.children.map(u),
|
|
272
286
|
t.attributes
|
|
273
287
|
);
|
|
274
288
|
if (t.tagName === e.SPACE)
|
|
275
|
-
return
|
|
289
|
+
return l.span(" ".repeat(t.attributes.size || 1));
|
|
276
290
|
if (t.tagName === e.STRONG)
|
|
277
|
-
return t.tagName = e.TEXT, t.attributes.weight = "bold",
|
|
291
|
+
return t.tagName = e.TEXT, t.attributes.weight = "bold", u(t);
|
|
278
292
|
if (t.tagName === e.BASELINE)
|
|
279
|
-
return t.tagName = e.BOX, t.attributes.layout = "baseline",
|
|
293
|
+
return t.tagName = e.BOX, t.attributes.layout = "baseline", u(t);
|
|
280
294
|
if (t.tagName === e.ROW)
|
|
281
|
-
return t.tagName = e.BOX, t.attributes.layout = "horizontal",
|
|
295
|
+
return t.tagName = e.BOX, t.attributes.layout = "horizontal", u(t);
|
|
282
296
|
if (t.tagName === e.VERTICAL)
|
|
283
|
-
return t.tagName = e.BOX, t.attributes.layout = "vertical",
|
|
297
|
+
return t.tagName = e.BOX, t.attributes.layout = "vertical", u(t);
|
|
284
298
|
if (t.tagName === e.ACTION) {
|
|
285
|
-
const
|
|
286
|
-
switch (
|
|
299
|
+
const c = t.attributes.type;
|
|
300
|
+
switch (c) {
|
|
287
301
|
case "uri":
|
|
288
|
-
return
|
|
302
|
+
return l.uri(t.attributes);
|
|
289
303
|
case "postback":
|
|
290
|
-
return
|
|
304
|
+
return l.postback(t.attributes);
|
|
291
305
|
case "message":
|
|
292
|
-
return
|
|
306
|
+
return l.message(t.attributes);
|
|
293
307
|
case "datetimepicker":
|
|
294
|
-
return
|
|
308
|
+
return l.datetimepicker(t.attributes);
|
|
295
309
|
case "camera":
|
|
296
|
-
return
|
|
310
|
+
return l.camera(t.attributes);
|
|
297
311
|
case "cameraRoll":
|
|
298
|
-
return
|
|
312
|
+
return l.cameraRoll(t.attributes);
|
|
299
313
|
case "location":
|
|
300
|
-
return
|
|
314
|
+
return l.location(t.attributes);
|
|
301
315
|
case "richmenuswitch":
|
|
302
|
-
return
|
|
316
|
+
return l.richmenuswitch(t.attributes);
|
|
303
317
|
case "clipboard":
|
|
304
|
-
return
|
|
318
|
+
return l.clipboard(t.attributes);
|
|
305
319
|
default:
|
|
306
|
-
h(`Unsupported action type: ${
|
|
320
|
+
h(`Unsupported action type: ${c}`);
|
|
307
321
|
}
|
|
308
322
|
}
|
|
309
323
|
if (t.tagName === e.BACKGROUND)
|
|
310
324
|
return t.attributes;
|
|
311
325
|
}
|
|
312
|
-
const
|
|
313
|
-
createElement: (t, r = {}, n = [],
|
|
314
|
-
const
|
|
326
|
+
const m = {
|
|
327
|
+
createElement: (t, r = {}, n = [], c = 0) => {
|
|
328
|
+
const a = Object.entries(r).filter(([p, s]) => s != null).map(([p, s]) => typeof s == "object" ? `${p}="${JSON.stringify(s).replace(/"/g, """)}"` : `${p}="${s}"`).join(" "), i = a ? ` ${a}` : "";
|
|
315
329
|
if (n.length === 0)
|
|
316
|
-
return ` <${t}${
|
|
330
|
+
return ` <${t}${i} />`;
|
|
317
331
|
{
|
|
318
|
-
const
|
|
319
|
-
`).map((
|
|
320
|
-
`) :
|
|
332
|
+
const p = n.map((s) => typeof s == "string" ? s.split(`
|
|
333
|
+
`).map((b) => b ? " " + b : "").join(`
|
|
334
|
+
`) : s).join(`
|
|
321
335
|
`);
|
|
322
|
-
return ` <${t}${
|
|
323
|
-
${
|
|
336
|
+
return ` <${t}${i}>
|
|
337
|
+
${p}
|
|
324
338
|
</${t}>`;
|
|
325
339
|
}
|
|
326
340
|
},
|
|
327
341
|
createText: (t) => t
|
|
328
|
-
}
|
|
329
|
-
|
|
342
|
+
}, A = (t, r, n, c) => {
|
|
343
|
+
const o = [f(r, c + 1)];
|
|
344
|
+
return n && Object.keys(n).length > 0 && o.unshift(f(k("style", n), c + 1)), m.createElement(t, {}, o, c);
|
|
345
|
+
}, k = (t, r) => ({ ...r, type: t });
|
|
346
|
+
function f(t, r = 0) {
|
|
330
347
|
if (!t || typeof t != "object")
|
|
331
348
|
return "";
|
|
332
|
-
const { type: n, ...
|
|
349
|
+
const { type: n, ...c } = t, { action: o, ...a } = c, i = o ? f(o, r + 1) : "";
|
|
333
350
|
switch (n) {
|
|
334
351
|
case "carousel":
|
|
335
|
-
const { contents:
|
|
336
|
-
return
|
|
352
|
+
const { contents: p, ...s } = a, b = p.map((N) => f(N, r + 1));
|
|
353
|
+
return i && b.unshift(i), m.createElement(e.CAROUSEL, s, b, r);
|
|
337
354
|
case "bubble":
|
|
338
|
-
const { header:
|
|
339
|
-
return
|
|
355
|
+
const { header: R, hero: B, body: S, footer: x, styles: T = {}, ...X } = a, g = [];
|
|
356
|
+
return i && g.push(i), R && g.push(A(e.HEADER, R, T.header, r + 1)), B && g.push(A(e.HERO, B, T.hero, r + 1)), S && g.push(A(e.BODY, S, T.body, r + 1)), x && g.push(A(e.FOOTER, x, T.footer, r + 1)), m.createElement(e.BUBBLE, X, g, r);
|
|
340
357
|
case "box":
|
|
341
|
-
const { contents:
|
|
342
|
-
|
|
343
|
-
const
|
|
344
|
-
return
|
|
358
|
+
const { contents: $, background: I, ...d } = a;
|
|
359
|
+
d.layout || (d.layout = "vertical");
|
|
360
|
+
const y = [];
|
|
361
|
+
return i && y.push(i), I && y.push(f(k("background", I), r + 1)), y.push(...($ || []).map((N) => f(N, r + 1))), m.createElement(e.BOX, d, y, r);
|
|
345
362
|
case "text":
|
|
346
|
-
const { text:
|
|
347
|
-
return
|
|
363
|
+
const { text: G, contents: C, ...H } = a, v = C && C.length > 0 ? C.map((N) => f(N, r + 1)) : [G || ""];
|
|
364
|
+
return i && v.unshift(i), m.createElement(e.TEXT, H, v, r);
|
|
348
365
|
case "span":
|
|
349
|
-
const { text:
|
|
350
|
-
return
|
|
366
|
+
const { text: F, ...V } = a, L = [F || ""];
|
|
367
|
+
return i && L.unshift(i), m.createElement(e.SPAN, V, L, r);
|
|
351
368
|
case "image":
|
|
352
|
-
const {
|
|
353
|
-
return
|
|
369
|
+
const { ...M } = a, P = i ? [i] : [];
|
|
370
|
+
return m.createElement(e.IMAGE, M, P, r);
|
|
354
371
|
case "video":
|
|
355
|
-
const { altContent:
|
|
356
|
-
return
|
|
372
|
+
const { altContent: w, ...Y } = a, U = w ? [f(w, r + 1)] : [];
|
|
373
|
+
return i && U.unshift(i), m.createElement(e.VIDEO, Y, U, r);
|
|
357
374
|
case "icon":
|
|
358
|
-
const { ...
|
|
359
|
-
return
|
|
375
|
+
const { ...j } = a, K = i ? [i] : [];
|
|
376
|
+
return m.createElement(e.ICON, j, K, r);
|
|
360
377
|
case "button":
|
|
361
|
-
const { ...
|
|
362
|
-
return
|
|
378
|
+
const { ...W } = a, J = i ? [i] : [];
|
|
379
|
+
return m.createElement(e.BUTTON, W, J, r);
|
|
363
380
|
case "separator":
|
|
364
|
-
const
|
|
365
|
-
return
|
|
381
|
+
const z = i ? [i] : [];
|
|
382
|
+
return m.createElement(e.SEPARATOR, a, z, r);
|
|
366
383
|
case "filler":
|
|
367
|
-
const
|
|
368
|
-
return
|
|
384
|
+
const q = i ? [i] : [];
|
|
385
|
+
return m.createElement(e.FILLER, a, q, r);
|
|
369
386
|
// Action types
|
|
370
387
|
case "uri":
|
|
371
388
|
case "message":
|
|
@@ -376,21 +393,23 @@ function b(t, r = 0) {
|
|
|
376
393
|
case "location":
|
|
377
394
|
case "richmenuswitch":
|
|
378
395
|
case "clipboard":
|
|
379
|
-
return
|
|
396
|
+
return m.createElement(e.ACTION, { type: n, ...a }, [], r);
|
|
380
397
|
case "background":
|
|
381
|
-
return
|
|
398
|
+
return m.createElement(e.BACKGROUND, a, [], r);
|
|
399
|
+
case "style":
|
|
400
|
+
return m.createElement(e.STYLE, a, [], r);
|
|
382
401
|
default:
|
|
383
402
|
return "";
|
|
384
403
|
}
|
|
385
404
|
}
|
|
386
|
-
function
|
|
405
|
+
function lt(t) {
|
|
387
406
|
try {
|
|
388
|
-
return
|
|
407
|
+
return at(t).map(u);
|
|
389
408
|
} catch (r) {
|
|
390
409
|
throw console.error("Error converting HTML to Flex Message:", r), r;
|
|
391
410
|
}
|
|
392
411
|
}
|
|
393
412
|
export {
|
|
394
|
-
|
|
395
|
-
|
|
413
|
+
f as convertJsonToHtml,
|
|
414
|
+
lt as default
|
|
396
415
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
(function(b,T){typeof exports=="object"&&typeof module<"u"?T(exports,require("htmlparser2")):typeof define=="function"&&define.amd?define(["exports","htmlparser2"],T):(b=typeof globalThis<"u"?globalThis:b||self,T(b.FlexHtmlRender={},b.htmlparser2))})(this,(function(b,T){"use strict";const E={ELEMENT:"element",TEXT:"text"},e={CAROUSEL:"carousel",BUBBLE:"bubble",HEADER:"header",HERO:"hero",BODY:"body",FOOTER:"footer",BOX:"box",TEXT:"text",SPAN:"span",IMAGE:"image",VIDEO:"video",ICON:"icon",SEPARATOR:"separator",BUTTON:"button",FILLER:"filler",SPACE:"space",STRONG:"strong",BASELINE:"baseline",ROW:"row",VERTICAL:"vertical",DIV:"div",ARTICLE:"article",ACTION:"action",BACKGROUND:"background"},
|
|
1
|
+
(function(b,T){typeof exports=="object"&&typeof module<"u"?T(exports,require("htmlparser2")):typeof define=="function"&&define.amd?define(["exports","htmlparser2"],T):(b=typeof globalThis<"u"?globalThis:b||self,T(b.FlexHtmlRender={},b.htmlparser2))})(this,(function(b,T){"use strict";const E={ELEMENT:"element",TEXT:"text"},e={CAROUSEL:"carousel",BUBBLE:"bubble",HEADER:"header",HERO:"hero",BODY:"body",FOOTER:"footer",BOX:"box",TEXT:"text",SPAN:"span",IMAGE:"image",VIDEO:"video",ICON:"icon",SEPARATOR:"separator",BUTTON:"button",FILLER:"filler",SPACE:"space",STRONG:"strong",BASELINE:"baseline",ROW:"row",VERTICAL:"vertical",DIV:"div",ARTICLE:"article",ACTION:"action",BACKGROUND:"background",STYLE:"style"},S=[e.HEADER,e.HERO,e.BODY,e.FOOTER],H=[e.BOX,e.VERTICAL,e.ROW,e.BASELINE,e.DIV,e.ARTICLE],G=[e.TEXT,e.STRONG];function F(t){const r=Number(t);return isNaN(r)?t:r}function M(t){return t==="true"?!0:t==="false"?!1:t}function P(t){return[F,M].reduce((n,c)=>c(n),t)}function V(t){const r={type:"root",children:[]},n=[r],c=new T.Parser({onopentag(o,a){const i={type:E.ELEMENT,tagName:o,attributes:Object.fromEntries(Object.entries(a).map(([s,g])=>[s,P(g)])),children:[]};n[n.length-1].children.push(i),n.push(i)},ontext(o){const a=n[n.length-1];if(a.tagName==="span"){a.children.push({type:E.TEXT,content:o});return}o.trim()&&a.children.push({type:E.TEXT,content:o.replace(/\n/g,"").trim()})},onclosetag(){n.pop()},onerror(o){console.error("解析錯誤:",o)}},{xmlMode:!0,lowerCaseTags:!1,lowerCaseAttributeNames:!1});return c.write(t),c.end(),r.children}const m=t=>{throw Error(`[Flex Html Render]: ${t}`)},l={carousel:t=>({type:"carousel",contents:t}),bubble:(t={})=>({type:"bubble",...t}),box:(t,r={})=>({type:"box",contents:t,...r}),text:(t,r={})=>({type:"text",...typeof t=="string"?{text:t}:{contents:t},...r}),span:(t,r={})=>({type:"span",text:t,...r}),image:(t={})=>({type:"image",...t}),video:(t={})=>({type:"video",...t}),icon:(t={})=>({type:"icon",...t}),button:(t={})=>({type:"button",...t}),separator:(t={color:"#E0E3EA"})=>({type:"separator",...t}),filler:(t={})=>({type:"filler",...t}),uri:(t={})=>({type:"uri",altUri:t.altUri?{desktop:t.altUri}:void 0,...t}),postback:(t={})=>({type:"postback",...t}),message:(t={})=>({type:"message",...t}),datetimepicker:(t={})=>({type:"datetimepicker",...t}),camera:(t={})=>({type:"camera",...t}),cameraRoll:(t={})=>({type:"cameraRoll",...t}),location:(t={})=>({type:"location",...t}),richmenuswitch:(t={})=>({type:"richmenuswitch",...t}),clipboard:(t={})=>({type:"clipboard",...t})};function j(t){if(t.tagName!==e.BACKGROUND&&t.children&&t.children.length>0){const r=t.children.filter(n=>n.tagName===e.BACKGROUND);return r.length>1&&m("A box node can only allowed with one background node inside"),t.children=t.children.filter(n=>n.tagName!==e.BACKGROUND),r[0]}return null}function Y(t){if(t.tagName!==e.ACTION&&t.children&&t.children.length>0){const r=t.children.filter(n=>n.tagName===e.ACTION);return r.length>1&&m("A node can only allowed with one action node inside"),t.children=t.children.filter(n=>n.tagName!==e.ACTION),r[0]}return null}function K(t){![...G,e.SPAN].includes(t.tagName)&&t.children?.some(a=>a.type===E.TEXT)&&m("Span component only allowed inside Text component"),t.tagName===e.VIDEO&&t.children?.some(a=>![e.BOX,e.IMAGE].includes(a.tagName))&&m("Video component only allowed Box or Image as altContent child"),!H.includes(t.tagName)&&t.children?.some(a=>a.tagName===e.BACKGROUND)&&m("Only Box component allowed to have Background child"),!S.includes(t.tagName)&&t.children?.filter(a=>a.tagName===e.STYLE).length>=1&&m("Only top-level section(header, hero, body, footer) can have Style child")}function d(t){if(t){const r=t.children.find(n=>n.tagName===e.STYLE);if(r)return t.children=t.children.filter(n=>n.tagName!==e.STYLE),r.attributes}}function u(t){t.attributes=t.attributes||{},K(t);const r=Y(t);r&&(t.attributes.action=u(r));const n=j(t);if(n&&(t.attributes.background=u(n)),t.type===E.TEXT)return l.span(t.content,t.attributes);if(t.tagName===e.BUBBLE){const c=t.children.find(s=>s.tagName===e.HEADER),o=t.children.find(s=>s.tagName===e.HERO),a=t.children.find(s=>s.tagName===e.BODY),i=t.children.find(s=>s.tagName===e.FOOTER),f={header:d(c),hero:d(o),body:d(a),footer:d(i)};return l.bubble({...t.attributes,header:c?u(c):void 0,hero:o?u(o):void 0,body:a?u(a):void 0,footer:i?u(i):void 0,styles:Object.values(f).some(s=>s!==void 0)?f:void 0})}if(t.tagName===e.CAROUSEL)return t.children.some(c=>c.tagName!==e.BUBBLE)&&m("Carousel can only have Bubble as children"),t.children.length>12&&m("Carousel can have maximum 12 bubbles"),l.carousel(t.children.map(u));if(S.includes(t.tagName))return t.children.length!==1&&m(`${t.tagName} should have exactly one child node`),u(t.children[0]);if(t.tagName===e.BUTTON)return t.attributes.action||m("Button component should contain an action node"),l.button(t.attributes);if(t.tagName===e.SPAN){t.children.length>1&&m("Span component can only have one text child");const c=t.children[0];if(c&&c.type===E.TEXT)return l.span(c.content,t.attributes);m(c?"Span component only allowed text child":"Span component can not be empty")}if(t.tagName===e.TEXT)return l.text(t.children.map(u),t.attributes);if(t.tagName===e.SEPARATOR)return l.separator(t.attributes);if(t.tagName===e.IMAGE)return l.image(t.attributes);if(t.tagName===e.VIDEO)return t.children.length!==1&&m("Video component should only has one Box or Image as altContent"),t.attributes.altContent=u(t.children[0]),l.video(t.attributes);if(t.tagName===e.ICON)return l.icon(t.attributes);if(t.tagName===e.FILLER)return l.filler(t.attributes);if(t.tagName===e.BOX||t.tagName===e.DIV||t.tagName===e.ARTICLE)return t.attributes.layout||(t.attributes.layout="vertical"),l.box(t.children.map(u),t.attributes);if(t.tagName===e.SPACE)return l.span(" ".repeat(t.attributes.size||1));if(t.tagName===e.STRONG)return t.tagName=e.TEXT,t.attributes.weight="bold",u(t);if(t.tagName===e.BASELINE)return t.tagName=e.BOX,t.attributes.layout="baseline",u(t);if(t.tagName===e.ROW)return t.tagName=e.BOX,t.attributes.layout="horizontal",u(t);if(t.tagName===e.VERTICAL)return t.tagName=e.BOX,t.attributes.layout="vertical",u(t);if(t.tagName===e.ACTION){const c=t.attributes.type;switch(c){case"uri":return l.uri(t.attributes);case"postback":return l.postback(t.attributes);case"message":return l.message(t.attributes);case"datetimepicker":return l.datetimepicker(t.attributes);case"camera":return l.camera(t.attributes);case"cameraRoll":return l.cameraRoll(t.attributes);case"location":return l.location(t.attributes);case"richmenuswitch":return l.richmenuswitch(t.attributes);case"clipboard":return l.clipboard(t.attributes);default:m(`Unsupported action type: ${c}`)}}if(t.tagName===e.BACKGROUND)return t.attributes}const h={createElement:(t,r={},n=[],c=0)=>{const a=Object.entries(r).filter(([f,s])=>s!=null).map(([f,s])=>typeof s=="object"?`${f}="${JSON.stringify(s).replace(/"/g,""")}"`:`${f}="${s}"`).join(" "),i=a?` ${a}`:"";if(n.length===0)return` <${t}${i} />`;{const f=n.map(s=>typeof s=="string"?s.split(`
|
|
2
2
|
`).map(g=>g?" "+g:"").join(`
|
|
3
|
-
`):
|
|
4
|
-
`);return` <${t}${
|
|
5
|
-
${
|
|
6
|
-
</${t}>`}},createText:t=>t};function
|
|
3
|
+
`):s).join(`
|
|
4
|
+
`);return` <${t}${i}>
|
|
5
|
+
${f}
|
|
6
|
+
</${t}>`}},createText:t=>t},O=(t,r,n,c)=>{const o=[p(r,c+1)];return n&&Object.keys(n).length>0&&o.unshift(p(x("style",n),c+1)),h.createElement(t,{},o,c)},x=(t,r)=>({...r,type:t});function p(t,r=0){if(!t||typeof t!="object")return"";const{type:n,...c}=t,{action:o,...a}=c,i=o?p(o,r+1):"";switch(n){case"carousel":const{contents:f,...s}=a,g=f.map(y=>p(y,r+1));return i&&g.unshift(i),h.createElement(e.CAROUSEL,s,g,r);case"bubble":const{header:v,hero:I,body:L,footer:w,styles:A={},...W}=a,N=[];return i&&N.push(i),v&&N.push(O(e.HEADER,v,A.header,r+1)),I&&N.push(O(e.HERO,I,A.hero,r+1)),L&&N.push(O(e.BODY,L,A.body,r+1)),w&&N.push(O(e.FOOTER,w,A.footer,r+1)),h.createElement(e.BUBBLE,W,N,r);case"box":const{contents:q,background:U,...R}=a;R.layout||(R.layout="vertical");const C=[];return i&&C.push(i),U&&C.push(p(x("background",U),r+1)),C.push(...(q||[]).map(y=>p(y,r+1))),h.createElement(e.BOX,R,C,r);case"text":const{text:z,contents:B,..._}=a,D=B&&B.length>0?B.map(y=>p(y,r+1)):[z||""];return i&&D.unshift(i),h.createElement(e.TEXT,_,D,r);case"span":const{text:Q,...Z}=a,k=[Q||""];return i&&k.unshift(i),h.createElement(e.SPAN,Z,k,r);case"image":const{...tt}=a,et=i?[i]:[];return h.createElement(e.IMAGE,tt,et,r);case"video":const{altContent:X,...rt}=a,$=X?[p(X,r+1)]:[];return i&&$.unshift(i),h.createElement(e.VIDEO,rt,$,r);case"icon":const{...at}=a,nt=i?[i]:[];return h.createElement(e.ICON,at,nt,r);case"button":const{...it}=a,ct=i?[i]:[];return h.createElement(e.BUTTON,it,ct,r);case"separator":const st=i?[i]:[];return h.createElement(e.SEPARATOR,a,st,r);case"filler":const lt=i?[i]:[];return h.createElement(e.FILLER,a,lt,r);case"uri":case"message":case"postback":case"datetimepicker":case"camera":case"cameraRoll":case"location":case"richmenuswitch":case"clipboard":return h.createElement(e.ACTION,{type:n,...a},[],r);case"background":return h.createElement(e.BACKGROUND,a,[],r);case"style":return h.createElement(e.STYLE,a,[],r);default:return""}}function J(t){try{return V(t).map(u)}catch(r){throw console.error("Error converting HTML to Flex Message:",r),r}}b.convertJsonToHtml=p,b.default=J,Object.defineProperties(b,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
|