

    





/**
 *
 * Connect APIs are split into mutiple "features". The app developers
 * can choose to only the necessary features they need.
 *
 */

/**
 * Connect configurations for Renren
 */
if (!window.Connect_Config) {
  Connect_Config = {
    "domain": "renren.com",
    "mainsite_name": "Renren",
    "static_url": "http://xnimg.connect.renren.com",
    "mainsite_name_cn": "\u4eba\u4eba\u7f51"
  };
}

// Create XN namespace if necessary
if (!window.XN) {
  XN = {};
}

// Only load if this class is not already loaded
if (!XN.Bootstrap) {
  XN.Bootstrap = {
    /*
     * Use this to request loading of features in Xiaonei Client JavaScript library
     * @param features  array of features (see wiki for options)
     * @param callback  callback function to be executed when all required features
     *                  are finished loading
     */
    requireFeatures : function(features, callback) {
      // Don't do anything if this page is a cross domain channel page
      if (XN.Bootstrap.isXdChannel) {
        return;
      }

      XN.Bootstrap.enqueueFeatureRequest({"features": features,
            "callback": callback,
            "loadedCount": 0});
      if (XN.Bootstrap.FeatureMap) {
        if (XN.FeatureLoader) {
          XN.FeatureLoader.singleton.checkRequestQueue();
        } else {
          XN.Bootstrap.addScript(XN.Bootstrap.FeatureMap["Base"].src);
        }
      }
    },

    /*
     * Convenient wrapper for calling Xiaonei API calls. Because the Xiaonei
     * API is dynamically loaded, this guarantees that your function isn't called
     * until both the libraries are loaded and initialized.
     *
     * Use in conjunction with XN.init.
     * Example usage:
     XN.ensureInit (  function () {
     // ... any code in the Xiaonei library
     });
     *
     * @param callback   function to call when Xiaonei is dynamically loaded.
     * @throws exception if XN.init is not called within the document.
     */
    ensureInit : function(callback) {
      if (!callback) {
        throw("XN.ensureInit called without a valid callback");
      }

      // short-circuit if initialization has already been called
      if (XN.Main &&
          XN.Main.get_initialized &&
          XN.Main.get_initialized().get_isReady() &&
          XN.Main.get_initialized().result) {
        return callback();
      }

      // if it's not already initialized, then queue it up
      // by the time this callback is executed, XN.Main.init
      // must have been called or else
      XN.Bootstrap.requireFeatures(XN.Bootstrap.features, function() {
        XN.Main.get_initialized().waitForValue(true, callback);
        });
    },

    /*
     * This safely initializes the Xiaonei API for use on a Connect or iframe site.
     *
     * It is a wrapper around XN.Main.init, provided here so that it is available
     * before the rest of the library is dynamically loaded. All subsequent calls
     * must be wrapped in XN.ensureInit() in order to guarantee that the init function is
     * called first.
     *
     * Example Usage:
     *
     <body>
     ...
     <script type="text/javascript" src="http://static.connect.renren.com/js/v1.0/FeatureLoader.jsp"></script>
     <script type="text/javascript">
     XN.init("API_KEY", "xd_receiver.php")
     </script>
     </body>
     *
     *  @param api_key       your API key provided by the developer app
     *  @param xd_receiver   The cross-domain receiver file on your domain.
     *                       Suggest using an absolute URL like "/xd_receiver.htm"
     *  @param appSettings   Optional application settings.
     */
    init : function(api_key, xd_receiver, appSettings) {
      // bind to the onload handler
      XN.Bootstrap.requireFeatures(XN.Bootstrap.features, function() {
          if (XN.Main) {
            // init has changed definition by now
            XN.Main.init(api_key, xd_receiver, appSettings);
          }
        });
    },

    /*
     * Dynamically add a script tag to the document.
     */
    addScript : function(src) {
      var scriptElement;

      // Check if we have the script loaded already
      var scriptElements = document.getElementsByTagName('script');
      if (scriptElements ) {
        var c = scriptElements.length;
        for (var i = 0; i < c; i++) {
          scriptElement = scriptElements[i];
          if (scriptElement.src == src) {
            // Found a match
            return;
          }
        }
      }


      scriptElement = document.createElement("script");
      scriptElement.type = "text/javascript";
      scriptElement.src = src;
      document.getElementsByTagName("HEAD")[0].appendChild(scriptElement);
    },

    /*
     * Initialize global page, one-time setup for the cross domain channel.
     *
     * Some sites may not have a dedicated cross domain channel page, but
     * use an existing page url as the channel page by using the special
     * xnc_receiver=1 query parameter. This is not very performant but we
     * support in cases where a dedicated channel is difficult to create.
     *
     */
    initializeXdChannel : function () {
      XN.Bootstrap.isXdChannel =
        window.location.search.indexOf(XN.Bootstrap.xnc_channel_token) >= 0;

      if (!XN.Bootstrap.isXdChannel) {
        XN.Bootstrap.createHiddenDiv();
        XN.Bootstrap.detectDOMContentReady();
      }
    },

    /*
     * Use detectDOMContentReady to determine whether window is loaded.
     * Because there is no way to determine a window is loaded after it is
     * already loaded, we must initialize the state to false in a code that
     * will be executed before the window is loaded, then listen to the window
     * load event.
     *
     * Since FeatureLoader.js.php is the only script we have that is not
     * dynamically loaded, we must place this code in this file.
     */
    detectDOMContentReady : function() {
      if (window.navigator.userAgent.toLowerCase().indexOf("msie") >= 0) {
        window.attachEvent("onload", function() {
            XN.Bootstrap.IsDomContentReady = true;
          });
      } else {
        window.addEventListener("DOMContentLoaded", function() {
            XN.Bootstrap.IsDomContentReady = true;
          }, false);
      }
    },

    /*
     * Create a hidden DOM container element. This is used to store hidden
     * iframes. If developers do not want the document.write to be called,
     * they can create their own hidden div named "XN_HiddenContainer".
     */
    createHiddenDiv : function() {
      if (document.getElementById('XN_HiddenContainer') == null) {
        if (document.body) {
          window.setTimeout(function() {
            var div = document.createElement("div");
            div.id = "XN_HiddenContainer";
            div.style.position = "absolute";
            div.style.top = "-10000px";
            div.style.left = "-10000px";
            div.style.width = "0px";
            div.style.height = "0px";
            document.body.appendChild(div);
          }, 0);
        }
        else {
          document.write('<div id="XN_HiddenContainer" '
                       + 'style="position:absolute; top:-10000px; left:-10000px; width:0px; height:0px;" >'
                       + '</div>');
        }
      }
    },

    /*
     * Loads the map of feature => file that enables dynamic loading of JS files.
     * Note that for now, these are pretty much all pointing to the same file,
     * but we hope to implement some optimizations in the future to make this
     * more customizable.
     *
     * @param  featureMap          map of feature => file
     * @param  staticResourceMap   map of static resource identifier => file
     * @param  siteVarsMap         map of server-side relevant siteVars
     */
    loadServerMaps : function(featureMap, staticResourceMap, siteVarsMap) {
      if(!this.FeatureMap.length) {
        this.FeatureMap = featureMap;
        this.StaticResourceVersions = staticResourceMap;
        if (XN.FeatureLoader) {
          XN.FeatureLoader.singleton.checkRequestQueue();
        }
      }
      if (!this.siteVars.length) {
        this.siteVars = siteVarsMap;
      }
    },

    /*
     * Submit a given feature request for loading.
     */
    enqueueFeatureRequest : function(request) {
      this.FeatureRequestQueue[this.FeatureRequestQueue.length] = request;
    },

    /*
     * For IE, we will try to detect if document.namespaces contains 'xn' already
     * and add it if it does not exist.
     */
    detectDocumentNamespaces : function() {
      if (document.namespaces && !document.namespaces.item['xn']) {
        document.namespaces.add('xn');
      }
    },

    /*
     * If a dedicated cross domain channel url cannot be created.
     * Use this function create an url based on current page by
     * adding a special query string to the url of the current page.
     * This should be avoided unless there is other choice because
     * it is not efficient.
     */
    createDefaultXdChannelUrl : function() {
      var xd_receiver = location.protocol + '//' + location.hostname +
      location.pathname + location.search;
      if(location.search || location.search.length > 0) {
        xd_receiver += '&';
      } else {
        xd_receiver += '?';
      }
      xd_receiver += 'xnc_channel=1';
      return xd_receiver;
    },

    /*
     * Global state variables
     */
    features                 : ["EXNML", "CanvasUtil"],

    IsDomContentReady        : false,
    FeatureRequestQueue      : [],
    FeatureMap               : {},
    StaticResourceVersions   : {},
    CustomFeatureMap         : [],
    siteVars                 : {},
    xnc_channel_token        : 'xnc_channel=1'
  };

  /*
   * Define shorthand functions for ease of use.
   */
  window.XN_RequireFeatures        = XN.Bootstrap.requireFeatures;
  window.XN.init                   = XN.Bootstrap.init;
  window.XN.ensureInit             = XN.Bootstrap.ensureInit;
}

