flex-html-render 1.1.2 → 1.1.3

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.
@@ -1,6 +1,6 @@
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,"&quot;")}"`:`${p}="${s}"`).join(" "),i=a?` ${a}`:"";if(n.length===0)return` <${t}${i} />`;{const p=n.map(s=>typeof s=="string"?s.split(`
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const Q=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],k=[e.BOX,e.VERTICAL,e.ROW,e.BASELINE,e.DIV,e.ARTICLE],Z=[e.TEXT,e.STRONG];function tt(t,r){if(new Set(["flex","maxLines"]).has(t)){const i=Number(r);return isNaN(i)?r:i}return r}function et(t,r){return r==="true"?!0:r==="false"?!1:r}function rt(t,r){return[tt,et].reduce((i,o)=>o(t,i),r)}function at(t){const r={type:"root",children:[]},n=[r],i=new Q.Parser({onopentag(o,s){const a={type:E.ELEMENT,tagName:o,attributes:Object.fromEntries(Object.entries(s).map(([c,b])=>[c,rt(c,b)])),children:[]};n[n.length-1].children.push(a),n.push(a)},ontext(o){const s=n[n.length-1];if(s.tagName==="span"){s.children.push({type:E.TEXT,content:o});return}o.trim()&&s.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 i.write(t),i.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 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&&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 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&&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 st(t){![...Z,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"),!k.includes(t.tagName)&&t.children?.some(a=>a.tagName===e.BACKGROUND)&&m("Only Box component allowed to have Background child"),!k.includes(t.tagName)&&Object.keys(t.attributes||{}).some(a=>a.startsWith("padding"))&&m(`Padding property is not supported in ${t.tagName} component`),!D.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||{},st(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 i=t.children.find(c=>c.tagName===e.HEADER),o=t.children.find(c=>c.tagName===e.HERO),s=t.children.find(c=>c.tagName===e.BODY),a=t.children.find(c=>c.tagName===e.FOOTER),p={header:d(i),hero:d(o),body:d(s),footer:d(a)};return l.bubble({...t.attributes,header:i?u(i):void 0,hero:o?u(o):void 0,body:s?u(s):void 0,footer:a?u(a):void 0,styles:Object.values(p).some(c=>c!==void 0)?p:void 0})}if(t.tagName===e.CAROUSEL)return t.children.some(i=>i.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(D.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 i=t.children[0];if(i&&i.type===E.TEXT)return l.span(i.content,t.attributes);m(i?"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 i=t.attributes.type;switch(i){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: ${i}`)}}if(t.tagName===e.BACKGROUND)return t.attributes}const h={createElement:(t,r={},n=[],i=0)=>{const s=Object.entries(r).filter(([p,c])=>c!=null).map(([p,c])=>typeof c=="object"?`${p}="${JSON.stringify(c).replace(/"/g,"&quot;")}"`:`${p}="${c}"`).join(" "),a=s?` ${s}`:"";if(n.length===0)return` <${t}${a} />`;{const p=n.map(c=>typeof c=="string"?c.split(`
2
2
  `).map(b=>b?" "+b:"").join(`
3
- `):s).join(`
4
- `);return` <${t}${i}>
3
+ `):c).join(`
4
+ `);return` <${t}${a}>
5
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;
6
+ </${t}>`}},createText:t=>t},O=(t,r,n,i)=>{const o=[f(r,i+1)];return n&&Object.keys(n).length>0&&o.unshift(f(X("style",n),i+1)),h.createElement(t,{},o,i)},X=(t,r)=>({...r,type:t});function f(t,r=0){if(!t||typeof t!="object")return"";const{type:n,...i}=t,{action:o,...s}=i,a=o?f(o,r+1):"";switch(n){case"carousel":const{contents:p,...c}=s,b=p.map(N=>f(N,r+1));return a&&b.unshift(a),h.createElement(e.CAROUSEL,c,b,r);case"bubble":const{header:R,hero:B,body:S,footer:x,styles:y={},...$}=s,g=[];return a&&g.push(a),R&&g.push(O(e.HEADER,R,y.header,r+1)),B&&g.push(O(e.HERO,B,y.hero,r+1)),S&&g.push(O(e.BODY,S,y.body,r+1)),x&&g.push(O(e.FOOTER,x,y.footer,r+1)),h.createElement(e.BUBBLE,$,g,r);case"box":const{contents:P,background:v,...A}=s;A.layout||(A.layout="vertical");const T=[];return a&&T.push(a),v&&T.push(f(X("background",v),r+1)),T.push(...(P||[]).map(N=>f(N,r+1))),h.createElement(e.BOX,A,T,r);case"text":const{text:H,contents:C,...G}=s,I=C&&C.length>0?C.map(N=>f(N,r+1)):[H||""];return a&&I.unshift(a),h.createElement(e.TEXT,G,I,r);case"span":const{text:M,...F}=s,L=[M||""];return a&&L.unshift(a),h.createElement(e.SPAN,F,L,r);case"image":const{...V}=s,j=a?[a]:[];return h.createElement(e.IMAGE,V,j,r);case"video":const{altContent:w,...K}=s,U=w?[f(w,r+1)]:[];return a&&U.unshift(a),h.createElement(e.VIDEO,K,U,r);case"icon":const{...Y}=s,W=a?[a]:[];return h.createElement(e.ICON,Y,W,r);case"button":const{...J}=s,q=a?[a]:[];return h.createElement(e.BUTTON,J,q,r);case"separator":const z=a?[a]:[];return h.createElement(e.SEPARATOR,s,z,r);case"filler":const _=a?[a]:[];return h.createElement(e.FILLER,s,_,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,...s},[],r);case"background":return h.createElement(e.BACKGROUND,s,[],r);case"style":return h.createElement(e.STYLE,s,[],r);default:return""}}function ct(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=ct;
@@ -1,4 +1,4 @@
1
- import { Parser as Q } from "htmlparser2";
1
+ import { Parser as Z } from "htmlparser2";
2
2
  const E = {
3
3
  ELEMENT: "element",
4
4
  TEXT: "text"
@@ -39,7 +39,7 @@ const E = {
39
39
  e.HERO,
40
40
  e.BODY,
41
41
  e.FOOTER
42
- ], Z = [
42
+ ], k = [
43
43
  e.BOX,
44
44
  e.VERTICAL,
45
45
  e.ROW,
@@ -50,43 +50,46 @@ const E = {
50
50
  e.TEXT,
51
51
  e.STRONG
52
52
  ];
53
- function tt(t) {
54
- const r = Number(t);
55
- return isNaN(r) ? t : r;
53
+ function tt(t, r) {
54
+ if ((/* @__PURE__ */ new Set(["flex", "maxLines"])).has(t)) {
55
+ const i = Number(r);
56
+ return isNaN(i) ? r : i;
57
+ }
58
+ return r;
56
59
  }
57
- function et(t) {
58
- return t === "true" ? !0 : t === "false" ? !1 : t;
60
+ function et(t, r) {
61
+ return r === "true" ? !0 : r === "false" ? !1 : r;
59
62
  }
60
- function rt(t) {
63
+ function rt(t, r) {
61
64
  return [
62
65
  tt,
63
66
  et
64
- ].reduce((n, c) => c(n), t);
67
+ ].reduce((i, o) => o(t, i), r);
65
68
  }
66
69
  function at(t) {
67
- const r = { type: "root", children: [] }, n = [r], c = new Q(
70
+ const r = { type: "root", children: [] }, n = [r], i = new Z(
68
71
  {
69
- onopentag(o, a) {
70
- const i = {
72
+ onopentag(o, c) {
73
+ const a = {
71
74
  type: E.ELEMENT,
72
75
  tagName: o,
73
76
  attributes: Object.fromEntries(
74
- Object.entries(a).map(([s, b]) => [s, rt(b)])
77
+ Object.entries(c).map(([s, b]) => [s, rt(s, b)])
75
78
  ),
76
79
  children: []
77
80
  };
78
- n[n.length - 1].children.push(i), n.push(i);
81
+ n[n.length - 1].children.push(a), n.push(a);
79
82
  },
80
83
  ontext(o) {
81
- const a = n[n.length - 1];
82
- if (a.tagName === "span") {
83
- a.children.push({
84
+ const c = n[n.length - 1];
85
+ if (c.tagName === "span") {
86
+ c.children.push({
84
87
  type: E.TEXT,
85
88
  content: o
86
89
  });
87
90
  return;
88
91
  }
89
- o.trim() && a.children.push({
92
+ o.trim() && c.children.push({
90
93
  type: E.TEXT,
91
94
  content: o.replace(/\n/g, "").trim()
92
95
  });
@@ -106,9 +109,9 @@ function at(t) {
106
109
  lowerCaseAttributeNames: !1
107
110
  }
108
111
  );
109
- return c.write(t), c.end(), r.children;
112
+ return i.write(t), i.end(), r.children;
110
113
  }
111
- const h = (t) => {
114
+ const m = (t) => {
112
115
  throw Error(`[Flex Html Render]: ${t}`);
113
116
  }, l = {
114
117
  carousel: (t) => ({
@@ -203,21 +206,21 @@ const h = (t) => {
203
206
  function nt(t) {
204
207
  if (t.tagName !== e.BACKGROUND && t.children && t.children.length > 0) {
205
208
  const r = t.children.filter((n) => n.tagName === e.BACKGROUND);
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];
209
+ 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];
207
210
  }
208
211
  return null;
209
212
  }
210
213
  function it(t) {
211
214
  if (t.tagName !== e.ACTION && t.children && t.children.length > 0) {
212
215
  const r = t.children.filter((n) => n.tagName === e.ACTION);
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];
216
+ 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];
214
217
  }
215
218
  return null;
216
219
  }
217
220
  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");
221
+ ![..._, 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"), !k.includes(t.tagName) && t.children?.some((a) => a.tagName === e.BACKGROUND) && m("Only Box component allowed to have Background child"), !k.includes(t.tagName) && Object.keys(t.attributes || {}).some((a) => a.startsWith("padding")) && m(`Padding property is not supported in ${t.tagName} component`), !D.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");
219
222
  }
220
- function O(t) {
223
+ function d(t) {
221
224
  if (t) {
222
225
  const r = t.children.find((n) => n.tagName === e.STYLE);
223
226
  if (r)
@@ -232,38 +235,38 @@ function u(t) {
232
235
  if (n && (t.attributes.background = u(n)), t.type === E.TEXT)
233
236
  return l.span(t.content, t.attributes);
234
237
  if (t.tagName === e.BUBBLE) {
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)
238
+ const i = t.children.find((s) => s.tagName === e.HEADER), o = t.children.find((s) => s.tagName === e.HERO), c = t.children.find((s) => s.tagName === e.BODY), a = t.children.find((s) => s.tagName === e.FOOTER), p = {
239
+ header: d(i),
240
+ hero: d(o),
241
+ body: d(c),
242
+ footer: d(a)
240
243
  };
241
244
  return l.bubble({
242
245
  ...t.attributes,
243
- header: c ? u(c) : void 0,
246
+ header: i ? u(i) : void 0,
244
247
  hero: o ? u(o) : void 0,
245
- body: a ? u(a) : void 0,
246
- footer: i ? u(i) : void 0,
248
+ body: c ? u(c) : void 0,
249
+ footer: a ? u(a) : void 0,
247
250
  styles: Object.values(p).some((s) => s !== void 0) ? p : void 0
248
251
  });
249
252
  }
250
253
  if (t.tagName === e.CAROUSEL)
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(
254
+ return t.children.some((i) => i.tagName !== e.BUBBLE) && m("Carousel can only have Bubble as children"), t.children.length > 12 && m("Carousel can have maximum 12 bubbles"), l.carousel(
252
255
  t.children.map(u)
253
256
  );
254
257
  if (D.includes(t.tagName))
255
- return t.children.length !== 1 && h(`${t.tagName} should have exactly one child node`), u(t.children[0]);
258
+ return t.children.length !== 1 && m(`${t.tagName} should have exactly one child node`), u(t.children[0]);
256
259
  if (t.tagName === e.BUTTON)
257
- return t.attributes.action || h("Button component should contain an action node"), l.button(t.attributes);
260
+ return t.attributes.action || m("Button component should contain an action node"), l.button(t.attributes);
258
261
  if (t.tagName === e.SPAN) {
259
- t.children.length > 1 && h("Span component can only have one text child");
260
- const c = t.children[0];
261
- if (c && c.type === E.TEXT)
262
+ t.children.length > 1 && m("Span component can only have one text child");
263
+ const i = t.children[0];
264
+ if (i && i.type === E.TEXT)
262
265
  return l.span(
263
- c.content,
266
+ i.content,
264
267
  t.attributes
265
268
  );
266
- h(c ? "Span component only allowed text child" : "Span component can not be empty");
269
+ m(i ? "Span component only allowed text child" : "Span component can not be empty");
267
270
  }
268
271
  if (t.tagName === e.TEXT)
269
272
  return l.text(
@@ -275,7 +278,7 @@ function u(t) {
275
278
  if (t.tagName === e.IMAGE)
276
279
  return l.image(t.attributes);
277
280
  if (t.tagName === e.VIDEO)
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);
281
+ 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);
279
282
  if (t.tagName === e.ICON)
280
283
  return l.icon(t.attributes);
281
284
  if (t.tagName === e.FILLER)
@@ -296,8 +299,8 @@ function u(t) {
296
299
  if (t.tagName === e.VERTICAL)
297
300
  return t.tagName = e.BOX, t.attributes.layout = "vertical", u(t);
298
301
  if (t.tagName === e.ACTION) {
299
- const c = t.attributes.type;
300
- switch (c) {
302
+ const i = t.attributes.type;
303
+ switch (i) {
301
304
  case "uri":
302
305
  return l.uri(t.attributes);
303
306
  case "postback":
@@ -317,72 +320,72 @@ function u(t) {
317
320
  case "clipboard":
318
321
  return l.clipboard(t.attributes);
319
322
  default:
320
- h(`Unsupported action type: ${c}`);
323
+ m(`Unsupported action type: ${i}`);
321
324
  }
322
325
  }
323
326
  if (t.tagName === e.BACKGROUND)
324
327
  return t.attributes;
325
328
  }
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, "&quot;")}"` : `${p}="${s}"`).join(" "), i = a ? ` ${a}` : "";
329
+ const h = {
330
+ createElement: (t, r = {}, n = [], i = 0) => {
331
+ const c = Object.entries(r).filter(([p, s]) => s != null).map(([p, s]) => typeof s == "object" ? `${p}="${JSON.stringify(s).replace(/"/g, "&quot;")}"` : `${p}="${s}"`).join(" "), a = c ? ` ${c}` : "";
329
332
  if (n.length === 0)
330
- return ` <${t}${i} />`;
333
+ return ` <${t}${a} />`;
331
334
  {
332
335
  const p = n.map((s) => typeof s == "string" ? s.split(`
333
336
  `).map((b) => b ? " " + b : "").join(`
334
337
  `) : s).join(`
335
338
  `);
336
- return ` <${t}${i}>
339
+ return ` <${t}${a}>
337
340
  ${p}
338
341
  </${t}>`;
339
342
  }
340
343
  },
341
344
  createText: (t) => t
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 });
345
+ }, O = (t, r, n, i) => {
346
+ const o = [f(r, i + 1)];
347
+ return n && Object.keys(n).length > 0 && o.unshift(f(X("style", n), i + 1)), h.createElement(t, {}, o, i);
348
+ }, X = (t, r) => ({ ...r, type: t });
346
349
  function f(t, r = 0) {
347
350
  if (!t || typeof t != "object")
348
351
  return "";
349
- const { type: n, ...c } = t, { action: o, ...a } = c, i = o ? f(o, r + 1) : "";
352
+ const { type: n, ...i } = t, { action: o, ...c } = i, a = o ? f(o, r + 1) : "";
350
353
  switch (n) {
351
354
  case "carousel":
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);
355
+ const { contents: p, ...s } = c, b = p.map((N) => f(N, r + 1));
356
+ return a && b.unshift(a), h.createElement(e.CAROUSEL, s, b, r);
354
357
  case "bubble":
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);
358
+ const { header: R, hero: B, body: S, footer: x, styles: y = {}, ...$ } = c, g = [];
359
+ return a && g.push(a), R && g.push(O(e.HEADER, R, y.header, r + 1)), B && g.push(O(e.HERO, B, y.hero, r + 1)), S && g.push(O(e.BODY, S, y.body, r + 1)), x && g.push(O(e.FOOTER, x, y.footer, r + 1)), h.createElement(e.BUBBLE, $, g, r);
357
360
  case "box":
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);
361
+ const { contents: P, background: I, ...A } = c;
362
+ A.layout || (A.layout = "vertical");
363
+ const T = [];
364
+ return a && T.push(a), I && T.push(f(X("background", I), r + 1)), T.push(...(P || []).map((N) => f(N, r + 1))), h.createElement(e.BOX, A, T, r);
362
365
  case "text":
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);
366
+ const { text: G, contents: C, ...H } = c, v = C && C.length > 0 ? C.map((N) => f(N, r + 1)) : [G || ""];
367
+ return a && v.unshift(a), h.createElement(e.TEXT, H, v, r);
365
368
  case "span":
366
- const { text: F, ...V } = a, L = [F || ""];
367
- return i && L.unshift(i), m.createElement(e.SPAN, V, L, r);
369
+ const { text: F, ...V } = c, L = [F || ""];
370
+ return a && L.unshift(a), h.createElement(e.SPAN, V, L, r);
368
371
  case "image":
369
- const { ...M } = a, P = i ? [i] : [];
370
- return m.createElement(e.IMAGE, M, P, r);
372
+ const { ...M } = c, j = a ? [a] : [];
373
+ return h.createElement(e.IMAGE, M, j, r);
371
374
  case "video":
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);
375
+ const { altContent: w, ...K } = c, U = w ? [f(w, r + 1)] : [];
376
+ return a && U.unshift(a), h.createElement(e.VIDEO, K, U, r);
374
377
  case "icon":
375
- const { ...j } = a, K = i ? [i] : [];
376
- return m.createElement(e.ICON, j, K, r);
378
+ const { ...Y } = c, W = a ? [a] : [];
379
+ return h.createElement(e.ICON, Y, W, r);
377
380
  case "button":
378
- const { ...W } = a, J = i ? [i] : [];
379
- return m.createElement(e.BUTTON, W, J, r);
381
+ const { ...J } = c, z = a ? [a] : [];
382
+ return h.createElement(e.BUTTON, J, z, r);
380
383
  case "separator":
381
- const z = i ? [i] : [];
382
- return m.createElement(e.SEPARATOR, a, z, r);
384
+ const q = a ? [a] : [];
385
+ return h.createElement(e.SEPARATOR, c, q, r);
383
386
  case "filler":
384
- const q = i ? [i] : [];
385
- return m.createElement(e.FILLER, a, q, r);
387
+ const Q = a ? [a] : [];
388
+ return h.createElement(e.FILLER, c, Q, r);
386
389
  // Action types
387
390
  case "uri":
388
391
  case "message":
@@ -393,11 +396,11 @@ function f(t, r = 0) {
393
396
  case "location":
394
397
  case "richmenuswitch":
395
398
  case "clipboard":
396
- return m.createElement(e.ACTION, { type: n, ...a }, [], r);
399
+ return h.createElement(e.ACTION, { type: n, ...c }, [], r);
397
400
  case "background":
398
- return m.createElement(e.BACKGROUND, a, [], r);
401
+ return h.createElement(e.BACKGROUND, c, [], r);
399
402
  case "style":
400
- return m.createElement(e.STYLE, a, [], r);
403
+ return h.createElement(e.STYLE, c, [], r);
401
404
  default:
402
405
  return "";
403
406
  }
@@ -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",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,"&quot;")}"`:`${f}="${s}"`).join(" "),i=a?` ${a}`:"";if(n.length===0)return` <${t}${i} />`;{const f=n.map(s=>typeof s=="string"?s.split(`
1
+ (function(b,y){typeof exports=="object"&&typeof module<"u"?y(exports,require("htmlparser2")):typeof define=="function"&&define.amd?define(["exports","htmlparser2"],y):(b=typeof globalThis<"u"?globalThis:b||self,y(b.FlexHtmlRender={},b.htmlparser2))})(this,(function(b,y){"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],x=[e.BOX,e.VERTICAL,e.ROW,e.BASELINE,e.DIV,e.ARTICLE],H=[e.TEXT,e.STRONG];function G(t,r){if(new Set(["flex","maxLines"]).has(t)){const i=Number(r);return isNaN(i)?r:i}return r}function F(t,r){return r==="true"?!0:r==="false"?!1:r}function M(t,r){return[G,F].reduce((i,o)=>o(t,i),r)}function V(t){const r={type:"root",children:[]},n=[r],i=new y.Parser({onopentag(o,s){const a={type:E.ELEMENT,tagName:o,attributes:Object.fromEntries(Object.entries(s).map(([c,g])=>[c,M(c,g)])),children:[]};n[n.length-1].children.push(a),n.push(a)},ontext(o){const s=n[n.length-1];if(s.tagName==="span"){s.children.push({type:E.TEXT,content:o});return}o.trim()&&s.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 i.write(t),i.end(),r.children}const u=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&&u("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 K(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&&u("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 Y(t){![...H,e.SPAN].includes(t.tagName)&&t.children?.some(a=>a.type===E.TEXT)&&u("Span component only allowed inside Text component"),t.tagName===e.VIDEO&&t.children?.some(a=>![e.BOX,e.IMAGE].includes(a.tagName))&&u("Video component only allowed Box or Image as altContent child"),!x.includes(t.tagName)&&t.children?.some(a=>a.tagName===e.BACKGROUND)&&u("Only Box component allowed to have Background child"),!x.includes(t.tagName)&&Object.keys(t.attributes||{}).some(a=>a.startsWith("padding"))&&u(`Padding property is not supported in ${t.tagName} component`),!S.includes(t.tagName)&&t.children?.filter(a=>a.tagName===e.STYLE).length>=1&&u("Only top-level section(header, hero, body, footer) can have Style child")}function T(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 m(t){t.attributes=t.attributes||{},Y(t);const r=K(t);r&&(t.attributes.action=m(r));const n=j(t);if(n&&(t.attributes.background=m(n)),t.type===E.TEXT)return l.span(t.content,t.attributes);if(t.tagName===e.BUBBLE){const i=t.children.find(c=>c.tagName===e.HEADER),o=t.children.find(c=>c.tagName===e.HERO),s=t.children.find(c=>c.tagName===e.BODY),a=t.children.find(c=>c.tagName===e.FOOTER),p={header:T(i),hero:T(o),body:T(s),footer:T(a)};return l.bubble({...t.attributes,header:i?m(i):void 0,hero:o?m(o):void 0,body:s?m(s):void 0,footer:a?m(a):void 0,styles:Object.values(p).some(c=>c!==void 0)?p:void 0})}if(t.tagName===e.CAROUSEL)return t.children.some(i=>i.tagName!==e.BUBBLE)&&u("Carousel can only have Bubble as children"),t.children.length>12&&u("Carousel can have maximum 12 bubbles"),l.carousel(t.children.map(m));if(S.includes(t.tagName))return t.children.length!==1&&u(`${t.tagName} should have exactly one child node`),m(t.children[0]);if(t.tagName===e.BUTTON)return t.attributes.action||u("Button component should contain an action node"),l.button(t.attributes);if(t.tagName===e.SPAN){t.children.length>1&&u("Span component can only have one text child");const i=t.children[0];if(i&&i.type===E.TEXT)return l.span(i.content,t.attributes);u(i?"Span component only allowed text child":"Span component can not be empty")}if(t.tagName===e.TEXT)return l.text(t.children.map(m),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&&u("Video component should only has one Box or Image as altContent"),t.attributes.altContent=m(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(m),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",m(t);if(t.tagName===e.BASELINE)return t.tagName=e.BOX,t.attributes.layout="baseline",m(t);if(t.tagName===e.ROW)return t.tagName=e.BOX,t.attributes.layout="horizontal",m(t);if(t.tagName===e.VERTICAL)return t.tagName=e.BOX,t.attributes.layout="vertical",m(t);if(t.tagName===e.ACTION){const i=t.attributes.type;switch(i){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:u(`Unsupported action type: ${i}`)}}if(t.tagName===e.BACKGROUND)return t.attributes}const h={createElement:(t,r={},n=[],i=0)=>{const s=Object.entries(r).filter(([p,c])=>c!=null).map(([p,c])=>typeof c=="object"?`${p}="${JSON.stringify(c).replace(/"/g,"&quot;")}"`:`${p}="${c}"`).join(" "),a=s?` ${s}`:"";if(n.length===0)return` <${t}${a} />`;{const p=n.map(c=>typeof c=="string"?c.split(`
2
2
  `).map(g=>g?" "+g:"").join(`
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"}})}));
3
+ `):c).join(`
4
+ `);return` <${t}${a}>
5
+ ${p}
6
+ </${t}>`}},createText:t=>t},O=(t,r,n,i)=>{const o=[f(r,i+1)];return n&&Object.keys(n).length>0&&o.unshift(f(v("style",n),i+1)),h.createElement(t,{},o,i)},v=(t,r)=>({...r,type:t});function f(t,r=0){if(!t||typeof t!="object")return"";const{type:n,...i}=t,{action:o,...s}=i,a=o?f(o,r+1):"";switch(n){case"carousel":const{contents:p,...c}=s,g=p.map(d=>f(d,r+1));return a&&g.unshift(a),h.createElement(e.CAROUSEL,c,g,r);case"bubble":const{header:I,hero:L,body:w,footer:U,styles:A={},...J}=s,N=[];return a&&N.push(a),I&&N.push(O(e.HEADER,I,A.header,r+1)),L&&N.push(O(e.HERO,L,A.hero,r+1)),w&&N.push(O(e.BODY,w,A.body,r+1)),U&&N.push(O(e.FOOTER,U,A.footer,r+1)),h.createElement(e.BUBBLE,J,N,r);case"box":const{contents:q,background:k,...R}=s;R.layout||(R.layout="vertical");const C=[];return a&&C.push(a),k&&C.push(f(v("background",k),r+1)),C.push(...(q||[]).map(d=>f(d,r+1))),h.createElement(e.BOX,R,C,r);case"text":const{text:z,contents:B,..._}=s,D=B&&B.length>0?B.map(d=>f(d,r+1)):[z||""];return a&&D.unshift(a),h.createElement(e.TEXT,_,D,r);case"span":const{text:Q,...Z}=s,X=[Q||""];return a&&X.unshift(a),h.createElement(e.SPAN,Z,X,r);case"image":const{...tt}=s,et=a?[a]:[];return h.createElement(e.IMAGE,tt,et,r);case"video":const{altContent:$,...rt}=s,P=$?[f($,r+1)]:[];return a&&P.unshift(a),h.createElement(e.VIDEO,rt,P,r);case"icon":const{...at}=s,nt=a?[a]:[];return h.createElement(e.ICON,at,nt,r);case"button":const{...it}=s,st=a?[a]:[];return h.createElement(e.BUTTON,it,st,r);case"separator":const ct=a?[a]:[];return h.createElement(e.SEPARATOR,s,ct,r);case"filler":const lt=a?[a]:[];return h.createElement(e.FILLER,s,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,...s},[],r);case"background":return h.createElement(e.BACKGROUND,s,[],r);case"style":return h.createElement(e.STYLE,s,[],r);default:return""}}function W(t){try{return V(t).map(m)}catch(r){throw console.error("Error converting HTML to Flex Message:",r),r}}b.convertJsonToHtml=f,b.default=W,Object.defineProperties(b,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flex-html-render",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "description": "將 HTML 字串轉換為 LINE Flex Message JSON 結構的工具",
5
5
  "type": "module",
6
6
  "main": "dist/flex-html-render.cjs.js",