Thursday, December 30, 2010

CRM Gotcha: Using Javascript URIs in SiteMap

Donna Edwards, CRM forums co-owner and established MVP, will often bounce threads from the “main” CRM forum into the CRM Development forum, which I comfortably call home, whenever the question is a particularly obscure one and hasn’t received an answer from the cabal of experts usually found in the “main” CRM forum.  I delight in any opportunity to take her “escalations” as a personal challenge.  Today, I found it in this thread.

The author explains that his usage of a “javascript:” URI produces interesting behavior when placed into the Url attribute of a SubArea element within the CRM SiteMap.  At first, with some simple JavaScript, he was receiving the text “[object]” in the dynamic CRM content frame.  Then, when he voided the return of the URI’s script, the “Loading…” message and graphic would remain (until some other area was loaded).

I encountered a similar behavior when working on the Embedded Advanced Find View project, and guessed that the same situational elements must be present here.  Not wanting to be wrong, I pulled out the IE Developer Tools (side-note: Microsoft, this is seriously the coolest feature of IE 8), and confirmed it.

So, what explains the behavior?  The answer is simple:  AJAX.  See, CRM’s UI scripts don’t simply pass the Url value into the src attribute of a frame (or Iframe); how would it achieve the “Loading…” message, if it did?  The trick, is that CRM scripts overwrite the contents of the dynamic content frame with the HTML necessary to display that message, and then instantiates a new, ActiveX [FreeThreaded]DOMDocument object behind-the-scenes to load the target URI.  When the status of the DOM document object becomes complete, the dynamic content frame’s DOM is overridden with the results.

This means that the original contents are lost.  Because the previous contents were also loaded in this dynamic fashion, and don’t exist in the browsing history, the frame can’t be historically reverted (e.g. javascript:history.go(-1)).  Additionally, a “javascript:” URI isn’t loaded into the DOM document object until after the contents have already been replaced by the “Loading…” message.  So, it makes any reference to the information that had originally been in the frame nearly impossible to obtain.

I’m sure somebody will figure out how best to produce content or redirection within the dynamic content frame, while simultaneously using a “javascript:” URI, but I’m unaware of any such process available today.  I think it’s simply safer to say that, though not expressly declared as such in the SDK, “javascript:” URIs aren’t supported.