@elliemae/ssf-host 2.23.6 → 2.24.0

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.
Files changed (91) hide show
  1. package/dist/cjs/callchain-host.html +262 -0
  2. package/dist/cjs/callchain-intermediate.html +92 -0
  3. package/dist/cjs/e2e-host.html +603 -0
  4. package/dist/cjs/e2e-index.html +234 -0
  5. package/dist/cjs/host.js +93 -36
  6. package/dist/cjs/index.html +304 -151
  7. package/dist/cjs/popup-focus-host.html +318 -0
  8. package/dist/cjs/utils.js +14 -1
  9. package/dist/cjs/v2-host-v1-guest.html +3 -0
  10. package/dist/esm/callchain-host.html +262 -0
  11. package/dist/esm/callchain-intermediate.html +92 -0
  12. package/dist/esm/e2e-host.html +603 -0
  13. package/dist/esm/e2e-index.html +234 -0
  14. package/dist/esm/host.js +94 -37
  15. package/dist/esm/index.html +304 -151
  16. package/dist/esm/popup-focus-host.html +318 -0
  17. package/dist/esm/utils.js +14 -1
  18. package/dist/esm/v2-host-v1-guest.html +3 -0
  19. package/dist/public/callchain-host.html +34 -0
  20. package/dist/public/callchain-host.js +3 -0
  21. package/dist/public/callchain-host.js.br +0 -0
  22. package/dist/public/callchain-host.js.gz +0 -0
  23. package/dist/public/callchain-host.js.map +1 -0
  24. package/dist/public/callchain-intermediate.html +1 -0
  25. package/dist/public/e2e-host.html +5 -0
  26. package/dist/public/e2e-host.js +8 -0
  27. package/dist/public/e2e-host.js.br +0 -0
  28. package/dist/public/e2e-host.js.gz +0 -0
  29. package/dist/public/e2e-host.js.map +1 -0
  30. package/dist/public/e2e-index.html +1 -0
  31. package/dist/public/index.html +1 -1
  32. package/dist/public/init.js +1 -1
  33. package/dist/public/init.js.br +0 -0
  34. package/dist/public/init.js.gz +0 -0
  35. package/dist/public/init.js.map +1 -1
  36. package/dist/public/js/emuiSsfHost.071827d0d7e775690fbb.js +3 -0
  37. package/dist/public/js/emuiSsfHost.071827d0d7e775690fbb.js.br +0 -0
  38. package/dist/public/js/emuiSsfHost.071827d0d7e775690fbb.js.gz +0 -0
  39. package/dist/public/js/emuiSsfHost.071827d0d7e775690fbb.js.map +1 -0
  40. package/dist/public/loan-object.js +1 -1
  41. package/dist/public/loan-object.js.br +0 -0
  42. package/dist/public/loan-object.js.gz +0 -0
  43. package/dist/public/loan-object.js.map +1 -1
  44. package/dist/public/popup-focus-host.html +1 -0
  45. package/dist/public/popup-focus-host.js +6 -0
  46. package/dist/public/popup-focus-host.js.br +0 -0
  47. package/dist/public/popup-focus-host.js.gz +0 -0
  48. package/dist/public/popup-focus-host.js.map +1 -0
  49. package/dist/public/v1-guest-v2-host.html +1 -1
  50. package/dist/public/v2-host-v1-guest.html +1 -1
  51. package/dist/types/lib/host.d.ts +1 -0
  52. package/dist/types/lib/ihost.d.ts +15 -0
  53. package/dist/types/lib/tests/timingDedup.test.d.ts +1 -0
  54. package/dist/types/lib/utils.d.ts +1 -0
  55. package/dist/types/tsconfig.tsbuildinfo +1 -1
  56. package/dist/umd/callchain-host.html +34 -0
  57. package/dist/umd/callchain-host.js +3 -0
  58. package/dist/umd/callchain-host.js.br +0 -0
  59. package/dist/umd/callchain-host.js.gz +0 -0
  60. package/dist/umd/callchain-host.js.map +1 -0
  61. package/dist/umd/callchain-intermediate.html +1 -0
  62. package/dist/umd/e2e-host.html +5 -0
  63. package/dist/umd/e2e-host.js +8 -0
  64. package/dist/umd/e2e-host.js.br +0 -0
  65. package/dist/umd/e2e-host.js.gz +0 -0
  66. package/dist/umd/e2e-host.js.map +1 -0
  67. package/dist/umd/e2e-index.html +1 -0
  68. package/dist/umd/index.html +1 -1
  69. package/dist/umd/index.js +1 -1
  70. package/dist/umd/index.js.br +0 -0
  71. package/dist/umd/index.js.gz +0 -0
  72. package/dist/umd/index.js.map +1 -1
  73. package/dist/umd/init.js +1 -1
  74. package/dist/umd/init.js.br +0 -0
  75. package/dist/umd/init.js.gz +0 -0
  76. package/dist/umd/init.js.map +1 -1
  77. package/dist/umd/loan-object.js +1 -1
  78. package/dist/umd/loan-object.js.br +0 -0
  79. package/dist/umd/loan-object.js.gz +0 -0
  80. package/dist/umd/loan-object.js.map +1 -1
  81. package/dist/umd/popup-focus-host.html +1 -0
  82. package/dist/umd/popup-focus-host.js +6 -0
  83. package/dist/umd/popup-focus-host.js.br +0 -0
  84. package/dist/umd/popup-focus-host.js.gz +0 -0
  85. package/dist/umd/popup-focus-host.js.map +1 -0
  86. package/dist/umd/v2-host-v1-guest.html +1 -1
  87. package/package.json +5 -5
  88. package/dist/public/js/emuiSsfHost.5855ec3cd0fa60013d84.js +0 -3
  89. package/dist/public/js/emuiSsfHost.5855ec3cd0fa60013d84.js.br +0 -0
  90. package/dist/public/js/emuiSsfHost.5855ec3cd0fa60013d84.js.gz +0 -0
  91. package/dist/public/js/emuiSsfHost.5855ec3cd0fa60013d84.js.map +0 -1
package/dist/umd/init.js CHANGED
@@ -1,3 +1,3 @@
1
- import{Loan as s}from"./loan-object.js";import{Analytics as a}from"./analytics-object-v2.js";import{Application as r}from"./application-object-v2.js";import{getGuestBaseUrl as o,getHost as d}from"./utils.js";let n=null,i=null;const l=async()=>{const e=await o();document.getElementById("credit").addEventListener("click",()=>{const{id:t}=n.loadGuest({id:"creditService",url:new URL("./creditService.html",e).href,title:"Credit Service Corp",searchParams:{src:new URL("./creditScoreService.js",e).href},targetElement:document.getElementById("bottom-container"),options:{fitToContent:!0}})})},m=async()=>{const e=await o(),t={};n.loadGuest({id:"pricingService",url:new URL("./pricingService.html",e).href,title:"Pricing Service Corp",params:t,targetElement:document.getElementById("aside-container"),options:{fitToContent:!0}})},u=async()=>{const e=await o(),t={};n.loadGuest({id:"loanValidation",url:new URL("./loanValidation.html",e).href,title:"Loan Validation Service Corp",params:t,targetElement:document.getElementById("bottom-container"),options:{fitToContent:!0}})},p=async()=>{const e=await o(),t={};n.loadGuest({id:"titleService",url:new URL("./titleService.html",e).href,title:"Title Service Corp",params:t,targetElement:document.getElementById("aside-container"),options:{openMode:ice.host.OpenMode.Popup}})},v=()=>{i=new s,n.addScriptingObject(i);const e=new r;n.addScriptingObject(e)},g=async()=>{const e=i.getLoanDetails();(await n.dispatchEvent({event:i.onPreSave,eventParams:e,eventOptions:{timeout:1e3}})).some(c=>c===!1)?document.getElementById("errorFeedback").classList.remove("hidden"):document.getElementById("successFeedback").classList.remove("hidden")},L=()=>{const e=new a;n=d(e),v();const t=document.getElementById("saveLoan");t&&t.addEventListener("click",g),l(),m(),u(),document.getElementById("title")?.addEventListener?.("click",p)};window.addEventListener("DOMContentLoaded",L);
1
+ import{Loan as a}from"./loan-object.js";import{Analytics as c}from"./analytics-object-v2.js";import{Application as s}from"./application-object-v2.js";import{getGuestBaseUrl as i,getHost as d}from"./utils.js";let n=null,o=null;const l=async()=>{const e=await i();document.getElementById("credit").addEventListener("click",()=>{const{id:t}=n.loadGuest({id:"creditService",url:new URL("./creditService.html",e).href,title:"Credit Service Corp",searchParams:{src:new URL("./creditScoreService.js",e).href},targetElement:document.getElementById("bottom-container"),options:{fitToContent:!0},metadata:{serviceType:"credit",provider:"CreditCorp"}})})},m=async()=>{const e=await i(),t={};n.loadGuest({id:"pricingService",url:new URL("./pricingService.html",e).href,title:"Pricing Service Corp",params:t,targetElement:document.getElementById("aside-container"),options:{fitToContent:!0},metadata:{serviceType:"pricing",provider:"PricingCorp"}})},p=async()=>{const e=await i(),t={};n.loadGuest({id:"loanValidation",url:new URL("./loanValidation.html",e).href,title:"Loan Validation Service Corp",params:t,targetElement:document.getElementById("bottom-container"),options:{fitToContent:!0},metadata:{serviceType:"validation",provider:"LoanValidators Inc"}})},v=async()=>{const e=await i(),t={};n.loadGuest({id:"titleService",url:new URL("./titleService.html",e).href,title:"Title Service Corp",params:t,targetElement:document.getElementById("aside-container"),options:{openMode:ice.host.OpenMode.Popup},metadata:{serviceType:"title",provider:"TitleService LLC"}})},u=()=>{o=new a,n.addScriptingObject(o);const e=new s;n.addScriptingObject(e)},g=async()=>{const e=o.getLoanDetails();(await n.dispatchEvent({event:o.onPreSave,eventParams:e,eventOptions:{timeout:1e3}})).some(r=>r===!1)?document.getElementById("errorFeedback").classList.remove("hidden"):document.getElementById("successFeedback").classList.remove("hidden")},L=()=>{const e=new c;n=d(e),u();const t=document.getElementById("saveLoan");t&&t.addEventListener("click",g),l(),m(),p(),document.getElementById("title")?.addEventListener?.("click",v)};window.addEventListener("DOMContentLoaded",L);
2
2
 
3
3
  //# sourceMappingURL=init.js.map
