Clever workaround for getting dynamically inserted javascript or stylesheets to work in Help Viewer 1.0

Working with our Visual Studio 2010 (and earlier!) partners, I'm frequently impressed with the ingenuity they demonstrate in just getting things to work. Even though Help systems these days are generally HTML based, there are often some gotchas that come up that are generally limitations due to an implementation.

With Help Viewer 1.0, one of the current limitations is that when .js or .css files (and other resources in general) are referenced, they essentially need to be hard coded in the topic in order for them to work. The reason for this is that just prior to loading and rendering the topic, the Help runtime does some transforms on the content to fix up the paths so that they are able to be extracted from our MSHC file format. (Just renamed .zip files.)

What if you want to dynamically reference a .css or .js file depending on the context of the topic itself? For example, suppose the exact same topic is meant to be used in a .CHM or .HxS file, or even possibly on a website? In general, this is currently not supported in Help Viewer 1.0. The reference that would be inserted would not happen until after our transforms are applied, and therefore the path to the .css would not express the full path into the MSHC. It would just not get used at all.

Richard Sloggett at Innovasys worked out an ingenious solution that he is leveraging in their Document!X and HelpStudio Pro authoring tools, and has kindly agreed to let me share it with the community. Here's what he writes:

Here’s the core function to get the resource base url - it relies on having a named script element – e.g.

<script id="mshs_support_script" src="scripts/mshs.js" mce_src="scripts/mshs.js" type="text/javascript"></script>

That script element can be anything – it’s just there to discover the store root. Just then append the relative bit (e.g. ResourceBaseUrl + ‘myscript.js’) when adding the new script.

/* Gets the MSHS base url for resources */

function ResourceBaseUrl() {

    if (isDesignTime) {

        return '';

    }

    else {

        // Get the first script tag

        var script = document.getElementById('mshs_support_script');

        // Extract the src which is a full resource url to within our origin .mshc

        var scriptSrc = script.src;

        // Get the portion up to the ; (the base url for resource references)

        var startIndex = scriptSrc.indexOf(';') + 1;

        var scriptUrl = scriptSrc.substring(0, startIndex);

        return scriptUrl;

    }

}

Brilliant! Thanks Richard, for allowing me to share this with the community.