Skip to content
Browse files

adding examples dir for sencha touch examples

  • Loading branch information...
1 parent 1b664d0 commit 6fcf95a8b4ba2a20573ad9e36b290cd38f722d4a @devendram devendram committed Oct 2, 2012
View
50 sencha/3.3/examples/here_now/app.js
@@ -0,0 +1,50 @@
+var pubnub = PUBNUB.init({
+ publish_key : 'demo',
+ subscribe_key : 'demo',
+ ssl : false,
+ origin : 'pubsub.pubnub.com'
+});
+
+
+Ext.application({
+ launch: function () {
+ var myStore = Ext.create('Ext.data.Store', {
+ storeId: 'list',
+ fields: ['txt']
+ });
+
+ Ext.create('Ext.List', {
+ fullscreen: true,
+ store: 'list',
+ itemTpl: '{txt}',
+ items: [{
+ xtype: 'titlebar',
+ docked: 'top',
+ items: [
+ {
+ xtype: 'textfield',
+ label: 'Channel',
+ name: 'channel',
+ id: 'channel'
+ },
+ {
+ text: 'Here Now',
+ handler: function () {
+ var channel = Ext.getCmp('channel').getValue() || 'sencha-demo-channel';
+ myStore.removeAll();
+ pubnub.here_now({
+ channel: channel,
+ callback: function(response){
+ for ( x in response["uuids"] ) {
+ myStore.insert(0,{txt : JSON.stringify(response["uuids"][x])});
+ }
+ }
+ });
+ }
+ }
+ ]
+ }]
+ });
+ }
+});
+
View
65 sencha/3.3/examples/here_now/index.html
@@ -0,0 +1,65 @@
+<!DOCTYPE HTML>
+<html manifest="" lang="en-US">
+<head>
+ <meta charset="UTF-8">
+ <title>history</title>
+ <style type="text/css">
+ /**
+ * Example of an initial loading indicator.
+ * It is recommended to keep this as minimal as possible to provide instant feedback
+ * while other resources are still being loaded for the first time
+ */
+ html, body {
+ height: 100%;
+ background-color: #1985D0
+ }
+
+ #appLoadingIndicator {
+ position: absolute;
+ top: 50%;
+ margin-top: -15px;
+ text-align: center;
+ width: 100%;
+ height: 30px;
+ -webkit-animation-name: appLoadingIndicator;
+ -webkit-animation-duration: 0.5s;
+ -webkit-animation-iteration-count: infinite;
+ -webkit-animation-direction: linear;
+ }
+
+ #appLoadingIndicator > * {
+ background-color: #FFFFFF;
+ display: inline-block;
+ height: 30px;
+ -webkit-border-radius: 15px;
+ margin: 0 5px;
+ width: 30px;
+ opacity: 0.8;
+ }
+
+ @-webkit-keyframes appLoadingIndicator{
+ 0% {
+ opacity: 0.8
+ }
+ 50% {
+ opacity: 0
+ }
+ 100% {
+ opacity: 0.8
+ }
+ }
+ </style>
+ <!-- The line below must be kept intact for Sencha Command to build your application -->
+ <link href=sencha-touch.css rel="stylesheet" type="text/css" />
+ <script src=sencha-touch-all.js type="text/javascript"></script>
+ <script src=pubnub-3.3.js type="text/javascript"></script>
+ <script src="app.js" type="text/javascript"></script>
+</head>
+<body>
+ <div id="appLoadingIndicator">
+ <div></div>
+ <div></div>
+ <div></div>
+ </div>
+</body>
+</html>
View
1,032 sencha/3.3/examples/here_now/pubnub-3.3.js
@@ -0,0 +1,1032 @@
+/* ---------------------------------------------------------------------------
+WAIT! - This file depends on instructions from the PUBNUB Cloud.
+http://www.pubnub.com/account-javascript-api-include
+--------------------------------------------------------------------------- */
+
+/* ---------------------------------------------------------------------------
+PubNub Real-time Cloud-Hosted Push API and Push Notification Client Frameworks
+Copyright (c) 2011 PubNub Inc.
+http://www.pubnub.com/
+http://www.pubnub.com/terms
+--------------------------------------------------------------------------- */
+
+/* ---------------------------------------------------------------------------
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+--------------------------------------------------------------------------- */
+
+/* =-====================================================================-= */
+/* =-====================================================================-= */
+/* =-========================= JSON =============================-= */
+/* =-====================================================================-= */
+/* =-====================================================================-= */
+
+(window['JSON'] && window['JSON']['stringify']) || (function () {
+ window['JSON'] || (window['JSON'] = {});
+
+ if (typeof String.prototype.toJSON !== 'function') {
+ String.prototype.toJSON =
+ Number.prototype.toJSON =
+ Boolean.prototype.toJSON = function (key) {
+ return this.valueOf();
+ };
+ }
+
+ var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ gap,
+ indent,
+ meta = { // table of character substitutions
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '"' : '\\"',
+ '\\': '\\\\'
+ },
+ rep;
+
+ function quote(string) {
+ escapable.lastIndex = 0;
+ return escapable.test(string) ?
+ '"' + string.replace(escapable, function (a) {
+ var c = meta[a];
+ return typeof c === 'string' ? c :
+ '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ }) + '"' :
+ '"' + string + '"';
+ }
+
+
+ function str(key, holder) {
+ var i, // The loop counter.
+ k, // The member key.
+ v, // The member value.
+ length,
+ mind = gap,
+ partial,
+ value = holder[key];
+
+ if (value && typeof value === 'object' &&
+ typeof value.toJSON === 'function') {
+ value = value.toJSON(key);
+ }
+
+ if (typeof rep === 'function') {
+ value = rep.call(holder, key, value);
+ }
+
+ switch (typeof value) {
+ case 'string':
+ return quote(value);
+
+ case 'number':
+ return isFinite(value) ? String(value) : 'null';
+
+ case 'boolean':
+ case 'null':
+ return String(value);
+
+ case 'object':
+
+ if (!value) {
+ return 'null';
+ }
+
+ gap += indent;
+ partial = [];
+
+ if (Object.prototype.toString.apply(value) === '[object Array]') {
+
+ length = value.length;
+ for (i = 0; i < length; i += 1) {
+ partial[i] = str(i, value) || 'null';
+ }
+
+ v = partial.length === 0 ? '[]' :
+ gap ? '[\n' + gap +
+ partial.join(',\n' + gap) + '\n' +
+ mind + ']' :
+ '[' + partial.join(',') + ']';
+ gap = mind;
+ return v;
+ }
+ if (rep && typeof rep === 'object') {
+ length = rep.length;
+ for (i = 0; i < length; i += 1) {
+ k = rep[i];
+ if (typeof k === 'string') {
+ v = str(k, value);
+ if (v) {
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
+ }
+ }
+ }
+ } else {
+ for (k in value) {
+ if (Object.hasOwnProperty.call(value, k)) {
+ v = str(k, value);
+ if (v) {
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
+ }
+ }
+ }
+ }
+
+ v = partial.length === 0 ? '{}' :
+ gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
+ mind + '}' : '{' + partial.join(',') + '}';
+ gap = mind;
+ return v;
+ }
+ }
+
+ if (typeof JSON['stringify'] !== 'function') {
+ JSON['stringify'] = function (value, replacer, space) {
+ var i;
+ gap = '';
+ indent = '';
+
+ if (typeof space === 'number') {
+ for (i = 0; i < space; i += 1) {
+ indent += ' ';
+ }
+ } else if (typeof space === 'string') {
+ indent = space;
+ }
+ rep = replacer;
+ if (replacer && typeof replacer !== 'function' &&
+ (typeof replacer !== 'object' ||
+ typeof replacer.length !== 'number')) {
+ throw new Error('JSON.stringify');
+ }
+ return str('', {'': value});
+ };
+ }
+
+ if (typeof JSON['parse'] !== 'function') {
+ // JSON is parsed on the server for security.
+ JSON['parse'] = function (text) {return eval('('+text+')')};
+ }
+}());
+
+
+/* =-====================================================================-= */
+/* =-====================================================================-= */
+/* =-======================= DOM UTIL ===========================-= */
+/* =-====================================================================-= */
+/* =-====================================================================-= */
+
+window['PUBNUB'] || (function() {
+
+/**
+ * CONSOLE COMPATIBILITY
+ */
+window.console||(window.console=window.console||{});
+console.log||(console.log=((window.opera||{}).postError||function(){}));
+
+/**
+ * UTILITIES
+ */
+function unique() { return'x'+ ++NOW+''+(+new Date) }
+function rnow() { return+new Date }
+
+/**
+ * LOCAL STORAGE OR COOKIE
+ */
+var db = (function(){
+ var ls = window['localStorage'];
+ return {
+ 'get' : function(key) {
+ try {
+ if (ls) return ls.getItem(key);
+ if (document.cookie.indexOf(key) == -1) return null;
+ return ((document.cookie||'').match(
+ RegExp(key+'=([^;]+)')
+ )||[])[1] || null;
+ } catch(e) { return }
+ },
+ 'set' : function( key, value ) {
+ try {
+ if (ls) return ls.setItem( key, value ) && 0;
+ document.cookie = key + '=' + value +
+ '; expires=Thu, 1 Aug 2030 20:00:00 UTC; path=/';
+ } catch(e) { return }
+ }
+ };
+})();
+
+/**
+ * UTIL LOCALS
+ */
+var NOW = 1
+, SWF = 'https://dh15atwfs066y.cloudfront.net/pubnub.swf'
+, REPL = /{([\w\-]+)}/g
+, ASYNC = 'async'
+, URLBIT = '/'
+, PARAMSBIT = '&'
+, XHRTME = 310000
+, SECOND = 1000
+, PRESENCE_SUFFIX = '-pnpres'
+, UA = navigator.userAgent
+, XORIGN = UA.indexOf('MSIE 6') == -1;
+
+/**
+ * NEXTORIGIN
+ * ==========
+ * var next_origin = nextorigin();
+ */
+var nextorigin = (function() {
+ var ori = Math.floor(Math.random() * 9) + 1;
+ return function(origin) {
+ return origin.indexOf('pubsub') > 0
+ && origin.replace(
+ 'pubsub', 'ps' + (++ori < 10 ? ori : ori=1)
+ ) || origin;
+ }
+})();
+
+/**
+ * UPDATER
+ * ======
+ * var timestamp = unique();
+ */
+function updater( fun, rate ) {
+ var timeout
+ , last = 0
+ , runnit = function() {
+ if (last + rate > rnow()) {
+ clearTimeout(timeout);
+ timeout = setTimeout( runnit, rate );
+ }
+ else {
+ last = rnow();
+ fun();
+ }
+ };
+
+ return runnit;
+}
+
+/**
+ * $
+ * =
+ * var div = $('divid');
+ */
+function $(id) { return document.getElementById(id) }
+
+/**
+ * LOG
+ * ===
+ * log('message');
+ */
+function log(message) { console['log'](message) }
+
+/**
+ * SEARCH
+ * ======
+ * var elements = search('a div span');
+ */
+function search( elements, start ) {
+ var list = [];
+ each( elements.split(/\s+/), function(el) {
+ each( (start || document).getElementsByTagName(el), function(node) {
+ list.push(node);
+ } );
+ } );
+ return list;
+}
+
+/**
+ * EACH
+ * ====
+ * each( [1,2,3], function(item) { console.log(item) } )
+ */
+function each( o, f ) {
+ if ( !o || !f ) return;
+
+ if ( typeof o[0] != 'undefined' )
+ for ( var i = 0, l = o.length; i < l; )
+ f.call( o[i], o[i], i++ );
+ else
+ for ( var i in o )
+ o.hasOwnProperty &&
+ o.hasOwnProperty(i) &&
+ f.call( o[i], i, o[i] );
+}
+
+/**
+ * MAP
+ * ===
+ * var list = map( [1,2,3], function(item) { return item + 1 } )
+ */
+function map( list, fun ) {
+ var fin = [];
+ each( list || [], function( k, v ) { fin.push(fun( k, v )) } );
+ return fin;
+}
+
+/**
+ * GREP
+ * ====
+ * var list = grep( [1,2,3], function(item) { return item % 2 } )
+ */
+function grep( list, fun ) {
+ var fin = [];
+ each( list || [], function(l) { fun(l) && fin.push(l) } );
+ return fin
+}
+
+/**
+ * SUPPLANT
+ * ========
+ * var text = supplant( 'Hello {name}!', { name : 'John' } )
+ */
+function supplant( str, values ) {
+ return str.replace( REPL, function( _, match ) {
+ return values[match] || _
+ } );
+}
+
+/**
+ * BIND
+ * ====
+ * bind( 'keydown', search('a')[0], function(element) {
+ * console.log( element, '1st anchor' )
+ * } );
+ */
+function bind( type, el, fun ) {
+ each( type.split(','), function(etype) {
+ var rapfun = function(e) {
+ if (!e) e = window.event;
+ if (!fun(e)) {
+ e.cancelBubble = true;
+ e.returnValue = false;
+ e.preventDefault && e.preventDefault();
+ e.stopPropagation && e.stopPropagation();
+ }
+ };
+
+ if ( el.addEventListener ) el.addEventListener( etype, rapfun, false );
+ else if ( el.attachEvent ) el.attachEvent( 'on' + etype, rapfun );
+ else el[ 'on' + etype ] = rapfun;
+ } );
+}
+
+/**
+ * UNBIND
+ * ======
+ * unbind( 'keydown', search('a')[0] );
+ */
+function unbind( type, el, fun ) {
+ if ( el.removeEventListener ) el.removeEventListener( type, false );
+ else if ( el.detachEvent ) el.detachEvent( 'on' + type, false );
+ else el[ 'on' + type ] = null;
+}
+
+/**
+ * HEAD
+ * ====
+ * head().appendChild(elm);
+ */
+function head() { return search('head')[0] }
+
+/**
+ * ATTR
+ * ====
+ * var attribute = attr( node, 'attribute' );
+ */
+function attr( node, attribute, value ) {
+ if (value) node.setAttribute( attribute, value );
+ else return node && node.getAttribute && node.getAttribute(attribute);
+}
+
+/**
+ * CSS
+ * ===
+ * var obj = create('div');
+ */
+function css( element, styles ) {
+ for (var style in styles) if (styles.hasOwnProperty(style))
+ try {element.style[style] = styles[style] + (
+ '|width|height|top|left|'.indexOf(style) > 0 &&
+ typeof styles[style] == 'number'
+ ? 'px' : ''
+ )}catch(e){}
+}
+
+/**
+ * CREATE
+ * ======
+ * var obj = create('div');
+ */
+function create(element) { return document.createElement(element) }
+
+/**
+ * timeout
+ * =======
+ * timeout( function(){}, 100 );
+ */
+function timeout( fun, wait ) {
+ return setTimeout( fun, wait );
+}
+
+/**
+ * jsonp_cb
+ * ========
+ * var callback = jsonp_cb();
+ */
+function jsonp_cb() { return XORIGN || FDomainRequest() ? 0 : unique() }
+
+/**
+ * ENCODE
+ * ======
+ * var encoded_path = encode('path');
+ */
+function encode(path) {
+ return map( (encodeURIComponent(path)).split(''), function(chr) {
+ return "-_.!~*'()".indexOf(chr) < 0 ? chr :
+ "%"+chr.charCodeAt(0).toString(16).toUpperCase()
+ } ).join('');
+}
+
+/**
+ * EVENTS
+ * ======
+ * PUBNUB.events.bind( 'you-stepped-on-flower', function(message) {
+ * // Do Stuff with message
+ * } );
+ *
+ * PUBNUB.events.fire( 'you-stepped-on-flower', "message-data" );
+ * PUBNUB.events.fire( 'you-stepped-on-flower', {message:"data"} );
+ * PUBNUB.events.fire( 'you-stepped-on-flower', [1,2,3] );
+ *
+ */
+var events = {
+ 'list' : {},
+ 'unbind' : function( name ) { events.list[name] = [] },
+ 'bind' : function( name, fun ) {
+ (events.list[name] = events.list[name] || []).push(fun);
+ },
+ 'fire' : function( name, data ) {
+ each(
+ events.list[name] || [],
+ function(fun) { fun(data) }
+ );
+ }
+};
+
+/**
+ * XDR Cross Domain Request
+ * ========================
+ * xdr({
+ * url : ['http://www.blah.com/url'],
+ * success : function(response) {},
+ * fail : function() {}
+ * });
+ */
+function xdr( setup ) {
+ if (XORIGN || FDomainRequest()) return ajax(setup);
+
+ var script = create('script')
+ , callback = setup.callback
+ , id = unique()
+ , finished = 0
+ , timer = timeout( function(){done(1)}, XHRTME )
+ , fail = setup.fail || function(){}
+ , success = setup.success || function(){}
+
+ , append = function() {
+ head().appendChild(script);
+ }
+
+ , done = function( failed, response ) {
+ if (finished) return;
+ finished = 1;
+
+ failed || success(response);
+ script.onerror = null;
+ clearTimeout(timer);
+
+ timeout( function() {
+ failed && fail();
+ var s = $(id)
+ , p = s && s.parentNode;
+ p && p.removeChild(s);
+ }, SECOND );
+ };
+
+ window[callback] = function(response) {
+ done( 0, response );
+ };
+
+ script[ASYNC] = ASYNC;
+ script.onerror = function() { done(1) };
+ script.src = setup.url.join(URLBIT);
+ if (setup.data) {
+ var params = [];
+ script.src += "?";
+ for (key in setup.data) {
+ params.push(key+"="+setup.data[key]);
+ }
+ script.src += params.join(PARAMSBIT);
+ }
+ attr( script, 'id', id );
+
+ append();
+ return done;
+}
+
+/**
+ * CORS XHR Request
+ * ================
+ * xdr({
+ * url : ['http://www.blah.com/url'],
+ * success : function(response) {},
+ * fail : function() {}
+ * });
+ */
+function ajax( setup ) {
+ var xhr, response
+ , finished = function() {
+ if (loaded) return;
+ loaded = 1;
+
+ clearTimeout(timer);
+
+ try { response = JSON['parse'](xhr.responseText); }
+ catch (r) { return done(1); }
+
+ success(response);
+ }
+ , complete = 0
+ , loaded = 0
+ , timer = timeout( function(){done(1)}, XHRTME )
+ , fail = setup.fail || function(){}
+ , success = setup.success || function(){}
+ , done = function(failed) {
+ if (complete) return;
+ complete = 1;
+
+ clearTimeout(timer);
+
+ if (xhr) {
+ xhr.onerror = xhr.onload = null;
+ xhr.abort && xhr.abort();
+ xhr = null;
+ }
+
+ failed && fail();
+ };
+
+ // Send
+ try {
+ xhr = FDomainRequest() ||
+ window.XDomainRequest &&
+ new XDomainRequest() ||
+ new XMLHttpRequest();
+
+ xhr.onerror = xhr.onabort = function(){ done(1) };
+ xhr.onload = xhr.onloadend = finished;
+ xhr.timeout = XHRTME;
+
+ url = setup.url.join(URLBIT);
+ if (setup.data) {
+ var params = [];
+ url += "?";
+ for (key in setup.data) {
+ params.push(key+"="+setup.data[key]);
+ }
+ url += params.join(PARAMSBIT);
+ }
+
+ xhr.open( 'GET', url, true );
+ xhr.send();
+ }
+ catch(eee) {
+ done(0);
+ XORIGN = 0;
+ return xdr(setup);
+ }
+
+ // Return 'done'
+ return done;
+}
+
+
+/* =-====================================================================-= */
+/* =-====================================================================-= */
+/* =-========================= PUBNUB ===========================-= */
+/* =-====================================================================-= */
+/* =-====================================================================-= */
+
+var PDIV = $('pubnub') || {}
+, READY = 0
+, READY_BUFFER = []
+, CREATE_PUBNUB = function(setup) {
+ var CHANNELS = {}
+ , PUBLISH_KEY = setup['publish_key'] || ''
+ , SUBSCRIBE_KEY = setup['subscribe_key'] || ''
+ , SSL = setup['ssl'] ? 's' : ''
+ , UUID = setup['uuid'] || db.get(SUBSCRIBE_KEY+'uuid') || ''
+ , ORIGIN = 'http'+SSL+'://'+(setup['origin']||'pubsub.pubnub.com')
+ , SELF = {
+ /*
+ PUBNUB.history({
+ channel : 'my_chat_channel',
+ limit : 100,
+ callback : function(messages) { console.log(messages) }
+ });
+ */
+ 'history' : function( args, callback ) {
+ var callback = args['callback'] || callback
+ , limit = args['limit'] || 100
+ , channel = args['channel']
+ , jsonp = jsonp_cb();
+
+ // Make sure we have a Channel
+ if (!channel) return log('Missing Channel');
+ if (!callback) return log('Missing Callback');
+
+ // Send Message
+ xdr({
+ callback : jsonp,
+ url : [
+ ORIGIN, 'history',
+ SUBSCRIBE_KEY, encode(channel),
+ jsonp, limit
+ ],
+ success : function(response) { callback(response) },
+ fail : function(response) { log(response) }
+ });
+ },
+
+ /*
+ PUBNUB.detailedHistory({
+ channel : 'my_chat_channel',
+ count : 100,
+ callback : function(messages) { console.log(messages) }
+ });
+ */
+ 'detailedHistory' : function( args, callback ) {
+ var callback = args['callback'] || callback
+ , count = args['count'] || 100
+ , channel = args['channel']
+ , reverse = args['reverse'] || "false"
+ , start = args['start']
+ , end = args['end']
+ , jsonp = jsonp_cb();
+
+ // Make sure we have a Channel
+ if (!channel) return log('Missing Channel');
+ if (!callback) return log('Missing Callback');
+
+ var params = {};
+ params["count"] = count;
+ params["reverse"] = reverse;
+ if (start)
+ params["start"] = start;
+ if (end)
+ params["end"] = end;
+
+ // Send Message
+ xdr({
+ callback : jsonp,
+ url : [
+ ORIGIN, 'v2', 'history',
+ 'sub-key', SUBSCRIBE_KEY, 'channel', encode(channel)
+ ],
+ data : params,
+ success : function(response) { callback(response) },
+ fail : function(response) { log(response) }
+ });
+ },
+
+ /*
+ PUBNUB.time(function(time){ console.log(time) });
+ */
+ 'time' : function(callback) {
+ var jsonp = jsonp_cb();
+ xdr({
+ callback : jsonp,
+ url : [ORIGIN, 'time', jsonp],
+ success : function(response) { callback(response[0]) },
+ fail : function() { callback(0) }
+ });
+ },
+
+ /*
+ PUBNUB.uuid(function(uuid) { console.log(uuid) });
+ */
+ 'uuid' : function(callback) {
+ var u = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
+ var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
+ return v.toString(16);
+ });
+ if (callback) callback(u);
+ return u;
+ },
+
+ /*
+ PUBNUB.publish({
+ channel : 'my_chat_channel',
+ message : 'hello!'
+ });
+ */
+ 'publish' : function( args, callback ) {
+ var callback = callback || args['callback'] || function(){}
+ , message = args['message']
+ , channel = args['channel']
+ , jsonp = jsonp_cb()
+ , url;
+
+ if (!message) return log('Missing Message');
+ if (!channel) return log('Missing Channel');
+ if (!PUBLISH_KEY) return log('Missing Publish Key');
+
+ // If trying to send Object
+ message = JSON['stringify'](message);
+
+ // Create URL
+ url = [
+ ORIGIN, 'publish',
+ PUBLISH_KEY, SUBSCRIBE_KEY,
+ 0, encode(channel),
+ jsonp, encode(message)
+ ];
+
+ // Send Message
+ xdr({
+ callback : jsonp,
+ success : function(response) { callback(response) },
+ fail : function() { callback([ 0, 'Disconnected' ]) },
+ url : url,
+ data : { uuid: UUID }
+ });
+ },
+ /*
+ PUBNUB.unsubscribe({ channel : 'my_chat' });
+ */
+ 'unsubscribe' : function(args) {
+ // Unsubscribe from both the Channel and the Presence Channel
+ _unsubscribe(args['channel']);
+ _unsubscribe(args['channel'] + PRESENCE_SUFFIX);
+
+ function _unsubscribe(channel) {
+ // Leave if there never was a channel.
+ if (!(channel in CHANNELS)) return;
+
+ // Disable Channel
+ CHANNELS[channel].connected = 0;
+
+ // Abort and Remove Script
+ CHANNELS[channel].done &&
+ CHANNELS[channel].done(0);
+ }
+ },
+
+ /*
+ PUBNUB.subscribe({
+ channel : 'my_chat'
+ callback : function(message) { console.log(message) }
+ });
+ */
+ 'subscribe' : function( args, callback ) {
+ var channel = args['channel']
+ , callback = callback || args['callback']
+ , subscribe_key= args['subscribe_key'] || SUBSCRIBE_KEY
+ , restore = args['restore']
+ , timetoken = 0
+ , error = args['error'] || function(){}
+ , connect = args['connect'] || function(){}
+ , reconnect = args['reconnect'] || function(){}
+ , disconnect = args['disconnect'] || function(){}
+ , presence = args['presence'] || function(){}
+ , disconnected = 0
+ , connected = 0
+ , origin = nextorigin(ORIGIN);
+
+ // Reduce Status Flicker
+ if (!READY) return READY_BUFFER.push([ args, callback, SELF ]);
+
+ // Make sure we have a Channel
+ if (!channel) return log('Missing Channel');
+ if (!callback) return log('Missing Callback');
+ if (!SUBSCRIBE_KEY) return log('Missing Subscribe Key');
+
+ if (!(channel in CHANNELS)) CHANNELS[channel] = {};
+
+ // Make sure we have a Channel
+ if (CHANNELS[channel].connected) return log('Already Connected');
+ CHANNELS[channel].connected = 1;
+
+ // Recurse Subscribe
+ function _connect() {
+ var jsonp = jsonp_cb();
+
+ // Stop Connection
+ if (!CHANNELS[channel].connected) return;
+
+ // Connect to PubNub Subscribe Servers
+ CHANNELS[channel].done = xdr({
+ callback : jsonp,
+ url : [
+ origin, 'subscribe',
+ subscribe_key, encode(channel),
+ jsonp, timetoken
+ ],
+ data : { uuid: UUID },
+ fail : function() {
+ // Disconnect
+ if (!disconnected) {
+ disconnected = 1;
+ disconnect();
+ }
+ timeout( _connect, SECOND );
+ SELF['time'](function(success){
+ // Reconnect
+ if (success && disconnected) {
+ disconnected = 0;
+ reconnect();
+ }
+ else {
+ error();
+ }
+ });
+ },
+ success : function(messages) {
+ if (!CHANNELS[channel].connected) return;
+
+ // Connect
+ if (!connected) {
+ connected = 1;
+ connect();
+ }
+
+ // Reconnect
+ if (disconnected) {
+ disconnected = 0;
+ reconnect();
+ }
+
+ // Restore Previous Connection Point if Needed
+ // Also Update Timetoken
+ restore = db.set(
+ SUBSCRIBE_KEY + channel,
+ timetoken = restore && db.get(
+ subscribe_key + channel
+ ) || messages[1]
+ );
+
+ each( messages[0], function(msg) {
+ callback( msg, messages );
+ } );
+
+ timeout( _connect, 10 );
+ }
+ });
+ }
+
+ // Presence Subscribe
+ if (args['presence']) SELF.subscribe({
+ channel : args['channel'] + PRESENCE_SUFFIX,
+ callback : presence,
+ restore : args['restore']
+ });
+
+ // Begin Recursive Subscribe
+ _connect();
+ },
+ 'here_now' : function( args, callback ) {
+ var callback = args['callback'] || callback
+ , channel = args['channel']
+ , jsonp = jsonp_cb()
+ , origin = nextorigin(ORIGIN);
+
+ // Make sure we have a Channel
+ if (!channel) return log('Missing Channel');
+ if (!callback) return log('Missing Callback');
+
+ data = null;
+ if (jsonp != '0') { data['callback']=jsonp; }
+
+ // Send Message
+ xdr({
+ callback : jsonp,
+ url : [
+ origin, 'v2', 'presence',
+ 'sub_key', SUBSCRIBE_KEY,
+ 'channel', encode(channel)
+ ],
+ data: data,
+ success : function(response) { callback(response) },
+ fail : function(response) { log(response) }
+ });
+ },
+
+ // Expose PUBNUB Functions
+ 'xdr' : xdr,
+ 'ready' : ready,
+ 'db' : db,
+ 'each' : each,
+ 'map' : map,
+ 'css' : css,
+ '$' : $,
+ 'create' : create,
+ 'bind' : bind,
+ 'supplant' : supplant,
+ 'head' : head,
+ 'search' : search,
+ 'attr' : attr,
+ 'now' : rnow,
+ 'unique' : unique,
+ 'events' : events,
+ 'updater' : updater,
+ 'init' : CREATE_PUBNUB
+ };
+
+ if (UUID == '') UUID = SELF.uuid();
+ db.set(SUBSCRIBE_KEY+'uuid', UUID);
+
+ return SELF;
+};
+
+// CREATE A PUBNUB GLOBAL OBJECT
+PUBNUB = CREATE_PUBNUB({
+ 'publish_key' : attr( PDIV, 'pub-key' ),
+ 'subscribe_key' : attr( PDIV, 'sub-key' ),
+ 'ssl' : attr( PDIV, 'ssl' ) == 'on',
+ 'origin' : attr( PDIV, 'origin' ),
+ 'uuid' : attr( PDIV, 'uuid' )
+});
+
+// PUBNUB Flash Socket
+css( PDIV, { 'position' : 'absolute', 'top' : -SECOND } );
+
+if ('opera' in window || attr( PDIV, 'flash' )) PDIV['innerHTML'] =
+ '<object id=pubnubs data=' + SWF +
+ '><param name=movie value=' + SWF +
+ '><param name=allowscriptaccess value=always></object>';
+
+var pubnubs = $('pubnubs') || {};
+
+// PUBNUB READY TO CONNECT
+function ready() { PUBNUB['time'](rnow);
+PUBNUB['time'](function(t){ timeout( function() {
+ if (READY) return;
+ READY = 1;
+ each( READY_BUFFER, function(sub) {
+ sub[2]['subscribe']( sub[0], sub[1] )
+ } );
+}, SECOND ); }); }
+
+// Bind for PUBNUB Readiness to Subscribe
+bind( 'load', window, function(){ timeout( ready, 0 ) } );
+
+// Create Interface for Opera Flash
+PUBNUB['rdx'] = function( id, data ) {
+ if (!data) return FDomainRequest[id]['onerror']();
+ FDomainRequest[id]['responseText'] = unescape(data);
+ FDomainRequest[id]['onload']();
+};
+
+function FDomainRequest() {
+ if (!pubnubs['get']) return 0;
+
+ var fdomainrequest = {
+ 'id' : FDomainRequest['id']++,
+ 'send' : function() {},
+ 'abort' : function() { fdomainrequest['id'] = {} },
+ 'open' : function( method, url ) {
+ FDomainRequest[fdomainrequest['id']] = fdomainrequest;
+ pubnubs['get']( fdomainrequest['id'], url );
+ }
+ };
+
+ return fdomainrequest;
+}
+FDomainRequest['id'] = SECOND;
+
+// jQuery Interface
+window['jQuery'] && (window['jQuery']['PUBNUB'] = PUBNUB);
+
+// For Testling.js - http://testling.com/
+typeof module !== 'undefined' && (module.exports = PUBNUB) && ready();
+
+})();
View
32 sencha/3.3/examples/here_now/sencha-touch-all.js
32 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
1 sencha/3.3/examples/here_now/sencha-touch.css
1 addition, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
93 sencha/3.3/examples/history/app.js
@@ -0,0 +1,93 @@
+var pubnub = PUBNUB.init({
+ publish_key : 'demo',
+ subscribe_key : 'demo',
+ ssl : false,
+ origin : 'pubsub.pubnub.com'
+});
+
+
+Ext.application({
+ launch: function () {
+ var myStore = Ext.create('Ext.data.Store', {
+ storeId: 'list',
+ fields: ['txt']
+ });
+
+ Ext.create('Ext.List', {
+ fullscreen: true,
+ store: 'list',
+ itemTpl: '{txt}',
+ items: [{
+ xtype: 'titlebar',
+ docked: 'top',
+ border: 0,
+ items: [
+ {
+ xtype: 'textfield',
+ name: 'channel',
+ id: 'channel',
+ label: 'Channel',
+ },
+ {
+ xtype: 'textfield',
+ label: 'Count',
+ name: 'count',
+ id: 'count'
+ },
+ {
+ xtype: 'textfield',
+ label: 'Start',
+ name: 'start',
+ id: 'start'
+ },
+ {
+ xtype: 'textfield',
+ label: 'End',
+ name: 'end',
+ id: 'end'
+ },
+ ]
+ },
+ {
+ xtype: 'titlebar',
+ docked: 'top',
+ height: '70px',
+ border: 0,
+ items: [
+ {
+ xtype: 'togglefield',
+ name : 'reverse',
+ id: 'reverse',
+ label: 'Reverse ?',
+ },
+ {
+ text: 'Get History',
+ align: 'left',
+ handler: function () {
+ var channel = Ext.getCmp('channel').getValue() || 'sencha-demo-channel';
+ var count = Ext.getCmp('count').getValue() || 100;
+ var start = Ext.getCmp('start').getValue();
+ var end = Ext.getCmp('end').getValue();
+ var reverse = Ext.getCmp('reverse').getValue() ;
+
+ myStore.removeAll();
+ pubnub.detailedHistory({
+ channel: channel,
+ count: count,
+ start: start,
+ end: end,
+ reverse: reverse?'true':'false',
+ callback: function(response){
+ for ( x in response[0] ) {
+ myStore.insert(0,{txt : JSON.stringify(response[0][x])});
+ }
+ }
+ });
+ }
+ }
+ ]
+ }]
+ });
+ }
+});
+
View
65 sencha/3.3/examples/history/index.html
@@ -0,0 +1,65 @@
+<!DOCTYPE HTML>
+<html manifest="" lang="en-US">
+<head>
+ <meta charset="UTF-8">
+ <title>history</title>
+ <style type="text/css">
+ /**
+ * Example of an initial loading indicator.
+ * It is recommended to keep this as minimal as possible to provide instant feedback
+ * while other resources are still being loaded for the first time
+ */
+ html, body {
+ height: 100%;
+ background-color: #1985D0
+ }
+
+ #appLoadingIndicator {
+ position: absolute;
+ top: 50%;
+ margin-top: -15px;
+ text-align: center;
+ width: 100%;
+ height: 30px;
+ -webkit-animation-name: appLoadingIndicator;
+ -webkit-animation-duration: 0.5s;
+ -webkit-animation-iteration-count: infinite;
+ -webkit-animation-direction: linear;
+ }
+
+ #appLoadingIndicator > * {
+ background-color: #FFFFFF;
+ display: inline-block;
+ height: 30px;
+ -webkit-border-radius: 15px;
+ margin: 0 5px;
+ width: 30px;
+ opacity: 0.8;
+ }
+
+ @-webkit-keyframes appLoadingIndicator{
+ 0% {
+ opacity: 0.8
+ }
+ 50% {
+ opacity: 0
+ }
+ 100% {
+ opacity: 0.8
+ }
+ }
+ </style>
+ <!-- The line below must be kept intact for Sencha Command to build your application -->
+ <link href=sencha-touch.css rel="stylesheet" type="text/css" />
+ <script src=sencha-touch-all.js type="text/javascript"></script>
+ <script src=pubnub-3.3.js type="text/javascript"></script>
+ <script src="app.js" type="text/javascript"></script>
+</head>
+<body>
+ <div id="appLoadingIndicator">
+ <div></div>
+ <div></div>
+ <div></div>
+ </div>
+</body>
+</html>
View
1,032 sencha/3.3/examples/history/pubnub-3.3.js
@@ -0,0 +1,1032 @@
+/* ---------------------------------------------------------------------------
+WAIT! - This file depends on instructions from the PUBNUB Cloud.
+http://www.pubnub.com/account-javascript-api-include
+--------------------------------------------------------------------------- */
+
+/* ---------------------------------------------------------------------------
+PubNub Real-time Cloud-Hosted Push API and Push Notification Client Frameworks
+Copyright (c) 2011 PubNub Inc.
+http://www.pubnub.com/
+http://www.pubnub.com/terms
+--------------------------------------------------------------------------- */
+
+/* ---------------------------------------------------------------------------
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+--------------------------------------------------------------------------- */
+
+/* =-====================================================================-= */
+/* =-====================================================================-= */
+/* =-========================= JSON =============================-= */
+/* =-====================================================================-= */
+/* =-====================================================================-= */
+
+(window['JSON'] && window['JSON']['stringify']) || (function () {
+ window['JSON'] || (window['JSON'] = {});
+
+ if (typeof String.prototype.toJSON !== 'function') {
+ String.prototype.toJSON =
+ Number.prototype.toJSON =
+ Boolean.prototype.toJSON = function (key) {
+ return this.valueOf();
+ };
+ }
+
+ var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ gap,
+ indent,
+ meta = { // table of character substitutions
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '"' : '\\"',
+ '\\': '\\\\'
+ },
+ rep;
+
+ function quote(string) {
+ escapable.lastIndex = 0;
+ return escapable.test(string) ?
+ '"' + string.replace(escapable, function (a) {
+ var c = meta[a];
+ return typeof c === 'string' ? c :
+ '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ }) + '"' :
+ '"' + string + '"';
+ }
+
+
+ function str(key, holder) {
+ var i, // The loop counter.
+ k, // The member key.
+ v, // The member value.
+ length,
+ mind = gap,
+ partial,
+ value = holder[key];
+
+ if (value && typeof value === 'object' &&
+ typeof value.toJSON === 'function') {
+ value = value.toJSON(key);
+ }
+
+ if (typeof rep === 'function') {
+ value = rep.call(holder, key, value);
+ }
+
+ switch (typeof value) {
+ case 'string':
+ return quote(value);
+
+ case 'number':
+ return isFinite(value) ? String(value) : 'null';
+
+ case 'boolean':
+ case 'null':
+ return String(value);
+
+ case 'object':
+
+ if (!value) {
+ return 'null';
+ }
+
+ gap += indent;
+ partial = [];
+
+ if (Object.prototype.toString.apply(value) === '[object Array]') {
+
+ length = value.length;
+ for (i = 0; i < length; i += 1) {
+ partial[i] = str(i, value) || 'null';
+ }
+
+ v = partial.length === 0 ? '[]' :
+ gap ? '[\n' + gap +
+ partial.join(',\n' + gap) + '\n' +
+ mind + ']' :
+ '[' + partial.join(',') + ']';
+ gap = mind;
+ return v;
+ }
+ if (rep && typeof rep === 'object') {
+ length = rep.length;
+ for (i = 0; i < length; i += 1) {
+ k = rep[i];
+ if (typeof k === 'string') {
+ v = str(k, value);
+ if (v) {
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
+ }
+ }
+ }
+ } else {
+ for (k in value) {
+ if (Object.hasOwnProperty.call(value, k)) {
+ v = str(k, value);
+ if (v) {
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
+ }
+ }
+ }
+ }
+
+ v = partial.length === 0 ? '{}' :
+ gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
+ mind + '}' : '{' + partial.join(',') + '}';
+ gap = mind;
+ return v;
+ }
+ }
+
+ if (typeof JSON['stringify'] !== 'function') {
+ JSON['stringify'] = function (value, replacer, space) {
+ var i;
+ gap = '';
+ indent = '';
+
+ if (typeof space === 'number') {
+ for (i = 0; i < space; i += 1) {
+ indent += ' ';
+ }
+ } else if (typeof space === 'string') {
+ indent = space;
+ }
+ rep = replacer;
+ if (replacer && typeof replacer !== 'function' &&
+ (typeof replacer !== 'object' ||
+ typeof replacer.length !== 'number')) {
+ throw new Error('JSON.stringify');
+ }
+ return str('', {'': value});
+ };
+ }
+
+ if (typeof JSON['parse'] !== 'function') {
+ // JSON is parsed on the server for security.
+ JSON['parse'] = function (text) {return eval('('+text+')')};
+ }
+}());
+
+
+/* =-====================================================================-= */
+/* =-====================================================================-= */
+/* =-======================= DOM UTIL ===========================-= */
+/* =-====================================================================-= */
+/* =-====================================================================-= */
+
+window['PUBNUB'] || (function() {
+
+/**
+ * CONSOLE COMPATIBILITY
+ */
+window.console||(window.console=window.console||{});
+console.log||(console.log=((window.opera||{}).postError||function(){}));
+
+/**
+ * UTILITIES
+ */
+function unique() { return'x'+ ++NOW+''+(+new Date) }
+function rnow() { return+new Date }
+
+/**
+ * LOCAL STORAGE OR COOKIE
+ */
+var db = (function(){
+ var ls = window['localStorage'];
+ return {
+ 'get' : function(key) {
+ try {
+ if (ls) return ls.getItem(key);
+ if (document.cookie.indexOf(key) == -1) return null;
+ return ((document.cookie||'').match(
+ RegExp(key+'=([^;]+)')
+ )||[])[1] || null;
+ } catch(e) { return }
+ },
+ 'set' : function( key, value ) {
+ try {
+ if (ls) return ls.setItem( key, value ) && 0;
+ document.cookie = key + '=' + value +
+ '; expires=Thu, 1 Aug 2030 20:00:00 UTC; path=/';
+ } catch(e) { return }
+ }
+ };
+})();
+
+/**
+ * UTIL LOCALS
+ */
+var NOW = 1
+, SWF = 'https://dh15atwfs066y.cloudfront.net/pubnub.swf'
+, REPL = /{([\w\-]+)}/g
+, ASYNC = 'async'
+, URLBIT = '/'
+, PARAMSBIT = '&'
+, XHRTME = 310000
+, SECOND = 1000
+, PRESENCE_SUFFIX = '-pnpres'
+, UA = navigator.userAgent
+, XORIGN = UA.indexOf('MSIE 6') == -1;
+
+/**
+ * NEXTORIGIN
+ * ==========
+ * var next_origin = nextorigin();
+ */
+var nextorigin = (function() {
+ var ori = Math.floor(Math.random() * 9) + 1;
+ return function(origin) {
+ return origin.indexOf('pubsub') > 0
+ && origin.replace(
+ 'pubsub', 'ps' + (++ori < 10 ? ori : ori=1)
+ ) || origin;
+ }
+})();
+
+/**
+ * UPDATER
+ * ======
+ * var timestamp = unique();
+ */
+function updater( fun, rate ) {
+ var timeout
+ , last = 0
+ , runnit = function() {
+ if (last + rate > rnow()) {
+ clearTimeout(timeout);
+ timeout = setTimeout( runnit, rate );
+ }
+ else {
+ last = rnow();
+ fun();
+ }
+ };
+
+ return runnit;
+}
+
+/**
+ * $
+ * =
+ * var div = $('divid');
+ */
+function $(id) { return document.getElementById(id) }
+
+/**
+ * LOG
+ * ===
+ * log('message');
+ */
+function log(message) { console['log'](message) }
+
+/**
+ * SEARCH
+ * ======
+ * var elements = search('a div span');
+ */
+function search( elements, start ) {
+ var list = [];
+ each( elements.split(/\s+/), function(el) {
+ each( (start || document).getElementsByTagName(el), function(node) {
+ list.push(node);
+ } );
+ } );
+ return list;
+}
+
+/**
+ * EACH
+ * ====
+ * each( [1,2,3], function(item) { console.log(item) } )
+ */
+function each( o, f ) {
+ if ( !o || !f ) return;
+
+ if ( typeof o[0] != 'undefined' )
+ for ( var i = 0, l = o.length; i < l; )
+ f.call( o[i], o[i], i++ );
+ else
+ for ( var i in o )
+ o.hasOwnProperty &&
+ o.hasOwnProperty(i) &&
+ f.call( o[i], i, o[i] );
+}
+
+/**
+ * MAP
+ * ===
+ * var list = map( [1,2,3], function(item) { return item + 1 } )
+ */
+function map( list, fun ) {
+ var fin = [];
+ each( list || [], function( k, v ) { fin.push(fun( k, v )) } );
+ return fin;
+}
+
+/**
+ * GREP
+ * ====
+ * var list = grep( [1,2,3], function(item) { return item % 2 } )
+ */
+function grep( list, fun ) {
+ var fin = [];
+ each( list || [], function(l) { fun(l) && fin.push(l) } );
+ return fin
+}
+
+/**
+ * SUPPLANT
+ * ========
+ * var text = supplant( 'Hello {name}!', { name : 'John' } )
+ */
+function supplant( str, values ) {
+ return str.replace( REPL, function( _, match ) {
+ return values[match] || _
+ } );
+}
+
+/**
+ * BIND
+ * ====
+ * bind( 'keydown', search('a')[0], function(element) {
+ * console.log( element, '1st anchor' )
+ * } );
+ */
+function bind( type, el, fun ) {
+ each( type.split(','), function(etype) {
+ var rapfun = function(e) {
+ if (!e) e = window.event;
+ if (!fun(e)) {
+ e.cancelBubble = true;
+ e.returnValue = false;
+ e.preventDefault && e.preventDefault();
+ e.stopPropagation && e.stopPropagation();
+ }
+ };
+
+ if ( el.addEventListener ) el.addEventListener( etype, rapfun, false );
+ else if ( el.attachEvent ) el.attachEvent( 'on' + etype, rapfun );
+ else el[ 'on' + etype ] = rapfun;
+ } );
+}
+
+/**
+ * UNBIND
+ * ======
+ * unbind( 'keydown', search('a')[0] );
+ */
+function unbind( type, el, fun ) {
+ if ( el.removeEventListener ) el.removeEventListener( type, false );
+ else if ( el.detachEvent ) el.detachEvent( 'on' + type, false );
+ else el[ 'on' + type ] = null;
+}
+
+/**
+ * HEAD
+ * ====
+ * head().appendChild(elm);
+ */
+function head() { return search('head')[0] }
+
+/**
+ * ATTR
+ * ====
+ * var attribute = attr( node, 'attribute' );
+ */
+function attr( node, attribute, value ) {
+ if (value) node.setAttribute( attribute, value );
+ else return node && node.getAttribute && node.getAttribute(attribute);
+}
+
+/**
+ * CSS
+ * ===
+ * var obj = create('div');
+ */
+function css( element, styles ) {
+ for (var style in styles) if (styles.hasOwnProperty(style))
+ try {element.style[style] = styles[style] + (
+ '|width|height|top|left|'.indexOf(style) > 0 &&
+ typeof styles[style] == 'number'
+ ? 'px' : ''
+ )}catch(e){}
+}
+
+/**
+ * CREATE
+ * ======
+ * var obj = create('div');
+ */
+function create(element) { return document.createElement(element) }
+
+/**
+ * timeout
+ * =======
+ * timeout( function(){}, 100 );
+ */
+function timeout( fun, wait ) {
+ return setTimeout( fun, wait );
+}
+
+/**
+ * jsonp_cb
+ * ========
+ * var callback = jsonp_cb();
+ */
+function jsonp_cb() { return XORIGN || FDomainRequest() ? 0 : unique() }
+
+/**
+ * ENCODE
+ * ======
+ * var encoded_path = encode('path');
+ */
+function encode(path) {
+ return map( (encodeURIComponent(path)).split(''), function(chr) {
+ return "-_.!~*'()".indexOf(chr) < 0 ? chr :
+ "%"+chr.charCodeAt(0).toString(16).toUpperCase()
+ } ).join('');
+}
+
+/**
+ * EVENTS
+ * ======
+ * PUBNUB.events.bind( 'you-stepped-on-flower', function(message) {
+ * // Do Stuff with message
+ * } );
+ *
+ * PUBNUB.events.fire( 'you-stepped-on-flower', "message-data" );
+ * PUBNUB.events.fire( 'you-stepped-on-flower', {message:"data"} );
+ * PUBNUB.events.fire( 'you-stepped-on-flower', [1,2,3] );
+ *
+ */
+var events = {
+ 'list' : {},
+ 'unbind' : function( name ) { events.list[name] = [] },
+ 'bind' : function( name, fun ) {
+ (events.list[name] = events.list[name] || []).push(fun);
+ },
+ 'fire' : function( name, data ) {
+ each(
+ events.list[name] || [],
+ function(fun) { fun(data) }
+ );
+ }
+};
+
+/**
+ * XDR Cross Domain Request
+ * ========================
+ * xdr({
+ * url : ['http://www.blah.com/url'],
+ * success : function(response) {},
+ * fail : function() {}
+ * });
+ */
+function xdr( setup ) {
+ if (XORIGN || FDomainRequest()) return ajax(setup);
+
+ var script = create('script')
+ , callback = setup.callback
+ , id = unique()
+ , finished = 0
+ , timer = timeout( function(){done(1)}, XHRTME )
+ , fail = setup.fail || function(){}
+ , success = setup.success || function(){}
+
+ , append = function() {
+ head().appendChild(script);
+ }
+
+ , done = function( failed, response ) {
+ if (finished) return;
+ finished = 1;
+
+ failed || success(response);
+ script.onerror = null;
+ clearTimeout(timer);
+
+ timeout( function() {
+ failed && fail();
+ var s = $(id)
+ , p = s && s.parentNode;
+ p && p.removeChild(s);
+ }, SECOND );
+ };
+
+ window[callback] = function(response) {
+ done( 0, response );
+ };
+
+ script[ASYNC] = ASYNC;
+ script.onerror = function() { done(1) };
+ script.src = setup.url.join(URLBIT);
+ if (setup.data) {
+ var params = [];
+ script.src += "?";
+ for (key in setup.data) {
+ params.push(key+"="+setup.data[key]);
+ }
+ script.src += params.join(PARAMSBIT);
+ }
+ attr( script, 'id', id );
+
+ append();
+ return done;
+}
+
+/**
+ * CORS XHR Request
+ * ================
+ * xdr({
+ * url : ['http://www.blah.com/url'],
+ * success : function(response) {},
+ * fail : function() {}
+ * });
+ */
+function ajax( setup ) {
+ var xhr, response
+ , finished = function() {
+ if (loaded) return;
+ loaded = 1;
+
+ clearTimeout(timer);
+
+ try { response = JSON['parse'](xhr.responseText); }
+ catch (r) { return done(1); }
+
+ success(response);
+ }
+ , complete = 0
+ , loaded = 0
+ , timer = timeout( function(){done(1)}, XHRTME )
+ , fail = setup.fail || function(){}
+ , success = setup.success || function(){}
+ , done = function(failed) {
+ if (complete) return;
+ complete = 1;
+
+ clearTimeout(timer);
+
+ if (xhr) {
+ xhr.onerror = xhr.onload = null;
+ xhr.abort && xhr.abort();
+ xhr = null;
+ }
+
+ failed && fail();
+ };
+
+ // Send
+ try {
+ xhr = FDomainRequest() ||
+ window.XDomainRequest &&
+ new XDomainRequest() ||
+ new XMLHttpRequest();
+
+ xhr.onerror = xhr.onabort = function(){ done(1) };
+ xhr.onload = xhr.onloadend = finished;
+ xhr.timeout = XHRTME;
+
+ url = setup.url.join(URLBIT);
+ if (setup.data) {
+ var params = [];
+ url += "?";
+ for (key in setup.data) {
+ params.push(key+"="+setup.data[key]);
+ }
+ url += params.join(PARAMSBIT);
+ }
+
+ xhr.open( 'GET', url, true );
+ xhr.send();
+ }
+ catch(eee) {
+ done(0);
+ XORIGN = 0;
+ return xdr(setup);
+ }
+
+ // Return 'done'
+ return done;
+}
+
+
+/* =-====================================================================-= */
+/* =-====================================================================-= */
+/* =-========================= PUBNUB ===========================-= */
+/* =-====================================================================-= */
+/* =-====================================================================-= */
+
+var PDIV = $('pubnub') || {}
+, READY = 0
+, READY_BUFFER = []
+, CREATE_PUBNUB = function(setup) {
+ var CHANNELS = {}
+ , PUBLISH_KEY = setup['publish_key'] || ''
+ , SUBSCRIBE_KEY = setup['subscribe_key'] || ''
+ , SSL = setup['ssl'] ? 's' : ''
+ , UUID = setup['uuid'] || db.get(SUBSCRIBE_KEY+'uuid') || ''
+ , ORIGIN = 'http'+SSL+'://'+(setup['origin']||'pubsub.pubnub.com')
+ , SELF = {
+ /*
+ PUBNUB.history({
+ channel : 'my_chat_channel',
+ limit : 100,
+ callback : function(messages) { console.log(messages) }
+ });
+ */
+ 'history' : function( args, callback ) {
+ var callback = args['callback'] || callback
+ , limit = args['limit'] || 100
+ , channel = args['channel']
+ , jsonp = jsonp_cb();
+
+ // Make sure we have a Channel
+ if (!channel) return log('Missing Channel');
+ if (!callback) return log('Missing Callback');
+
+ // Send Message
+ xdr({
+ callback : jsonp,
+ url : [
+ ORIGIN, 'history',
+ SUBSCRIBE_KEY, encode(channel),
+ jsonp, limit
+ ],
+ success : function(response) { callback(response) },
+ fail : function(response) { log(response) }
+ });
+ },
+
+ /*
+ PUBNUB.detailedHistory({
+ channel : 'my_chat_channel',
+ count : 100,
+ callback : function(messages) { console.log(messages) }
+ });
+ */
+ 'detailedHistory' : function( args, callback ) {
+ var callback = args['callback'] || callback
+ , count = args['count'] || 100
+ , channel = args['channel']
+ , reverse = args['reverse'] || "false"
+ , start = args['start']
+ , end = args['end']
+ , jsonp = jsonp_cb();
+
+ // Make sure we have a Channel
+ if (!channel) return log('Missing Channel');
+ if (!callback) return log('Missing Callback');
+
+ var params = {};
+ params["count"] = count;
+ params["reverse"] = reverse;
+ if (start)
+ params["start"] = start;
+ if (end)
+ params["end"] = end;
+
+ // Send Message
+ xdr({
+ callback : jsonp,
+ url : [
+ ORIGIN, 'v2', 'history',
+ 'sub-key', SUBSCRIBE_KEY, 'channel', encode(channel)
+ ],
+ data : params,
+ success : function(response) { callback(response) },
+ fail : function(response) { log(response) }
+ });
+ },
+
+ /*
+ PUBNUB.time(function(time){ console.log(time) });
+ */
+ 'time' : function(callback) {
+ var jsonp = jsonp_cb();
+ xdr({
+ callback : jsonp,
+ url : [ORIGIN, 'time', jsonp],
+ success : function(response) { callback(response[0]) },
+ fail : function() { callback(0) }
+ });
+ },
+
+ /*
+ PUBNUB.uuid(function(uuid) { console.log(uuid) });
+ */
+ 'uuid' : function(callback) {
+ var u = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
+ var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
+ return v.toString(16);
+ });
+ if (callback) callback(u);
+ return u;
+ },
+
+ /*
+ PUBNUB.publish({
+ channel : 'my_chat_channel',
+ message : 'hello!'
+ });
+ */
+ 'publish' : function( args, callback ) {
+ var callback = callback || args['callback'] || function(){}
+ , message = args['message']
+ , channel = args['channel']
+ , jsonp = jsonp_cb()
+ , url;
+
+ if (!message) return log('Missing Message');
+ if (!channel) return log('Missing Channel');
+ if (!PUBLISH_KEY) return log('Missing Publish Key');
+
+ // If trying to send Object
+ message = JSON['stringify'](message);
+
+ // Create URL
+ url = [
+ ORIGIN, 'publish',
+ PUBLISH_KEY, SUBSCRIBE_KEY,
+ 0, encode(channel),
+ jsonp, encode(message)
+ ];
+
+ // Send Message
+ xdr({
+ callback : jsonp,
+ success : function(response) { callback(response) },
+ fail : function() { callback([ 0, 'Disconnected' ]) },
+ url : url,
+ data : { uuid: UUID }
+ });
+ },
+ /*
+ PUBNUB.unsubscribe({ channel : 'my_chat' });
+ */
+ 'unsubscribe' : function(args) {
+ // Unsubscribe from both the Channel and the Presence Channel
+ _unsubscribe(args['channel']);
+ _unsubscribe(args['channel'] + PRESENCE_SUFFIX);
+
+ function _unsubscribe(channel) {
+ // Leave if there never was a channel.
+ if (!(channel in CHANNELS)) return;
+
+ // Disable Channel
+ CHANNELS[channel].connected = 0;
+
+ // Abort and Remove Script
+ CHANNELS[channel].done &&
+ CHANNELS[channel].done(0);
+ }
+ },
+
+ /*
+ PUBNUB.subscribe({
+ channel : 'my_chat'
+ callback : function(message) { console.log(message) }
+ });
+ */
+ 'subscribe' : function( args, callback ) {
+ var channel = args['channel']
+ , callback = callback || args['callback']
+ , subscribe_key= args['subscribe_key'] || SUBSCRIBE_KEY
+ , restore = args['restore']
+ , timetoken = 0
+ , error = args['error'] || function(){}
+ , connect = args['connect'] || function(){}
+ , reconnect = args['reconnect'] || function(){}
+ , disconnect = args['disconnect'] || function(){}
+ , presence = args['presence'] || function(){}
+ , disconnected = 0
+ , connected = 0
+ , origin = nextorigin(ORIGIN);
+
+ // Reduce Status Flicker
+ if (!READY) return READY_BUFFER.push([ args, callback, SELF ]);
+
+ // Make sure we have a Channel
+ if (!channel) return log('Missing Channel');
+ if (!callback) return log('Missing Callback');
+ if (!SUBSCRIBE_KEY) return log('Missing Subscribe Key');
+
+ if (!(channel in CHANNELS)) CHANNELS[channel] = {};
+
+ // Make sure we have a Channel
+ if (CHANNELS[channel].connected) return log('Already Connected');
+ CHANNELS[channel].connected = 1;
+
+ // Recurse Subscribe
+ function _connect() {
+ var jsonp = jsonp_cb();
+
+ // Stop Connection
+ if (!CHANNELS[channel].connected) return;
+
+ // Connect to PubNub Subscribe Servers
+ CHANNELS[channel].done = xdr({
+ callback : jsonp,
+ url : [
+ origin, 'subscribe',
+ subscribe_key, encode(channel),
+ jsonp, timetoken
+ ],
+ data : { uuid: UUID },
+ fail : function() {
+ // Disconnect
+ if (!disconnected) {
+ disconnected = 1;
+ disconnect();
+ }
+ timeout( _connect, SECOND );
+ SELF['time'](function(success){
+ // Reconnect
+ if (success && disconnected) {
+ disconnected = 0;
+ reconnect();
+ }
+ else {
+ error();
+ }
+ });
+ },
+ success : function(messages) {
+ if (!CHANNELS[channel].connected) return;
+
+ // Connect
+ if (!connected) {
+ connected = 1;
+ connect();
+ }
+
+ // Reconnect
+ if (disconnected) {
+ disconnected = 0;
+ reconnect();
+ }
+
+ // Restore Previous Connection Point if Needed
+ // Also Update Timetoken
+ restore = db.set(
+ SUBSCRIBE_KEY + channel,
+ timetoken = restore && db.get(
+ subscribe_key + channel
+ ) || messages[1]
+ );
+
+ each( messages[0], function(msg) {
+ callback( msg, messages );
+ } );
+
+ timeout( _connect, 10 );
+ }
+ });
+ }
+
+ // Presence Subscribe
+ if (args['presence']) SELF.subscribe({
+ channel : args['channel'] + PRESENCE_SUFFIX,
+ callback : presence,
+ restore : args['restore']
+ });
+
+ // Begin Recursive Subscribe
+ _connect();
+ },
+ 'here_now' : function( args, callback ) {
+ var callback = args['callback'] || callback
+ , channel = args['channel']
+ , jsonp = jsonp_cb()
+ , origin = nextorigin(ORIGIN);
+
+ // Make sure we have a Channel
+ if (!channel) return log('Missing Channel');
+ if (!callback) return log('Missing Callback');
+
+ data = null;
+ if (jsonp != '0') { data['callback']=jsonp; }
+
+ // Send Message
+ xdr({
+ callback : jsonp,
+ url : [
+ origin, 'v2', 'presence',
+ 'sub_key', SUBSCRIBE_KEY,
+ 'channel', encode(channel)
+ ],
+ data: data,
+ success : function(response) { callback(response) },
+ fail : function(response) { log(response) }
+ });
+ },
+
+ // Expose PUBNUB Functions
+ 'xdr' : xdr,
+ 'ready' : ready,
+ 'db' : db,
+ 'each' : each,
+ 'map' : map,
+ 'css' : css,
+ '$' : $,
+ 'create' : create,
+ 'bind' : bind,
+ 'supplant' : supplant,
+ 'head' : head,
+ 'search' : search,
+ 'attr' : attr,
+ 'now' : rnow,
+ 'unique' : unique,
+ 'events' : events,
+ 'updater' : updater,
+ 'init' : CREATE_PUBNUB
+ };
+
+ if (UUID == '') UUID = SELF.uuid();
+ db.set(SUBSCRIBE_KEY+'uuid', UUID);
+
+ return SELF;
+};
+
+// CREATE A PUBNUB GLOBAL OBJECT
+PUBNUB = CREATE_PUBNUB({
+ 'publish_key' : attr( PDIV, 'pub-key' ),
+ 'subscribe_key' : attr( PDIV, 'sub-key' ),
+ 'ssl' : attr( PDIV, 'ssl' ) == 'on',
+ 'origin' : attr( PDIV, 'origin' ),
+ 'uuid' : attr( PDIV, 'uuid' )
+});
+
+// PUBNUB Flash Socket
+css( PDIV, { 'position' : 'absolute', 'top' : -SECOND } );
+
+if ('opera' in window || attr( PDIV, 'flash' )) PDIV['innerHTML'] =
+ '<object id=pubnubs data=' + SWF +