/** Kept as a separate module to make bundling easier. */ import { XRM } from "./xrm" /** * Get Xrm from a Promise. Uses polling to wait for * Xrm to become available. Default polling lasts 60 seconds * every 1/2 second. This only checks for Xrm on the parent window * it does *not* walk the window hierarchy. */ export function getXrmP(maxIter: number=120, delta: number=500, getXrm: () => XRM = () => (window.parent.Xrm as XRM)): Promise { return wait(() => { const x = getXrm() return typeof x !== "undefined" }, maxIter, delta).then(() => getXrm()) } /** * Get FormContext as a promise either from Xrm.Page or through the * FormContextHolder. */ export function getFormContextP(maxIter: number=120, delta: number=500): Promise { const fchP = wait(() =>{ const tmp = (window.parent as any) return typeof tmp.FormContextP !== "undefined" }, maxIter, delta).then(() => (window.parent as any).FormContextP as Xrm.FormContext) const parentP = wait(() => { const x = (window.parent.Xrm as XRM) return x && (typeof x.Page !== "undefined") }, maxIter, delta).then(() => (window.parent.Xrm as XRM).Page) return Promise.race([parentP, fchP]) } /** Wait for some condition to be true. Uses polling (setInterval) to iterate. */ export function wait(cond: (iteration: number) => boolean, maxIter: number, delta: number): Promise { if(maxIter <= 0 || delta <= 0) throw Error("maxIter and delta must be > 0") return new Promise(function(resolve, reject) { let count=0 const cancellable = setInterval(function() { if(count > maxIter) reject(null) count = count + 1 const proceed = cond(count) if(proceed) { clearInterval(cancellable) resolve() } }, delta) }) }