Source: VisitorAPI.js

/**
 * VisitorAPI.js
 *
 * Copyright (c) 2013 Visisoft GbR. All rights reserved.
 *
 * How to build the documentation with JSDoc3:
 * from inside the visitor_api/v2 directory execute the command line:
 * jsdoc -d ~/Documents/Projects/yalst/yalst-trunk/Documentation/visitor_api/ api/<wildcard star>*.js ../Readme.md --verbose --tutorials ../tutorials/ --query projectTitle=yalst%20VisitorAPI
 *
 * Specifying the project title on the generated html pages requires these changes to the
 * JSDoc template files:
   [publish.js]
   ...
   function generate(title, docs, filename, resolveLinks) {
    resolveLinks = resolveLinks === false ? false : true;

    var docData = {
        title: title,
        docs: docs,
        projectTitle: ""
    };

    if ( global.env.opts.query &&  (typeof global.env.opts.query.projectTitle == "string") )
    {
    	docData.projectTitle = global.env.opts.query.projectTitle + ' - ';
    }

    var outpath = path.join(outdir, filename),
        html = view.render('container.tmpl', docData);

    ...

    ////// repeat this for the generateTutorial function //////
    ...

    [layout.tmpl]

    <div id="main">

    <h1 class="page-title"><?js= projectTitle ?><?js= title ?></h1>

    <?js= content ?>
 *
 * ---- Syntax Highlighting ----
 *
 * should work out of the box since https://github.com/jsdoc3/jsdoc/pull/635
 *
 * -- previous workarounds:
 *
 * JSDoc 3.0 postprocessing:
 *  in index.html add class="prettyprint" to all <pre> tags which contain code
 *
 * JSDoc 3.3.0 postprocessing:
 * Either
 * Include jQuery then fire this script on document ready. The DOM must be loaded in order for the post-processing to have something to act upon. Of course if your target browsers are modern you can use pure JS and not jQuery.
 *
 *	$('code').parent('pre').addClass('prettyprint source linenums');
 *	window.prettyPrint && prettyPrint();
 *
 * or
 *
 * use modified jsdoc/templates/default/tmpl/examples.tmpl + mainpage.tmpl
 *
 *	(see: https://github.com/jsdoc3/jsdoc/pull/424#issuecomment-28893173)
 *
 *****************
 * How to change the namespace when distributing for API version 2.0 integration code:
 *
 * 1. change 2x in build.js - or use custom build.js file
 * 2. change GLOBAL_NAMESPACE in api/configuration.js
 * 3. change the GLOBAL_NAMESPACE variable in the build.sh script
 * 4. collect the Api under the global namespace with r.js (build script is ./build.sh)
 *
 * use "LiveSupport" as the namespace according to the documentation
 *
 * see http://requirejs.org/docs/faq-advanced.html#rename and
 * http://links.yalst.de/?link=non-conflicting-use-of-requirejs
 *
 *****************
 * Distributing as single file for API version 2.1 integration code:
 *
 * just change the name in build_namespaced.sh script
 *
 *****************
 *
 * @overview Documentation of the public yalst Visitor API
 * @copyright Visisoft OHG 2013-2015
 * @author Matthias Seemann
 * @version 2.1
 * @license License of the yalst Live Support Tool applies
 */