XN.Bootstrap.initializeXdChannel();
XN.Bootstrap.detectDocumentNamespaces();
XN.Bootstrap.loadServerMaps(
        /* featureMap        */ {
        	"Base":{"src":Connect_Config.static_url + "/js/api/connect/connect.js?ver=10410","dependencies":null},
        	"Common":{"src":Connect_Config.static_url + "/js/api/connect/connect.js?ver=10410","dependencies":["Base"]},
        	"XdComm":{"src":Connect_Config.static_url + "/js/api/connect/connect.js?ver=10410","dependencies":["Common"]},
        	"CacheData":{"src":Connect_Config.static_url + "/js/api/connect/CacheData.js?ver=10410","dependencies":["Common","XdComm"]},
        	"Api":{"src":Connect_Config.static_url + "/js/api/connect/connect.js?ver=10410","dependencies":["XdComm"]},
        	"CanvasUtil":{"src":Connect_Config.static_url + "/js/api/connect/connect.js?ver=10410","dependencies":["Common","XdComm"]},
        	"Connect":{"src":Connect_Config.static_url + "/js/api/connect/connect.js?ver=10410","dependencies":["CanvasUtil","Api"],
        		"styleSheets":[Connect_Config.static_url + "/css/connect/xn_connect.css?ver=10410"]},
        	"EXNML":{"src":Connect_Config.static_url + "/js/api/connect/connect.js?ver=10410","dependencies":["CanvasUtil","Api","Connect"]},
        	"Integration":{"src":Connect_Config.static_url + "/js/api/connect/Integration.js?ver=10410","dependencies":["Connect"]},
        	"Comments":{"src":Connect_Config.static_url + "/js/api/connect/Comments.js?ver=10410","dependencies":["XdComm","EXNML"]}},
        /* staticResourceMap */ {"base_url_format":"http:\/\/{0}.connect." + Connect_Config.domain + "\/","loginout_url":"http://login.api." + Connect_Config.domain + "/connect/{0}.do","stream_box_url":"http://www.connect." + Connect_Config.domain + "/widget/livewidget.do","api_channel":10000,"api_server":10000,"www_channel":10000,"xd_comm_swf_url":Connect_Config.static_url + "/swf/connect/XNConnect2.swf","login_img_dark_small":Connect_Config.static_url + "/img/connect/login_buttons/renren/connect_light_small.png","login_img_dark_medium":Connect_Config.static_url + "/img/connect/login_buttons/renren/connect_light_medium.png","login_img_dark_large":Connect_Config.static_url + "/img/connect/login_buttons/renren/connect_light_large.png","login_img_light_small":Connect_Config.static_url + "/img/connect/login_buttons/renren/connect_light_small.png","login_img_light_medium":Connect_Config.static_url + "/img/connect/login_buttons/renren/connect_light_medium.png","login_img_light_large":Connect_Config.static_url + "/img/connect/login_buttons/renren/connect_light_large.png","login_img_white_small":Connect_Config.static_url + "/img/connect/login_buttons/renren/connect_light_small.png","login_img_white_medium":Connect_Config.static_url + "/img/connect/login_buttons/renren/connect_light_medium.png","login_img_white_large":Connect_Config.static_url + "/img/connect/login_buttons/renren/connect_light_large.png","logout_img_small":Connect_Config.static_url + "/img/connect/login_buttons/renren/logout_small.gif","logout_img_medium":Connect_Config.static_url + "/img/connect/login_buttons/renren/logout_medium.gif","logout_img_large":Connect_Config.static_url + "/img/connect/login_buttons/renren/logout_large.gif", "share_img_standard_dark":Connect_Config.static_url + "/img/connect/share_buttons/renren/share_img_standard_dark.png", "share_img_standard_light":Connect_Config.static_url + "/img/connect/share_buttons/renren/share_img_standard_light.png", "expose_close_mark":Connect_Config.static_url + "/img/connect/login_buttons/renren/expose/close_mark.png", "expose_close_mark_mouseover":Connect_Config.static_url + "/img/connect/login_buttons/renren/expose/close_mark_mover.png", "expose_guide":Connect_Config.static_url + "/img/connect/login_buttons/renren/expose/guide.gif", "expose_guide_arrow_left":Connect_Config.static_url + "/img/connect/login_buttons/renren/expose/guide_arrow_left.gif", "expose_guide_arrow_right":Connect_Config.static_url + "/img/connect/login_buttons/renren/expose/guide_arrow_right.gif", "guide_close_mark":Connect_Config.static_url + "/img/connect/login_buttons/renren/expose/guide_close_mark.png", "guide_close_mark_mover":Connect_Config.static_url + "/img/connect/login_buttons/renren/expose/guide_close_mark_mover.png"},
        /* siteVarSettings   */ {"canvas_client_compute_content_size_method":1,"use_postMessage":0, "use_flash": 1, "api_cache_max_age": 600000, "xnml_cache_max_age": 600000, "expose_guide_width": 423, "expose_guide_height": 249, "expose_guide_arrow_width": 28, "expose_guide_arrow_height": 26});

