Source: startControlling.js

/**
 * startControlling.js
 *
 * Created by Matthias Seemann on 15.01.2013.
 * Copyright (c) 2013 Visisoft GbR. All rights reserved.
 */

define(['underscore', 'api/errorCodes', 'api/configuration', 'api/ManagedError', 'lib/DataFormats', 'lib/asyncLoadElement']
, function(_, ErrorCode, Configuration, ManagedError, DataFormats, asyncLoadExternalSourceIntoElement)
{
	var didBeginControlling = false;
	/**
	 * id of the one and only yalst.js.php Javascript in the page
	 * @const
	 * @type {String}
	 */
	var controllingScriptId = "LiveSupport_Controlling_Script_Id";

	/**
	 * Begins identification of the user and opens a command socket in the website
	 * available to the Live Support operator console.<br><br>
	 * This method ensures it is called but once per each webpage document (and per
	 * VisitorAPI Javascript of course) loaded by the browser.
	 * Subsequent calls to this method will fail quietly.
	 * In order to track the user through a whole web presence this method must be called
	 * in each applicable webpage.<br>
	 * <h6>Integration warning</h6>
	 * The current implementation of this method adds a few <em>DOM elements (dialog box drop shadow)</em> to the page.
	 * @param {?string} [department=undefined] a particular yalst department id,
	 * if empty string any department otherwise the previously associated department id applies
	 * @param {?object} [customParameters=empty] parameters in the form
	 * <tt>{key1: value1, key2: value2}</tt>
	 * which become user-defined parameters of yalst' tracking php-script
	 * @param {(userCallback|function)} [callback] optional user callback executed when the script
	 * has finished loading with no arguments or if an error has occurred with a
	 * {@link LiveSupport.ManagedError}
	 * @memberof LiveSupport.VisitorAPI
	 * @throws {LiveSupport.ManagedError} in case no callback is provided and
	 * <ul><li>{@link LiveSupport.VisitorAPI.associateWithLiveSupportProduct}
	 * was not called before, or</li>
	 * <li>the method is called for the first time but user controlling is already running
	 * on the page.</li>
	 * </ul>
	 * @example
LiveSupport.VisitorAPI.startControlling('C', {}, function(error){
	if (error){
		alert("Error: " + error.message + "(#" + error.number + ")");
	}
	else{
		// user should now appear in the yalst console for operators of department 'C'
	}
});
	 */
	function startControlling(department, customParameters, callback)
	{
		if (didBeginControlling)
		{
			if (typeof callback == "function")
			{
				callback();
			}

			return;
		}

		var sanityCheckError;

		if (!Configuration.configuration.IS_ASSOCIATED)
		{
			sanityCheckError = new ManagedError(ErrorCode.ServerNotYetAssociated
				, "Illegal API use. Attempt to call the method 'startControlling'" +
					" before associated to a live support server.");
		}

		if (sanityCheckError)
		{
			if (typeof callback != "function")
			{
				throw sanityCheckError;
			}

			_.defer(_.bind(callback, null, sanityCheckError));

			return;
		}

		var queryParameters = {
			site: Configuration.configuration.PRODUCT_SITE
			, button : 'no'
			, y_span_id : 'y' + Math.random().toString()
		};

		if ((typeof department == "string") && (department.length > 0))
		{
			queryParameters.dept = department;
		}
		else if ((typeof department != "string")
			&& (typeof Configuration.configuration.PRODUCT_DEPARTMENT == "string")
			&& (Configuration.configuration.PRODUCT_DEPARTMENT.length > 0))
		{
			queryParameters.dept = Configuration.configuration.PRODUCT_DEPARTMENT;
		}

		if (typeof customParameters == "object")
		{
			_(queryParameters).extend(customParameters);
		}

		var oldScript = document.getElementById(controllingScriptId);
		if (oldScript)
		{
			 oldScript.parentNode.removeChild(oldScript);
		}

		var targetSpan = document.createElement('span');
		targetSpan.id = queryParameters.y_span_id;

		document.body.appendChild(targetSpan);

		/// load the traditional yalst.js.php script asynchronously
		var script = document.createElement('script');

		asyncLoadExternalSourceIntoElement(script
			, Configuration.configuration.PRODUCT_URL + "yalst.js.php?"
			+ DataFormats.urlQueryStringFromObject(queryParameters)
			, function()
			{
				didBeginControlling = true;

				if (typeof callback == "function")
				{
					callback();
				}
			}
		);

		script.id = controllingScriptId;
	}

	return startControlling;
});