Binary file
Binary file
@@ -1 +1 @@
1
- {"version":3,"sources":["webpack://ice.host/init.js"],"sourcesContent":["import { Loan } from './loan-object.js';\nimport { Analytics } from './analytics-object-v2.js';\nimport { Application } from './application-object-v2.js';\nimport { getGuestBaseUrl, getHost } from './utils.js';\n\nlet host = null;\nlet loanObj = null;\n\nconst setupCreditService = async () => {\n const baseUrl = await getGuestBaseUrl();\n document.getElementById('credit').addEventListener('click', () => {\n const { id } = host.loadGuest({\n id: 'creditService',\n url: new URL('./creditService.html', baseUrl).href,\n title: 'Credit Service Corp',\n searchParams: { src: new URL('./creditScoreService.js', baseUrl).href },\n targetElement: document.getElementById('bottom-container'),\n options: { fitToContent: true },\n });\n });\n};\n\nconst setupPricingService = async () => {\n const baseUrl = await getGuestBaseUrl();\n const params = {};\n host.loadGuest({\n id: 'pricingService',\n url: new URL('./pricingService.html', baseUrl).href,\n title: 'Pricing Service Corp',\n params,\n targetElement: document.getElementById('aside-container'),\n options: { fitToContent: true },\n });\n};\n\nconst setupLoanValidationService = async () => {\n const baseUrl = await getGuestBaseUrl();\n const params = {};\n host.loadGuest({\n id: 'loanValidation',\n url: new URL('./loanValidation.html', baseUrl).href,\n title: 'Loan Validation Service Corp',\n params,\n targetElement: document.getElementById('bottom-container'),\n options: { fitToContent: true },\n });\n};\n\nconst setupTitleService = async () => {\n const baseUrl = await getGuestBaseUrl();\n const params = {};\n host.loadGuest({\n id: 'titleService',\n url: new URL('./titleService.html', baseUrl).href,\n title: 'Title Service Corp',\n params,\n targetElement: document.getElementById('aside-container'),\n options: { openMode: ice.host.OpenMode.Popup },\n });\n};\n\nconst setupObjects = () => {\n loanObj = new Loan();\n host.addScriptingObject(loanObj);\n const appObj = new Application();\n host.addScriptingObject(appObj);\n};\n\nconst saveLoan = async () => {\n const loanDetails = loanObj.getLoanDetails();\n const results = await host.dispatchEvent({\n event: loanObj.onPreSave,\n eventParams: loanDetails,\n eventOptions: {\n timeout: 1000,\n },\n });\n if (results.some((result) => result === false)) {\n const errorFeedback = document.getElementById('errorFeedback');\n errorFeedback.classList.remove('hidden');\n } else {\n const successFeedback = document.getElementById('successFeedback');\n successFeedback.classList.remove('hidden');\n }\n};\n\nconst init = () => {\n // elli.ssf.setLogLevel(0);\n const analyticsObj = new Analytics();\n host = getHost(analyticsObj);\n setupObjects();\n const saveLoanButton = document.getElementById('saveLoan');\n if (saveLoanButton) saveLoanButton.addEventListener('click', saveLoan);\n setupCreditService();\n setupPricingService();\n setupLoanValidationService();\n document\n .getElementById('title')\n ?.addEventListener?.('click', setupTitleService);\n};\n\nwindow.addEventListener('DOMContentLoaded', init);\n"],"mappings":"AAAA,OAAS,QAAAA,MAAY,mBACrB,OAAS,aAAAC,MAAiB,2BAC1B,OAAS,eAAAC,MAAmB,6BAC5B,OAAS,mBAAAC,EAAiB,WAAAC,MAAe,aAEzC,IAAIC,EAAO,KACPC,EAAU,KAEd,MAAMC,EAAqB,SAAY,CACrC,MAAMC,EAAU,MAAML,EAAgB,EACtC,SAAS,eAAe,QAAQ,EAAE,iBAAiB,QAAS,IAAM,CAChE,KAAM,CAAE,GAAAM,CAAG,EAAIJ,EAAK,UAAU,CAC5B,GAAI,gBACJ,IAAK,IAAI,IAAI,uBAAwBG,CAAO,EAAE,KAC9C,MAAO,sBACP,aAAc,CAAE,IAAK,IAAI,IAAI,0BAA2BA,CAAO,EAAE,IAAK,EACtE,cAAe,SAAS,eAAe,kBAAkB,EACzD,QAAS,CAAE,aAAc,EAAK,CAChC,CAAC,CACH,CAAC,CACH,EAEME,EAAsB,SAAY,CACtC,MAAMF,EAAU,MAAML,EAAgB,EAChCQ,EAAS,CAAC,EAChBN,EAAK,UAAU,CACb,GAAI,iBACJ,IAAK,IAAI,IAAI,wBAAyBG,CAAO,EAAE,KAC/C,MAAO,uBACP,OAAAG,EACA,cAAe,SAAS,eAAe,iBAAiB,EACxD,QAAS,CAAE,aAAc,EAAK,CAChC,CAAC,CACH,EAEMC,EAA6B,SAAY,CAC7C,MAAMJ,EAAU,MAAML,EAAgB,EAChCQ,EAAS,CAAC,EAChBN,EAAK,UAAU,CACb,GAAI,iBACJ,IAAK,IAAI,IAAI,wBAAyBG,CAAO,EAAE,KAC/C,MAAO,+BACP,OAAAG,EACA,cAAe,SAAS,eAAe,kBAAkB,EACzD,QAAS,CAAE,aAAc,EAAK,CAChC,CAAC,CACH,EAEME,EAAoB,SAAY,CACpC,MAAML,EAAU,MAAML,EAAgB,EAChCQ,EAAS,CAAC,EAChBN,EAAK,UAAU,CACb,GAAI,eACJ,IAAK,IAAI,IAAI,sBAAuBG,CAAO,EAAE,KAC7C,MAAO,qBACP,OAAAG,EACA,cAAe,SAAS,eAAe,iBAAiB,EACxD,QAAS,CAAE,SAAU,IAAI,KAAK,SAAS,KAAM,CAC/C,CAAC,CACH,EAEMG,EAAe,IAAM,CACzBR,EAAU,IAAIN,EACdK,EAAK,mBAAmBC,CAAO,EAC/B,MAAMS,EAAS,IAAIb,EACnBG,EAAK,mBAAmBU,CAAM,CAChC,EAEMC,EAAW,SAAY,CAC3B,MAAMC,EAAcX,EAAQ,eAAe,GAC3B,MAAMD,EAAK,cAAc,CACvC,MAAOC,EAAQ,UACf,YAAaW,EACb,aAAc,CACZ,QAAS,GACX,CACF,CAAC,GACW,KAAMC,GAAWA,IAAW,EAAK,EACrB,SAAS,eAAe,eAAe,EAC/C,UAAU,OAAO,QAAQ,EAEf,SAAS,eAAe,iBAAiB,EACjD,UAAU,OAAO,QAAQ,CAE7C,EAEMC,EAAO,IAAM,CAEjB,MAAMC,EAAe,IAAInB,EACzBI,EAAOD,EAAQgB,CAAY,EAC3BN,EAAa,EACb,MAAMO,EAAiB,SAAS,eAAe,UAAU,EACrDA,GAAgBA,EAAe,iBAAiB,QAASL,CAAQ,EACrET,EAAmB,EACnBG,EAAoB,EACpBE,EAA2B,EAC3B,SACG,eAAe,OAAO,GACrB,mBAAmB,QAASC,CAAiB,CACnD,EAEA,OAAO,iBAAiB,mBAAoBM,CAAI","names":["Loan","Analytics","Application","getGuestBaseUrl","getHost","host","loanObj","setupCreditService","baseUrl","id","setupPricingService","params","setupLoanValidationService","setupTitleService","setupObjects","appObj","saveLoan","loanDetails","result","init","analyticsObj","saveLoanButton"],"sourceRoot":"","file":"init.js"}
1
+ {"version":3,"sources":["webpack://ice.host/init.js"],"sourcesContent":["import { Loan } from './loan-object.js';\nimport { Analytics } from './analytics-object-v2.js';\nimport { Application } from './application-object-v2.js';\nimport { getGuestBaseUrl, getHost } from './utils.js';\n\nlet host = null;\nlet loanObj = null;\n\nconst setupCreditService = async () => {\n const baseUrl = await getGuestBaseUrl();\n document.getElementById('credit').addEventListener('click', () => {\n const { id } = host.loadGuest({\n id: 'creditService',\n url: new URL('./creditService.html', baseUrl).href,\n title: 'Credit Service Corp',\n searchParams: { src: new URL('./creditScoreService.js', baseUrl).href },\n targetElement: document.getElementById('bottom-container'),\n options: { fitToContent: true },\n metadata: { serviceType: 'credit', provider: 'CreditCorp' },\n });\n });\n};\n\nconst setupPricingService = async () => {\n const baseUrl = await getGuestBaseUrl();\n const params = {};\n host.loadGuest({\n id: 'pricingService',\n url: new URL('./pricingService.html', baseUrl).href,\n title: 'Pricing Service Corp',\n params,\n targetElement: document.getElementById('aside-container'),\n options: { fitToContent: true },\n metadata: { serviceType: 'pricing', provider: 'PricingCorp' },\n });\n};\n\nconst setupLoanValidationService = async () => {\n const baseUrl = await getGuestBaseUrl();\n const params = {};\n host.loadGuest({\n id: 'loanValidation',\n url: new URL('./loanValidation.html', baseUrl).href,\n title: 'Loan Validation Service Corp',\n params,\n targetElement: document.getElementById('bottom-container'),\n options: { fitToContent: true },\n metadata: { serviceType: 'validation', provider: 'LoanValidators Inc' },\n });\n};\n\nconst setupTitleService = async () => {\n const baseUrl = await getGuestBaseUrl();\n const params = {};\n host.loadGuest({\n id: 'titleService',\n url: new URL('./titleService.html', baseUrl).href,\n title: 'Title Service Corp',\n params,\n targetElement: document.getElementById('aside-container'),\n options: { openMode: ice.host.OpenMode.Popup },\n metadata: { serviceType: 'title', provider: 'TitleService LLC' },\n });\n};\n\nconst setupObjects = () => {\n loanObj = new Loan();\n host.addScriptingObject(loanObj);\n const appObj = new Application();\n host.addScriptingObject(appObj);\n};\n\nconst saveLoan = async () => {\n const loanDetails = loanObj.getLoanDetails();\n const results = await host.dispatchEvent({\n event: loanObj.onPreSave,\n eventParams: loanDetails,\n eventOptions: {\n timeout: 1000,\n },\n });\n if (results.some((result) => result === false)) {\n const errorFeedback = document.getElementById('errorFeedback');\n errorFeedback.classList.remove('hidden');\n } else {\n const successFeedback = document.getElementById('successFeedback');\n successFeedback.classList.remove('hidden');\n }\n};\n\nconst init = () => {\n // elli.ssf.setLogLevel(0);\n const analyticsObj = new Analytics();\n host = getHost(analyticsObj);\n setupObjects();\n const saveLoanButton = document.getElementById('saveLoan');\n if (saveLoanButton) saveLoanButton.addEventListener('click', saveLoan);\n setupCreditService();\n setupPricingService();\n setupLoanValidationService();\n document\n .getElementById('title')\n ?.addEventListener?.('click', setupTitleService);\n};\n\nwindow.addEventListener('DOMContentLoaded', init);\n"],"mappings":"AAAA,OAAS,QAAAA,MAAY,mBACrB,OAAS,aAAAC,MAAiB,2BAC1B,OAAS,eAAAC,MAAmB,6BAC5B,OAAS,mBAAAC,EAAiB,WAAAC,MAAe,aAEzC,IAAIC,EAAO,KACPC,EAAU,KAEd,MAAMC,EAAqB,SAAY,CACrC,MAAMC,EAAU,MAAML,EAAgB,EACtC,SAAS,eAAe,QAAQ,EAAE,iBAAiB,QAAS,IAAM,CAChE,KAAM,CAAE,GAAAM,CAAG,EAAIJ,EAAK,UAAU,CAC5B,GAAI,gBACJ,IAAK,IAAI,IAAI,uBAAwBG,CAAO,EAAE,KAC9C,MAAO,sBACP,aAAc,CAAE,IAAK,IAAI,IAAI,0BAA2BA,CAAO,EAAE,IAAK,EACtE,cAAe,SAAS,eAAe,kBAAkB,EACzD,QAAS,CAAE,aAAc,EAAK,EAC9B,SAAU,CAAE,YAAa,SAAU,SAAU,YAAa,CAC5D,CAAC,CACH,CAAC,CACH,EAEME,EAAsB,SAAY,CACtC,MAAMF,EAAU,MAAML,EAAgB,EAChCQ,EAAS,CAAC,EAChBN,EAAK,UAAU,CACb,GAAI,iBACJ,IAAK,IAAI,IAAI,wBAAyBG,CAAO,EAAE,KAC/C,MAAO,uBACP,OAAAG,EACA,cAAe,SAAS,eAAe,iBAAiB,EACxD,QAAS,CAAE,aAAc,EAAK,EAC9B,SAAU,CAAE,YAAa,UAAW,SAAU,aAAc,CAC9D,CAAC,CACH,EAEMC,EAA6B,SAAY,CAC7C,MAAMJ,EAAU,MAAML,EAAgB,EAChCQ,EAAS,CAAC,EAChBN,EAAK,UAAU,CACb,GAAI,iBACJ,IAAK,IAAI,IAAI,wBAAyBG,CAAO,EAAE,KAC/C,MAAO,+BACP,OAAAG,EACA,cAAe,SAAS,eAAe,kBAAkB,EACzD,QAAS,CAAE,aAAc,EAAK,EAC9B,SAAU,CAAE,YAAa,aAAc,SAAU,oBAAqB,CACxE,CAAC,CACH,EAEME,EAAoB,SAAY,CACpC,MAAML,EAAU,MAAML,EAAgB,EAChCQ,EAAS,CAAC,EAChBN,EAAK,UAAU,CACb,GAAI,eACJ,IAAK,IAAI,IAAI,sBAAuBG,CAAO,EAAE,KAC7C,MAAO,qBACP,OAAAG,EACA,cAAe,SAAS,eAAe,iBAAiB,EACxD,QAAS,CAAE,SAAU,IAAI,KAAK,SAAS,KAAM,EAC7C,SAAU,CAAE,YAAa,QAAS,SAAU,kBAAmB,CACjE,CAAC,CACH,EAEMG,EAAe,IAAM,CACzBR,EAAU,IAAIN,EACdK,EAAK,mBAAmBC,CAAO,EAC/B,MAAMS,EAAS,IAAIb,EACnBG,EAAK,mBAAmBU,CAAM,CAChC,EAEMC,EAAW,SAAY,CAC3B,MAAMC,EAAcX,EAAQ,eAAe,GAC3B,MAAMD,EAAK,cAAc,CACvC,MAAOC,EAAQ,UACf,YAAaW,EACb,aAAc,CACZ,QAAS,GACX,CACF,CAAC,GACW,KAAMC,GAAWA,IAAW,EAAK,EACrB,SAAS,eAAe,eAAe,EAC/C,UAAU,OAAO,QAAQ,EAEf,SAAS,eAAe,iBAAiB,EACjD,UAAU,OAAO,QAAQ,CAE7C,EAEMC,EAAO,IAAM,CAEjB,MAAMC,EAAe,IAAInB,EACzBI,EAAOD,EAAQgB,CAAY,EAC3BN,EAAa,EACb,MAAMO,EAAiB,SAAS,eAAe,UAAU,EACrDA,GAAgBA,EAAe,iBAAiB,QAASL,CAAQ,EACrET,EAAmB,EACnBG,EAAoB,EACpBE,EAA2B,EAC3B,SACG,eAAe,OAAO,GACrB,mBAAmB,QAASC,CAAiB,CACnD,EAEA,OAAO,iBAAiB,mBAAoBM,CAAI","names":["Loan","Analytics","Application","getGuestBaseUrl","getHost","host","loanObj","setupCreditService","baseUrl","id","setupPricingService","params","setupLoanValidationService","setupTitleService","setupObjects","appObj","saveLoan","loanDetails","result","init","analyticsObj","saveLoanButton"],"sourceRoot":"","file":"init.js"}
@@ -1,3 +1,3 @@
1
- import{getHost as r}from"./utils.js";import{Analytics as i}from"./analytics-object-v2.js";const t=s=>document.getElementById(s),o=r(new i);class d extends ice.host.ScriptingObject{constructor(){super("Loan"),this.loanId="ABC123",this.creditScore=0,this.serviceOrderStatus={title:!1,credit:!1},this.onSaved=new ice.host.Event({name:"onSaved",objectId:this.constructor.name}),this.onPreSave=new ice.host.Event({name:"onPreSave",objectId:this.constructor.name}),this.onLoanAmountChanged=new ice.host.Event({name:"onLoanAmountChanged",objectId:this.constructor.name}),this.onLoanTermChanged=new ice.host.Event({name:"onLoanTermChanged",objectId:this.constructor.name}),this.onDownPaymentChanged=new ice.host.Event({name:"onDownPaymentChanged",objectId:this.constructor.name}),t("amount")?.addEventListener?.("blur",e=>{o.dispatchEvent({event:this.onLoanAmountChanged,eventParams:{amount:e.target.value}})}),t("term")?.addEventListener?.("blur",e=>{o.dispatchEvent({event:this.onLoanTermChanged,eventParams:{term:e.target.value}})}),t("downPayment")?.addEventListener?.("blur",e=>{o.dispatchEvent({event:this.onDownPaymentChanged,eventParams:{downPayment:e.target.value}})})}getLoanDetails=()=>({id:this.loanId,firstName:t("firstName")?.value,lastName:t("lastName")?.value,ssn:t("ssn")?.value,amount:t("amount")?.value,term:t("term")?.value,downPayment:t("downPayment")?.value,creditScore:this.creditScore});setCreditScore=e=>{this.serviceOrderStatus.credit=!0,this.creditScore=e;const n=document.getElementById("credit");n&&(n.disabled=!0,n.textContent=`${n.textContent} : ${e}`)};setServiceOrderStatus=(e,n)=>{this.serviceOrderStatus[e]=n;const a=document.getElementById(e);a&&(a.disabled=n,a.textContent=`${a.textContent} : Done`)};saveLoan=async()=>{o.dispatchEvent({event:this.onSaved,eventParams:{id:this.loanId}})}}export{d as Loan};
1
+ import{getHost as r}from"./utils.js";import{Analytics as c}from"./analytics-object-v2.js";const e=i=>document.getElementById(i),s=r(new c);class d extends ice.host.ScriptingObject{constructor(){super("Loan"),this.loanId="ABC123",this.creditScore=0,this.serviceOrderStatus={title:!1,credit:!1},this.onSaved=new ice.host.Event({name:"onSaved",objectId:this.constructor.name}),this.onPreSave=new ice.host.Event({name:"onPreSave",objectId:this.constructor.name}),this.onLoanAmountChanged=new ice.host.Event({name:"onLoanAmountChanged",objectId:this.constructor.name}),this.onLoanTermChanged=new ice.host.Event({name:"onLoanTermChanged",objectId:this.constructor.name}),this.onDownPaymentChanged=new ice.host.Event({name:"onDownPaymentChanged",objectId:this.constructor.name}),e("amount")?.addEventListener?.("blur",t=>{s.dispatchEvent({event:this.onLoanAmountChanged,eventParams:{amount:t.target.value}})}),e("term")?.addEventListener?.("blur",t=>{s.dispatchEvent({event:this.onLoanTermChanged,eventParams:{term:t.target.value}})}),e("downPayment")?.addEventListener?.("blur",t=>{s.dispatchEvent({event:this.onDownPaymentChanged,eventParams:{downPayment:t.target.value}})})}getLoanDetails=()=>{const t=this.getLoanDetails.callContext;return t?.callChain?.length&&JSON.stringify(t.callChain),{id:this.loanId,firstName:e("firstName")?.value,lastName:e("lastName")?.value,ssn:e("ssn")?.value,amount:e("amount")?.value,term:e("term")?.value,downPayment:e("downPayment")?.value,creditScore:this.creditScore}};setCreditScore=t=>{const a=this.setCreditScore.callContext;a?.callChain?.length&&JSON.stringify(a.callChain),this.serviceOrderStatus.credit=!0,this.creditScore=t;const n=document.getElementById("credit");n&&(n.disabled=!0,n.textContent=`${n.textContent} : ${t}`)};setServiceOrderStatus=(t,a)=>{const n=this.setServiceOrderStatus.callContext;n?.callChain?.length&&JSON.stringify(n.callChain),this.serviceOrderStatus[t]=a;const o=document.getElementById(t);o&&(o.disabled=a,o.textContent=`${o.textContent} : Done`)};saveLoan=async()=>{s.dispatchEvent({event:this.onSaved,eventParams:{id:this.loanId}})}}export{d as Loan};
2
2
 
