flex-html-render 1.1.1 → 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 z=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"},_=[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((a,c)=>c(a),t)}function at(t){const r={type:"root",children:[]},a=[r],c=new z.Parser({onopentag(s,i){const n={type:E.ELEMENT,tagName:s,attributes:Object.fromEntries(Object.entries(i).map(([l,b])=>[l,rt(b)])),children:[]};a[a.length-1].children.push(n),a.push(n)},ontext(s){const i=a[a.length-1];if(i.tagName==="span"){i.children.push({type:E.TEXT,content:s});return}s.trim()&&i.children.push({type:E.TEXT,content:s.replace(/\n/g,"").trim()})},onclosetag(){a.pop()},onerror(s){console.error("解析錯誤:",s)}},{xmlMode:!0,lowerCaseTags:!1,lowerCaseAttributeNames:!1});return c.write(t),c.end(),r.children}const h=t=>{throw Error(`[Flex Html Render]: ${t}`)},o={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(a=>a.tagName===e.BACKGROUND);return r.length>1&&h("A box node can only allowed with one background node inside"),t.children=t.children.filter(a=>a.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(a=>a.tagName===e.ACTION);return r.length>1&&h("A node can only allowed with one action node inside"),t.children=t.children.filter(a=>a.tagName!==e.ACTION),r[0]}return null}function ct(t){![...Z,e.SPAN].includes(t.tagName)&&t.children?.some(s=>s.type===E.TEXT)&&h("Span component only allowed inside Text component"),t.tagName===e.VIDEO&&t.children?.some(s=>![e.BOX,e.IMAGE].includes(s.tagName))&&h("Video component only allowed Box or Image as altContent child"),!Q.includes(t.tagName)&&t.children?.some(s=>s.tagName===e.BACKGROUND)&&h("Only Box component allowed to have Background child")}function O(t){if(t){const r=t.children.find(a=>a.tagName===e.STYLE);if(r)return t.children=t.children.filter(a=>a.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 a=nt(t);if(a&&(t.attributes.background=u(a)),t.type===E.TEXT)return o.span(t.content,t.attributes);if(t.tagName===e.BUBBLE){const c=t.children.find(l=>l.tagName===e.HEADER),s=t.children.find(l=>l.tagName===e.HERO),i=t.children.find(l=>l.tagName===e.BODY),n=t.children.find(l=>l.tagName===e.FOOTER),p={header:O(c),hero:O(s),body:O(i),footer:O(n)};return o.bubble({...t.attributes,header:c?u(c):void 0,hero:s?u(s):void 0,body:i?u(i):void 0,footer:n?u(n):void 0,styles:Object.values(p).some(l=>l!==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"),o.carousel(t.children.map(u));if(_.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"),o.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 o.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 o.text(t.children.map(u),t.attributes);if(t.tagName===e.SEPARATOR)return o.separator(t.attributes);if(t.tagName===e.IMAGE)return o.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]),o.video(t.attributes);if(t.tagName===e.ICON)return o.icon(t.attributes);if(t.tagName===e.FILLER)return o.filler(t.attributes);if(t.tagName===e.BOX||t.tagName===e.DIV||t.tagName===e.ARTICLE)return t.attributes.layout||(t.attributes.layout="vertical"),o.box(t.children.map(u),t.attributes);if(t.tagName===e.SPACE)return o.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 o.uri(t.attributes);case"postback":return o.postback(t.attributes);case"message":return o.message(t.attributes);case"datetimepicker":return o.datetimepicker(t.attributes);case"camera":return o.camera(t.attributes);case"cameraRoll":return o.cameraRoll(t.attributes);case"location":return o.location(t.attributes);case"richmenuswitch":return o.richmenuswitch(t.attributes);case"clipboard":return o.clipboard(t.attributes);default:h(`Unsupported action type: ${c}`)}}if(t.tagName===e.BACKGROUND)return t.attributes}const m={createElement:(t,r={},a=[],c=0)=>{const i=Object.entries(r).filter(([p,l])=>l!=null).map(([p,l])=>typeof l=="object"?`${p}="${JSON.stringify(l).replace(/"/g,"&quot;")}"`:`${p}="${l}"`).join(" "),n=i?` ${i}`:"";if(a.length===0)return` <${t}${n} />`;{const p=a.map(l=>typeof l=="string"?l.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
- `):l).join(`
4
- `);return` <${t}${n}>
3
+ `):c).join(`
4
+ `);return` <${t}${a}>
5
5
  ${p}
6
- </${t}>`}},createText:t=>t},A=(t,r,a,c)=>{const s=[f(r,c+1)];return a&&Object.keys(a).length>0&&s.unshift(f(D("style",a),c+1)),m.createElement(t,{},s,c)},D=(t,r)=>({...r,type:t});function f(t,r=0){if(!t||typeof t!="object")return"";const{type:a,...c}=t,{action:s,...i}=c,n=s?f(s,r+1):"";switch(a){case"carousel":const{contents:p,...l}=i,b=p.map(N=>f(N,r+1));return n&&b.unshift(n),m.createElement(e.CAROUSEL,l,b,r);case"bubble":const{header:R,hero:B,body:S,footer:x,styles:T={},...k}=i,g=[];return n&&g.push(n),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,k,g,r);case"box":const{contents:X,background:I,...C}=i;C.layout||(C.layout="vertical");const y=[];return n&&y.push(n),I&&y.push(f(D("background",I),r+1)),y.push(...(X||[]).map(N=>f(N,r+1))),m.createElement(e.BOX,C,y,r);case"text":const{text:$,contents:d,...H}=i,v=d&&d.length>0?d.map(N=>f(N,r+1)):[$||""];return n&&v.unshift(n),m.createElement(e.TEXT,H,v,r);case"span":const{text:G,...M}=i,L=[G||""];return n&&L.unshift(n),m.createElement(e.SPAN,M,L,r);case"image":const{...F}=i,P=n?[n]:[];return m.createElement(e.IMAGE,F,P,r);case"video":const{altContent:w,...V}=i,U=w?[f(w,r+1)]:[];return n&&U.unshift(n),m.createElement(e.VIDEO,V,U,r);case"icon":const{...j}=i,Y=n?[n]:[];return m.createElement(e.ICON,j,Y,r);case"button":const{...K}=i,J=n?[n]:[];return m.createElement(e.BUTTON,K,J,r);case"separator":const W=n?[n]:[];return m.createElement(e.SEPARATOR,i,W,r);case"filler":const q=n?[n]:[];return m.createElement(e.FILLER,i,q,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:a,...i},[],r);case"background":return m.createElement(e.BACKGROUND,i,[],r);case"style":return m.createElement(e.STYLE,i,[],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"
@@ -34,12 +34,12 @@ const E = {
34
34
  ACTION: "action",
35
35
  BACKGROUND: "background",
36
36
  STYLE: "style"
37
- }, Q = [
37
+ }, D = [
38
38
  e.HEADER,
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,52 +50,55 @@ 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((a, c) => c(a), t);
67
+ ].reduce((i, o) => o(t, i), r);
65
68
  }
