PageRenderTime 113ms CodeModel.GetById 28ms RepoModel.GetById 2ms app.codeStats 0ms

/example/export/xd_connection.js

https://bitbucket.org/AquaBarbus/c2-vkapi
JavaScript | 519 lines | 459 code | 52 blank | 8 comment | 118 complexity | 5cdf79c403c5dca2663658ff819ea146 MD5 | raw file
  1. (function(w) {
  2. if (w.fastXDM) return;
  3. var handlers = {};
  4. var onEnvLoad = [];
  5. var env = {};
  6. // Key generation
  7. function genKey() {
  8. var key = '';
  9. for (i=0;i<5;i++) key += Math.ceil(Math.random()*15).toString(16);
  10. return key;
  11. }
  12. function waitFor(obj, prop, func, self, count) {
  13. if (obj[prop]) {
  14. func.apply(self);
  15. } else {
  16. count = count || 0;
  17. if (count < 1000) setTimeout(function() {
  18. waitFor(obj, prop, func, self, count + 1)
  19. }, 0);
  20. }
  21. }
  22. function attachScript(url) {
  23. setTimeout(function() {
  24. var newScript = document.createElement('script');
  25. newScript.type = 'text/javascript';
  26. newScript.src = url || w.fastXDM.helperUrl;
  27. waitFor(document, 'body', function() {
  28. document.getElementsByTagName('HEAD')[0].appendChild(newScript);
  29. });
  30. }, 0);
  31. }
  32. // Env functions
  33. function getEnv(callback, self) {
  34. if (env.loaded) {
  35. callback.apply(self, [env]);
  36. } else {
  37. onEnvLoad.push([self, callback]);
  38. }
  39. }
  40. function envLoaded() {
  41. env.loaded = true;
  42. var i = onEnvLoad.length;
  43. while (i--) {
  44. onEnvLoad[i][1].apply(onEnvLoad[i][0], [env]);
  45. }
  46. }
  47. function applyMethod(strData, self) {
  48. getEnv(function(env) {
  49. var data = env.json.parse(strData);
  50. if (data[0]) {
  51. if (!data[1]) data[1] = [];
  52. var i = data[1].length;
  53. while (i--) {
  54. if (data[1][i]._func) {
  55. var funcNum = data[1][i]._func;
  56. data[1][i] = function() {
  57. var args = Array.prototype.slice.call(arguments);
  58. args.unshift('_func'+funcNum);
  59. self.callMethod.apply(self, args);
  60. }
  61. }
  62. }
  63. setTimeout(function() {
  64. if (!self.methods[data[0]]) throw Error('fastXDM: Method ' + data[0] + ' is undefined');
  65. self.methods[data[0]].apply(self, data[1]);
  66. }, 0);
  67. }
  68. });
  69. }
  70. // XDM object
  71. w.fastXDM = {
  72. _id: 0,
  73. helperUrl: ((location.protocol === 'https:') ? 'https:' : 'http:') + '//vk.com/js/api/xdmHelper.js',
  74. Server: function(methods, filter) {
  75. this.methods = methods || {};
  76. this.id = w.fastXDM._id++;
  77. this.filter = filter;
  78. this.key = genKey();
  79. this.methods['%init%'] = this.methods['__fxdm_i'] = function() {
  80. w.fastXDM.run(this.id);
  81. if (this.methods['onInit']) this.methods['onInit']();
  82. };
  83. this.frameName = 'fXD'+this.key;
  84. this.server = true;
  85. handlers[this.key] = [applyMethod, this];
  86. },
  87. Client: function(methods) {
  88. this.methods = methods || {};
  89. this.id = w.fastXDM._id++;
  90. w.fastXDM.run(this.id);
  91. if (window.name.indexOf('fXD') == 0) {
  92. this.key = window.name.substr(3);
  93. } else {
  94. throw Error('Wrong window.name property.');
  95. }
  96. this.caller = window.parent;
  97. handlers[this.key] = [applyMethod, this];
  98. this.client = true;
  99. w.fastXDM.on('helper', function() {
  100. w.fastXDM.onClientStart(this);
  101. }, this);
  102. getEnv(function(env) {
  103. env.send(this, env.json.stringify(['%init%']));
  104. var methods = this.methods;
  105. setTimeout(function() {
  106. if (methods['onInit']) methods['onInit']();
  107. }, 0);
  108. }, this);
  109. },
  110. onMessage: function(e) {
  111. if (!e.data) return false;
  112. var key = e.data.substr(0, 5);
  113. if (handlers[key]) {
  114. var self = handlers[key][1];
  115. if (self && (!self.filter || self.filter(e.origin))) {
  116. handlers[key][0](e.data.substr(6), self);
  117. }
  118. }
  119. },
  120. setJSON: function(json) {
  121. env.json = json;
  122. },
  123. getJSON: function(callback) {
  124. if (!callback) return env.json;
  125. getEnv(function(env) {
  126. callback(env.json);
  127. });
  128. },
  129. setEnv: function(exEnv) {
  130. for (i in exEnv) {
  131. env[i] = exEnv[i];
  132. }
  133. envLoaded();
  134. },
  135. _q: {},
  136. on: function(key, act, self) {
  137. if (!this._q[key]) this._q[key] = [];
  138. if (this._q[key] == -1) {
  139. act.apply(self);
  140. } else {
  141. this._q[key].push([act, self]);
  142. }
  143. },
  144. run: function(key) {
  145. var len = (this._q[key] || []).length;
  146. if (this._q[key] && len > 0) {
  147. for (var i = 0; i < len; i++) this._q[key][i][0].apply(this._q[key][i][1]);
  148. }
  149. this._q[key] = -1;
  150. },
  151. waitFor: waitFor
  152. }
  153. w.fastXDM.Server.prototype.start = function(obj, count) {
  154. if (obj.contentWindow) {
  155. this.caller = obj.contentWindow;
  156. this.frame = obj;
  157. w.fastXDM.on('helper', function() {
  158. w.fastXDM.onServerStart(this);
  159. }, this);
  160. } else { // Opera old versions
  161. var self = this;
  162. count = count || 0;
  163. if (count < 50) setTimeout(function() {
  164. self.start.apply(self, [obj, count+1]);
  165. }, 100);
  166. }
  167. }
  168. function extend(obj1, obj2){
  169. for (var i in obj2) {
  170. if (obj1[i] && typeof(obj1[i]) == 'object') {
  171. extend(obj1[i], obj2[i])
  172. } else {
  173. obj1[i] = obj2[i];
  174. }
  175. }
  176. }
  177. w.fastXDM.Server.prototype.append = function(obj, options) {
  178. var div = document.createElement('DIV');
  179. div.innerHTML = '<iframe name="'+this.frameName+'" />';
  180. var frame = div.firstChild;
  181. var self = this;
  182. setTimeout(function() {
  183. frame.frameBorder = '0';
  184. if (options) extend(frame, options);
  185. obj.insertBefore(frame, obj.firstChild);
  186. self.start(frame);
  187. }, 0);
  188. return frame;
  189. }
  190. w.fastXDM.Client.prototype.callMethod = w.fastXDM.Server.prototype.callMethod = function() {
  191. var args = Array.prototype.slice.call(arguments);
  192. var method = args.shift();
  193. var i = args.length;
  194. while (i--) {
  195. if (typeof(args[i]) == 'function') {
  196. this.funcsCount = (this.funcsCount || 0) + 1;
  197. var func = args[i];
  198. var funcName = '_func' + this.funcsCount;
  199. this.methods[funcName] = function() {
  200. func.apply(this, arguments);
  201. delete this.methods[funcName];
  202. }
  203. args[i] = {_func: this.funcsCount};
  204. }
  205. }
  206. waitFor(this, 'caller', function() {
  207. w.fastXDM.on(this.id, function() {
  208. getEnv(function(env) {
  209. env.send(this, env.json.stringify([method, args]));
  210. }, this);
  211. }, this);
  212. }, this);
  213. }
  214. if (w.JSON && typeof(w.JSON) == 'object' && w.JSON.parse && w.JSON.stringify && w.JSON.stringify({a:[1,2,3]}).replace(/ /g, '') == '{"a":[1,2,3]}') {
  215. env.json = {parse: w.JSON.parse, stringify: w.JSON.stringify};
  216. } else {
  217. w.fastXDM._needJSON = true;
  218. }
  219. // PostMessage cover
  220. if (w.postMessage) {
  221. env.protocol = 'p';
  222. env.send = function(xdm, strData) {
  223. // alert(key+':'+strData);
  224. xdm.caller.postMessage(xdm.key+':'+strData, "*");
  225. }
  226. if (w.addEventListener) {
  227. w.addEventListener("message", w.fastXDM.onMessage, false);
  228. } else {
  229. w.attachEvent("onmessage", w.fastXDM.onMessage);
  230. }
  231. if (w.fastXDM._needJSON) {
  232. w.fastXDM._onlyJSON = true;
  233. attachScript();
  234. } else {
  235. envLoaded();
  236. }
  237. } else {
  238. attachScript();
  239. }
  240. })(window);
  241. if (typeof(VK) == 'undefined') VK = {};
  242. VK._Rpc = null;
  243. VK._v = false;
  244. VK._callbacks = {};
  245. VK._initQueue = [];
  246. VK._inited = false;
  247. VK.init = function(success, failure, ver) {
  248. if (ver) {
  249. VK._v = ver;
  250. }
  251. if (!VK._inited) {
  252. VK._inited = true;
  253. if (!parent) failure();
  254. window.vk_onConnectionInit = function() {
  255. if (VK.isFunc(success)) success();
  256. };
  257. VK.initXDConn();
  258. } else {
  259. if (VK.isFunc(success)) success();
  260. }
  261. };
  262. VK.initXDConn = function() {
  263. if (window.name.length > 10) {
  264. VK._Rpc = new easyXDM.Rpc({
  265. local: '/xd_receiver.html',
  266. onReady: function() {
  267. //try {
  268. while (VK._initQueue.length > 0) {
  269. var func = VK._initQueue.pop();
  270. if (VK.isFunc(func)) func();
  271. }
  272. //} catch(e) {}
  273. window.vk_onConnectionInit();
  274. }
  275. },{
  276. remote: {
  277. callMethod: {},
  278. ApiCall: {}
  279. },
  280. local: {
  281. runCallback: function(args) {
  282. var eventName;
  283. eventName = args.shift();
  284. if (VK.isFunc(VK._callbacks[eventName])) VK._callbacks[eventName].apply(VK,args);
  285. }
  286. }
  287. });
  288. } else {
  289. VK.fxdm = true;
  290. VK._Rpc = new fastXDM.Client({
  291. onInit: function() {
  292. while (VK._initQueue.length > 0) {
  293. var func = VK._initQueue.pop();
  294. if (VK.isFunc(func)) func();
  295. }
  296. window.vk_onConnectionInit();
  297. },
  298. runCallback: function(args) {
  299. var eventName;
  300. eventName = args.shift();
  301. if (VK.isFunc(VK._callbacks[eventName])) VK._callbacks[eventName].apply(VK,args);
  302. },
  303. getHeight: function(callback) {
  304. var calcHeight = function() {
  305. var height = document.body.offsetHeight;
  306. if (height) {
  307. if (window.getComputedStyle !== undefined) {
  308. var st = window.getComputedStyle(document.body, null);
  309. height += parseInt(st.getPropertyValue('margin-top').replace('px', ''));
  310. height += parseInt(st.getPropertyValue('margin-bottom').replace('px', ''));
  311. } else {
  312. height += parseInt(document.body.currentStyle['marginTop'].replace('px', ''));
  313. height += parseInt(document.body.currentStyle['marginBottom'].replace('px', ''));
  314. }
  315. return height;
  316. } else {
  317. return document.body.scrollHeight;
  318. }
  319. }
  320. var resize = function() {
  321. VK._Rpc.callMethod('setHeight', calcHeight());
  322. }
  323. setInterval(resize, 1000);
  324. document.addEventListener("click", function() {
  325. setTimeout(resize, 0);
  326. }, false);
  327. document.addEventListener("DOMSubtreeModified", function() {
  328. setTimeout(resize, 0);
  329. });
  330. return callback(calcHeight());
  331. }
  332. });
  333. VK._Rpc.ApiCall = function(args, callback) {
  334. VK._Rpc.callMethod('ApiCall', args, callback);
  335. }
  336. }
  337. };
  338. VK.callMethod = function() {
  339. var args = Array.prototype.slice.call(arguments);
  340. var callback;
  341. if (VK._Rpc != null) {
  342. if (VK.fxdm) {
  343. VK._Rpc.callMethod.apply(VK._Rpc, args);
  344. } else {
  345. if (VK.isFunc(args[args.length-1])) callback = args.pop();
  346. VK._Rpc.callMethod(args,callback);
  347. }
  348. } else {
  349. VK._initQueue.push(function() {VK.callMethod.apply(VK, args);});
  350. VK.init();
  351. }
  352. };
  353. VK.addCallback = function(eventName, callback) {
  354. if (callback) VK._callbacks[eventName] = callback;
  355. };
  356. VK.removeCallback = function(eventName) {
  357. if (VK._callbacks[eventName]) delete VK._callbacks[eventName];
  358. };
  359. VK.isFunc = function(obj) {
  360. return Object.prototype.toString.call(obj) === "[object Function]";
  361. };
  362. VK.params = {};
  363. VK.loadParams = function(q) {
  364. if (typeof q == 'Object') VK.params = q;
  365. else {
  366. var tmp = q.substr(q.indexOf('?') + 1).split('&');
  367. var i = tmp.length;
  368. while (i--) {
  369. var v = tmp[i].split('=');
  370. VK.params[v[0]] = decodeURIComponent(v[1]);
  371. }
  372. }
  373. };
  374. VK.addScript = function(url) {
  375. var el = document.createElement('script');
  376. el.type = 'text/javascript';
  377. el.src = url;
  378. document.getElementsByTagName('head')[0].appendChild(el);
  379. };
  380. VK.api = function() {
  381. var args = Array.prototype.slice.call(arguments);
  382. var callback;
  383. if (VK._Rpc != null) {
  384. if (VK.isFunc(args[args.length-1])) {
  385. callback = args.pop();
  386. }
  387. if (!args[1]) {
  388. args[1] = {};
  389. }
  390. if (!args[1]['v'] && VK._v) {
  391. args[1]['v'] = VK._v;
  392. }
  393. VK._Rpc.ApiCall(args,callback);
  394. } else {
  395. VK._initQueue.push(function() {VK.api.apply(VK, args);});
  396. VK.init();
  397. }
  398. };
  399. VK.Modules = {
  400. callbacks: {},
  401. loaded: function(name) {
  402. if (this.callbacks[name]) {
  403. var i = this.callbacks[name].length;
  404. while (i--) {
  405. if (VK.isFunc(this.callbacks[name][i])) this.callbacks[name][i]();
  406. }
  407. }
  408. },
  409. load: function(name, callback, path) {
  410. if (!this.callbacks[name]) {
  411. this.callbacks[name] = [callback];
  412. if (path == null) path = 'http://vk.com/js/api/modules/' + name + '.js';
  413. VK.addScript(path);
  414. } else {
  415. this.callbacks[name].push(callback);
  416. }
  417. }
  418. };
  419. VK.showPortlet = function(opts) {
  420. VK.callMethod('showPortlet', opts)
  421. }
  422. if (VK._protocol !== 'https:') {
  423. VK._protocol = ((location.protocol === 'https:') ? 'https:' : 'http:');
  424. }
  425. if (VK._protocol !== 'https:') {
  426. VK.callMethod('getLocationProtocol', function(protocol) {
  427. if (protocol === 'https:') {
  428. VK._protocol = 'https:';
  429. }
  430. });
  431. }
  432. (function(){
  433. try {
  434. var scripts = document.getElementsByTagName('script');
  435. var script = scripts[scripts.length - 1];
  436. VK._base_domain = script.src.match(/^https?:\/\/((?:\w+\.)*vk.com)/)[1];
  437. } catch (e) {}
  438. })();
  439. if (!VK.Widgets) {
  440. VK.Widgets = (function() {
  441. var obj = {};
  442. var widgetlist = ['Comments', 'CommentsBrowse', 'Auth', 'Group', 'Post', 'Donate', 'Like', 'Poll', 'Recommended', 'Subscribe', 'Ads'];
  443. VK.xdConnectionCallbacks = [];
  444. var i = widgetlist.length;
  445. while (i--) (function(f) {
  446. obj[f] = function() {
  447. var args = arguments;
  448. VK.xdConnectionCallbacks.push(function() {
  449. VK._iframeAppWidget = true;
  450. VK.Widgets[f].apply(VK, args);
  451. });
  452. if (!VK._openApiAttached) {
  453. VK.callMethod('_getAppInfo', function(data) {
  454. var baseDomain = ((VK._base_domain && VK._base_domain.match(/^(\w+\.)*vk.com$/)) ? VK._base_domain : 'vk.com');
  455. VK._apiId = data[0];
  456. VK._browserHash = data[1];
  457. VK.addScript(VK._protocol + '//' + baseDomain + '/js/api/openapi.js?116');
  458. });
  459. VK._openApiAttached = true;
  460. }
  461. }
  462. })(widgetlist[i]);
  463. return obj;
  464. })();
  465. }
  466. /* Obsolete methods */
  467. VK.External={showPaymentBox:function(a){VK.callMethod("showPaymentBox",a)},showSettingsBox:function(a){VK.callMethod("showSettingsBox",a)},showInstallBox:function(){VK.callMethod("showInstallBox")},showInviteBox:function(){VK.callMethod("showInviteBox")},resizeWindow:function(b,a){VK.callMethod("resizeWindow",b,a)},scrollWindow:function(b,a){VK.callMethod("scrollWindow",b,a)},setLocation:function(a,b){VK.callMethod("setLocation",a,b)},setTitle:function(a){VK.callMethod("setTitle",a)},saveWallPost:function(a){VK.callMethod("saveWallPost",a)},showProfilePhotoBox:function(a){VK.callMethod("showProfilePhotoBox",a)},showMerchantPaymentBox:function(a){VK.callMethod("showMerchantPaymentBox",a)}};