function ExternCore(sid){ this._sid = null; this._user = null; this.client = {'origin':'*'}; this.inited = false; this.sid = sid; this._init(); }; // логгирование в консоль браузера ExternCore.prototype.trace = function(){ try{ var self = this.extern().toUpperCase() + '(' + (this.parent() ? 'par' : 'inc') + ')'; console.info('[' + self + ' => ' + arguments[0] + ']', ', ', arguments[1], ', ', arguments[2], ', ', arguments[3], ', ', arguments[4], ', ', arguments[5], ', ', arguments[6], ', ', arguments[7]); }catch(e){}; }; // получение домена верхнего уровня ExternCore.prototype.domain = function(){ return window.location.host.replace(/^(.*\.)*([^.]+\.[^.]+)$/, '$2'); }; // динамическое подключение css/js ExternCore.prototype.include = function(url, id, async){ this.trace('include', url, id, async); var inc = null, reg_js = /\.js(\?.*)*$/i, reg_css = /\.css(\?.*)*$/i, head = document.getElementsByTagName('HEAD')[0]; if(reg_css.test(url)){ inc = document.createElement('link'); inc.type = 'text/css'; inc.href = url; }else if(reg_js.test(url)){ inc = document.createElement('script'); inc.type = 'text/javascript'; inc.src = url; if(async){ inc.async = 'async'; }; }; if(inc){ if(id){ inc.id = id; }; head.appendChild(inc); this.trace('- included', inc.type); }else{ this.trace('- error'); }; }; // алиасы для работы с JSON-форматом (страховочка) ExternCore.prototype.tostr = function(data){ var result = null; try{ result = JSON.stringify(data); }catch(e){ this.trace('ERROR', 'objtostr', data, e); result = null; }; return result; }; ExternCore.prototype.toobj = function(data){ var result = null; try{ result = JSON.parse(data); }catch(e){ this.trace('ERROR', 'strtoobj', data, e); result = null; }; return result; }; // получение свойства объекта/самого объекта ExternCore.prototype.prop = function(data, prop){ if(typeof data == 'undefined'){ return null; }; if(typeof prop == 'undefined'){ return data; }; var result = data; prop = (prop + '').trim(); var path = prop.split('/'); var key = ''; while(path.length > 0){ if((key = path.shift().trim()) == ''){ continue; }; if(typeof result[key] == 'undefined'){ return null; }; result = result[key]; }; return result; }; // базовая инициализация ExternCore.prototype._init = function(){ var self = this; this.trace('_init'); try{ document.domain = this.domain(); }catch(e){}; if(window.addEventListener){ window.addEventListener("message", function(e){ self._onMessage(e); }, false); }else if(window.attachEvent){ window.attachEvent("onmessage", function(e){ self._onMessage(e); }); }else{ window.onmessage = function(e){ self._onMessage(e); }; }; this._extern(); this.init(); }; ExternCore.prototype._inited = function(inited){ this.inited = (inited ? true : false); this.trace('_inited', this.inited); this._extern(); }; ExternCore.prototype._extern = function(){ this.trace('_extern', 'send extern state'); var params = {'origin':window.location.href, 'parent':this.parent(), 'extern':this.extern(), 'inited':this.inited, 'loaded':true}; this._toClient('extern', params); // this._message('extern', params); }; // отправка post-сообщения в родительское окно ExternCore.prototype._message = function(action, params, handler, origin){ this.trace('_message', action, params, handler, origin); try{ var origin = (origin && origin.length > 1 ? origin : this.client.origin), message = {'to':'client', 'extern':this.extern(), 'sid':this.sid, 'action':action, 'params':params, 'handler':handler}; this.window().postMessage(this.tostr(message), origin); }catch(e){}; }; // выполнение AJAX-подзапроса с доп. параметрами ExternCore.prototype._api = function(action, params, func, config){ var self = this; if(typeof config == 'undefined'){ config = {}; }else if(typeof config != 'object'){ config = {}; }; if(typeof params == 'undefined'){ params = {}; }else if(typeof params != 'object'){ params = {}; }; params.action = action; this.trace('api', this.apiurl(), params, config); var options = { url:this.apiurl(), type:'POST', data:params, cache:false, timeout:7000, dataType:'jsonp', crossDomain:true, xhrFields:{ withCredentials:true }, success:function(data){ self.trace('- success', data); if(typeof func == 'function'){ func(data); }; }, error:function(data){ self.trace('- error', data); if(typeof func == 'function'){ data = {'result':'error', 'error':'AJAX_FAIL', 'info':data}; func(data); }; }, }; for(var key in config) { options[key] = config[key]; }; $.ajax(options); }; // приватные методы/обработчики ExternCore.prototype._onMessage = function(event){ this.trace('_onMessage', event); var data = event.data; if(typeof data === 'string'){ data = this.toobj(data); }; if(data && data.action && data.to && data.to == 'extern' && data.sid && data.sid == this.sid && data.extern && (data.extern == '*' || data.extern == this.extern())){ this._toExtern(data.action, data.params, data.handler); }; return data; }; ExternCore.prototype._toExtern = function(action, params, handler){ this.trace('_toExtern', action, params, handler); switch(action){ case 'client': for(var key in params){ this.client[key] = params[key]; }; this._extern(); break; case 'extern': if(this.inited){ this._extern(); }else{ this.init(); }; break; case 'profile': this.actionProfile(action, params, handler); break; case 'check': this.actionCheck(action, params, handler); break; case 'friends': this.actionFriends(action, params, handler); break; case 'invite': this.actionInvite(action, params, handler); break; case 'payment': this.actionPayment(action, params, handler); break; case 'public': this.actionPublic(action, params, handler); break; case 'group': this.actionGroup(action, params, handler); break; case 'like': this.actionLike(action, params, handler); break; }; this.toExtern(action, params, handler); }; ExternCore.prototype._toClient = function(action, params, handler){ this.trace('_toClient', action, params, handler); this._message(action, params, handler); }; // переопределяемые методы ExternCore.prototype.init = function(){ this.trace('init'); this._inited(); }; ExternCore.prototype.user = function(field){ return this.prop(this._user, field); }; ExternCore.prototype.profile = function(){ var result = {}; result = this.user(); return result; }; ExternCore.prototype.sidval = function(field){ return this.prop(this._sid, field); }; ExternCore.prototype.window = function(){ var win = document.getElementById('client-iframe'); return (win ? win.contentWindow : window); }; ExternCore.prototype.extern = function(){ return 'extern.core'; }; ExternCore.prototype.parent = function(){ return false; }; ExternCore.prototype.apiurl = function(){ return false; }; ExternCore.prototype.page = function(page, params){ return false; }; ExternCore.prototype.toExtern = function(action, params, handler){ this.trace('toExtern', action, params, handler); }; ExternCore.prototype.toClient = function(action, params, handler){ this.trace('toClient', action, params, handler); this._toClient(action, params, handler); }; // "псевдо-абстрактные" методы ExternCore.prototype.actionProfile = function(action, params, handler){ this.trace('actionProfile : CORE', params, handler); var data = (this.user() ? {'result':'success', 'profile':this.profile()} : {'result':'error', 'error':'USER_FAIL'}); this.toClient(action, data, handler); }; ExternCore.prototype.actionCheck = function(action, params, handler){ this.trace('actionCheck : CORE', params, handler); this.toClient(action, {'result':'success'}, handler); }; ExternCore.prototype.actionFriends = function(action, params, handler){ this.trace('actionFriends : CORE', params, handler); var result = {'result':'error', 'error':'ACTION_FAIL'}; this.toClient(action, result, handler); }; ExternCore.prototype.actionInvite = function(action, params, handler){ this.trace('actionInvite : CORE', params, handler); var result = {'result':'error', 'error':'ACTION_FAIL'}; this.toClient(action, result, handler); }; ExternCore.prototype.actionPayment = function(action, params, handler){ this.trace('actionPayment : CORE', params, handler); var result = {'result':'error', 'error':'ACTION_FAIL'}; this.toClient(action, result, handler); }; ExternCore.prototype.actionPublic = function(action, params, handler){ this.trace('actionPublic : CORE', params, handler); var result = {'result':'error', 'error':'ACTION_FAIL'}; this.toClient(action, result, handler); }; ExternCore.prototype.actionGroup = function(action, params, handler){ this.trace('actionGroup : CORE', params, handler); var result = {'result':'error', 'error':'ACTION_FAIL'}; this.toClient(action, result, handler); }; ExternCore.prototype.actionLike = function(action, params, handler){ this.trace('actionLike : CORE', params, handler); var result = {'result':'error', 'error':'ACTION_FAIL'}; this.toClient(action, result, handler); };