3
3
  //# sourceMappingURL=loan-object.js.map
Binary file
Binary file
@@ -1 +1 @@
1
- {"version":3,"sources":["webpack://ice.host/loan-object.js"],"sourcesContent":["import { getHost } from './utils.js';\nimport { Analytics } from './analytics-object-v2.js';\n\nconst getLoanField = (name) => document.getElementById(name);\n\nconst host = getHost(new Analytics());\n\nclass Loan extends ice.host.ScriptingObject {\n constructor() {\n super('Loan');\n this.loanId = 'ABC123';\n this.creditScore = 0;\n this.serviceOrderStatus = {\n title: false,\n credit: false,\n };\n this.onSaved = new ice.host.Event({\n name: 'onSaved',\n objectId: this.constructor.name,\n });\n this.onPreSave = new ice.host.Event({\n name: 'onPreSave',\n objectId: this.constructor.name,\n });\n this.onLoanAmountChanged = new ice.host.Event({\n name: 'onLoanAmountChanged',\n objectId: this.constructor.name,\n });\n this.onLoanTermChanged = new ice.host.Event({\n name: 'onLoanTermChanged',\n objectId: this.constructor.name,\n });\n this.onDownPaymentChanged = new ice.host.Event({\n name: 'onDownPaymentChanged',\n objectId: this.constructor.name,\n });\n\n getLoanField('amount')?.addEventListener?.('blur', (e) => {\n host.dispatchEvent({\n event: this.onLoanAmountChanged,\n eventParams: {\n amount: e.target.value,\n },\n });\n });\n\n getLoanField('term')?.addEventListener?.('blur', (e) => {\n host.dispatchEvent({\n event: this.onLoanTermChanged,\n eventParams: { term: e.target.value },\n });\n });\n\n getLoanField('downPayment')?.addEventListener?.('blur', (e) => {\n host.dispatchEvent({\n event: this.onDownPaymentChanged,\n eventParams: {\n downPayment: e.target.value,\n },\n });\n });\n }\n\n getLoanDetails = () => ({\n id: this.loanId,\n firstName: getLoanField('firstName')?.value,\n lastName: getLoanField('lastName')?.value,\n ssn: getLoanField('ssn')?.value,\n amount: getLoanField('amount')?.value,\n term: getLoanField('term')?.value,\n downPayment: getLoanField('downPayment')?.value,\n creditScore: this.creditScore,\n });\n\n setCreditScore = (creditScore) => {\n this.serviceOrderStatus.credit = true;\n this.creditScore = creditScore;\n const creditBtn = document.getElementById('credit');\n if (creditBtn) {\n creditBtn.disabled = true;\n creditBtn.textContent = `${creditBtn.textContent} : ${creditScore}`;\n }\n };\n\n setServiceOrderStatus = (service, completed) => {\n this.serviceOrderStatus[service] = completed;\n const btn = document.getElementById(service);\n if (btn) {\n btn.disabled = completed;\n btn.textContent = `${btn.textContent} : Done`;\n }\n };\n\n saveLoan = async () => {\n host.dispatchEvent({\n event: this.onSaved,\n eventParams: { id: this.loanId },\n });\n };\n}\n\nexport { Loan };\n"],"mappings":"AAAA,OAAS,WAAAA,MAAe,aACxB,OAAS,aAAAC,MAAiB,2BAE1B,MAAMC,EAAgBC,GAAS,SAAS,eAAeA,CAAI,EAErDC,EAAOJ,EAAQ,IAAIC,CAAW,EAEpC,MAAMI,UAAa,IAAI,KAAK,eAAgB,CAC1C,aAAc,CACZ,MAAM,MAAM,EACZ,KAAK,OAAS,SACd,KAAK,YAAc,EACnB,KAAK,mBAAqB,CACxB,MAAO,GACP,OAAQ,EACV,EACA,KAAK,QAAU,IAAI,IAAI,KAAK,MAAM,CAChC,KAAM,UACN,SAAU,KAAK,YAAY,IAC7B,CAAC,EACD,KAAK,UAAY,IAAI,IAAI,KAAK,MAAM,CAClC,KAAM,YACN,SAAU,KAAK,YAAY,IAC7B,CAAC,EACD,KAAK,oBAAsB,IAAI,IAAI,KAAK,MAAM,CAC5C,KAAM,sBACN,SAAU,KAAK,YAAY,IAC7B,CAAC,EACD,KAAK,kBAAoB,IAAI,IAAI,KAAK,MAAM,CAC1C,KAAM,oBACN,SAAU,KAAK,YAAY,IAC7B,CAAC,EACD,KAAK,qBAAuB,IAAI,IAAI,KAAK,MAAM,CAC7C,KAAM,uBACN,SAAU,KAAK,YAAY,IAC7B,CAAC,EAEDH,EAAa,QAAQ,GAAG,mBAAmB,OAAS,GAAM,CACxDE,EAAK,cAAc,CACjB,MAAO,KAAK,oBACZ,YAAa,CACX,OAAQ,EAAE,OAAO,KACnB,CACF,CAAC,CACH,CAAC,EAEDF,EAAa,MAAM,GAAG,mBAAmB,OAAS,GAAM,CACtDE,EAAK,cAAc,CACjB,MAAO,KAAK,kBACZ,YAAa,CAAE,KAAM,EAAE,OAAO,KAAM,CACtC,CAAC,CACH,CAAC,EAEDF,EAAa,aAAa,GAAG,mBAAmB,OAAS,GAAM,CAC7DE,EAAK,cAAc,CACjB,MAAO,KAAK,qBACZ,YAAa,CACX,YAAa,EAAE,OAAO,KACxB,CACF,CAAC,CACH,CAAC,CACH,CAEA,eAAiB,KAAO,CACtB,GAAI,KAAK,OACT,UAAWF,EAAa,WAAW,GAAG,MACtC,SAAUA,EAAa,UAAU,GAAG,MACpC,IAAKA,EAAa,KAAK,GAAG,MAC1B,OAAQA,EAAa,QAAQ,GAAG,MAChC,KAAMA,EAAa,MAAM,GAAG,MAC5B,YAAaA,EAAa,aAAa,GAAG,MAC1C,YAAa,KAAK,WACpB,GAEA,eAAkBI,GAAgB,CAChC,KAAK,mBAAmB,OAAS,GACjC,KAAK,YAAcA,EACnB,MAAMC,EAAY,SAAS,eAAe,QAAQ,EAC9CA,IACFA,EAAU,SAAW,GACrBA,EAAU,YAAc,GAAGA,EAAU,WAAW,MAAMD,CAAW,GAErE,EAEA,sBAAwB,CAACE,EAASC,IAAc,CAC9C,KAAK,mBAAmBD,CAAO,EAAIC,EACnC,MAAMC,EAAM,SAAS,eAAeF,CAAO,EACvCE,IACFA,EAAI,SAAWD,EACfC,EAAI,YAAc,GAAGA,EAAI,WAAW,UAExC,EAEA,SAAW,SAAY,CACrBN,EAAK,cAAc,CACjB,MAAO,KAAK,QACZ,YAAa,CAAE,GAAI,KAAK,MAAO,CACjC,CAAC,CACH,CACF,CAEA,OAASC,KAAA","names":["getHost","Analytics","getLoanField","name","host","Loan","creditScore","creditBtn","service","completed","btn"],"sourceRoot":"","file":"loan-object.js"}
1
+ {"version":3,"sources":["webpack://ice.host/loan-object.js"],"sourcesContent":["import { getHost } from './utils.js';\nimport { Analytics } from './analytics-object-v2.js';\n\nconst getLoanField = (name) => document.getElementById(name);\n\nconst host = getHost(new Analytics());\n\nclass Loan extends ice.host.ScriptingObject {\n constructor() {\n super('Loan');\n this.loanId = 'ABC123';\n this.creditScore = 0;\n this.serviceOrderStatus = {\n title: false,\n credit: false,\n };\n this.onSaved = new ice.host.Event({\n name: 'onSaved',\n objectId: this.constructor.name,\n });\n this.onPreSave = new ice.host.Event({\n name: 'onPreSave',\n objectId: this.constructor.name,\n });\n this.onLoanAmountChanged = new ice.host.Event({\n name: 'onLoanAmountChanged',\n objectId: this.constructor.name,\n });\n this.onLoanTermChanged = new ice.host.Event({\n name: 'onLoanTermChanged',\n objectId: this.constructor.name,\n });\n this.onDownPaymentChanged = new ice.host.Event({\n name: 'onDownPaymentChanged',\n objectId: this.constructor.name,\n });\n\n getLoanField('amount')?.addEventListener?.('blur', (e) => {\n host.dispatchEvent({\n event: this.onLoanAmountChanged,\n eventParams: {\n amount: e.target.value,\n },\n });\n });\n\n getLoanField('term')?.addEventListener?.('blur', (e) => {\n host.dispatchEvent({\n event: this.onLoanTermChanged,\n eventParams: { term: e.target.value },\n });\n });\n\n getLoanField('downPayment')?.addEventListener?.('blur', (e) => {\n host.dispatchEvent({\n event: this.onDownPaymentChanged,\n eventParams: {\n downPayment: e.target.value,\n },\n });\n });\n }\n\n getLoanDetails = () => {\n const ctx = this.getLoanDetails.callContext;\n if (ctx?.callChain?.length) {\n console.log(\n '[Loan.getLoanDetails] callChain:',\n JSON.stringify(ctx.callChain),\n );\n }\n return {\n id: this.loanId,\n firstName: getLoanField('firstName')?.value,\n lastName: getLoanField('lastName')?.value,\n ssn: getLoanField('ssn')?.value,\n amount: getLoanField('amount')?.value,\n term: getLoanField('term')?.value,\n downPayment: getLoanField('downPayment')?.value,\n creditScore: this.creditScore,\n };\n };\n\n setCreditScore = (creditScore) => {\n const ctx = this.setCreditScore.callContext;\n if (ctx?.callChain?.length) {\n console.log(\n '[Loan.setCreditScore] callChain:',\n JSON.stringify(ctx.callChain),\n );\n }\n this.serviceOrderStatus.credit = true;\n this.creditScore = creditScore;\n const creditBtn = document.getElementById('credit');\n if (creditBtn) {\n creditBtn.disabled = true;\n creditBtn.textContent = `${creditBtn.textContent} : ${creditScore}`;\n }\n };\n\n setServiceOrderStatus = (service, completed) => {\n const ctx = this.setServiceOrderStatus.callContext;\n if (ctx?.callChain?.length) {\n console.log(\n '[Loan.setServiceOrderStatus] callChain:',\n JSON.stringify(ctx.callChain),\n );\n }\n this.serviceOrderStatus[service] = completed;\n const btn = document.getElementById(service);\n if (btn) {\n btn.disabled = completed;\n btn.textContent = `${btn.textContent} : Done`;\n }\n };\n\n saveLoan = async () => {\n host.dispatchEvent({\n event: this.onSaved,\n eventParams: { id: this.loanId },\n });\n };\n}\n\nexport { Loan };\n"],"mappings":"AAAA,OAAS,WAAAA,MAAe,aACxB,OAAS,aAAAC,MAAiB,2BAE1B,MAAMC,EAAgBC,GAAS,SAAS,eAAeA,CAAI,EAErDC,EAAOJ,EAAQ,IAAIC,CAAW,EAEpC,MAAMI,UAAa,IAAI,KAAK,eAAgB,CAC1C,aAAc,CACZ,MAAM,MAAM,EACZ,KAAK,OAAS,SACd,KAAK,YAAc,EACnB,KAAK,mBAAqB,CACxB,MAAO,GACP,OAAQ,EACV,EACA,KAAK,QAAU,IAAI,IAAI,KAAK,MAAM,CAChC,KAAM,UACN,SAAU,KAAK,YAAY,IAC7B,CAAC,EACD,KAAK,UAAY,IAAI,IAAI,KAAK,MAAM,CAClC,KAAM,YACN,SAAU,KAAK,YAAY,IAC7B,CAAC,EACD,KAAK,oBAAsB,IAAI,IAAI,KAAK,MAAM,CAC5C,KAAM,sBACN,SAAU,KAAK,YAAY,IAC7B,CAAC,EACD,KAAK,kBAAoB,IAAI,IAAI,KAAK,MAAM,CAC1C,KAAM,oBACN,SAAU,KAAK,YAAY,IAC7B,CAAC,EACD,KAAK,qBAAuB,IAAI,IAAI,KAAK,MAAM,CAC7C,KAAM,uBACN,SAAU,KAAK,YAAY,IAC7B,CAAC,EAEDH,EAAa,QAAQ,GAAG,mBAAmB,OAASI,GAAM,CACxDF,EAAK,cAAc,CACjB,MAAO,KAAK,oBACZ,YAAa,CACX,OAAQE,EAAE,OAAO,KACnB,CACF,CAAC,CACH,CAAC,EAEDJ,EAAa,MAAM,GAAG,mBAAmB,OAASI,GAAM,CACtDF,EAAK,cAAc,CACjB,MAAO,KAAK,kBACZ,YAAa,CAAE,KAAME,EAAE,OAAO,KAAM,CACtC,CAAC,CACH,CAAC,EAEDJ,EAAa,aAAa,GAAG,mBAAmB,OAASI,GAAM,CAC7DF,EAAK,cAAc,CACjB,MAAO,KAAK,qBACZ,YAAa,CACX,YAAaE,EAAE,OAAO,KACxB,CACF,CAAC,CACH,CAAC,CACH,CAEA,eAAiB,IAAM,CACrB,MAAMC,EAAM,KAAK,eAAe,YAChC,OAAIA,GAAK,WAAW,QAGhB,KAAK,UAAUA,EAAI,SAAS,EAGzB,CACL,GAAI,KAAK,OACT,UAAWL,EAAa,WAAW,GAAG,MACtC,SAAUA,EAAa,UAAU,GAAG,MACpC,IAAKA,EAAa,KAAK,GAAG,MAC1B,OAAQA,EAAa,QAAQ,GAAG,MAChC,KAAMA,EAAa,MAAM,GAAG,MAC5B,YAAaA,EAAa,aAAa,GAAG,MAC1C,YAAa,KAAK,WACpB,CACF,EAEA,eAAkBM,GAAgB,CAChC,MAAMD,EAAM,KAAK,eAAe,YAC5BA,GAAK,WAAW,QAGhB,KAAK,UAAUA,EAAI,SAAS,EAGhC,KAAK,mBAAmB,OAAS,GACjC,KAAK,YAAcC,EACnB,MAAMC,EAAY,SAAS,eAAe,QAAQ,EAC9CA,IACFA,EAAU,SAAW,GACrBA,EAAU,YAAc,GAAGA,EAAU,WAAW,MAAMD,CAAW,GAErE,EAEA,sBAAwB,CAACE,EAASC,IAAc,CAC9C,MAAMJ,EAAM,KAAK,sBAAsB,YACnCA,GAAK,WAAW,QAGhB,KAAK,UAAUA,EAAI,SAAS,EAGhC,KAAK,mBAAmBG,CAAO,EAAIC,EACnC,MAAMC,EAAM,SAAS,eAAeF,CAAO,EACvCE,IACFA,EAAI,SAAWD,EACfC,EAAI,YAAc,GAAGA,EAAI,WAAW,UAExC,EAEA,SAAW,SAAY,CACrBR,EAAK,cAAc,CACjB,MAAO,KAAK,QACZ,YAAa,CAAE,GAAI,KAAK,MAAO,CACjC,CAAC,CACH,CACF,CAEA,OAASC,KAAA","names":["getHost","Analytics","getLoanField","name","host","Loan","e","ctx","creditScore","creditBtn","service","completed","btn"],"sourceRoot":"","file":"loan-object.js"}
@@ -0,0 +1 @@
1
+ <!doctype html><html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><title>Popup Focus E2E Test</title><script src="https://cdn.tailwindcss.com?plugins=forms"></script><script src="https://cdn.mortgagetech.q1.ice.com/pui-diagnostics@3"></script><script defer="defer" src="index.js"></script></head><body class="bg-gray-50"><header class="bg-purple-600 text-white px-4 py-3 flex items-center justify-between"><h1 class="text-lg font-semibold">Popup Focus E2E Test</h1><a href="./index.html" class="text-purple-200 hover:text-white text-sm">&larr; Back to main</a></header><main class="mx-auto max-w-5xl px-4 py-4"><div class="grid grid-cols-2 gap-4 mb-4"><div class="bg-purple-50 border border-purple-200 rounded-md p-3"><h2 class="text-sm font-bold text-purple-900 mb-2">Behavior Under Test</h2><ul class="text-xs text-purple-800 space-y-1 list-disc list-inside"><li><strong>Trusted domains</strong> (.ice.com, .elliemae.com, .ellielabs.com, localhost): <code>window.opener</code> is kept intact. Re-opening uses <code>window.open('', name)</code> to bring the popup to front.</li><li><strong>Untrusted domains</strong> (everything else): <code>window.opener = null</code> is set for security. Re-opening falls back to <code>guest.window.focus()</code>.</li><li>The host tracks popup windows and detects closure via a periodic monitor.</li></ul></div><div class="bg-green-50 border border-green-200 rounded-md p-3"><h2 class="text-sm font-bold text-green-900 mb-2">Test Steps</h2><ol class="text-xs text-green-800 space-y-1.5 list-decimal list-inside"><li>Wait for <code>"Popup Focus Host ready"</code> in the Event Log.</li><li><strong>Trusted popup test:</strong> Click "Open Title Service" → popup opens. Click "Re-open Title Service" → the <em>existing</em> popup should come to the foreground (no new window).</li><li><strong>Second trusted popup:</strong> Click "Open Credit Service" → second popup opens. Click "Re-open Credit" → same foreground behavior.</li><li><strong>Untrusted popup test:</strong> Click "Open Third-Party" → popup opens to <code>example.com</code>. Click "Re-open Third-Party" → focus may or may not work (opener was nulled). Observe the behavior.</li><li>Verify the Guest Status panel shows the open/closed state of each popup.</li><li>Manually close a popup window, then check Guest Status updates to "closed".</li></ol></div></div><div class="bg-amber-50 border border-amber-200 rounded-md p-3 mb-4"><h2 class="text-sm font-bold text-amber-900 mb-2">Expected Behavior</h2><div class="grid grid-cols-3 gap-3 text-xs"><div><h3 class="font-semibold text-amber-800 mb-1">Title / Credit Service (Trusted)</h3><ul class="text-amber-900 list-disc list-inside space-y-0.5"><li>"Open" → new popup window appears</li><li>"Re-open" → existing popup comes to front, <strong>no new window</strong></li><li>Guest Status shows <span class="text-green-600 font-semibold">open</span></li><li>Embedded Pricing Service renders normally</li></ul></div><div><h3 class="font-semibold text-amber-800 mb-1">Third-Party (Untrusted)</h3><ul class="text-amber-900 list-disc list-inside space-y-0.5"><li>"Open" → popup opens to <code>example.com</code></li><li>"Re-open" → <code>focus()</code> is called on stored reference (browser may or may not honor it)</li><li><code>opener</code> is <code>null</code> inside the popup</li></ul></div><div><h3 class="font-semibold text-amber-800 mb-1">Popup Closure</h3><ul class="text-amber-900 list-disc list-inside space-y-0.5"><li>Close a popup manually (X button)</li><li>Guest Status updates to <span class="text-red-500 font-semibold">closed</span> within 2 seconds</li><li>Re-opening a closed popup should open a new window</li></ul></div></div></div><div class="grid grid-cols-2 gap-4 mb-4"><div class="bg-white rounded-lg shadow p-4"><h2 class="text-sm font-semibold text-gray-700 mb-3">Popup Actions</h2><div class="flex flex-col gap-2"><p class="text-xs text-gray-400 font-medium">Trusted (localhost — opener preserved)</p><button data-testid="btn-open-title-popup" id="btnOpenTitle" class="rounded bg-purple-600 px-4 py-2 text-sm text-white hover:bg-purple-700">Open Title Service (Popup)</button> <button data-testid="btn-reopen-title-popup" id="btnReopenTitle" class="rounded bg-purple-500 px-4 py-2 text-sm text-white hover:bg-purple-600">Re-open Title Service (should focus existing)</button> <button data-testid="btn-open-credit-popup" id="btnOpenCredit" class="rounded bg-indigo-600 px-4 py-2 text-sm text-white hover:bg-indigo-700">Open Credit Service (Popup)</button> <button data-testid="btn-reopen-credit-popup" id="btnReopenCredit" class="rounded bg-indigo-500 px-4 py-2 text-sm text-white hover:bg-indigo-600">Re-open Credit Service (should focus existing)</button><hr class="my-2 border-gray-300"/><p class="text-xs text-gray-400 font-medium">Untrusted (opener nulled)</p><button data-testid="btn-open-thirdparty-popup" id="btnOpenThirdParty" class="rounded bg-red-600 px-4 py-2 text-sm text-white hover:bg-red-700">Open Third-Party (Popup) — untrusted</button> <button data-testid="btn-reopen-thirdparty-popup" id="btnReopenThirdParty" class="rounded bg-red-500 px-4 py-2 text-sm text-white hover:bg-red-600">Re-open Third-Party (focus test — opener nulled)</button></div></div><div class="bg-white rounded-lg shadow p-4"><h2 class="text-sm font-semibold text-gray-700 mb-3">Guest Status</h2><div data-testid="popup-guest-list" id="guestList" class="text-xs space-y-1 min-h-[100px]"><p class="text-gray-400">No popup guests loaded yet</p></div></div></div><div class="bg-white rounded-lg shadow p-4 mb-4"><h2 class="text-sm font-semibold text-gray-700 mb-2">Event Log</h2><div data-testid="popup-event-log" id="eventLog" class="text-xs bg-gray-100 rounded p-2 min-h-[100px] max-h-[250px] overflow-y-auto"></div></div><div class="mb-4"><h2 class="text-sm font-semibold text-gray-700 mb-2">Embedded Guest (for comparison)</h2><div data-testid="embedded-container" id="embedded-container" class="border-2 border-dashed border-purple-300 rounded-lg min-h-[150px]"></div></div><div class="bg-gray-100 border border-gray-300 rounded-md p-3"><h2 class="text-sm font-bold text-gray-800 mb-2">Verification Checklist</h2><div class="grid grid-cols-2 gap-2 text-xs"><label class="flex items-start gap-2"><input type="checkbox" class="mt-0.5"/> <span><strong>TC-POP-01:</strong> Host initializes, embedded Pricing Service guest loads without error</span></label> <label class="flex items-start gap-2"><input type="checkbox" class="mt-0.5"/> <span><strong>TC-POP-02:</strong> "Open Title Service" opens a new popup window</span></label> <label class="flex items-start gap-2"><input type="checkbox" class="mt-0.5"/> <span><strong>TC-POP-03:</strong> "Re-open Title Service" brings the existing popup to front — <strong>no new window or about:blank tab</strong></span></label> <label class="flex items-start gap-2"><input type="checkbox" class="mt-0.5"/> <span><strong>TC-POP-04:</strong> "Open Credit Service" opens a second popup (both coexist)</span></label> <label class="flex items-start gap-2"><input type="checkbox" class="mt-0.5"/> <span><strong>TC-POP-05:</strong> "Re-open Credit Service" brings credit popup to front</span></label> <label class="flex items-start gap-2"><input type="checkbox" class="mt-0.5"/> <span><strong>TC-POP-06:</strong> Guest Status shows each popup as <span class="text-green-600 font-semibold">open</span></span></label> <label class="flex items-start gap-2"><input type="checkbox" class="mt-0.5"/> <span><strong>TC-POP-07:</strong> Manually close a popup → Guest Status updates to <span class="text-red-500 font-semibold">closed</span> within ~2s</span></label> <label class="flex items-start gap-2"><input type="checkbox" class="mt-0.5"/> <span><strong>TC-POP-08:</strong> Re-opening a closed popup opens a new window (not just focus)</span></label> <label class="flex items-start gap-2"><input type="checkbox" class="mt-0.5"/> <span><strong>TC-POP-09:</strong> "Open Third-Party" opens <code>example.com</code> popup</span></label> <label class="flex items-start gap-2"><input type="checkbox" class="mt-0.5"/> <span><strong>TC-POP-10:</strong> "Re-open Third-Party" attempts <code>focus()</code> (may open about:blank — expected for untrusted, opener was nulled)</span></label> <label class="flex items-start gap-2"><input type="checkbox" class="mt-0.5"/> <span><strong>TC-POP-11:</strong> No console errors during trusted popup operations</span></label></div></div></main><script src="./popup-focus-host.js" type="module"></script></body></html>
@@ -0,0 +1,6 @@
1
+ import{Analytics as v}from"./analytics-object-v2.js";import{getGuestBaseUrl as L,getHost as S}from"./utils.js";const p=document.getElementById("eventLog"),m=document.getElementById("guestList"),e=i=>{const t=new Date().toLocaleTimeString();p.innerHTML+=`<div>[${t}] ${i}</div>`,p.scrollTop=p.scrollHeight},l=i=>{const t=i.getGuests();if(!t.length){m.innerHTML='<p class="text-gray-400">No popup guests loaded</p>';return}m.innerHTML=t.map(n=>`<div class="flex justify-between items-center p-1 bg-gray-50 rounded">
2
+ <span><strong>${n.id}</strong> \u2014 ${n.title??"untitled"}</span>
3
+ <span class="${n.window?.closed?"text-red-500":"text-green-500"}">${n.window?.closed?"closed":"open"}</span>
4
+ </div>`).join("")},y=async()=>{e("Initializing Popup Focus Host...");const i=new v,t=S(i);if(!t){e("ERROR: Failed to create SSFHost");return}class n extends ice.host.ScriptingObject{constructor(){super("Loan"),this.onLoanAmountChanged=new ice.host.Event({name:"onLoanAmountChanged",objectId:this.constructor.name}),this.onLoanTermChanged=new ice.host.Event({name:"onLoanTermChanged",objectId:this.constructor.name}),this.onDownPaymentChanged=new ice.host.Event({name:"onDownPaymentChanged",objectId:this.constructor.name})}getLoanDetails=()=>({id:"POPUP-LOAN",amount:25e4,term:30,downPayment:5e4,creditScore:720});setCreditScore=d=>{e(`setCreditScore(${d}) called by popup guest`)};setServiceOrderStatus=(d,s)=>{e(`setServiceOrderStatus("${d}", ${s}) called by popup guest`)}}const g=new n;t.addScriptingObject(g),e("Loan scripting object registered");const r=await L();t.loadGuest({id:"pricingService",url:new URL("./pricingService.html",r).href,title:"Pricing Service (Embedded)",targetElement:document.getElementById("embedded-container"),options:{fitToContent:!0},onLoad:()=>e("Pricing Service (embedded) loaded")});const o=(c,d,s)=>{e(`loadGuest("${c}") as popup...`);const h=t.loadGuest({id:c,url:d,title:s,targetElement:document.getElementById("embedded-container"),options:{openMode:ice.host.OpenMode.Popup},onLoad:a=>{e(`Popup guest "${a}" loaded`),l(t)},onError:a=>e(`ERROR: Popup guest "${a}" failed`)});return l(t),h};document.getElementById("btnOpenTitle").addEventListener("click",()=>{o("titleService",new URL("./titleService.html",r).href,"Title Service Corp")}),document.getElementById("btnReopenTitle").addEventListener("click",()=>{e("Re-opening Title Service popup (should bring to front)..."),o("titleService",new URL("./titleService.html",r).href,"Title Service Corp"),e("Check if Title Service popup came to front")}),document.getElementById("btnOpenCredit").addEventListener("click",()=>{o("creditService",new URL("./creditService.html",r).href,"Credit Service Corp")}),document.getElementById("btnReopenCredit").addEventListener("click",()=>{e("Re-opening Credit Service popup (should bring to front)..."),o("creditService",new URL("./creditService.html",r).href,"Credit Service Corp"),e("Check if Credit Service popup came to front")});const u="https://example.com";document.getElementById("btnOpenThirdParty").addEventListener("click",()=>{o("thirdPartyGuest",u,"Third Party App")}),document.getElementById("btnReopenThirdParty").addEventListener("click",()=>{e("Re-opening Third Party popup (opener was nulled \u2014 focus may not work)..."),o("thirdPartyGuest",u,"Third Party App"),e("Check if Third Party popup came to front or a new about:blank opened")}),setInterval(()=>l(t),2e3),e("Popup Focus Host ready")};window.addEventListener("DOMContentLoaded",y);
5
+
6
+ //# sourceMappingURL=popup-focus-host.js.map
Binary file
Binary file
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["webpack://ice.host/popup-focus-host.js"],"sourcesContent":["import { Analytics } from './analytics-object-v2.js';\nimport { getGuestBaseUrl, getHost } from './utils.js';\n\nconst logEl = document.getElementById('eventLog');\nconst guestListEl = document.getElementById('guestList');\n\nconst log = (msg) => {\n const ts = new Date().toLocaleTimeString();\n logEl.innerHTML += `<div>[${ts}] ${msg}</div>`;\n logEl.scrollTop = logEl.scrollHeight;\n};\n\nconst refreshGuestList = (host) => {\n const guests = host.getGuests();\n if (!guests.length) {\n guestListEl.innerHTML =\n '<p class=\"text-gray-400\">No popup guests loaded</p>';\n return;\n }\n guestListEl.innerHTML = guests\n .map(\n (g) =>\n `<div class=\"flex justify-between items-center p-1 bg-gray-50 rounded\">\n <span><strong>${g.id}</strong> — ${g.title ?? 'untitled'}</span>\n <span class=\"${\n g.window?.closed ? 'text-red-500' : 'text-green-500'\n }\">${g.window?.closed ? 'closed' : 'open'}</span>\n </div>`,\n )\n .join('');\n};\n\nconst init = async () => {\n log('Initializing Popup Focus Host...');\n const analyticsObj = new Analytics();\n const host = getHost(analyticsObj);\n if (!host) {\n log('ERROR: Failed to create SSFHost');\n return;\n }\n\n // Scripting object compatible with the shared pricingService guest\n class Loan extends ice.host.ScriptingObject {\n constructor() {\n super('Loan');\n this.onLoanAmountChanged = new ice.host.Event({\n name: 'onLoanAmountChanged',\n objectId: this.constructor.name,\n });\n this.onLoanTermChanged = new ice.host.Event({\n name: 'onLoanTermChanged',\n objectId: this.constructor.name,\n });\n this.onDownPaymentChanged = new ice.host.Event({\n name: 'onDownPaymentChanged',\n objectId: this.constructor.name,\n });\n }\n getLoanDetails = () => ({\n id: 'POPUP-LOAN',\n amount: 250000,\n term: 30,\n downPayment: 50000,\n creditScore: 720,\n });\n setCreditScore = (score) => {\n log(`setCreditScore(${score}) called by popup guest`);\n };\n setServiceOrderStatus = (service, done) => {\n log(`setServiceOrderStatus(\"${service}\", ${done}) called by popup guest`);\n };\n }\n\n const loanObj = new Loan();\n host.addScriptingObject(loanObj);\n log('Loan scripting object registered');\n\n const guestBaseUrl = await getGuestBaseUrl();\n\n // Load an embedded guest for comparison\n host.loadGuest({\n id: 'pricingService',\n url: new URL('./pricingService.html', guestBaseUrl).href,\n title: 'Pricing Service (Embedded)',\n targetElement: document.getElementById('embedded-container'),\n options: { fitToContent: true },\n onLoad: () => log('Pricing Service (embedded) loaded'),\n });\n\n const loadPopup = (id, url, title) => {\n log(`loadGuest(\"${id}\") as popup...`);\n const guest = host.loadGuest({\n id,\n url,\n title,\n targetElement: document.getElementById('embedded-container'),\n options: { openMode: ice.host.OpenMode.Popup },\n onLoad: (guestId) => {\n log(`Popup guest \"${guestId}\" loaded`);\n refreshGuestList(host);\n },\n onError: (guestId) => log(`ERROR: Popup guest \"${guestId}\" failed`),\n });\n refreshGuestList(host);\n return guest;\n };\n\n // Title Service popup\n document.getElementById('btnOpenTitle').addEventListener('click', () => {\n loadPopup(\n 'titleService',\n new URL('./titleService.html', guestBaseUrl).href,\n 'Title Service Corp',\n );\n });\n\n document.getElementById('btnReopenTitle').addEventListener('click', () => {\n log('Re-opening Title Service popup (should bring to front)...');\n loadPopup(\n 'titleService',\n new URL('./titleService.html', guestBaseUrl).href,\n 'Title Service Corp',\n );\n log('Check if Title Service popup came to front');\n });\n\n // Credit Service popup\n document.getElementById('btnOpenCredit').addEventListener('click', () => {\n loadPopup(\n 'creditService',\n new URL('./creditService.html', guestBaseUrl).href,\n 'Credit Service Corp',\n );\n });\n\n document.getElementById('btnReopenCredit').addEventListener('click', () => {\n log('Re-opening Credit Service popup (should bring to front)...');\n loadPopup(\n 'creditService',\n new URL('./creditService.html', guestBaseUrl).href,\n 'Credit Service Corp',\n );\n log('Check if Credit Service popup came to front');\n });\n\n // Third-party (untrusted) popup — opener will be nulled\n const THIRD_PARTY_URL = 'https://example.com';\n document.getElementById('btnOpenThirdParty').addEventListener('click', () => {\n loadPopup('thirdPartyGuest', THIRD_PARTY_URL, 'Third Party App');\n });\n\n document\n .getElementById('btnReopenThirdParty')\n .addEventListener('click', () => {\n log(\n 'Re-opening Third Party popup (opener was nulled — focus may not work)...',\n );\n loadPopup('thirdPartyGuest', THIRD_PARTY_URL, 'Third Party App');\n log(\n 'Check if Third Party popup came to front or a new about:blank opened',\n );\n });\n\n // Periodic guest list refresh\n setInterval(() => refreshGuestList(host), 2000);\n\n log('Popup Focus Host ready');\n};\n\nwindow.addEventListener('DOMContentLoaded', init);\n"],"mappings":"AAAA,OAAS,aAAAA,MAAiB,2BAC1B,OAAS,mBAAAC,EAAiB,WAAAC,MAAe,aAEzC,MAAMC,EAAQ,SAAS,eAAe,UAAU,EAC1CC,EAAc,SAAS,eAAe,WAAW,EAEjDC,EAAOC,GAAQ,CACnB,MAAMC,EAAK,IAAI,KAAK,EAAE,mBAAmB,EACzCJ,EAAM,WAAa,SAASI,CAAE,KAAKD,CAAG,SACtCH,EAAM,UAAYA,EAAM,YAC1B,EAEMK,EAAoBC,GAAS,CACjC,MAAMC,EAASD,EAAK,UAAU,EAC9B,GAAI,CAACC,EAAO,OAAQ,CAClBN,EAAY,UACV,sDACF,MACF,CACAA,EAAY,UAAYM,EACrB,IACEC,GACC;AAAA,0BACkBA,EAAE,EAAE,oBAAeA,EAAE,OAAS,UAAU;AAAA,yBAEtDA,EAAE,QAAQ,OAAS,eAAiB,gBACtC,KAAKA,EAAE,QAAQ,OAAS,SAAW,MAAM;AAAA,eAE/C,EACC,KAAK,EAAE,CACZ,EAEMC,EAAO,SAAY,CACvBP,EAAI,kCAAkC,EACtC,MAAMQ,EAAe,IAAIb,EACnBS,EAAOP,EAAQW,CAAY,EACjC,GAAI,CAACJ,EAAM,CACTJ,EAAI,iCAAiC,EACrC,MACF,CAGA,MAAMS,UAAa,IAAI,KAAK,eAAgB,CAC1C,aAAc,CACZ,MAAM,MAAM,EACZ,KAAK,oBAAsB,IAAI,IAAI,KAAK,MAAM,CAC5C,KAAM,sBACN,SAAU,KAAK,YAAY,IAC7B,CAAC,EACD,KAAK,kBAAoB,IAAI,IAAI,KAAK,MAAM,CAC1C,KAAM,oBACN,SAAU,KAAK,YAAY,IAC7B,CAAC,EACD,KAAK,qBAAuB,IAAI,IAAI,KAAK,MAAM,CAC7C,KAAM,uBACN,SAAU,KAAK,YAAY,IAC7B,CAAC,CACH,CACA,eAAiB,KAAO,CACtB,GAAI,aACJ,OAAQ,KACR,KAAM,GACN,YAAa,IACb,YAAa,GACf,GACA,eAAkBC,GAAU,CAC1BV,EAAI,kBAAkBU,CAAK,yBAAyB,CACtD,EACA,sBAAwB,CAACC,EAASC,IAAS,CACzCZ,EAAI,0BAA0BW,CAAO,MAAMC,CAAI,yBAAyB,CAC1E,CACF,CAEA,MAAMC,EAAU,IAAIJ,EACpBL,EAAK,mBAAmBS,CAAO,EAC/Bb,EAAI,kCAAkC,EAEtC,MAAMc,EAAe,MAAMlB,EAAgB,EAG3CQ,EAAK,UAAU,CACb,GAAI,iBACJ,IAAK,IAAI,IAAI,wBAAyBU,CAAY,EAAE,KACpD,MAAO,6BACP,cAAe,SAAS,eAAe,oBAAoB,EAC3D,QAAS,CAAE,aAAc,EAAK,EAC9B,OAAQ,IAAMd,EAAI,mCAAmC,CACvD,CAAC,EAED,MAAMe,EAAY,CAACC,EAAIC,EAAKC,IAAU,CACpClB,EAAI,cAAcgB,CAAE,gBAAgB,EACpC,MAAMG,EAAQf,EAAK,UAAU,CAC3B,GAAAY,EACA,IAAAC,EACA,MAAAC,EACA,cAAe,SAAS,eAAe,oBAAoB,EAC3D,QAAS,CAAE,SAAU,IAAI,KAAK,SAAS,KAAM,EAC7C,OAASE,GAAY,CACnBpB,EAAI,gBAAgBoB,CAAO,UAAU,EACrCjB,EAAiBC,CAAI,CACvB,EACA,QAAUgB,GAAYpB,EAAI,uBAAuBoB,CAAO,UAAU,CACpE,CAAC,EACD,OAAAjB,EAAiBC,CAAI,EACde,CACT,EAGA,SAAS,eAAe,cAAc,EAAE,iBAAiB,QAAS,IAAM,CACtEJ,EACE,eACA,IAAI,IAAI,sBAAuBD,CAAY,EAAE,KAC7C,oBACF,CACF,CAAC,EAED,SAAS,eAAe,gBAAgB,EAAE,iBAAiB,QAAS,IAAM,CACxEd,EAAI,2DAA2D,EAC/De,EACE,eACA,IAAI,IAAI,sBAAuBD,CAAY,EAAE,KAC7C,oBACF,EACAd,EAAI,4CAA4C,CAClD,CAAC,EAGD,SAAS,eAAe,eAAe,EAAE,iBAAiB,QAAS,IAAM,CACvEe,EACE,gBACA,IAAI,IAAI,uBAAwBD,CAAY,EAAE,KAC9C,qBACF,CACF,CAAC,EAED,SAAS,eAAe,iBAAiB,EAAE,iBAAiB,QAAS,IAAM,CACzEd,EAAI,4DAA4D,EAChEe,EACE,gBACA,IAAI,IAAI,uBAAwBD,CAAY,EAAE,KAC9C,qBACF,EACAd,EAAI,6CAA6C,CACnD,CAAC,EAGD,MAAMqB,EAAkB,sBACxB,SAAS,eAAe,mBAAmB,EAAE,iBAAiB,QAAS,IAAM,CAC3EN,EAAU,kBAAmBM,EAAiB,iBAAiB,CACjE,CAAC,EAED,SACG,eAAe,qBAAqB,EACpC,iBAAiB,QAAS,IAAM,CAC/BrB,EACE,+EACF,EACAe,EAAU,kBAAmBM,EAAiB,iBAAiB,EAC/DrB,EACE,sEACF,CACF,CAAC,EAGH,YAAY,IAAMG,EAAiBC,CAAI,EAAG,GAAI,EAE9CJ,EAAI,wBAAwB,CAC9B,EAEA,OAAO,iBAAiB,mBAAoBO,CAAI","names":["Analytics","getGuestBaseUrl","getHost","logEl","guestListEl","log","msg","ts","refreshGuestList","host","guests","g","init","analyticsObj","Loan","score","service","done","loanObj","guestBaseUrl","loadPopup","id","url","title","guest","guestId","THIRD_PARTY_URL"],"sourceRoot":"","file":"popup-focus-host.js"}
@@ -1 +1 @@
1
- <!doctype html><html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><title>Host V2 -> V1 Guest</title><style>body,html,main{height:100%;margin:4px;padding:0}iframe{width:100%;height:100%;border:none}#guest-container{height:100%}</style><script src="https://cdn.mortgagetech.q1.ice.com/pui-diagnostics@3"></script><script defer="defer" src="index.js"></script></head><body><main><h1>Host V2 nesting V1 Guest</h1><button id="save-btn" type="button" onclick="saveLoan()">Save Loan</button><div id="results"><p id="pre-save-feedback-result"></p></div><div id="guest-container"></div></main><script type="module">import{Loan}from"./loan-object.js";import{getGuestBaseUrl,getHost}from"./utils.js";import{Analytics}from"./analytics-object-v2.js";const analyticsObj=new Analytics,hostV2=getHost(analyticsObj),loanObj=new Loan;hostV2.addScriptingObject(loanObj);const params=new URLSearchParams(document.location.search),{id:id}=hostV2.loadGuest({id:"guestV1",url:new URL("true"!==params.get("nestV1GuestV2Host")?"./v1-guest.html":"./v1-guest-v2-host.html",window.location.href).href,searchParams:{nestHostV1:!0},title:"Guest V1",targetElement:document.getElementById("guest-container")});window.saveLoan=async()=>{const e=loanObj.getLoanDetails();(await hostV2.dispatchEvent({event:loanObj.onPreSave,eventParams:e,eventOptions:{timeout:1e3}})).some(e=>!1===e)?document.getElementById("pre-save-feedback-result").innerText="Pre save failed":document.getElementById("pre-save-feedback-result").innerText="Pre save succeeded"}</script></body></html>
1
+ <!doctype html><html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><title>Host V2 -> V1 Guest</title><style>body,html,main{height:100%;margin:4px;padding:0}iframe{width:100%;height:100%;border:none}#guest-container{height:100%}</style><script src="https://cdn.mortgagetech.q1.ice.com/pui-diagnostics@3"></script><script defer="defer" src="index.js"></script></head><body><main><h1>Host V2 nesting V1 Guest</h1><button id="save-btn" type="button" onclick="saveLoan()">Save Loan</button><div id="results"><p id="pre-save-feedback-result"></p></div><div id="guest-container"></div></main><script type="module">import{Loan}from"./loan-object.js";import{Application}from"./application-object-v2.js";import{getGuestBaseUrl,getHost}from"./utils.js";import{Analytics}from"./analytics-object-v2.js";const analyticsObj=new Analytics,hostV2=getHost(analyticsObj),loanObj=new Loan,appObj=new Application;hostV2.addScriptingObject(loanObj),hostV2.addScriptingObject(appObj);const params=new URLSearchParams(document.location.search),{id:id}=hostV2.loadGuest({id:"guestV1",url:new URL("true"!==params.get("nestV1GuestV2Host")?"./v1-guest.html":"./v1-guest-v2-host.html",window.location.href).href,searchParams:{nestHostV1:!0},title:"Guest V1",targetElement:document.getElementById("guest-container")});window.saveLoan=async()=>{const e=loanObj.getLoanDetails();(await hostV2.dispatchEvent({event:loanObj.onPreSave,eventParams:e,eventOptions:{timeout:1e3}})).some(e=>!1===e)?document.getElementById("pre-save-feedback-result").innerText="Pre save failed":document.getElementById("pre-save-feedback-result").innerText="Pre save succeeded"}</script></body></html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elliemae/ssf-host",
3
- "version": "2.23.6",
3
+ "version": "2.24.0",
4
4
  "description": "ICE MT SSF Host Library",
