Using GreyBox in your HTML Applications
By
You may have never heard of Orangoo's GreyBox library, but you've almost certainly
seen it. The GreyBox library is an extension to the AJS JavaScript
Framework that displays websites, images, and other content in an eye-catching
popup window. Its striking appearance combined with small size and ease of use
has made it a hit with numerous websites. In fact, WebReference uses it to display
images and links to external sites. It has also been ported to other JS frameworks,
such as jQuery. That version is called GreyBox Redux. Impressed by its sleek
design, I chose to include it in an HTML Application (HTA) that I was building.
Imagine my surprise when it didn't work! I went through my code with a fine-toothed
comb, but to no avail; the GreyBox window was nowhere to be seen. Not to be deterred,
I sought to get to the bottom of this frustrating apparent incompatibility.
You'll be happy to know that my story is one of redemption. Now, in the hopes
of saving other developers from a similar fate, I will share my discoveries
with you and reveal how I got GreyBox to work within an HTA!
The HTA Security Model
On the MSDN site, I learned that HTAs differ from HTML pages in a number of ways. A cross between Visual Basic Scripts (VBS) and HTML, they really belong to a class all to themselves. HTAs run outside of Internet Explorer's usually restrictive runtime environment, and therefore are unhampered by the security constraints imposed by the browser. The process that they run under is called mshta.exe. You can see it in the Windows Task Manager while an HTA is running:
They do have one security feature to prevent cross-domain scripting attacks from
untrusted content. This risk is particularly salient in HTAs where downloading
content from the WWW is all too easy. As a precaution, the HTAs enable the
APPLICATION attribute for frame and iframe objects.
This security measure greatly interferes with GreyBox as it uses an iframe to
display the popup content. HTAs are designed so that untrusted HTML frame and
iframe objects have no script access to the HTA containing them. In the case
of frame objects that are not HTA-enabled, the highest level frame comprises
the top window for all frame objects it contains. Hence, for that frame object,
the window.top and window.self properties are one and the same. In addition,
unsafe frame and iframe objects receive neither a referrer nor an opener URL
from the parent HTA. The end result is that they are unaware of the containing
HTA as the parent window.
The gb_scripts.js file contains several references to the parent of the iframe:
The parent property is used by the GreyBox iframe to retrieve the GB_CURRENT
object. As explained above, the parent property always returns a pointer to
itself! Since the GB_CURRENT is not known to the iframe, the object is instanciated
to a value of undefined. All subsequent references to GB_CURRENT and its properties
will throw an error such as the one in Figure 2:
The Workaround
There are a few obstacles to making this an easy fix. This first is that the
APPLICATION attribute must be set to "yes" in the <IFRAME> tag. In other words,
it must be in the source code when the iframe is created; you cannot add it
later via scripting. Further complicating matters is the fact that the GreyBox
script is not easy to follow - by design. In order to make it lightweight, the
writers of the script use extremely short variable names, and include no indentations
or other style features that would otherwise improve the code's readability.
Moreover, if those first two points are not enough, it is written using the equally
difficult to follow AJS framework.
I am always hesitant to delve into framework code that I don't fully understand.
As a practitioner of Unobtrusive JavaScript, I want to make changes that will
not affect anything else in the slightest degree. After all, the whole point of
using a framework is to use it as a sort of "black box" that does what you
want without having to worry about the specific implementation details. While
I don't recommend that you attempt this type of thing at home, I feel confident
in suggesting a workaround here because my tweaking yielded a highly satisfactory
solution, if I may say so.