66
69
  function at(t) {
67
- const r = { type: "root", children: [] }, a = [r], c = new q(
70
+ const r = { type: "root", children: [] }, n = [r], i = new Z(
68
71
  {
69
- onopentag(s, i) {
70
- const n = {
72
+ onopentag(o, c) {
73
+ const a = {
71
74
  type: E.ELEMENT,
72
- tagName: s,
75
+ tagName: o,
73
76
  attributes: Object.fromEntries(
74
- Object.entries(i).map(([l, b]) => [l, rt(b)])
77
+ Object.entries(c).map(([s, b]) => [s, rt(s, b)])
75
78
  ),
76
79
  children: []
77
80
  };
78
- a[a.length - 1].children.push(n), a.push(n);
81
+ n[n.length - 1].children.push(a), n.push(a);
79
82
  },
80
- ontext(s) {
81
- const i = a[a.length - 1];
82
- if (i.tagName === "span") {
83
- i.children.push({
83
+ ontext(o) {
84
+ const c = n[n.length - 1];
85
+ if (c.tagName === "span") {
86
+ c.children.push({
84
87
  type: E.TEXT,
85
- content: s
88
+ content: o
86
89
  });
87
90
  return;
88
91
  }
89
- s.trim() && i.children.push({
92
+ o.trim() && c.children.push({
90
93
  type: E.TEXT,
91
- content: s.replace(/\n/g, "").trim()
94
+ content: o.replace(/\n/g, "").trim()
92
95
  });
93
96
  },
94
97
  onclosetag() {
95
- a.pop();
98
+ n.pop();
96
99
  },
97
- onerror(s) {
98
- console.error("解析錯誤:", s);
100
+ onerror(o) {
101
+ console.error("解析錯誤:", o);
99
102
  }
100
103
  },
101
104
  {
@@ -106,11 +109,11 @@ 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
- }, o = {
116
+ }, l = {
114
117
  carousel: (t) => ({
115
118
  type: "carousel",
116
119
  contents: t
@@ -202,91 +205,91 @@ const h = (t) => {
202
205
  };
203
206
  function nt(t) {
204
207
  if (t.tagName !== e.BACKGROUND && t.children && t.children.length > 0) {
205
- const r = t.children.filter((a) => a.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((a) => a.tagName !== e.BACKGROUND), r[0];
208
+ const r = t.children.filter((n) => n.tagName === e.BACKGROUND);
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
- const r = t.children.filter((a) => a.tagName === e.ACTION);
213
- return r.length > 1 && h("A node can only allowed with one action node inside"), t.children = t.children.filter((a) => a.tagName !== e.ACTION), r[0];
215
+ const r = t.children.filter((n) => n.tagName === e.ACTION);
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((s) => s.type === E.TEXT) && h("Span component only allowed inside Text component"), t.tagName === e.VIDEO && t.children?.some((s) => ![e.BOX, e.IMAGE].includes(s.tagName)) && h("Video component only allowed Box or Image as altContent child"), !Z.includes(t.tagName) && t.children?.some((s) => s.tagName === e.BACKGROUND) && h("Only Box component allowed to have Background 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
- const r = t.children.find((a) => a.tagName === e.STYLE);
225
+ const r = t.children.find((n) => n.tagName === e.STYLE);
223
226
  if (r)
224
- return t.children = t.children.filter((a) => a.tagName !== e.STYLE), r.attributes;
227
+ return t.children = t.children.filter((n) => n.tagName !== e.STYLE), r.attributes;
225
228
  }
226
229
  }
227
230
  function u(t) {
228
231
  t.attributes = t.attributes || {}, ct(t);
229
232
  const r = it(t);
230
233
  r && (t.attributes.action = u(r));
231
- const a = nt(t);
232
- if (a && (t.attributes.background = u(a)), t.type === E.TEXT)
233
- return o.span(t.content, t.attributes);
234
+ const n = nt(t);
235
+ if (n && (t.attributes.background = u(n)), t.type === E.TEXT)
236
+ return l.span(t.content, t.attributes);
234
237
  if (t.tagName === e.BUBBLE) {
235
- const c = t.children.find((l) => l.tagName === e.HEADER), s = t.children.find((l) => l.tagName === e.HERO), i = t.children.find((l) => l.tagName === e.BODY), n = t.children.find((l) => l.tagName === e.FOOTER), p = {
236
- header: O(c),
237
- hero: O(s),
238
- body: O(i),
239
- footer: O(n)
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
- return o.bubble({
244
+ return l.bubble({
242
245
  ...t.attributes,
243
- header: c ? u(c) : void 0,
244
- hero: s ? u(s) : void 0,
245
- body: i ? u(i) : void 0,
246
- footer: n ? u(n) : void 0,
247
- styles: Object.values(p).some((l) => l !== void 0) ? p : void 0
246
+ header: i ? u(i) : void 0,
247
+ hero: o ? u(o) : void 0,
248
+ body: c ? u(c) : void 0,
249
+ footer: a ? u(a) : void 0,
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"), o.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
- if (Q.includes(t.tagName))
255
- return t.children.length !== 1 && h(`${t.tagName} should have exactly one child node`), u(t.children[0]);
257
+ if (D.includes(t.tagName))
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"), o.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
- return o.span(
263
- c.content,
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)
265
+ return l.span(
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
- return o.text(
272
+ return l.text(
270
273
  t.children.map(u),
271
274
  t.attributes
272
275
  );
273
276
  if (t.tagName === e.SEPARATOR)
274
- return o.separator(t.attributes);
277
+ return l.separator(t.attributes);
275
278
  if (t.tagName === e.IMAGE)
276
- return o.image(t.attributes);
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]), o.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
- return o.icon(t.attributes);
283
+ return l.icon(t.attributes);
281
284
  if (t.tagName === e.FILLER)
282
- return o.filler(t.attributes);
285
+ return l.filler(t.attributes);
283
286
  if (t.tagName === e.BOX || t.tagName === e.DIV || t.tagName === e.ARTICLE)
284
- return t.attributes.layout || (t.attributes.layout = "vertical"), o.box(
287
+ return t.attributes.layout || (t.attributes.layout = "vertical"), l.box(
285
288
  t.children.map(u),
286
289
  t.attributes
287
290
  );
288
291
  if (t.tagName === e.SPACE)
289
- return o.span(" ".repeat(t.attributes.size || 1));
292
+ return l.span(" ".repeat(t.attributes.size || 1));
290
293
  if (t.tagName === e.STRONG)
291
294
  return t.tagName = e.TEXT, t.attributes.weight = "bold", u(t);
292
295
  if (t.tagName === e.BASELINE)
@@ -296,93 +299,93 @@ 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
- return o.uri(t.attributes);
305
+ return l.uri(t.attributes);
303
306
  case "postback":
304
- return o.postback(t.attributes);
307
+ return l.postback(t.attributes);
305
308
  case "message":
306
- return o.message(t.attributes);
309
+ return l.message(t.attributes);
307
310
  case "datetimepicker":
308
- return o.datetimepicker(t.attributes);
311
+ return l.datetimepicker(t.attributes);
309
312
  case "camera":
310
- return o.camera(t.attributes);
313
+ return l.camera(t.attributes);
311
314
  case "cameraRoll":
312
- return o.cameraRoll(t.attributes);
315
+ return l.cameraRoll(t.attributes);
313
316
  case "location":
314
- return o.location(t.attributes);
317
+ return l.location(t.attributes);
315
318
  case "richmenuswitch":
316
- return o.richmenuswitch(t.attributes);
319
+ return l.richmenuswitch(t.attributes);
317
320
  case "clipboard":
318
- return o.clipboard(t.attributes);
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 = {}, a = [], c = 0) => {
328
- const i = Object.entries(r).filter(([p, l]) => l != null).map(([p, l]) => typeof l == "object" ? `${p}="${JSON.stringify(l).replace(/"/g, "&quot;")}"` : `${p}="${l}"`).join(" "), n = i ? ` ${i}` : "";
329
- if (a.length === 0)
330
- return ` <${t}${n} />`;
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}` : "";
332
+ if (n.length === 0)
333
+ return ` <${t}${a} />`;
331
334
  {
332
- const p = a.map((l) => typeof l == "string" ? l.split(`
335
+ const p = n.map((s) => typeof s == "string" ? s.split(`
333
336
  `).map((b) => b ? " " + b : "").join(`
334
- `) : l).join(`
337
+ `) : s).join(`
335
338
  `);
336
- return ` <${t}${n}>
339
+ return ` <${t}${a}>
337
340
  ${p}
338
341
  </${t}>`;
339
342
  }
340
343
  },
341
344
  createText: (t) => t
342
- }, A = (t, r, a, c) => {
343
- const s = [f(r, c + 1)];
344
- return a && Object.keys(a).length > 0 && s.unshift(f(D("style", a), c + 1)), m.createElement(t, {}, s, c);
345
- }, D = (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: a, ...c } = t, { action: s, ...i } = c, n = s ? f(s, r + 1) : "";
350
- switch (a) {
352
+ const { type: n, ...i } = t, { action: o, ...c } = i, a = o ? f(o, r + 1) : "";
353
+ switch (n) {
351
354
  case "carousel":
352
- const { contents: p, ...l } = i, b = p.map((N) => f(N, r + 1));
353
- return n && b.unshift(n), m.createElement(e.CAROUSEL, l, 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: x, footer: S, styles: T = {}, ...k } = i, g = [];
356
- return n && g.push(n), R && g.push(A(e.HEADER, R, T.header, r + 1)), B && g.push(A(e.HERO, B, T.hero, r + 1)), x && g.push(A(e.BODY, x, T.body, r + 1)), S && g.push(A(e.FOOTER, S, T.footer, r + 1)), m.createElement(e.BUBBLE, k, 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: X, background: I, ...C } = i;
359
- C.layout || (C.layout = "vertical");
360
- const y = [];
361
- return n && y.push(n), I && y.push(f(D("background", I), r + 1)), y.push(...(X || []).map((N) => f(N, r + 1))), m.createElement(e.BOX, C, 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: $, contents: d, ...G } = i, L = d && d.length > 0 ? d.map((N) => f(N, r + 1)) : [$ || ""];
364
- return n && L.unshift(n), m.createElement(e.TEXT, G, L, 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: H, ...F } = i, v = [H || ""];
367
- return n && v.unshift(n), m.createElement(e.SPAN, F, v, 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 { ...V } = i, M = n ? [n] : [];
370
- return m.createElement(e.IMAGE, V, M, 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, ...P } = i, U = w ? [f(w, r + 1)] : [];
373
- return n && U.unshift(n), m.createElement(e.VIDEO, P, 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 } = i, Y = n ? [n] : [];
376
- return m.createElement(e.ICON, j, Y, r);
378
+ const { ...Y } = c, W = a ? [a] : [];
379
+ return h.createElement(e.ICON, Y, W, r);
377
380
  case "button":
378
- const { ...K } = i, W = n ? [n] : [];
379
- return m.createElement(e.BUTTON, K, W, r);
381
+ const { ...J } = c, z = a ? [a] : [];
382
+ return h.createElement(e.BUTTON, J, z, r);
380
383
  case "separator":
381
- const J = n ? [n] : [];
382
- return m.createElement(e.SEPARATOR, i, J, r);
384
+ const q = a ? [a] : [];
385
+ return h.createElement(e.SEPARATOR, c, q, r);
383
386
  case "filler":
384
- const z = n ? [n] : [];
385
- return m.createElement(e.FILLER, i, z, 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: a, ...i }, [], r);
399
+ return h.createElement(e.ACTION, { type: n, ...c }, [], r);
397
400
  case "background":
398
- return m.createElement(e.BACKGROUND, i, [], r);
401
+ return h.createElement(e.BACKGROUND, c, [], r);
399
402
  case "style":
400
- return m.createElement(e.STYLE, i, [], 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"},$=[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((a,c)=>c(a),t)}function V(t){const r={type:"root",children:[]},a=[r],c=new T.Parser({onopentag(s,i){const n={type:E.ELEMENT,tagName:s,attributes:Object.fromEntries(Object.entries(i).map(([l,g])=>[l,P(g)])),children:[]};a[a.length-1].children.push(n),a.push(n)},ontext(s){const i=a[a.length-1];if(i.tagName==="span"){i.children.push({type:E.TEXT,content:s});return}s.trim()&&i.children.push({type:E.TEXT,content:s.replace(/\n/g,"").trim()})},onclosetag(){a.pop()},onerror(s){console.error("解析錯誤:",s)}},{xmlMode:!0,lowerCaseTags:!1,lowerCaseAttributeNames:!1});return c.write(t),c.end(),r.children}const h=t=>{throw Error(`[Flex Html Render]: ${t}`)},o={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(a=>a.tagName===e.BACKGROUND);return r.length>1&&h("A box node can only allowed with one background node inside"),t.children=t.children.filter(a=>a.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(a=>a.tagName===e.ACTION);return r.length>1&&h("A node can only allowed with one action node inside"),t.children=t.children.filter(a=>a.tagName!==e.ACTION),r[0]}return null}function K(t){![...G,e.SPAN].includes(t.tagName)&&t.children?.some(s=>s.type===E.TEXT)&&h("Span component only allowed inside Text component"),t.tagName===e.VIDEO&&t.children?.some(s=>![e.BOX,e.IMAGE].includes(s.tagName))&&h("Video component only allowed Box or Image as altContent child"),!H.includes(t.tagName)&&t.children?.some(s=>s.tagName===e.BACKGROUND)&&h("Only Box component allowed to have Background child")}function d(t){if(t){const r=t.children.find(a=>a.tagName===e.STYLE);if(r)return t.children=t.children.filter(a=>a.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 a=j(t);if(a&&(t.attributes.background=u(a)),t.type===E.TEXT)return o.span(t.content,t.attributes);if(t.tagName===e.BUBBLE){const c=t.children.find(l=>l.tagName===e.HEADER),s=t.children.find(l=>l.tagName===e.HERO),i=t.children.find(l=>l.tagName===e.BODY),n=t.children.find(l=>l.tagName===e.FOOTER),p={header:d(c),hero:d(s),body:d(i),footer:d(n)};return o.bubble({...t.attributes,header:c?u(c):void 0,hero:s?u(s):void 0,body:i?u(i):void 0,footer:n?u(n):void 0,styles:Object.values(p).some(l=>l!==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"),o.carousel(t.children.map(u));if($.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"),o.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 o.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 o.text(t.children.map(u),t.attributes);if(t.tagName===e.SEPARATOR)return o.separator(t.attributes);if(t.tagName===e.IMAGE)return o.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]),o.video(t.attributes);if(t.tagName===e.ICON)return o.icon(t.attributes);if(t.tagName===e.FILLER)return o.filler(t.attributes);if(t.tagName===e.BOX||t.tagName===e.DIV||t.tagName===e.ARTICLE)return t.attributes.layout||(t.attributes.layout="vertical"),o.box(t.children.map(u),t.attributes);if(t.tagName===e.SPACE)return o.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 o.uri(t.attributes);case"postback":return o.postback(t.attributes);case"message":return o.message(t.attributes);case"datetimepicker":return o.datetimepicker(t.attributes);case"camera":return o.camera(t.attributes);case"cameraRoll":return o.cameraRoll(t.attributes);case"location":return o.location(t.attributes);case"richmenuswitch":return o.richmenuswitch(t.attributes);case"clipboard":return o.clipboard(t.attributes);default:h(`Unsupported action type: ${c}`)}}if(t.tagName===e.BACKGROUND)return t.attributes}const m={createElement:(t,r={},a=[],c=0)=>{const i=Object.entries(r).filter(([p,l])=>l!=null).map(([p,l])=>typeof l=="object"?`${p}="${JSON.stringify(l).replace(/"/g,"&quot;")}"`:`${p}="${l}"`).join(" "),n=i?` ${i}`:"";if(a.length===0)return` <${t}${n} />`;{const p=a.map(l=>typeof l=="string"?l.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
- `):l).join(`
4
- `);return` <${t}${n}>
3
+ `):c).join(`
4
+ `);return` <${t}${a}>
5
5
  ${p}
6
- </${t}>`}},createText:t=>t},O=(t,r,a,c)=>{const s=[f(r,c+1)];return a&&Object.keys(a).length>0&&s.unshift(f(x("style",a),c+1)),m.createElement(t,{},s,c)},x=(t,r)=>({...r,type:t});function f(t,r=0){if(!t||typeof t!="object")return"";const{type:a,...c}=t,{action:s,...i}=c,n=s?f(s,r+1):"";switch(a){case"carousel":const{contents:p,...l}=i,g=p.map(y=>f(y,r+1));return n&&g.unshift(n),m.createElement(e.CAROUSEL,l,g,r);case"bubble":const{header:S,hero:I,body:v,footer:L,styles:A={},...W}=i,N=[];return n&&N.push(n),S&&N.push(O(e.HEADER,S,A.header,r+1)),I&&N.push(O(e.HERO,I,A.hero,r+1)),v&&N.push(O(e.BODY,v,A.body,r+1)),L&&N.push(O(e.FOOTER,L,A.footer,r+1)),m.createElement(e.BUBBLE,W,N,r);case"box":const{contents:q,background:w,...R}=i;R.layout||(R.layout="vertical");const C=[];return n&&C.push(n),w&&C.push(f(x("background",w),r+1)),C.push(...(q||[]).map(y=>f(y,r+1))),m.createElement(e.BOX,R,C,r);case"text":const{text:z,contents:B,..._}=i,U=B&&B.length>0?B.map(y=>f(y,r+1)):[z||""];return n&&U.unshift(n),m.createElement(e.TEXT,_,U,r);case"span":const{text:Q,...Z}=i,D=[Q||""];return n&&D.unshift(n),m.createElement(e.SPAN,Z,D,r);case"image":const{...tt}=i,et=n?[n]:[];return m.createElement(e.IMAGE,tt,et,r);case"video":const{altContent:k,...rt}=i,X=k?[f(k,r+1)]:[];return n&&X.unshift(n),m.createElement(e.VIDEO,rt,X,r);case"icon":const{...at}=i,nt=n?[n]:[];return m.createElement(e.ICON,at,nt,r);case"button":const{...it}=i,ct=n?[n]:[];return m.createElement(e.BUTTON,it,ct,r);case"separator":const st=n?[n]:[];return m.createElement(e.SEPARATOR,i,st,r);case"filler":const lt=n?[n]:[];return m.createElement(e.FILLER,i,lt,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:a,...i},[],r);case"background":return m.createElement(e.BACKGROUND,i,[],r);case"style":return m.createElement(e.STYLE,i,[],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=f,b.default=J,Object.defineProperties(b,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
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.1",
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",