5
5
  "repository": {
6
6
  "type": "git",
@@ -39,17 +39,17 @@
39
39
  },
40
40
  "dependencies": {
41
41
  "uuid": "~9.0.1",
42
- "@elliemae/microfe-common": "2.23.6"
42
+ "@elliemae/microfe-common": "2.24.0"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "@elliemae/pui-diagnostics": "^3.11.3"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@elliemae/browserslist-config-elliemae-latest-browsers": "~1.14.4",
49
- "@elliemae/pui-diagnostics": "~3.11.3",
50
- "@elliemae/pui-scripting-object": "~1.54.4",
49
+ "@elliemae/pui-diagnostics": "~3.12.1",
50
+ "@elliemae/pui-scripting-object": "~1.56.0",
51
51
  "@types/uuid": "~9.0.8",
52
- "@elliemae/ssf-guest": "2.23.6"
52
+ "@elliemae/ssf-guest": "2.24.0"
53
53
  },
54
54
  "scripts": {
55
55
  "build": "pui-cli pack -p",
@@ -1,3 +0,0 @@
1
- (function(I,O){typeof exports=="object"&&typeof module=="object"?module.exports=O():typeof define=="function"&&define.amd?define([],O):typeof exports=="object"?exports.ice=O():(I.ice=I.ice||{},I.ice.host=O())})(globalThis,()=>(()=>{"use strict";var j={};j.d=(n,e)=>{for(var t in e)j.o(e,t)&&!j.o(n,t)&&Object.defineProperty(n,t,{enumerable:!0,get:e[t]})},j.o=(n,e)=>Object.prototype.hasOwnProperty.call(n,e),j.r=n=>{typeof Symbol<"u"&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})};var I={};j.r(I),j.d(I,{Event:()=>O,Guest:()=>q,IFrameSandboxValues:()=>S,OpenMode:()=>f,SANDBOX_DEFAULT:()=>N,SSFHost:()=>ie,ScriptingObject:()=>U});class O{name;objectId;id;constructor(e){const{name:t,objectId:i}=e;if(!t)throw new Error("Event name is required");if(!i)throw new Error("Scripting object id is required");this.objectId=i,this.name=t,this.id=`${this.objectId}.${this.name}`.toLowerCase()}}class A{static[Symbol.hasInstance](e){return typeof e=="object"&&e!==null&&"getType"in e&&typeof e.getType=="function"&&e.getType()==="ProxyEvent"}#t;objectId;name;id;getType(){return"ProxyEvent"}constructor(e){const{name:t,objectId:i,eventSrc:s}=e;if(!t)throw new Error("Event name is required");if(!i)throw new Error("Scripting object id is required");if(!s)throw new Error("Event source is required");this.objectId=i,this.name=t,this.#t=s,this.id=`${this.objectId}.${this.name}`.toLowerCase()}subscribe=e=>this.#t.subscribe({eventId:this.id,callback:e});unsubscribe=e=>{this.#t.unsubscribe({eventId:this.id,token:e})}}const W=n=>n instanceof O,se=(n,e)=>`${n.toLowerCase()}.${e.toLowerCase()}`,H="function",F=(n,e)=>typeof n===H&&!!e&&!e.startsWith("_");class U{#t;#i="Object";constructor(e,t){this.#t=e,this.#i=t||this.#i}get id(){return this.#t}get objectType(){return this.#i}_toJSON=()=>{const e=[],t=[];return Object.keys(this).forEach(i=>{const s=this[i];W(s)?t.push(i):F(s,i)&&e.push(i)}),{objectId:this.#t,objectType:this.#i,functions:e,events:t}};_dispose=()=>{};dispose=()=>{}}var l=(n=>(n.GuestClose="guest:close",n.GuestEventSubscribe="guest:eventSubscribe",n.GuestEventUnsubscribe="guest:eventUnsubscribe",n.GuestFocus="guest:focus",n.GuestReady="guest:ready",n.GuestReadyComplete="guest:readyComplete",n.GuestResize="guest:resize",n.HandShake="handshake",n.HandShakeAck="handshake:ack",n.HostClose="host:close",n.HostConfig="host:config",n.ListObjects="list:objects",n.ObjectEvent="object:event",n.ObjectGet="object:get",n.ObjectInvoke="object:invoke",n))(l||{}),f=(n=>(n.Popup="popup",n.Embed="embed",n))(f||{}),S=(n=>(n.AllowDownloadsWithoutUserActivation="allow-downloads-without-user-activation",n.AllowDownloads="allow-downloads",n.AllowForms="allow-forms",n.AllowModals="allow-modals",n.AllowOrientationLock="allow-orientation-lock",n.AllowPointerLock="allow-pointer-lock",n.AllowPopups="allow-popups",n.AllowPopupsToEscapeSandbox="allow-popups-to-escape-sandbox",n.AllowPresentation="allow-presentation",n.AllowSameOrigin="allow-same-origin",n.AllowScripts="allow-scripts",n.AllowStorageAccessByUserActivation="allow-storage-access-by-user-activation",n.AllowTopNavigation="allow-top-navigation",n.AllowTopNavigationByUserActivation="allow-top-navigation-by-user-activation",n))(S||{});const J=n=>{if(n==="about:blank")return"*";try{const{origin:e}=new URL(n);return e==="null"||!e?n:e}catch{const{origin:t}=new URL(n,document.baseURI);return t}},Y=n=>n.flat(1/0).filter(e=>e!==void 0);function R(n){return typeof n=="function"}class q{id;title;url;searchParams;domElement;window;openMode;origin;initialized=!1;ready=!1;capabilities;#t;#i;constructor(e){const{guestId:t,domElement:i=null,title:s,url:o,window:r,searchParams:c={},openMode:a=f.Embed,remoting:d,analyticsObj:u}=e;this.id=t,this.title=s,this.url=o,this.origin=J(o),this.searchParams=c,this.domElement=i,this.window=r,this.openMode=a,this.capabilities={},this.#i=u,this.#t=d}dispose=()=>{if(this.openMode===f.Popup&&!this.window.closed)try{this.window.document,this.window.close()}catch{this.#t.send({targetWin:this.window,targetOrigin:this.origin,messageType:l.HostClose,messageBody:{}})}else this.domElement?.remove?.();this.#t.removeSender({origin:this.origin,window:this.window})};getInfo=()=>({guestId:this.id,guestTitle:this.title,guestUrl:this.url});handShake=()=>new Promise(e=>{let t=0;const i=5;let s;const o=()=>{clearInterval(s),this.#t.unlisten({messageType:l.HandShakeAck,callback:o}),e(!0)};s=setInterval(()=>{t>=i?(clearInterval(s),this.#t.unlisten({messageType:l.HandShakeAck,callback:o}),e(!1)):(this.#t.send({targetWin:this.window,targetOrigin:this.origin,messageType:l.HandShake,messageBody:{}}),t+=1)},1e3),this.#t.listen({messageType:l.HandShakeAck,callback:o})});init=()=>{this.#t.addSender({origin:this.origin,window:this.window}),this.openMode===f.Popup&&this.handShake().catch(()=>{})};dispatchEvent=(e,t)=>(this.#i.startTiming(`ScriptingObject.Event.${e.object.objectId}.${e.eventName}`,{appId:this.id,appUrl:this.url}).catch(()=>{}),this.#t.invoke({targetWin:this.window,targetOrigin:this.origin,messageType:l.ObjectEvent,messageBody:e,responseTimeoutMs:t}).finally(()=>{this.#i.endTiming(`ScriptingObject.Event.${e.object.objectId}.${e.eventName}`,{appId:this.id,appUrl:this.url}).catch(()=>{})}));send=e=>{this.#t.send({targetWin:this.window,targetOrigin:this.origin,...e})}}const _={randomUUID:typeof crypto<"u"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};let P;const X=new Uint8Array(16);function K(){if(!P&&(P=typeof crypto<"u"&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!P))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return P(X)}var Q;const h=[];for(let n=0;n<256;++n)h.push((n+256).toString(16).slice(1));function L(n,e=0){return h[n[e+0]]+h[n[e+1]]+h[n[e+2]]+h[n[e+3]]+"-"+h[n[e+4]]+h[n[e+5]]+"-"+h[n[e+6]]+h[n[e+7]]+"-"+h[n[e+8]]+h[n[e+9]]+"-"+h[n[e+10]]+h[n[e+11]]+h[n[e+12]]+h[n[e+13]]+h[n[e+14]]+h[n[e+15]]}function oe(n,e=0){const t=L(n,e);if(!Q(t))throw TypeError("Stringified UUID is invalid");return t}const re=null;function Z(n,e,t){if(_.randomUUID&&!e&&!n)return _.randomUUID();n=n||{};const i=n.random||(n.rng||K)();if(i[6]=i[6]&15|64,i[8]=i[8]&63|128,e){t=t||0;for(let s=0;s<16;++s)e[t+s]=i[s];return e}return L(i)}const M=Z,C="elli:remoting",x="elli:remoting:response",D="elli:remoting:exception",$=({messageType:n,messageBody:e,requestId:t,onewayMsg:i=!1})=>({requestId:t??(i?null:M()),source:C,type:n,body:e}),ce=n=>{const{targetWin:e,targetOrigin:t,messageType:i,messageBody:s}=n,o=$({messageType:i,messageBody:s});e.postMessage(o,t)};class V{#t;#i;#e=new Map;#n=new Map;#s=null;#o=null;#r=new Map;constructor(e,t){if(!e)throw new Error("logger is required");if(!t)throw new Error("correlationId is required");this.#t=t,this.#i=e}#l=()=>{this.#s=null;const e=Date.now(),t=[];let i=null;if(this.#n.forEach((s,o)=>{const{requestId:r,cancelTime:c}=s;c&&c<=e?(this.#i.debug(`Detected response timeout for requestId: ${r}...`),t.push(o),s.resolve(void 0)):c&&(i=i===null?c:Math.min(i,c))}),t.forEach(s=>{this.#n.delete(s)}),i!==null){const s=Math.max(i-Date.now(),0);this.#c(s)}};#c=e=>{this.#s===null&&(this.#s=window.setTimeout(this.#l,e))};#h=()=>{this.#s!==null&&(window.clearTimeout(this.#s),this.#s=null)};#a=e=>{const t=this.#n.get(e);return this.#i.debug(`serving requestId: ${e}`),this.#n.delete(e),t};#g=e=>{const{requestId:t}=e;this.#i.debug(`Response received for invocation requestId: ${t}`);const i=this.#a(t);return i?(i.resolve(e.body),!0):(this.#i.debug(`Received response to stale/invalid request with requestId: ${t}`),!1)};#p=e=>{this.#i.debug(`Exception received for invocation (requestId = ${e.requestId})`);const t=this.#a(e.requestId);return t?(t.reject(new Error(e.body)),!0):(this.#i.warn(`Received exception for stale/invalid request (requestId = ${e.requestId})`),!1)};#m=({sourceWin:e,sourceOrigin:t,message:i})=>{this.#i.debug(`Received message of type "${i.type}"`);const s=this.#e.get(i.type);return s?(s.forEach(o=>{this.#i.debug(`Invoking message handler ${o.name}`),o({sourceWin:e,sourceOrigin:t,requestId:i.requestId,type:i.type,body:i.body})}),!0):!1};#u=e=>{if(this.#r.size===0||!e.source)return!1;const t=this.#r.get(e.source);return!t||e?.data?.source!==C?!1:(this.#i.debug(`Remoting: Received message of type "${e.data.type}"`),e.data.type===x?this.#g(e.data):e.data.type===D?this.#p(e.data):this.#m({sourceWin:e.source,sourceOrigin:t,message:e.data}),!0)};addSender=e=>{const{origin:t,window:i}=e;if(!t)throw new Error("origin is required");if(!i)throw new Error("window is required");this.#r.set(i,t)};initialize=e=>{this.#o&&this.#o.removeEventListener("message",this.#u),e.addEventListener("message",this.#u),this.#o=e,this.#i.debug(`initialized remoting id: ${this.#t}`)};close=()=>{this.#o&&(this.#o.removeEventListener("message",this.#u),this.#o=null),this.#h(),this.#i.debug(`closed remoting id: ${this.#t}`)};invoke=e=>{const{targetWin:t,targetOrigin:i,messageType:s,messageBody:o,responseTimeoutMs:r}=e;return new Promise((c,a)=>{const d=$({messageType:s,messageBody:o});this.#n.set(d.requestId,{requestId:d.requestId,resolve:c,reject:a,cancelTime:r?Date.now()+r:null}),t.postMessage(d,i);const{requestId:u}=d;this.#i.debug(`Posted invocation message of type ${s} requestId: ${u||""}`),r&&(this.#i.debug(`scheduling timeout check for requestId: ${u||""} in ${r} ms`),this.#c(r))})};listen=e=>{const{messageType:t,callback:i}=e,s=this.#e.get(t)||[];s.push(i),this.#e.set(t,s)};unlisten=e=>{const{messageType:t,callback:i}=e,s=this.#e.get(t);if(!s)return;const o=s.indexOf(i);o!==-1&&s.splice(o,1)};send=e=>{const{targetWin:t,targetOrigin:i,messageType:s,messageBody:o}=e,r=$({messageType:s,messageBody:o,onewayMsg:!0});t.postMessage(r,i),this.#i.debug(`Posted one-way message of type "${s}"`)};removeSender=e=>{const{window:t}=e;t&&this.#r.delete(t)};respond=e=>{const{targetWin:t,targetOrigin:i,requestId:s,response:o}=e,r=$({messageType:x,messageBody:o,requestId:s});t.postMessage(r,i),this.#i.debug(`Response sent to caller for invocation requestId: ${s}`)};raiseException=e=>{const{targetWin:t,targetOrigin:i,requestId:s,ex:o}=e,r=o instanceof Error?o.message:o,c=$({messageType:D,messageBody:r,requestId:s});t.postMessage(c,i),this.#i.debug(`Exception sent to caller for invocation. requestId: ${s}`)}}const z="module";var ee=(n=>(n.USER="USER",n.PARTNER="PARTNER",n))(ee||{});class te{#t=e=>e.trim().toLowerCase();#i=new Map;#e=new Map;#n=e=>{const{so:t,guestId:i}=e,s=this.#t(t.id),o=this.#e.get(i);if(!o)this.#e.set(i,new Map([[s,e]]));else{if(o.has(s))throw new Error(`Scripting Object ${t.id} already exists for guest ${i}`);o.set(s,e)}};#s=({so:e})=>{if(e._dispose&&typeof e._dispose=="function")try{e._dispose()}catch{}};#o=({objectId:e,guestId:t})=>{if(e===z&&!t)for(const[,s]of this.#e){const o=s.get(e);if(o)return o}const i=t?this.#e.get(t):null;return i?i.get(e)??null:null};#r=({objectId:e,guestId:t}={})=>{if(t){if(!e){const s=this.#e.get(t);s&&s.forEach(this.#s),this.#e.delete(t);return}const i=this.#e.get(t);if(i){const s=i.get(e);s&&this.#s(s),i.delete(e)}}else e&&this.#e.forEach(i=>{const s=i.get(e);s&&this.#s(s),i.delete(e)})};addScriptingObject=(e,t)=>{const{guestId:i}=t||{};if(!e?.id||!e?._toJSON)throw new Error("Object is not derived from ScriptingObject");const s=this.#t(e.id);if(s===z&&!i)throw new Error("Guest id is required to add Module scripting object");if(i){this.#n({so:e,...t,guestId:i});return}if(this.#i.has(s))throw new Error(`Scripting Object ${e.id} already exists`);this.#i.set(s,{so:e,...t})};getObject=(e,t)=>{const i=this.#t(e);let s=this.#o({objectId:i,guestId:t?.id});s=s??this.#i.get(i)??null;const{so:o}=s||{};return o||null};has=(e,t)=>this.getObject(e,t)!==null;listScriptingObjects=e=>{const t=new Set(this.#i.keys()),i=this.#e.get(e);if(i)for(const s of i.keys())t.add(s);return Array.from(t)};removeScriptingObject=(e,t)=>{const i=this.#t(e);if(t)this.#r({objectId:i,guestId:t});else{this.#r({objectId:i});const s=this.#i.get(i);s&&this.#s(s),this.#i.delete(i)}};removeAllScriptingObjects=e=>{e?this.#r({guestId:e}):(this.#i.forEach(this.#s),this.#i.clear())}}class ae{__TYPE__="Proxy";id;objectType;constructor(e,t){this.id=e,this.objectType=t}}const B=n=>n?.constructor?.name==="Proxy"||n?.constructor?.name==="ScriptingObjectProxy"||n?.__TYPE__==="Proxy",N=[S.AllowScripts,S.AllowPopups,S.AllowModals,S.AllowForms,S.AllowDownloads,S.AllowSameOrigin];class ie{hostId;#t;#i;#e;#n;#s=new Map;#o=new Map;#r=new Map;#l=new Map;#c;#h=null;#a=null;#g=null;#p=null;constructor(e,t){if(this.hostId=e,!t?.logger)throw new Error("Logger is required");if(!t?.analyticsObj)throw new Error("Analytics object is required");if(this.#e=t.logger,this.#n=t.analyticsObj,this.#i=M(),this.#t=new V(this.#e,this.#i),t?.readyStateCallback&&typeof t?.readyStateCallback!="function")throw new Error("readyStateCallback must be a function");this.#h=t?.readyStateCallback||null,this.#g=t?.onGuestEventSubscribe||null,this.#p=t?.onGuestEventUnsubscribe||null,this.#c=new te,this.#t.initialize(window),this.#_(),window.addEventListener("beforeunload",this.#f),this.#e.debug(`host is initialized. hostId: ${this.hostId}, correlationId: ${this.#i}`)}#m=(e,t)=>{const i={event:e,...t};this.#n.sendBAEvent(i).catch(s=>{this.#e.debug(`Analytics sendBAEvent failed: ${s.message}`)})};#u=(e,t)=>{this.#n.startTiming(e,t).catch(i=>{this.#e.debug(`Analytics startTiming failed: ${i.message}`)})};#b=(e,t)=>{this.#n.endTiming(e,t).catch(i=>{this.#e.debug(`Analytics endTiming failed: ${i.message}`)})};#f=()=>{Array.from(this.#s.values()).filter(t=>t.openMode===f.Popup).map(t=>t.id).forEach(t=>this.unloadGuest(t))};#d=e=>this.#o.get(e);#O=e=>this.#r.get(e)??null;#S=e=>typeof e?._toJSON=="function";#v=(e,t)=>this.#S(e)?(this.#c.has(e?.id,t)||this.#c.addScriptingObject(e,t?{guestId:t?.id}:{}),{type:"object",object:e._toJSON()}):{type:"value",value:e};#B=e=>typeof e=="string"?e:e instanceof Error?e.message:"An unexpected error occurred in the host application";#y=e=>{e.ready&&this.#t.send({targetWin:e.window,targetOrigin:e.origin,messageType:l.HostConfig,messageBody:{logLevel:this.#e.getLogLevel(),...e.getInfo()}})};#I=({guest:e,obj:t,functionName:i,functionParams:s})=>{const o=t[i];return R(o)?(this.#e.debug(`Invoking host implementation of ${t.id}.${String(i)}()`),new Promise(r=>{Object.defineProperty(o,"callContext",{value:{guest:e},configurable:!0,enumerable:!0,writable:!0}),r(o(...s))})):(this.#e.warn(`Attempt to call invalid function on object type ${t.objectType}: ${String(i)}`),Promise.reject(new Error(`Method '${i}' not found in Scripting Object '${t.id}'`)))};#E=({sourceWin:e,sourceOrigin:t,requestId:i})=>{const s=this.#d(e);if(!s){this.#e.warn(`Received ready event for unknown guest. requestId: ${i}`);return}if(!s.initialized){this.#e.warn("Guest must be initialized before it is marked as ready"),this.#t.raiseException({targetWin:e,targetOrigin:t,requestId:i,ex:"Guest must be initialized before it is marked as ready"});return}if(!s.ready){s.ready=!0;const o=s.getInfo();this.#b("SSF.Guest.Load",{appId:o.guestId,appUrl:o.guestUrl}),this.#y(s),this.#h?.(s),this.#e.audit({message:"Guest is ready",...o})}};#$=({sourceWin:e,sourceOrigin:t,requestId:i,body:s})=>{const o=this.#d(e);if(!o){this.#e.warn(`Received ready event for unknown guest. requestid = ${i}`);return}o.initialized||(o.initialized=!0,o.capabilities=s||{},this.#e.audit({message:"Guest is initialized",...o.getInfo()})),(!s||!s.onReady)&&this.#E({sourceWin:e,sourceOrigin:t,requestId:i,type:"",body:null})};#k=async({sourceWin:e})=>{if(e?.window){const t=this.#w(e);t&&!await t.handShake()&&this.unloadGuest(e)}};#P=({sourceWin:e,sourceOrigin:t,requestId:i})=>{this.#e.debug(`Processing listObjects request. requestId = ${i}`);const s=this.#d(e);if(!s)return this.#e.warn("Rejected object request from unknown guest window"),!1;const o=this.#c.listScriptingObjects(s.id);return this.#t.respond({targetWin:e,targetOrigin:t,requestId:i,response:o}),this.#e.debug({message:"name of scripting objects returned",requestId:i,objects:o,...s.getInfo()}),!0};#T=({sourceWin:e,sourceOrigin:t,requestId:i,body:s})=>{const{objectId:o}=s;this.#e.debug(`Processing getObject request for object ${o}. requestId = ${i}`);const r=this.#d(e);if(!r)return this.#e.warn("Rejected object request from unknown guest window"),!1;const c=this.getScriptingObject(o,{guest:r});return c?(this.#t.respond({targetWin:e,targetOrigin:t,requestId:i,response:this.#v(c,r)}),this.#e.debug({message:"Scripting Object returned",requestId:i,scriptingObject:o,...r.getInfo()}),!0):(this.#e.warn(`unknown or unauthorized object ${o} from guest ${r.id}`),this.#t.raiseException({targetWin:e,targetOrigin:t,requestId:i,ex:`The requested object (${o}) is not available`}),!1)};#G=({sourceWin:e,requestId:t,body:i})=>{const{eventId:s,criteria:o,token:r}=i;this.#e.debug(`Processing guest event subscribe request for event ${s}. requestId = ${t}`);const c=this.#d(e);if(!c){this.#e.warn("Rejected event subscribe request from unknown guest window");return}setTimeout(()=>{try{this.#g?.({guestId:c.id,eventId:s,criteria:o,token:r})}catch(a){this.#e.warn(`Error in onGuestEventSubscribe callback for event ${s}: ${a.message}`)}},0)};#A=({sourceWin:e,requestId:t,body:i})=>{const{eventId:s,token:o}=i;this.#e.debug(`Processing guest event unsubscribe request for event ${s}. requestId = ${t}`);const r=this.#d(e);if(!r){this.#e.warn("Rejected event unsubscribe request from unknown guest window");return}setTimeout(()=>{try{this.#p?.({guestId:r.id,eventId:s,token:o})}catch(c){this.#e.warn(`Error in onGuestEventUnsubscribe callback for event ${s}: ${c.message}`)}},0)};#U=({sourceWin:e,requestId:t,body:i})=>{const s=this.#d(e);if(!s){this.#e.warn(`Received resize event from unknown guest. requestid = ${t}`);return}s.domElement&&(s.domElement.style.height=`${i.height}px`),this.#e.debug(`Guest ${s.id} resized to ${i.width}x${i.height}`)};#R=({sourceWin:e,sourceOrigin:t,requestId:i,body:s})=>{const{objectId:o}=s,r=this.#d(e);if(!r)return this.#e.warn("Rejected method invocation request from unknown guest window"),!1;this.#e.debug(`Function ${o}.${String(s.functionName)}() called from guest "${r.id}" (requestId = ${i})`);const c=this.getScriptingObject(o,{guest:r});if(!c)return this.#e.warn(`Invocation of unknown or unauthorized object ${o} from guest ${r.id}`),this.#t.raiseException({targetWin:e,targetOrigin:t,requestId:i,ex:`The requested object (${o}) is not available`}),!1;const a=r.getInfo();return this.#u(`ScriptingObject.API.${o}.${s.functionName}`,{appId:a.guestId,appUrl:a.guestUrl}),this.#I({guest:r,obj:c,functionName:s.functionName,functionParams:s.functionParams}).then(d=>{this.#t.respond({targetWin:e,targetOrigin:t,requestId:i,response:this.#v(d,r)}),this.#e.debug({message:"Value returned for Scripting Object method call",requestId:i,scriptingObject:o,scriptingMethod:s.functionName,...a})}).catch(d=>{this.#t.raiseException({targetWin:e,targetOrigin:r.origin,requestId:i,ex:d}),this.#e.error({message:"Exception thrown for Scripting Object method call",requestId:i,scriptingObject:o,scriptingMethod:s.functionName,...a})}).finally(()=>{this.#b(`ScriptingObject.API.${o}.${s.functionName}`,{appId:a.guestId,appUrl:a.guestUrl})}),!0};#q=()=>{this.#t.listen({messageType:l.GuestResize,callback:this.#U})};#_=()=>{this.#t.listen({messageType:l.GuestReady,callback:this.#$}),this.#t.listen({messageType:l.GuestReadyComplete,callback:this.#E}),this.#t.listen({messageType:l.GuestClose,callback:this.#k}),this.#t.listen({messageType:l.ListObjects,callback:this.#P}),this.#t.listen({messageType:l.ObjectGet,callback:this.#T}),this.#t.listen({messageType:l.ObjectInvoke,callback:this.#R}),this.#t.listen({messageType:l.GuestEventSubscribe,callback:this.#G}),this.#t.listen({messageType:l.GuestEventUnsubscribe,callback:this.#A})};#L=e=>e instanceof A||typeof e?.subscribe=="function";#j=e=>{const t=new q({...e,remoting:this.#t,analyticsObj:this.#n});return t.init(),this.#s.set(e.guestId,t),this.#o.set(t.window,t),this.#r.set(t.url,t),t};#w=e=>{if(typeof e=="string")return this.#s.get(e);const t=this.#o.get(e);return t||Array.from(this.#s.values()).find(i=>i.domElement===e)};#M=()=>{this.#a||(this.#a=setInterval(()=>{const e=[];this.#s.forEach(t=>{t.openMode===f.Popup&&t.window.closed&&e.push(t)}),e.forEach(t=>{const{id:i}=t;this.unloadGuest(i),this.#l.get(i)?.forEach(o=>{Promise.resolve(o({id:i})).catch(()=>{})})})},1e3))};#C=()=>{if(!this.#a)return;Array.from(this.#s.values()).some(t=>t.openMode===f.Popup)||(clearInterval(this.#a),this.#a=null)};#x=e=>{const{url:t,title:i,popupWindowFeatures:s={},searchParams:o,guestId:r,onLoad:c,onError:a}=e,{width:d=800,height:u=600,top:y=100,left:E=100}=s;let g=this.#O(t);if(g)g.window.closed||g.send({messageType:l.GuestFocus,messageBody:{}});else{const w=Object.entries({width:d,height:u,top:y,left:E}).filter(([,b])=>b).map(([b,p])=>`${b}=${p}`).join(","),m=window.open(t,i,`popup, ${w}`);if(m)setTimeout(()=>{try{c?.(r)}catch(b){this.#e.debug(`Error occurred in onLoad for guest with id '${r}': ${b.message}`)}},0);else throw setTimeout(()=>{try{a?.(r)}catch(b){this.#e.debug(`Error occurred in onError for guest with id '${r}': ${b.message}`)}},0),new Error("Failed to open guest application in popup window");m.opener=null,g=this.#j({guestId:r,window:m,title:i,url:t,searchParams:o,openMode:f.Popup}),this.#M()}return g};#D=e=>{const{url:t,title:i,targetElement:s,searchParams:o,guestId:r,onLoad:c,onError:a,options:d={}}=e,u=s.ownerDocument??document,{fitToContent:y=!1,disableSandbox:E=!1,sandboxValues:g=[],customSandboxValues:w=[],style:m="",permissionPolicy:b=""}=d;if(!i)throw new Error("title is required");y&&this.#q();const p=u.createElement("iframe");p.setAttribute("id",r);const T=()=>{setTimeout(()=>{try{c?.(r)}catch(G){this.#e.debug(`Error occurred in onLoad for guest with id '${r}': ${G.message}`)}},0),this.#e.debug(`frame loaded for guest with id '${r}'`),p.removeEventListener("load",T)},v=()=>{setTimeout(()=>{try{a?.(r)}catch(G){this.#e.debug(`Error occurred in onError for guest with id '${r}': ${G.message}`)}},0),this.#e.error(`frame load failed for guest with id '${r}'`),p.removeEventListener("error",v)};p.addEventListener("load",T),p.addEventListener("error",v),p.setAttribute("style",`min-width: 100%; height: 100%; border: 0px; ${m}`),E||p.setAttribute("sandbox",w.length>0?w.join(" "):[...N,...g].join(" ")),p.setAttribute("title",i),p.setAttribute("src",t),b&&p.setAttribute("allow",b),s.appendChild(p);const k=u.getElementById(r);return this.#j({guestId:r,domElement:k,window:k.contentWindow,title:i,url:t,searchParams:o,openMode:f.Embed})};#z=(e,t)=>{let i="";return Object.keys(t).forEach(s=>{i+=`${(i.length?"&":"")+encodeURIComponent(s)}=${encodeURIComponent(t[s])}`}),e+(i?(e.indexOf("?")>=0?"&":"?")+i:"")};addScriptingObject=(e,t)=>{if(B(e)){const i=this.cloneScriptingObject(e);this.#c.addScriptingObject(i,t)}else this.#c.addScriptingObject(e,t)};cloneScriptingObject=e=>{if(!e)throw new Error("proxy is required");const t=new U(e.id,e.objectType);let i=[];return Object.keys(e).forEach(s=>{const o=e[s];if(this.#L(o)){const r=new O({name:o.name||s,objectId:t.id});if(Object.defineProperty(t,s,{value:r,enumerable:!0}),o instanceof A){const c=({eventParams:d,eventOptions:u})=>this.dispatchEvent({event:r,eventParams:d,eventOptions:u}),a=o.subscribe(c);i.push(()=>{o.unsubscribe(a)})}else{const c=o.subscribe?.((a,d,u)=>this.dispatchEvent({event:r,eventParams:d,eventOptions:u}));i.push(()=>{o.unsubscribe?.(c)})}}else if(R(o)&&(Object.defineProperty(t,s,{value:async(...r)=>{const c=await o(...r);return B(c)?this.cloneScriptingObject(c):c},enumerable:!0}),s==="dispose")){const r=t.dispose;Object.defineProperty(t,s,{value:()=>(t._dispose(),r.apply(t)),enumerable:!0})}}),t._dispose=()=>{i.forEach(s=>{s?.()}),i=[]},t};close=()=>{this.#a&&(clearInterval(this.#a),this.#a=null),this.#f(),this.#t.close(),window.removeEventListener("beforeunload",this.#f),this.#e.debug(`host is closed. hostId: ${this.hostId}, correlationId: ${this.#i}`)};dispatchEvent=async e=>{const{event:{id:t,name:i},eventParams:s,eventOptions:o={}}=e,{eventHandler:r=null,timeout:c=null,window:a=null,guestId:d}=o,u=t.split(".")[0],y=d||a,E=y?this.#w(y):null,g=E?this.getScriptingObject(u,{guest:E}):this.getScriptingObject(u);if(!g)return this.#e.warn(`Attempt to dispatch event ${i} on unknown object ${u}`),Promise.resolve([]);const w={object:g._toJSON(),eventName:i,eventParams:s,eventHandler:r,eventOptions:{allowsFeedback:!1}};c&&!Number.isNaN(c)&&(w.eventOptions={allowsFeedback:!0,timeout:Number(c)});const m=[];let b=!1;const p=v=>{const k=v.getInfo();c&&v?.capabilities?.eventFeedback?(m.push(v.dispatchEvent(w,c)),b||(this.#u(`ScriptingObject.Event.${g.id}.${i}`,{appId:this.hostId,appUrl:window.location.href}),b=!0),this.#e.debug({message:"Event dispatched and awaiting feedback",scriptingEventId:t,...k})):(v.send({messageType:l.ObjectEvent,messageBody:w}),this.#e.debug({message:"Event dispatched",scriptingEventId:t,...k}))};return E?p(E):this.#s.forEach(p),await Promise.all(m).then(v=>(this.#e.debug({message:"Event feedback received",scriptingEventId:t}),Y(v))).catch(v=>{throw this.#e.error({message:"Error processing event",eventId:t,exception:v}),v}).finally(()=>{b&&this.#b(`ScriptingObject.Event.${g.id}.${i}`,{appId:this.hostId,appUrl:window.location.href})})};getGuests=()=>Array.from(this.#s.values());getScriptingObject=(e,t)=>this.#c.getObject(e,t?.guest);loadGuest=e=>{const{id:t,url:i,targetElement:s,title:o,searchParams:r={},onLoad:c,onError:a,options:d={}}=e;if(!t)throw new Error("id for guest application is required");let u=t;if(this.#s.has(u)){let m=1;for(;this.#s.has(`${t}-${m}`);)m+=1;u=`${t}-${m}`}const{openMode:y=f.Embed,popupWindowFeatures:E={}}=d,g=this.#z(i,r);let w=null;if(this.#u("SSF.Guest.Load",{appId:u,appUrl:g}),y===f.Popup)w=this.#x({guestId:u,url:g,title:o,searchParams:r,popupWindowFeatures:E,onLoad:c,onError:a});else if(y===f.Embed)w=this.#D({guestId:u,url:g,title:o,targetElement:s,searchParams:r,onLoad:c,onError:a,options:d});else throw new Error(`Invalid openMode: ${y}`);return this.#e.audit({message:"Guest loaded",...w.getInfo()}),w};loadGuests=e=>{const{id:t,url:i,targetElement:s,title:o,searchParamsList:r=[],options:c={}}=e;r.forEach((a,d)=>{this.loadGuest({id:`${t}-${d}`,url:i,title:o,targetElement:s,searchParams:a,options:c})},this)};removeAllScriptingObjects=e=>{this.#c.removeAllScriptingObjects(e)};removeScriptingObject=(e,t)=>{this.#c.removeScriptingObject(e,t)};setLogLevel=e=>{this.#e.setLogLevel(e),this.#s.forEach(this.#y),this.#e.debug("Dispatched config events to all guests")};unloadGuest=e=>{const t=this.#w(e);t&&(t.dispose(),this.#o.delete(t.window),this.#r.delete(t.url),this.#s.delete(t.id),this.#e.audit({message:"Guest is removed from host",...t.getInfo()}),this.#C())};onGuestClose=e=>{const{id:t,guestCloseCallback:i}=e,s=this.#l.get(t)||[];s.push(i),this.#l.set(t,s)}}return I})());
2
-
3
- //# sourceMappingURL=emuiSsfHost.5855ec3cd0fa60013d84.js.map