define(['underscore', 'api/errorCodes', 'api/configuration', 'api/ManagedError', 'api/operatorAvailability', 'api/startLiveChat', 'api/startControlling', 'api/ChatObserver', 'api/shouldInvite', 'lib/devTools'],
		function(_, ErrorCodes, Configuration, ManagedError, OperatorAvailability, StartLiveChat, startControlling, ChatObserver, shouldInvite, devTools)
	{
		/**
		 * The yalst namespace
		 * @namespace LiveSupport
		 */
		var LiveSupport = {};  // just for the documentation generator

		/**
		 * The Visitor API namespace
		 * @namespace LiveSupport.VisitorAPI
		 */
		LiveSupport.VisitorAPI = {};


		var api = {};

		/// insert the sub-apis

		api.ErrorCode = ErrorCodes;

		_(api).extend(Configuration);
		_(api).extend(OperatorAvailability);
		_(api).extend(StartLiveChat);
		api.startControlling = startControlling;
		api.ChatObserver = ChatObserver;
		api.shouldInvite = shouldInvite;

		/**
		 * Callback function provided by the implementer to receive the result of
		 * asynchronous API methods. <br/>
		 * Callbacks are always executed in a later run of the Javascript event loop like
		 * in Node's <tt>process.nextTick(callback)</tt> or <tt>setTimeout(callback, 0)</tt>, i.e.
		 * never immediately or synchronously to the method call.
		 * @callback resultCallback
		 * @param {*|LiveSupport.ManagedError|Error} resultOrError -
		 * The result of the asynchronous process or an
		 * API error. If the API call has failed <tt>resultOrError instanceof Error</tt> is true.
		 */

		/**
		 * The user callback taken by {@link LiveSupport.VisitorAPI.startControlling}.
		 *
		 * @callback userCallback
		 * @param {Error} error Error set in case of a failure.
		 */

		/**
		 * @function onYalstVisitorAPILoaded
		 * @description
		 * Global function optionally provided by the implementer. Called by the api loader once when the VisitorAPI is
		 * loaded into the JavaScript context of the web page. This only applies when loading the VisitorAPI library via
		 * a <tt>&lt;script&gt;</tt> tag or <tt>&lt;script&gt;</tt> tag injection.
		 * @param {object} api the VisitorAPI (same as <tt>LiveSupport.VisitorAPI</tt>)
		 */
		function onYalstVisitorAPILoaded(api){}


		/// redefine the invoke method to directly execute the method rather than queueing it

		/**
		 * Calls API methods regardless whether the browser has finished loading the API or not.
		 * It can be used right after the its definition in the Javascript code which loads
		 * the Visitor API asynchronously into the web page.
		 * If the API is not yet loaded  the calls are FIFO queued and
		 * invoked right when the API is ready.
		 * @param {string} method The method name like 'getVersionString'
		 * @param {array} parameterArray The parameters of the method or an empty array if there are no
		 * parameters required.
		 * @param {userCallback=} invocationCallback An optional invocationCallback function
		 * which receives the result of the immediately and synchronously executed method
		 * or an error
		 * @memberof LiveSupport.VisitorAPI
		 * @example
		 * LiveSupport.VisitorAPI.invoke('getVersionString', [], function(versionOrError){
		 * 	if (versionOrError instanceof Error){
		 * 		alert("Error :" + versionOrError.message; + "(#" + versionOrError.number + ")");
		 * 	}
		 * 	else{
		 * 		document.getElementById('apiVersion').innerHTML = "API version:" + versionOrError;
		 * 	}
		 * });
		 * @deprecated since version 2.1
		 */
		api.invoke = function(method, parameterArray, invocationCallback)
		{
			if (typeof method != "string")
			{
				if (typeof invocationCallback == "function")
				{
					_.defer(_.bind(invocationCallback, null, new ManagedError(ErrorCodes.ParameterTypeError
						, "invalid argument: 1 must be string")));
				}

				return;
			}

			invocationCallback = invocationCallback || function(){};

			if (!(method in api))
			{
				_.defer(_.bind(invocationCallback, null
					, new ManagedError(ErrorCodes.CallToUndefinedMethod
						, "Call to unknown method: " + method)
					)
				);
			}
			else
			{
				_.defer(_.bind(invocationCallback, null,
					api[method].apply(null, parameterArray))
				);
			}
		};

		if (Configuration.configuration.DEBUG)
		{
			devTools.console.log("VisitorAPI set up.");
		}

		return api;
	}
);