@bravophone/webphone 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/bravophone.mjs +20 -20
- package/dist/bravophone.umd.js +12 -12
- package/host/popup.js +1 -1
- package/host/shim/guest-bridge.js +15 -2
- package/package.json +1 -1
- package/types/index.d.ts +19 -0
package/README.md
CHANGED
|
@@ -430,10 +430,20 @@ Bravophone.init({
|
|
|
430
430
|
tenant: '…',
|
|
431
431
|
clienteId: '…',
|
|
432
432
|
ramaisUrl: '…',
|
|
433
|
+
|
|
434
|
+
// A segunda metade: sem ela o app fica na tela de login, mesmo com o
|
|
435
|
+
// vxToken válido. O checkToken do webphone exige as duas.
|
|
436
|
+
extension: { username: '…', password: '…', server: '…' },
|
|
433
437
|
},
|
|
434
438
|
})
|
|
435
439
|
```
|
|
436
440
|
|
|
441
|
+
**Onde a credencial SIP fica.** O `extension` viaja apenas pela ponte
|
|
442
|
+
(`postMessage`) e é aplicado no store em memória do webphone. Ele **não** entra
|
|
443
|
+
no HTML do iframe nem no `localStorage` — a senha não fica legível no DOM da sua
|
|
444
|
+
página. As outras sete chaves são pré-gravadas no storage, porque é de lá que o
|
|
445
|
+
bundle as lê.
|
|
446
|
+
|
|
437
447
|
O SDK grava essas chaves onde o bundle as procura, **antes** dele avaliar — a
|
|
438
448
|
sessão já sobe autenticada, sem piscar a tela de login.
|
|
439
449
|
|
package/dist/bravophone.mjs
CHANGED
|
@@ -435,7 +435,7 @@ function Ee({ root: e, handle: t, handles: n, preview: i, geometry: r, limits: d
|
|
|
435
435
|
}
|
|
436
436
|
i.hidden = !1, i.style.left = `${o.x}px`, i.style.top = `${o.y}px`, i.style.width = `${o.width}px`, i.style.height = `${o.height}px`;
|
|
437
437
|
}
|
|
438
|
-
},
|
|
438
|
+
}, R = (o, b) => {
|
|
439
439
|
const h = he(d);
|
|
440
440
|
let { x: E, y: v, width: M, height: T } = c;
|
|
441
441
|
p.includes("e") && (M = c.width + o), p.includes("w") && (M = c.width - o), p.includes("s") && (T = c.height + b), p.includes("n") && (T = c.height - b), M = Math.min(h.maxWidth, Math.max(h.minWidth, M)), T = Math.min(h.maxHeight, Math.max(h.minHeight, T)), p.includes("w") && (E = c.x + (c.width - M)), p.includes("n") && (v = c.y + (c.height - T)), p.includes("e") && Math.abs(E + M - window.innerWidth) <= X && (M = window.innerWidth - E), p.includes("w") && Math.abs(E) <= X && (M += E, E = 0), p.includes("s") && Math.abs(v + T - window.innerHeight) <= X && (T = window.innerHeight - v), p.includes("n") && Math.abs(v) <= X && (T += v, v = 0), a = { ...a, x: E, y: v, width: M, height: T, dock: null }, y();
|
|
@@ -458,7 +458,7 @@ function Ee({ root: e, handle: t, handles: n, preview: i, geometry: r, limits: d
|
|
|
458
458
|
}, F = (o) => {
|
|
459
459
|
if (!g || !c) return;
|
|
460
460
|
const b = o.clientX - c.px, h = o.clientY - c.py;
|
|
461
|
-
g === "drag" ? W(b, h, o.clientX, o.clientY) :
|
|
461
|
+
g === "drag" ? W(b, h, o.clientX, o.clientY) : R(b, h);
|
|
462
462
|
}, A = (o) => {
|
|
463
463
|
if (g) {
|
|
464
464
|
e.classList.remove("bp-dragging", "bp-resizing"), C(null), g === "drag" && j(), g = null, p = "", c = null, x = null;
|
|
@@ -540,11 +540,11 @@ function Te({ frame: e, origin: t, onEvent: n }) {
|
|
|
540
540
|
function a(g, p, { timeout: c = 15e3 } = {}) {
|
|
541
541
|
return new Promise((l, x) => {
|
|
542
542
|
const k = `${Date.now()}-${++r}`, y = () => {
|
|
543
|
-
var
|
|
543
|
+
var R;
|
|
544
544
|
const C = setTimeout(() => {
|
|
545
545
|
i.delete(k), x(new Error(`Bravophone: timeout no comando "${g}"`));
|
|
546
546
|
}, c);
|
|
547
|
-
i.set(k, { resolve: l, reject: x, timer: C }), (
|
|
547
|
+
i.set(k, { resolve: l, reject: x, timer: C }), (R = e.contentWindow) == null || R.postMessage(
|
|
548
548
|
{ protocol: be, type: "command", id: k, command: g, payload: p },
|
|
549
549
|
t
|
|
550
550
|
);
|
|
@@ -629,7 +629,7 @@ function Ce(e, t = "@bravophone/webphone") {
|
|
|
629
629
|
return `${Oe}/${t}@${e}/host/`;
|
|
630
630
|
}
|
|
631
631
|
function We({ version: e, parentOrigin: t, session: n, base: i }) {
|
|
632
|
-
const r = i || Ce(e), d = JSON.stringify({ parentOrigin: t, session:
|
|
632
|
+
const r = i || Ce(e), d = n ? { ...n, extension: void 0 } : null, u = JSON.stringify({ parentOrigin: t, session: d }).replace(/</g, "\\u003c");
|
|
633
633
|
return `<!doctype html>
|
|
634
634
|
<html lang="pt-BR">
|
|
635
635
|
<head>
|
|
@@ -650,7 +650,7 @@ function We({ version: e, parentOrigin: t, session: n, base: i }) {
|
|
|
650
650
|
</style>
|
|
651
651
|
<script>
|
|
652
652
|
(function () {
|
|
653
|
-
var cfg = ${
|
|
653
|
+
var cfg = ${u};
|
|
654
654
|
// O guest-bridge lê daqui: em srcdoc não há query string para carregar a
|
|
655
655
|
// origem do pai.
|
|
656
656
|
window.__bpParentOrigin = cfg.parentOrigin;
|
|
@@ -742,7 +742,7 @@ function Ae(e) {
|
|
|
742
742
|
hostBase: x,
|
|
743
743
|
version: k,
|
|
744
744
|
emit: y
|
|
745
|
-
} = e, C = l === "srcdoc",
|
|
745
|
+
} = e, C = l === "srcdoc", R = C ? window.location.origin : new URL(t).origin, W = w("div", { "data-bravophone": "root" });
|
|
746
746
|
W.style.cssText = "all:initial;position:static";
|
|
747
747
|
const j = W.attachShadow({ mode: "open" });
|
|
748
748
|
j.appendChild(w("style", { text: Le }));
|
|
@@ -771,7 +771,7 @@ function Ae(e) {
|
|
|
771
771
|
"srcdoc",
|
|
772
772
|
We({
|
|
773
773
|
version: k,
|
|
774
|
-
parentOrigin:
|
|
774
|
+
parentOrigin: R,
|
|
775
775
|
base: x,
|
|
776
776
|
// token sozinho vira uma sessão mínima; sem sip/ramal o webphone
|
|
777
777
|
// carrega mas não registra.
|
|
@@ -779,7 +779,7 @@ function Ae(e) {
|
|
|
779
779
|
})
|
|
780
780
|
) : b.setAttribute(
|
|
781
781
|
"src",
|
|
782
|
-
|
|
782
|
+
Re(new URL(t), { token: n, embed: "1", parent: location.origin })
|
|
783
783
|
);
|
|
784
784
|
const E = ["n", "s", "w", "e", "nw", "ne", "sw", "se"].map((s) => ({
|
|
785
785
|
el: w("div", { class: `bp-h bp-h-${s}` }),
|
|
@@ -825,7 +825,7 @@ function Ae(e) {
|
|
|
825
825
|
onChange: (s) => y("resize", { width: s.width, height: s.height, dock: s.dock || null })
|
|
826
826
|
}), ee = Te({
|
|
827
827
|
frame: b,
|
|
828
|
-
origin:
|
|
828
|
+
origin: R,
|
|
829
829
|
onEvent: (s, z) => {
|
|
830
830
|
var O;
|
|
831
831
|
if (s === "ready" && (A.dataset.state = "ready", H.dataset.state = "ready", (i || n) && ee.call("auth", { session: i || { vxToken: n } }).catch(() => {
|
|
@@ -911,24 +911,24 @@ function Ae(e) {
|
|
|
911
911
|
};
|
|
912
912
|
return G.addEventListener("click", () => $.hide()), B.addEventListener("click", () => $.minimize()), M.addEventListener("click", () => $.hide()), $;
|
|
913
913
|
}
|
|
914
|
-
function
|
|
914
|
+
function Re(e, t) {
|
|
915
915
|
const n = new URL(e.href);
|
|
916
916
|
for (const [i, r] of Object.entries(t))
|
|
917
917
|
r != null && r !== "" && n.searchParams.set(i, r);
|
|
918
918
|
return t.token && (n.searchParams.delete("token"), n.hash = `token=${encodeURIComponent(t.token)}`), n.href;
|
|
919
919
|
}
|
|
920
|
-
const
|
|
920
|
+
const De = "";
|
|
921
921
|
let S = null;
|
|
922
|
-
const
|
|
922
|
+
const D = /* @__PURE__ */ new Map();
|
|
923
923
|
function Be(e, t) {
|
|
924
924
|
var n, i;
|
|
925
|
-
(n =
|
|
925
|
+
(n = D.get(e)) == null || n.forEach((r) => {
|
|
926
926
|
try {
|
|
927
927
|
r(t);
|
|
928
928
|
} catch (d) {
|
|
929
929
|
console.error("[Bravophone] listener falhou:", d);
|
|
930
930
|
}
|
|
931
|
-
}), (i =
|
|
931
|
+
}), (i = D.get("*")) == null || i.forEach((r) => {
|
|
932
932
|
try {
|
|
933
933
|
r({ event: e, payload: t });
|
|
934
934
|
} catch (d) {
|
|
@@ -969,7 +969,7 @@ const ie = {
|
|
|
969
969
|
"Bravophone: mode 'hosted' exige hostUrl. Use mode 'srcdoc' (padrão) para carregar o webphone do CDN sem depender de um host próprio."
|
|
970
970
|
);
|
|
971
971
|
return S = Ae({
|
|
972
|
-
hostUrl:
|
|
972
|
+
hostUrl: De,
|
|
973
973
|
version: ie.version,
|
|
974
974
|
...e,
|
|
975
975
|
emit: Be
|
|
@@ -1056,17 +1056,17 @@ const ie = {
|
|
|
1056
1056
|
/** Eventos: ready, state, call:dialing, call:incoming, call:answered,
|
|
1057
1057
|
* call:ended, call:failed, resize, open, close, error. */
|
|
1058
1058
|
on(e, t) {
|
|
1059
|
-
return
|
|
1059
|
+
return D.has(e) || D.set(e, /* @__PURE__ */ new Set()), D.get(e).add(t), () => ie.off(e, t);
|
|
1060
1060
|
},
|
|
1061
1061
|
off(e, t) {
|
|
1062
1062
|
var n;
|
|
1063
|
-
(n =
|
|
1063
|
+
(n = D.get(e)) == null || n.delete(t);
|
|
1064
1064
|
},
|
|
1065
1065
|
destroy() {
|
|
1066
|
-
S == null || S.destroy(), S = null,
|
|
1066
|
+
S == null || S.destroy(), S = null, D.clear();
|
|
1067
1067
|
},
|
|
1068
1068
|
// Substituída em build time pelo valor do package.json (ver vite.config.js).
|
|
1069
|
-
version: "0.4.
|
|
1069
|
+
version: "0.4.1"
|
|
1070
1070
|
};
|
|
1071
1071
|
typeof window != "undefined" && (window.Bravophone = ie);
|
|
1072
1072
|
export {
|
package/dist/bravophone.umd.js
CHANGED
|
@@ -354,7 +354,7 @@
|
|
|
354
354
|
.bp-launcher-icon { transition: none; }
|
|
355
355
|
}
|
|
356
356
|
|
|
357
|
-
`,se="bravophone:widget:geometry",Y=28,V=32;function Me(e){try{const t=localStorage.getItem(se);if(!t)return{...e};const n=JSON.parse(t);return n.dock?{...e,...n,...P(n.dock,n)}:{...e,...n}}catch(t){return{...e}}}function J(e){try{localStorage.setItem(se,JSON.stringify(e))}catch(t){}}function de(e){return{minWidth:e.minWidth,minHeight:e.minHeight,maxWidth:Math.max(e.minWidth,Math.min(e.maxWidth,window.innerWidth)),maxHeight:Math.max(e.minHeight,Math.min(e.maxHeight,window.innerHeight))}}function U(e){const t=Math.max(0,window.innerWidth-e.width),n=Math.max(0,window.innerHeight-40);return{...e,x:Math.min(Math.max(0,e.x),t),y:Math.min(Math.max(0,e.y),n)}}function P(e,t){const n=window.innerWidth,
|
|
357
|
+
`,se="bravophone:widget:geometry",Y=28,V=32;function Me(e){try{const t=localStorage.getItem(se);if(!t)return{...e};const n=JSON.parse(t);return n.dock?{...e,...n,...P(n.dock,n)}:{...e,...n}}catch(t){return{...e}}}function J(e){try{localStorage.setItem(se,JSON.stringify(e))}catch(t){}}function de(e){return{minWidth:e.minWidth,minHeight:e.minHeight,maxWidth:Math.max(e.minWidth,Math.min(e.maxWidth,window.innerWidth)),maxHeight:Math.max(e.minHeight,Math.min(e.maxHeight,window.innerHeight))}}function U(e){const t=Math.max(0,window.innerWidth-e.width),n=Math.max(0,window.innerHeight-40);return{...e,x:Math.min(Math.max(0,e.x),t),y:Math.min(Math.max(0,e.y),n)}}function P(e,t){const n=window.innerWidth,r=window.innerHeight,i=Math.round(n/2),d=Math.round(r/2),u=Math.min(t.width,n);switch(e){case"left":return{x:0,y:0,width:u,height:r};case"right":return{x:n-u,y:0,width:u,height:r};case"left-half":return{x:0,y:0,width:i,height:r};case"right-half":return{x:n-i,y:0,width:i,height:r};case"top":return{x:t.x,y:0,width:u,height:d};case"bottom":return{x:t.x,y:r-d,width:u,height:d};case"top-half":return{x:0,y:0,width:n,height:d};case"bottom-half":return{x:0,y:r-d,width:n,height:d};case"max":return{x:0,y:0,width:n,height:r};default:return{x:t.x,y:t.y,width:t.width,height:t.height}}}function Le(e,t,n){const r=window.innerWidth,i=window.innerHeight,d=e<=Y,u=e>=r-Y,x=t<=Y,a=t>=i-Y;return(x||a)&&d?"left-half":(x||a)&&u?"right-half":x?n||"max":a?"bottom-half":d?"left":u?"right":null}function Se({root:e,handle:t,handles:n,preview:r,geometry:i,limits:d,topDock:u,onChange:x}){let a={...i},g=null,p="",c=null,l=null,w=null,M=null;const y=()=>{e.style.left=`${a.x}px`,e.style.top=`${a.y}px`,e.style.width=`${a.width}px`,e.style.height=`${a.height}px`,e.classList.toggle("bp-docked",!!a.dock),x==null||x(a)},A=o=>{if(r){if(!o){r.hidden=!0;return}r.hidden=!1,r.style.left=`${o.x}px`,r.style.top=`${o.y}px`,r.style.width=`${o.width}px`,r.style.height=`${o.height}px`}},D=(o,b)=>{const h=de(d);let{x:E,y:v,width:L,height:T}=c;p.includes("e")&&(L=c.width+o),p.includes("w")&&(L=c.width-o),p.includes("s")&&(T=c.height+b),p.includes("n")&&(T=c.height-b),L=Math.min(h.maxWidth,Math.max(h.minWidth,L)),T=Math.min(h.maxHeight,Math.max(h.minHeight,T)),p.includes("w")&&(E=c.x+(c.width-L)),p.includes("n")&&(v=c.y+(c.height-T)),p.includes("e")&&Math.abs(E+L-window.innerWidth)<=V&&(L=window.innerWidth-E),p.includes("w")&&Math.abs(E)<=V&&(L+=E,E=0),p.includes("s")&&Math.abs(v+T-window.innerHeight)<=V&&(T=window.innerHeight-v),p.includes("n")&&Math.abs(v)<=V&&(T+=v,v=0),a={...a,x:E,y:v,width:L,height:T,dock:null},y()},W=(o,b,h,E)=>{if(a.dock){const v=M||{width:d.width,height:d.height},L=l.x/Math.max(1,a.width);a={...a,...v,dock:null},l={x:Math.round(v.width*L),y:Math.min(l.y,32)},c={...c,x:h-l.x,y:E-l.y,px:c.px+o,py:c.py+b},o=0,b=0}a=U({...a,x:c.x+o,y:c.y+b}),y(),w=Le(h,E,u),A(w?P(w,a):null)},q=()=>{w&&(M=M||{width:a.width,height:a.height},a={...a,...P(w,a),dock:w},y())},K=(o,b)=>h=>{h.button===0&&(o==="drag"&&h.target.closest(".bp-btn")||(g=o,p=b||"",c={px:h.clientX,py:h.clientY,...a},l={x:h.clientX-a.x,y:h.clientY-a.y},a.dock||(M={width:a.width,height:a.height}),e.classList.add(o==="drag"?"bp-dragging":"bp-resizing"),h.currentTarget.setPointerCapture(h.pointerId),h.preventDefault()))},Z=o=>{if(!g||!c)return;const b=o.clientX-c.px,h=o.clientY-c.py;g==="drag"?W(b,h,o.clientX,o.clientY):D(b,h)},R=o=>{if(g){e.classList.remove("bp-dragging","bp-resizing"),A(null),g==="drag"&&q(),g=null,p="",c=null,w=null;try{o.currentTarget.releasePointerCapture(o.pointerId)}catch(b){}J(a)}};t.addEventListener("pointerdown",K("drag")),t.addEventListener("pointermove",Z),t.addEventListener("pointerup",R),t.addEventListener("pointercancel",R),(n||[]).forEach(({el:o,dir:b})=>{o.addEventListener("pointerdown",K("resize",b)),o.addEventListener("pointermove",Z),o.addEventListener("pointerup",R),o.addEventListener("pointercancel",R)});const j=()=>{a=a.dock?{...a,...P(a.dock,a)}:U(a),y()};window.addEventListener("resize",j);const Q={start(o){var b,h;g="drag",c={px:o.x,py:o.y,...a},l={x:(b=o.cx)!=null?b:a.width/2,y:(h=o.cy)!=null?h:20},a.dock||(M={width:a.width,height:a.height}),e.classList.add("bp-dragging")},move(o){if(g!=="drag"||!c)return;const b=o.x-c.px,h=o.y-c.py;W(b,h,c.x+b+l.x,c.y+h+l.y)},end(){g==="drag"&&(e.classList.remove("bp-dragging"),A(null),q(),g=null,c=null,w=null,J(a))}};return y(),{external:Q,get geometry(){return{...a}},set(o){const b=de(d),h={...a,...o,dock:null};h.width=Math.min(b.maxWidth,Math.max(b.minWidth,h.width)),h.height=Math.min(b.maxHeight,Math.max(b.minHeight,h.height)),a=U(h),y(),J(a)},dock(o){if(!o||o==="float"){const b=M||{width:d.width,height:d.height};a=U({...a,...b,dock:null})}else a.dock||(M={width:a.width,height:a.height}),a={...a,...P(o,a),dock:o};y(),J(a)},destroy(){window.removeEventListener("resize",j)}}}const ce="bravophone/v1";function ze({frame:e,origin:t,onEvent:n}){const r=new Map;let i=0,d=!1;const u=[],x=g=>{var c;if(g.origin!==t||g.source!==e.contentWindow)return;const p=g.data;if(!(!p||p.protocol!==ce)){if(p.type==="ready"){for(d=!0;u.length;)u.shift()();n==null||n("ready",(c=p.payload)!=null?c:{});return}if(p.type==="reply"){const l=r.get(p.id);if(!l)return;r.delete(p.id),clearTimeout(l.timer),p.error?l.reject(new Error(p.error)):l.resolve(p.payload);return}p.type==="event"&&(n==null||n(p.name,p.payload))}};window.addEventListener("message",x);function a(g,p,{timeout:c=15e3}={}){return new Promise((l,w)=>{const M=`${Date.now()}-${++i}`,y=()=>{var D;const A=setTimeout(()=>{r.delete(M),w(new Error(`Bravophone: timeout no comando "${g}"`))},c);r.set(M,{resolve:l,reject:w,timer:A}),(D=e.contentWindow)==null||D.postMessage({protocol:ce,type:"command",id:M,command:g,payload:p},t)};d?y():u.push(y)})}return{call:a,get ready(){return d},destroy(){window.removeEventListener("message",x),r.forEach(({reject:g,timer:p})=>{clearTimeout(p),g(new Error("Bravophone: widget destruído"))}),r.clear()}}}const pe="bravophone:launcher",Ee=4,ae=8;function Te(e){try{const t=localStorage.getItem(pe);return t?{...e,...JSON.parse(t)}:{...e}}catch(t){return{...e}}}function ne(e){try{localStorage.setItem(pe,JSON.stringify(e))}catch(t){}}function _(e,t){const n=Math.max(ae,window.innerHeight-t-ae);return Math.min(Math.max(ae,e),n)}function He({el:e,side:t,y:n,onOpen:r}){let i={side:t,y:_(n,e.offsetHeight||48)},d=null,u=!1;const x=()=>{e.dataset.side=i.side,e.style.top=`${i.y}px`,e.style.right=i.side==="right"?"0px":"auto",e.style.left=i.side==="left"?"0px":"auto"},a=l=>{l.button===0&&(d={py:l.clientY,y:i.y},u=!1,e.setPointerCapture(l.pointerId))},g=l=>{if(!d)return;const w=l.clientY-d.py;!u&&Math.abs(w)<Ee||(u||(u=!0,e.classList.add("bp-launcher-dragging")),i.y=_(d.y+w,e.offsetHeight),x())},p=l=>{if(!d)return;const w=u;d=null,u=!1,e.classList.remove("bp-launcher-dragging");try{e.releasePointerCapture(l.pointerId)}catch(M){}w?ne(i):r==null||r()};e.addEventListener("pointerdown",a),e.addEventListener("pointermove",g),e.addEventListener("pointerup",p),e.addEventListener("pointercancel",p),e.addEventListener("keydown",l=>{(l.key==="Enter"||l.key===" ")&&(l.preventDefault(),r==null||r())});const c=()=>{i.y=_(i.y,e.offsetHeight),x()};return window.addEventListener("resize",c),x(),{get state(){return{...i}},setSide(l){i.side=l,x(),ne(i)},moveTo(l){i.y=_(l,e.offsetHeight),x(),ne(i)},destroy(){window.removeEventListener("resize",c)}}}const Ie="https://cdn.jsdelivr.net/npm";function Oe(e,t="@bravophone/webphone"){return`${Ie}/${t}@${e}/host/`}function $e({version:e,parentOrigin:t,session:n,base:r}){const i=r||Oe(e),d=n?{...n,extension:void 0}:null,u=JSON.stringify({parentOrigin:t,session:d}).replace(/</g,"\\u003c");return`<!doctype html>
|
|
358
358
|
<html lang="pt-BR">
|
|
359
359
|
<head>
|
|
360
360
|
<meta charset="UTF-8">
|
|
@@ -365,16 +365,16 @@
|
|
|
365
365
|
elas resolvem contra a página do integrador — o documento herda o
|
|
366
366
|
baseURI do pai — e somem todas: logo, atender, desligar, mudo, hold,
|
|
367
367
|
transferir. Com <base>, resolvem contra o CDN. -->
|
|
368
|
-
<base href="${
|
|
369
|
-
<link rel="stylesheet" href="${
|
|
370
|
-
<link rel="stylesheet" href="${
|
|
368
|
+
<base href="${i}">
|
|
369
|
+
<link rel="stylesheet" href="${i}css/dark-theme.css">
|
|
370
|
+
<link rel="stylesheet" href="${i}styles/theme-fixes.css">
|
|
371
371
|
<style>
|
|
372
372
|
html, body { margin: 0; height: 100%; background: #10131c; overflow: hidden; }
|
|
373
373
|
#app { height: 100%; }
|
|
374
374
|
</style>
|
|
375
375
|
<script>
|
|
376
376
|
(function () {
|
|
377
|
-
var cfg = ${
|
|
377
|
+
var cfg = ${u};
|
|
378
378
|
// O guest-bridge lê daqui: em srcdoc não há query string para carregar a
|
|
379
379
|
// origem do pai.
|
|
380
380
|
window.__bpParentOrigin = cfg.parentOrigin;
|
|
@@ -404,15 +404,15 @@
|
|
|
404
404
|
}
|
|
405
405
|
})();
|
|
406
406
|
<\/script>
|
|
407
|
-
<script src="${
|
|
408
|
-
<script src="${
|
|
409
|
-
<script src="${
|
|
410
|
-
<script src="${
|
|
411
|
-
<script defer src="${
|
|
412
|
-
<script defer src="${
|
|
407
|
+
<script src="${i}shim/messages.js"><\/script>
|
|
408
|
+
<script src="${i}shim/chrome-shim.js"><\/script>
|
|
409
|
+
<script src="${i}js/libwebphone.js"><\/script>
|
|
410
|
+
<script src="${i}js/bravophone-route-selector.js"><\/script>
|
|
411
|
+
<script defer src="${i}popup.js"><\/script>
|
|
412
|
+
<script defer src="${i}shim/guest-bridge.js"><\/script>
|
|
413
413
|
</head>
|
|
414
414
|
<body>
|
|
415
415
|
<noscript><strong>O webphone precisa de JavaScript habilitado.</strong></noscript>
|
|
416
416
|
<div id="app"></div>
|
|
417
417
|
</body>
|
|
418
|
-
</html>`}const le={width:380,height:640,minWidth:320,minHeight:420,maxWidth:1600,maxHeight:1400,margin:24};function f(e,t={},n=[]){const
|
|
418
|
+
</html>`}const le={width:380,height:640,minWidth:320,minHeight:420,maxWidth:1600,maxHeight:1400,margin:24};function f(e,t={},n=[]){const r=document.createElement(e);for(const[i,d]of Object.entries(t))i==="class"?r.className=d:i==="text"?r.textContent=d:d!=null&&r.setAttribute(i,d);return n.forEach(i=>r.appendChild(i)),r}function Ce(e){const{hostUrl:t,token:n,session:r,position:i="bottom-right",open:d=!1,launcher:u=!0,title:x="BRAVOPHONE",frame:a="bar",dockTop:g="max",launcherSide:p="right",launcherIcon:c=te,mode:l="srcdoc",hostBase:w,version:M,emit:y}=e,A=l==="srcdoc",D=A?window.location.origin:new URL(t).origin,W=f("div",{"data-bravophone":"root"});W.style.cssText="all:initial;position:static";const q=W.attachShadow({mode:"open"});q.appendChild(f("style",{text:ke}));const K=(()=>{var fe;const{width:s,height:z,margin:$}=le,F=window.innerWidth-s-$,ge=window.innerHeight-z-$,me={"bottom-right":{x:F,y:ge},"bottom-left":{x:$,y:ge},"top-right":{x:F,y:$},"top-left":{x:$,y:$}};return U({...(fe=me[i])!=null?fe:me["bottom-right"],width:s,height:z})})(),Z=U(Me(K)),R=f("span",{class:"bp-status","data-state":"connecting"}),j=f("button",{class:"bp-btn bp-btn-min",title:"Minimizar",text:"—"}),Q=f("button",{class:"bp-btn bp-btn-close",title:"Fechar",text:"×"}),o=f("div",{class:"bp-header"},[R,f("span",{class:"bp-title",text:x}),j,Q]),b=f("iframe",{class:"bp-frame",allow:"microphone; autoplay; clipboard-write; speaker-selection",title:"Webphone BRAVOPHONE"});A?b.setAttribute("srcdoc",$e({version:M,parentOrigin:D,base:w,session:r||(n?{vxToken:n}:null)})):b.setAttribute("src",Ae(new URL(t),{token:n,embed:"1",parent:location.origin}));const E=["n","s","w","e","nw","ne","sw","se"].map(s=>({el:f("div",{class:`bp-h bp-h-${s}`}),dir:s})),v=f("div",{class:"bp-preview"});v.hidden=!0;const L=f("button",{class:"bp-btn bp-btn-close",title:"Fechar",text:"×"}),T=f("div",{class:"bp-overlay"},[L]),Be=f("div",{class:"bp-body"},[b,T]),S=f("div",{class:"bp-root"},[o,Be,...E.map(s=>s.el)]);a!=="bar"&&S.classList.add("bp-chromeless"),S.hidden=!d;const ie=f("span",{class:"bp-launcher-icon"});ie.innerHTML=G[c]||G[te];const he=f("span",{class:"bp-launcher-grip","aria-hidden":"true"});he.innerHTML=ve;const H=f("div",{class:"bp-launcher",role:"button",tabindex:"0",title:"Abrir webphone","aria-label":"Abrir webphone"},[he,ie,f("span",{class:"bp-badge"})]);H.dataset.state="connecting",H.hidden=!u,q.append(v,S,H),document.body.appendChild(W);const be=Te({side:p,y:Math.round(window.innerHeight/2-24)}),ue=He({el:H,side:be.side,y:_(be.y,48),onOpen:()=>O.reveal()}),I=Se({root:S,handle:o,handles:E,preview:v,geometry:Z,limits:le,topDock:g,onChange:s=>y("resize",{width:s.width,height:s.height,dock:s.dock||null})}),re=ze({frame:b,origin:D,onEvent:(s,z)=>{var $;if(s==="ready"&&(R.dataset.state="ready",H.dataset.state="ready",(r||n)&&re.call("auth",{session:r||{vxToken:n}}).catch(()=>{})),s==="state"){const F=($=z==null?void 0:z.state)!=null?$:"ready";R.dataset.state=F,H.dataset.state=F}if(s==="call:incoming"&&(O.show(),H.dataset.badge="1",H.dataset.state="ringing"),s==="call:answered"&&(H.dataset.state="incall"),s==="call:ended"&&(delete H.dataset.badge,H.dataset.state="ready"),s==="drag:start"){I.external.start(z);return}if(s==="drag:move"){I.external.move(z);return}if(s==="drag:end"){I.external.end();return}y(s,z)}});let ee=!1,oe=null;const O={el:W,bridge:re,show(){S.hidden=!1,y("open")},hide(){S.hidden=!0,y("close")},toggle(){S.hidden?O.show():O.hide()},reveal(){if(S.hidden){O.show();return}const s=I.geometry;(s.x+s.width<40||s.x>window.innerWidth-40||s.y>window.innerHeight-40)&&I.set({x:Math.round((window.innerWidth-s.width)/2),y:Math.round((window.innerHeight-s.height)/2)}),S.classList.remove("bp-attention"),S.offsetWidth,S.classList.add("bp-attention"),clearTimeout(oe),oe=setTimeout(()=>S.classList.remove("bp-attention"),1800),y("reveal")},get isOpen(){return!S.hidden},minimize(s){if(a!=="bar"){O.hide();return}ee=s!=null?s:!ee,S.classList.toggle("bp-minimized",ee),j.textContent=ee?"▢":"—"},move(s,z){I.set({x:s,y:z})},resize(s,z){I.set({width:s,height:z})},dock(s){I.dock(s)},setLauncherSide(s){ue.setSide(s)},setLauncherIcon(s){ie.innerHTML=G[s]||G[te]},get geometry(){return I.geometry},destroy(){clearTimeout(oe),re.destroy(),I.destroy(),ue.destroy(),v.remove(),W.remove()}};return Q.addEventListener("click",()=>O.hide()),j.addEventListener("click",()=>O.minimize()),L.addEventListener("click",()=>O.hide()),O}function Ae(e,t){const n=new URL(e.href);for(const[r,i]of Object.entries(t))i!=null&&i!==""&&n.searchParams.set(r,i);return t.token&&(n.searchParams.delete("token"),n.hash=`token=${encodeURIComponent(t.token)}`),n.href}const We="";let k=null;const B=new Map;function Re(e,t){var n,r;(n=B.get(e))==null||n.forEach(i=>{try{i(t)}catch(d){console.error("[Bravophone] listener falhou:",d)}}),(r=B.get("*"))==null||r.forEach(i=>{try{i({event:e,payload:t})}catch(d){console.error("[Bravophone] listener falhou:",d)}})}function m(){if(!k)throw new Error("Bravophone: chame Bravophone.init() antes.");return k}const X={init(e={}){if(k)return k;if(typeof window=="undefined"||!document.body)throw new Error("Bravophone: init() precisa rodar no browser, após o <body> existir.");if(location.protocol!=="https:"&&location.hostname!=="localhost"&&console.warn("[Bravophone] Contexto inseguro: o microfone exige HTTPS ou localhost."),e.mode==="hosted"&&!e.hostUrl)throw new Error("Bravophone: mode 'hosted' exige hostUrl. Use mode 'srcdoc' (padrão) para carregar o webphone do CDN sem depender de um host próprio.");return k=Ce({hostUrl:We,version:X.version,...e,emit:Re}),k},show(){m().show()},hide(){m().hide()},toggle(){m().toggle()},reveal(){m().reveal()},minimize(e){m().minimize(e)},move(e,t){m().move(e,t)},resize(e,t){m().resize(e,t)},dock(e){m().dock(e)},setLauncherSide(e){m().setLauncherSide(e)},setLauncherIcon(e){m().setLauncherIcon(e)},get isOpen(){return k?k.isOpen:!1},get geometry(){return k?k.geometry:null},call(e,t){return m().bridge.call("call",{number:e,meta:t})},hangup(){return m().bridge.call("hangup")},answer(){return m().bridge.call("answer")},mute(){return m().bridge.call("mute")},hold(){return m().bridge.call("hold")},sendDTMF(e){return m().bridge.call("dtmf",{tone:e})},transfer(e){return m().bridge.call("transfer",{to:e})},getStatus(){return m().bridge.call("status")},setAuth(e){const t=typeof e=="string"?{vxToken:e}:e;return m().bridge.call("auth",{session:t})},logout(){return m().bridge.call("logout")},on(e,t){return B.has(e)||B.set(e,new Set),B.get(e).add(t),()=>X.off(e,t)},off(e,t){var n;(n=B.get(e))==null||n.delete(t)},destroy(){k==null||k.destroy(),k=null,B.clear()},version:"0.4.1"};return typeof window!="undefined"&&(window.Bravophone=X),X});
|