lib/web/DocmaWeb.js
function DocmaWeb(data) {
    this._ = data || {};

    // Flag for page load. Used for triggering the "ready" event only for page
    // load and not for route changes.
    this._.initialLoad = false;
    // app entrance optionally set @ build-time
    this._.appEntranceRI = null;

    this._.emitter = new EventEmitter();

    /**
     *  Provides configuration data of the generated SPA, which is originally set
     *  at build-time, by the user.
     *  See {@link api/#Docma~BuildConfiguration|build configuration} for more
     *  details on how these settings take affect.
     *  @name DocmaWeb#app
     *  @type {Object}
     *
     *  @property {String} title
     *            Document title for the main file of the generated app.
     *            (Value of the `&lt;title/>` tag.)
     *  @property {Array} meta
     *            Array of arbitrary objects set for main document meta (tags).
     *  @property {String} base
     *            Base path of the generated web app.
     *  @property {String} entrance
     *            Name of the initial content displayed, when the web app is first
     *            loaded.
     *  @property {String|Object} routing
     *            Routing settings for the generated SPA.
     *  @property {String} server
     *            Server/host type of the generated SPA.
     */
    Object.defineProperty(this, 'app', {
        configurable: false,
        get: function () {
            return this._.app || null;
        }
    });

    /**
     *	Hash-map of JSDoc documentation outputs.
        *	Each key is the name of an API (formed by grouped Javascript files).
        *	e.g. `docma.apis["some-api"]`
        *
        *  Unnamed documentation data (consisting of ungrouped Javascript files) can be
        *  accessed via `docma.apis._def_`.
        *
        *	Each value is an `Object` with the following signature:
        *	`{ documentation:Array, symbols:Array }`. `documentation` is the actual
        *	JSDoc data, and `symbols` is a flat array of symbol names.
        *
        *  <blockquote>See {@link api/#Docma~BuildConfiguration|build configuration} for more
        *  details on how Javascript files can be grouped (and named) to form separate
        *  API documentations and SPA routes.</blockquote>
        *
        *  @name DocmaWeb#apis
        *  @type {Object}
        *
        *  @example <caption>Programmatic access to documentation data</caption>
        *  // output ungrouped (unnamed) API documentation data
        *  console.log(docma.apis._def_.documentation);
        *  console.log(docma.apis._def_.symbols); // flat list of symbol names
        *  // output one of the grouped (named) API documentation data
        *  console.log(docma.apis['my-scondary-api'].documentation);
        *
        *  @example <caption>Usage in a Dust partial</caption>
        *  <!--
        *  	Each API data is passed to the partial, according to the route.
        *  	So you'll always use `documentation` within the partials.
        *  -->
        *  {#documentation}
        *      <h4>{longname}</h4>
        *      <p>{description}</p>
        *      <hr />
        *  {/documentation}
        */
    Object.defineProperty(this, 'apis', {
        configurable: false,
        get: function () {
            return this._.apis || {};
        }
    });

    /**
     *  Array of available SPA routes of the documentation.
     *  This is created at build-time and defined via the `src` param of the
     *  {@link api/#Docma~BuildConfiguration|build configuration}.
     *
     *  @name DocmaWeb#routes
     *  @type {Array}
     *
     *  @see {@link #DocmaWeb.Route|`DocmaWeb.Route`}
     */
    Object.defineProperty(this, 'routes', {
        configurable: false,
        get: function () {
            return this._.routes || {};
        }
    });

    /**
     *  Provides template specific configuration data.
     *  This is also useful within the Dust partials of the Docma template.
     *  @name DocmaWeb#template
     *  @type {Object}
     *
     *  @property {Object} options - Docma template options. Defined at build-time,
     *  by the user.
     *  @property {String} name
     *            Name of the Docma template.
     *  @property {String} version
     *            Version of the Docma template.
     *  @property {String} author
     *            Author information for the Docma template.
     *  @property {String} license
     *            License information for the Docma template.
     *  @property {String} mainHTML
     *            Name of the main file of the template. i.e. `index.html`
     *
     *  @example <caption>Usage in a Dust partial</caption>
     *  <div>
     *      {?template.options.someOption}
     *      <span>Displayed if someOption is true.</span>
     *      {/template.options.someOption}
     *  </div>
     *  <div class="footer">{template.name} by {template.author}</div>
     */
    Object.defineProperty(this, 'template', {
        configurable: false,
        get: function () {
            return this._.template || {};
        }
    });

    // --------------------------------
    // DOCMA-WEB STATE
    // --------------------------------

    /**
     *  Similar to `window.location` but with differences and additional
     *  information.
     *
     *  @name DocmaWeb#location
     *  @type {Object}
     *  @readonly
     *
     *  @property {String} origin
     *            Gets the protocol, hostname and port number of the current URL.
     *  @property {String} host
     *            Gets the hostname and port number of the current URL.
     *  @property {String} hostname
     *            Gets the domain name of the web host.
     *  @property {String} protocol
     *            Gets the web protocol used, without `:` suffix.
     *  @property {String} href
     *            Gets the href (URL) of the current location.
     *  @property {String} entrance
     *            Gets the application entrance route, which is set at Docma build-time.
     *  @property {String} base
     *            Gets the base path of the application URL, which is set at Docma build-time.
     *  @property {String} fullpath
     *            Gets the path and filename of the current URL.
     *  @property {String} pathname
     *            Gets the path and filename of the current URL, without the base.
     *  @property {String} path
     *            Gets the path, filename and query-string of the current URL, without the base.
     *  @property {String} hash
     *            Gets the anchor `#` of the current URL, without `#` prefix.
     *  @property {String} query
     *            Gets the querystring part of the current URL, without `?` prefix.
     *  @property {Function} getQuery()
     *            Gets the value of the given querystring parameter.
     */
    Object.defineProperty(this, 'location', {
        configurable: false,
        get: function () {
            var fullpath = Utils._ensureSlash(true, window.location.pathname, true),
                base = Utils._ensureSlash(true, docma.app.base, true),
                pathname = fullpath;
            if (fullpath.slice(0, base.length) === base) {
                pathname = fullpath.slice(base.length - 1, fullpath.length);
            }
            return {
                host: window.location.host,
                hostname: window.location.hostname,
                origin: window.location.origin,
                port: window.location.port,
                protocol: (window.location.protocol || '').replace(/:$/, ''),
                entrance: Utils._ensureSlash(true, docma.app.entrance, false),
                base: base,
                hash: (window.location.hash || '').replace(/^#/, ''),
                query: (window.location.search || '').replace(/^\?/, ''),
                href: window.location.href,
                fullpath: fullpath,
                pathname: pathname,
                path: pathname + (window.location.search || ''),
                getQuery: function (name, query) {
                    // Modified from http://stackoverflow.com/a/901144/112731
                    query = query === undefined ? (window.location.search || '') : query;
                    if (query.slice(0, 1) === '?') query = query.slice(1);
                    name = (name || '').replace(/[[\]]/g, '\\$&');
                    var regex = new RegExp('&?' + name + '(=([^&#]*)|&|#|$)'),
                        results = regex.exec(query);
                    if (!results || !results[2]) return '';
                    return decodeURIComponent(results[2].replace(/\+/g, ' '));
                }

            };
        }
    });

    /**
     *  Gets the route information for the current rendered content being
     *  displayed.
     *
     *  @name DocmaWeb#currentRoute
     *  @type {DocmaWeb.Route}
     *  @readonly
     *
     *  @property {String} type
     *            Type of the current route. If a generated JSDoc API
     *            documentation is being displayed, this is set to `"api"`.
     *            If any other HTML content (such as a converted markdown) is
     *            being displayed; this is set to `"content"`.
     *  @property {String} name
     *            Name of the current route. For `api` routes, this is the name
     *            of the grouped JS files parsed. If no name is given, this is
     *            set to `"_def_"` by default. For `content` routes, this is
     *            either the custom name given at build-time or, by default; the
     *            name of the generated HTML file; lower-cased, without the
     *            extension. e.g. `"README.md"` will have the route name
     *            `"readme"` after the build.
     *  @property {String} path
     *            Path of the current route.
     */
    Object.defineProperty(this, 'currentRoute', {
        configurable: false,
        get: function () {
            return this._.currentRoute || null;
        }
    });

    /**
     *	JSDoc documentation data for the current API route.
     *	If current route is not an API route, this will be `null`.
     *
     *  <blockquote>See {@link api/#Docma~BuildConfiguration|build configuration} for more
     *  details on how Javascript files can be grouped (and named) to form
     *  separate API documentations and SPA routes.</blockquote>
     *
     *  @name DocmaWeb#documentation
     *  @type {Array}
     *
     *  @example <caption>Output current API documentation data</caption>
     *  if (docma.currentRoute.type === 'api') {
     *  	console.log(docma.documentation);
     *  }
     *
     *  @example <caption>Usage in (Dust) partial</caption>
     *  {#documentation}
     *      <h4>{longname}</h4>
     *      <p>{description}</p>
     *      <hr />
     *  {/documentation}
     */
    Object.defineProperty(this, 'documentation', {
        configurable: false,
        get: function () {
            return this._.documentation || [];
        }
    });

    /**
     *	A flat array of JSDoc documentation symbol names. This is useful for
     *	building menus, etc... If current route is not an API route, this will
     *	be `null`.
     *
     *  <blockquote>See {@link api/docma#Docma~BuildConfiguration|build configuration} for more
     *  details on how Javascript files can be grouped (and named) to form
     *  separate API documentations and SPA routes.</blockquote>
     *
     *  @name DocmaWeb#symbols
     *  @type {Array}
     *
     *  @example <caption>Usage in (Dust) partial</caption>
     *  <ul class="menu">
     *      {#symbols}
     *          <li><a href="#{.}">{.}</a></li>
     *      {/symbols}
     *  </ul>
     */
    Object.defineProperty(this, 'symbols', {
        configurable: false,
        get: function () {
            return this._.symbols || [];
        }
    });
}
function DocmaWeb(data) {
    this._ = data || {};

    // Flag for page load. Used for triggering the "ready" event only for page
    // load and not for route changes.
    this._.initialLoad = false;
    // app entrance optionally set @ build-time
    this._.appEntranceRI = null;

    this._.emitter = new EventEmitter();

    /**
     *  Provides configuration data of the generated SPA, which is originally set
     *  at build-time, by the user.
     *  See {@link api/#Docma~BuildConfiguration|build configuration} for more
     *  details on how these settings take affect.
     *  @name DocmaWeb#app
     *  @type {Object}
     *
     *  @property {String} title
     *            Document title for the main file of the generated app.
     *            (Value of the `&lt;title/>` tag.)
     *  @property {Array} meta
     *            Array of arbitrary objects set for main document meta (tags).
     *  @property {String} base
     *            Base path of the generated web app.
     *  @property {String} entrance
     *            Name of the initial content displayed, when the web app is first
     *            loaded.
     *  @property {String|Object} routing
     *            Routing settings for the generated SPA.
     *  @property {String} server
     *            Server/host type of the generated SPA.
     */
    Object.defineProperty(this, 'app', {
        configurable: false,
        get: function () {
            return this._.app || null;
        }
    });

    /**
     *	Hash-map of JSDoc documentation outputs.
        *	Each key is the name of an API (formed by grouped Javascript files).
        *	e.g. `docma.apis["some-api"]`
        *
        *  Unnamed documentation data (consisting of ungrouped Javascript files) can be
        *  accessed via `docma.apis._def_`.
        *
        *	Each value is an `Object` with the following signature:
        *	`{ documentation:Array, symbols:Array }`. `documentation` is the actual
        *	JSDoc data, and `symbols` is a flat array of symbol names.
        *
        *  <blockquote>See {@link api/#Docma~BuildConfiguration|build configuration} for more
        *  details on how Javascript files can be grouped (and named) to form separate
        *  API documentations and SPA routes.</blockquote>
        *
        *  @name DocmaWeb#apis
        *  @type {Object}
        *
        *  @example <caption>Programmatic access to documentation data</caption>
        *  // output ungrouped (unnamed) API documentation data
        *  console.log(docma.apis._def_.documentation);
        *  console.log(docma.apis._def_.symbols); // flat list of symbol names
        *  // output one of the grouped (named) API documentation data
        *  console.log(docma.apis['my-scondary-api'].documentation);
        *
        *  @example <caption>Usage in a Dust partial</caption>
        *  <!--
        *  	Each API data is passed to the partial, according to the route.
        *  	So you'll always use `documentation` within the partials.
        *  -->
        *  {#documentation}
        *      <h4>{longname}</h4>
        *      <p>{description}</p>
        *      <hr />
        *  {/documentation}
        */
    Object.defineProperty(this, 'apis', {
        configurable: false,
        get: function () {
            return this._.apis || {};
        }
    });

    /**
     *  Array of available SPA routes of the documentation.
     *  This is created at build-time and defined via the `src` param of the
     *  {@link api/#Docma~BuildConfiguration|build configuration}.
     *
     *  @name DocmaWeb#routes
     *  @type {Array}
     *
     *  @see {@link #DocmaWeb.Route|`DocmaWeb.Route`}
     */
    Object.defineProperty(this, 'routes', {
        configurable: false,
        get: function () {
            return this._.routes || {};
        }
    });

    /**
     *  Provides template specific configuration data.
     *  This is also useful within the Dust partials of the Docma template.
     *  @name DocmaWeb#template
     *  @type {Object}
     *
     *  @property {Object} options - Docma template options. Defined at build-time,
     *  by the user.
     *  @property {String} name
     *            Name of the Docma template.
     *  @property {String} version
     *            Version of the Docma template.
     *  @property {String} author
     *            Author information for the Docma template.
     *  @property {String} license
     *            License information for the Docma template.
     *  @property {String} mainHTML
     *            Name of the main file of the template. i.e. `index.html`
     *
     *  @example <caption>Usage in a Dust partial</caption>
     *  <div>
     *      {?template.options.someOption}
     *      <span>Displayed if someOption is true.</span>
     *      {/template.options.someOption}
     *  </div>
     *  <div class="footer">{template.name} by {template.author}</div>
     */
    Object.defineProperty(this, 'template', {
        configurable: false,
        get: function () {
            return this._.template || {};
        }
    });

    // --------------------------------
    // DOCMA-WEB STATE
    // --------------------------------

    /**
     *  Similar to `window.location` but with differences and additional
     *  information.
     *
     *  @name DocmaWeb#location
     *  @type {Object}
     *  @readonly
     *
     *  @property {String} origin
     *            Gets the protocol, hostname and port number of the current URL.
     *  @property {String} host
     *            Gets the hostname and port number of the current URL.
     *  @property {String} hostname
     *            Gets the domain name of the web host.
     *  @property {String} protocol
     *            Gets the web protocol used, without `:` suffix.
     *  @property {String} href
     *            Gets the href (URL) of the current location.
     *  @property {String} entrance
     *            Gets the application entrance route, which is set at Docma build-time.
     *  @property {String} base
     *            Gets the base path of the application URL, which is set at Docma build-time.
     *  @property {String} fullpath
     *            Gets the path and filename of the current URL.
     *  @property {String} pathname
     *            Gets the path and filename of the current URL, without the base.
     *  @property {String} path
     *            Gets the path, filename and query-string of the current URL, without the base.
     *  @property {String} hash
     *            Gets the anchor `#` of the current URL, without `#` prefix.
     *  @property {String} query
     *            Gets the querystring part of the current URL, without `?` prefix.
     *  @property {Function} getQuery()
     *            Gets the value of the given querystring parameter.
     */
    Object.defineProperty(this, 'location', {
        configurable: false,
        get: function () {
            var fullpath = Utils._ensureSlash(true, window.location.pathname, true),
                base = Utils._ensureSlash(true, docma.app.base, true),
                pathname = fullpath;
            if (fullpath.slice(0, base.length) === base) {
                pathname = fullpath.slice(base.length - 1, fullpath.length);
            }
            return {
                host: window.location.host,
                hostname: window.location.hostname,
                origin: window.location.origin,
                port: window.location.port,
                protocol: (window.location.protocol || '').replace(/:$/, ''),
                entrance: Utils._ensureSlash(true, docma.app.entrance, false),
                base: base,
                hash: (window.location.hash || '').replace(/^#/, ''),
                query: (window.location.search || '').replace(/^\?/, ''),
                href: window.location.href,
                fullpath: fullpath,
                pathname: pathname,
                path: pathname + (window.location.search || ''),
                getQuery: function (name, query) {
                    // Modified from http://stackoverflow.com/a/901144/112731
                    query = query === undefined ? (window.location.search || '') : query;
                    if (query.slice(0, 1) === '?') query = query.slice(1);
                    name = (name || '').replace(/[[\]]/g, '\\$&');
                    var regex = new RegExp('&?' + name + '(=([^&#]*)|&|#|$)'),
                        results = regex.exec(query);
                    if (!results || !results[2]) return '';
                    return decodeURIComponent(results[2].replace(/\+/g, ' '));
                }

            };
        }
    });

    /**
     *  Gets the route information for the current rendered content being
     *  displayed.
     *
     *  @name DocmaWeb#currentRoute
     *  @type {DocmaWeb.Route}
     *  @readonly
     *
     *  @property {String} type
     *            Type of the current route. If a generated JSDoc API
     *            documentation is being displayed, this is set to `"api"`.
     *            If any other HTML content (such as a converted markdown) is
     *            being displayed; this is set to `"content"`.
     *  @property {String} name
     *            Name of the current route. For `api` routes, this is the name
     *            of the grouped JS files parsed. If no name is given, this is
     *            set to `"_def_"` by default. For `content` routes, this is
     *            either the custom name given at build-time or, by default; the
     *            name of the generated HTML file; lower-cased, without the
     *            extension. e.g. `"README.md"` will have the route name
     *            `"readme"` after the build.
     *  @property {String} path
     *            Path of the current route.
     */
    Object.defineProperty(this, 'currentRoute', {
        configurable: false,
        get: function () {
            return this._.currentRoute || null;
        }
    });

    /**
     *	JSDoc documentation data for the current API route.
     *	If current route is not an API route, this will be `null`.
     *
     *  <blockquote>See {@link api/#Docma~BuildConfiguration|build configuration} for more
     *  details on how Javascript files can be grouped (and named) to form
     *  separate API documentations and SPA routes.</blockquote>
     *
     *  @name DocmaWeb#documentation
     *  @type {Array}
     *
     *  @example <caption>Output current API documentation data</caption>
     *  if (docma.currentRoute.type === 'api') {
     *  	console.log(docma.documentation);
     *  }
     *
     *  @example <caption>Usage in (Dust) partial</caption>
     *  {#documentation}
     *      <h4>{longname}</h4>
     *      <p>{description}</p>
     *      <hr />
     *  {/documentation}
     */
    Object.defineProperty(this, 'documentation', {
        configurable: false,
        get: function () {
            return this._.documentation || [];
        }
    });

    /**
     *	A flat array of JSDoc documentation symbol names. This is useful for
     *	building menus, etc... If current route is not an API route, this will
     *	be `null`.
     *
     *  <blockquote>See {@link api/docma#Docma~BuildConfiguration|build configuration} for more
     *  details on how Javascript files can be grouped (and named) to form
     *  separate API documentations and SPA routes.</blockquote>
     *
     *  @name DocmaWeb#symbols
     *  @type {Array}
     *
     *  @example <caption>Usage in (Dust) partial</caption>
     *  <ul class="menu">
     *      {#symbols}
     *          <li><a href="#{.}">{.}</a></li>
     *      {/symbols}
     *  </ul>
     */
    Object.defineProperty(this, 'symbols', {
        configurable: false,
        get: function () {
            return this._.symbols || [];
        }
    });
}
Gets Docma version which the documentation is built with.
@name DocmaWeb#version
@type {String}
 
Docma (web) core.

When you build the documentation with a template, `docma-web.js` will be
generated (and linked in the main HTML); which is the core engine for the
documentation web app. This will include everything the app needs such as
the documentation data, compiled partials, dustjs engine, etc...

<blockquote>An instance of this object is globally accessible within the generated SPA
as <code>docma</code>. Note that the size of the `docma-web.js` script depends primarily
on the generated documentation data.</blockquote>

@class
@name DocmaWeb
@hideconstructor
@emits DocmaWeb~event:ready
@emits DocmaWeb~event:render
@emits DocmaWeb~event:route
@emits DocmaWeb~event:navigate