diff --git a/src/bt-min.js b/src/bt-min.js index 63c313c..5d19cd5 100644 --- a/src/bt-min.js +++ b/src/bt-min.js @@ -1 +1 @@ -/* by a-sansara - v 0.8 - https://github.com/pluie-org/bt */var $l=function(){var a=localStorage;return{clear:function(){return a.clear()},get:function(n){return a.getItem(n)},rem:function(n){return a.removeItem(n)},set:function(n,o){return a.setItem(n,o)}}}(),$j=function(){var a=JSON;return{str:function(n){return a.stringify(n)},obj:function(s){return a.parse(s)}}}(),$bt={VERSION:.8,TRACE:!0&&!$.isNone(console),LS_TABS:"bt.list",LS_CURTAB:"bt.current",LS_CMD:"bt.event",CMD_SYNC:"bt.sync",CMD_VAR_SET:"bt.varset",CMD_VAR_SYNC:"bt.varsync",CMD_ATTR_SYNC:"bt.attr",CMD_APPEND:"bt.dom.append",CMD_PREPEND:"bt.dom.prepend",CMD_HTML:"bt.dom.rewrite",CMD_RELOAD:"bt.reload",CMD_ZOMBKILL:"bt.zombkill",CMD_DONTKILL:"bt.dontkill",vars:[],callbacks:[],zomblist:[],zkillonload:!0,zombTimeout:250,init:function(n){this._init(n)},log:function(n){this.TRACE&&console.log(n)},send:function(n){n.uid=this.id+Math.random(),n.from=this.id,$.isNone(n.to)&&(n.to="*"),n=$j.str(n),$bt.log("sending cmd : "+this.LS_CMD+" : "+n),$l.set(this.LS_CMD,n),$l.rem(this.LS_CMD)},append:function(n,o,i,b,c){this._dom(this.CMD_APPEND,i,n,o,b,c)},prepend:function(n,o,i,b,c){this._dom(this.CMD_PREPEND,i,n,o,b,c)},html:function(n,o,i,b,c){this._dom(this.CMD_HTML,i,n,o,b,c)},sync:function(n,o,i,b){var c=$.isNone(o)||null==o?document:parent.frames[o].document;this._dom(this.CMD_HTML,o,n,$(n,c).html(),i,b)},reload:function(n,o){$bt.send({name:$bt.CMD_RELOAD,url:n,to:o?o:"*"})},setCallback:function(n,o){$.isNone($bt.callbacks[n])?$bt.callbacks[n]=o:console.log("BT ERROR : callback name already exist")},zombkill:function(n,o){var i=(new Date).getTime();$bt.zomblist[""+i]=[],$bt.list.forEach(function(n){n!=$bt.id&&($bt.zomblist[""+i]["ping"+n]="")}),$bt.send({name:$bt.CMD_ZOMBKILL,askid:i,to:"*"});var b=setTimeout(function(){$bt._refresh();for(var o in $bt.zomblist[""+i])if("pong"!=$bt.zomblist[""+i][o]){var c=$bt.list.indexOf(parseInt(o.substring(4)));c>-1&&$bt.list.splice(c,1)}$l.set($bt.LS_TABS,$j.str($bt.list)),$bt._broadcast(),$bt.log($bt.list),clearTimeout(b),$.isFunc(n)&&n()},o?o:$bt.zombTimeout)},varset:function(n,o,i,b){try{var c=$j.str(o);$bt.vars[n]=o,$bt.send({name:$bt.CMD_VAR_SET,varName:n,data:c,callback:i,to:b?b:"*"})}catch(l){console.log(l)}},varsync:function(n,o,i){$bt.send({name:$bt.CMD_VAR_SYNC,varName:n,data:"",callback:o,to:i})},attr:function(n,o,i,b,c){var l=i?window.parent.frames[i].document:document;$.isStr(o)&&(o=[o]);var r=[];o.forEach(function(o){r.push("disabled"!=o?$(n,l).attr(o):$(n,l).first().disabled)}),$bt.send({name:$bt.CMD_ATTR_SYNC,attr:o,selector:n,data:r,context:i,callback:b,to:c?c:"*"})},_dontkill:function(n,o){$bt.send({name:$bt.CMD_DONTKILL,askid:n,to:o})},_refresh:function(){$bt.list=$j.obj($l.get($bt.LS_TABS))},_broadcast:function(){$bt.send({name:$bt.CMD_SYNC})},_remove:function(n){n||(n=$bt.id);var o=$bt.list.indexOf(n);o>-1&&$bt.list.splice(o,1)},_init:function(n){$(window).on("beforeunload",$bt._unload),$(window).on("storage",$bt._cmd),$bt._defHandlerCurrentTab(),$bt.id=(new Date).getTime();var t=$l.get($bt.LS_TABS);$bt.list=null==t?[]:$j.obj(t),$bt.list.push($bt.id),$l.set($bt.LS_TABS,$j.str($bt.list)),$bt._broadcast(),$bt.log($bt.list),$bt.zkillonload?$bt.zombkill(n):$.isFunc(n)&&n()},_defHandlerCurrentTab:function(){var n="hidden",o="visibilitychange";$.isNone(document.mozHidden)?$.isNone(document.msHidden)?$.isNone(document.webkitHidden)||(n="webkitHidden",o="webkitvisibilitychange"):(n="msHidden",o="msvisibilitychange"):(n="mozHidden",o="mozvisibilitychange"),$(window).on(o,function(){document[n]||($bt.log("SET CURRENT TAB : "+$bt.id),$l.set($bt.LS_CURTAB,$bt.id))},!1)},_dom:function(n,o,s,i,b,c){$bt.send({name:n,context:o,selector:s,data:i,callback:b,to:c?c:"*"})},_unload:function(){return $bt._refresh(),$bt._remove(),$l.set($bt.LS_TABS,$j.str($bt.list)),$bt._broadcast(),null},_cmd:function(o){if($.isNone(o.originalEvent)||(o=o.originalEvent),o.key==$bt.LS_CMD){var n=$j.obj(o.newValue);if(n&&("*"==n.to||n.to==$bt.id)){$bt.log("RECEIVING cmd "+n.name+" : "),$bt.log(n);try{n.context=$.isNone(n.context)||null==n.context||$.isNone(window.parent.frames[n.context])?document:window.parent.frames[n.context].document}catch(o){$bt.log("bad context "+n.context+" : "+o.message)}switch($.isFunc($bt.before)&&$bt.before(n),n.name){case $bt.CMD_SYNC:$bt._refresh(),$bt.log($bt.list);break;case $bt.CMD_APPEND:$(n.selector,n.context).append(n.data);break;case $bt.CMD_HTML:$(n.selector,n.context).html(n.data);break;case $bt.CMD_PREPEND:$(n.selector,n.context).prepend(n.data);break;case $bt.CMD_RELOAD:window.location=$.isNone(n.url)?window.location:n.url;break;case $bt.CMD_ZOMBKILL:$bt._dontkill(n.askid,n.from);break;case $bt.CMD_DONTKILL:$bt.zomblist[""+n.askid]["ping"+n.from]="pong";break;case $bt.CMD_VAR_SET:$bt.vars[n.varName]=n.data;break;case $bt.CMD_VAR_SYNC:$bt.varset(n.varName,$bt.vars[n.varName]);break;case $bt.CMD_ATTR_SYNC:n.attr.forEach(function(o,i){"disabled"!=n.attr?$(n.selector,n.context).attr(o,n.data[i]):$(n.selector,n.context).first().disabled=n.data[i]});break;default:$.isFunc($bt.on)&&$bt.on(n)}$.isStr(n.callback)&&n.callback.length>0&&!$.isNone($bt.callbacks[n.callback])&&$.isFunc($bt.callbacks[n.callback])&&($bt.log(n.callback),$bt.callbacks[n.callback].call({},n)),$.isFunc($bt.after)&&$bt.after(n)}}}}; +/* by a-sansara - v 0.8 - https://github.com/pluie-org/bt */var $l=function(){var a=localStorage;return{clear:function(){return a.clear()},get:function(n){return a.getItem(n)},rem:function(n){return a.removeItem(n)},set:function(n,i){return a.setItem(n,i)}}}(),$j=function(){var a=JSON;return{str:function(n){return a.stringify(n)},obj:function(s){return a.parse(s)}}}(),$bt={VERSION:.8,UID:null,HASH:null,TRACE:!0&&!$.isNone(console),setConstant:function(n,i){if(!i){if(null==this.UID)throw Error('UID is not define, you need to define $bt.UID or provide the "name" parameter');return null==this.HASH&&(this.HASH=this._getHash(this.UID)),this.HASH+"."+n}return _getHash(i)+"."+n},vars:[],callbacks:[],zomblist:[],zkillonload:!0,zombTimeout:250,init:function(n,i){if(!i&&$.isFunc(n)||0==arguments.length){if(null==this.UID)throw Error('UID is not define, you need to define $bt.UID or provide the "uid" parameter');arguments.length>0&&(i=n),n=this.UID}this._initConstant(n),this._init(i)},log:function(n){this.TRACE&&console.log(n)},send:function(n){n.uid=this.id+Math.random(),n.from=this.id,$.isNone(n.to)&&(n.to="*"),n=$j.str(n),$bt.log("sending cmd : "+this.LS_CMD+" : "+n),$l.set(this.LS_CMD,n),$l.rem(this.LS_CMD)},append:function(n,i,o,r,b){this._dom(this.CMD_APPEND,o,n,i,r,b)},prepend:function(n,i,o,r,b){this._dom(this.CMD_PREPEND,o,n,i,r,b)},html:function(n,i,o,r,b){this._dom(this.CMD_HTML,o,n,i,r,b)},sync:function(n,i,o,r){var b=$.isNone(i)||null==i?document:parent.frames[i].document;this._dom(this.CMD_HTML,i,n,$(n,b).html(),o,r)},reload:function(n,i){$bt.send({name:$bt.CMD_RELOAD,url:n,to:i?i:"*"})},setCallback:function(n,i){$.isNone($bt.callbacks[n])?$bt.callbacks[n]=i:console.log("BT ERROR : callback name already exist")},zombkill:function(n,i){var o=(new Date).getTime();$bt.zomblist[""+o]=[],$bt.list.forEach(function(n){n!=$bt.id&&($bt.zomblist[""+o]["ping"+n]="")}),$bt.send({name:$bt.CMD_ZOMBKILL,askid:o,to:"*"});var r=setTimeout(function(){$bt._refresh();for(var i in $bt.zomblist[""+o])if("pong"!=$bt.zomblist[""+o][i]){var b=$bt.list.indexOf(parseInt(i.substring(4)));b>-1&&$bt.list.splice(b,1)}$l.set($bt.LS_TABS,$j.str($bt.list)),$bt._broadcast(),$bt.log($bt.list),clearTimeout(r),$.isFunc(n)&&n()},i?i:$bt.zombTimeout)},varset:function(n,i,o,r){try{var b=$j.str(i);$bt.vars[n]=i,$bt.send({name:$bt.CMD_VAR_SET,varName:n,data:b,callback:o,to:r?r:"*"})}catch(l){console.log(l)}},varsync:function(n,i,o){$bt.send({name:$bt.CMD_VAR_SYNC,varName:n,data:"",callback:i,to:o})},attr:function(n,i,o,r,b){var l=o?window.parent.frames[o].document:document;$.isStr(i)&&(i=[i]);var c=[];i.forEach(function(i){c.push("disabled"!=i?$(n,l).attr(i):$(n,l).first().disabled)}),$bt.send({name:$bt.CMD_ATTR_SYNC,attr:i,selector:n,data:c,context:o,callback:r,to:b?b:"*"})},_dontkill:function(n,i){$bt.send({name:$bt.CMD_DONTKILL,askid:n,to:i})},_refresh:function(){$bt.list=$j.obj($l.get($bt.LS_TABS))},_broadcast:function(){$bt.send({name:$bt.CMD_SYNC})},_remove:function(n){n||(n=$bt.id);var i=$bt.list.indexOf(n);i>-1&&$bt.list.splice(i,1)},_getHash:function(n){n=window.location.host+"#"+n;for(var i=0,o=0,r=n.length;r>o;o++)i=(i<<5)-i+n.charCodeAt(o),i&=i;return Math.abs(i)},_initConstant:function(n){var i=null!=this.HASH?this.HASH:this._getHash(n);this.LS_TABS=i+".bt.list",this.LS_CURTAB=i+".bt.current",this.LS_CMD=i+".bt.event",this.CMD_SYNC=i+".bt.sync",this.CMD_VAR_SET=i+".bt.varset",this.CMD_VAR_SYNC=i+".bt.varsync",this.CMD_ATTR_SYNC=i+".bt.attr",this.CMD_APPEND=i+".bt.dom.append",this.CMD_PREPEND=i+".bt.dom.prepend",this.CMD_HTML=i+".bt.dom.rewrite",this.CMD_RELOAD=i+".bt.reload",this.CMD_ZOMBKILL=i+".bt.zombkill",this.CMD_DONTKILL=i+".bt.dontkill"},_init:function(n){$(window).on("beforeunload",$bt._unload),$(window).on("storage",$bt._cmd),$bt._defHandlerCurrentTab(),$bt.id=(new Date).getTime();var t=$l.get($bt.LS_TABS);$bt.list=null==t?[]:$j.obj(t),$bt.list.push($bt.id),$l.set($bt.LS_TABS,$j.str($bt.list)),$bt._broadcast(),$bt.log($bt.list),$bt.zkillonload?$bt.zombkill(n):$.isFunc(n)&&n()},_defHandlerCurrentTab:function(){var n="hidden",i="visibilitychange";$.isNone(document.mozHidden)?$.isNone(document.msHidden)?$.isNone(document.webkitHidden)||(n="webkitHidden",i="webkitvisibilitychange"):(n="msHidden",i="msvisibilitychange"):(n="mozHidden",i="mozvisibilitychange"),$(window).on(i,function(){document[n]||($bt.log("SET CURRENT TAB : "+$bt.id),$l.set($bt.LS_CURTAB,$bt.id))},!1)},_dom:function(n,i,s,o,r,b){$bt.send({name:n,context:i,selector:s,data:o,callback:r,to:b?b:"*"})},_unload:function(){return $bt._refresh(),$bt._remove(),$l.set($bt.LS_TABS,$j.str($bt.list)),$bt._broadcast(),null},_cmd:function(i){if($.isNone(i.originalEvent)||(i=i.originalEvent),i.key==$bt.LS_CMD){var n=$j.obj(i.newValue);if(n&&("*"==n.to||n.to==$bt.id)){console.log("RECEIVING cmd "+n.name+" : "),console.log(n);try{n.context=$.isNone(n.context)||null==n.context||$.isNone(window.parent.frames[n.context])?document:window.parent.frames[n.context].document}catch(i){$bt.log("bad context "+n.context+" : "+i.message)}switch($.isFunc($bt.before)&&$bt.before(n),n.name){case $bt.CMD_SYNC:$bt._refresh(),$bt.log($bt.list);break;case $bt.CMD_APPEND:$(n.selector,n.context).append(n.data);break;case $bt.CMD_HTML:$(n.selector,n.context).html(n.data);break;case $bt.CMD_PREPEND:$(n.selector,n.context).prepend(n.data);break;case $bt.CMD_RELOAD:window.location=$.isNone(n.url)?window.location:n.url;break;case $bt.CMD_ZOMBKILL:$bt._dontkill(n.askid,n.from);break;case $bt.CMD_DONTKILL:$bt.zomblist[""+n.askid]["ping"+n.from]="pong";break;case $bt.CMD_VAR_SET:$bt.vars[n.varName]=$j.obj(n.data);break;case $bt.CMD_VAR_SYNC:$.isNone($bt.vars[n.varName])||$bt.varset(n.varName,$bt.vars[n.varName]);break;case $bt.CMD_ATTR_SYNC:n.attr.forEach(function(i,o){"disabled"!=n.attr?$(n.selector,n.context).attr(i,n.data[o]):$(n.selector,n.context).first().disabled=n.data[o]});break;default:$.isFunc($bt.on)&&$bt.on(n)}$.isStr(n.callback)&&n.callback.length>0&&!$.isNone($bt.callbacks[n.callback])&&$.isFunc($bt.callbacks[n.callback])&&($bt.log(n.callback),$bt.callbacks[n.callback].call({},n)),$.isFunc($bt.after)&&$bt.after(n)}}}}; diff --git a/src/bt.js b/src/bt.js index 377f0c1..e335d54 100644 --- a/src/bt.js +++ b/src/bt.js @@ -127,33 +127,19 @@ var $j = (function alias() { var $bt = { VERSION : 0.8, + UID : null, + HASH : null, TRACE : true && !$.isNone(console), - /*! @constant LS_TABS localStorage key for browsertabs list */ - LS_TABS : 'bt.list', - /*! @constant LS_CURTAB localStorage key for current browsertab */ - LS_CURTAB : 'bt.current', - /*! @constant LS_CMD localStorage key command to interact with other tabs */ - LS_CMD : 'bt.event', - /*! @constant CMD_SYNC internal command to perform a browser tab synchro */ - CMD_SYNC : 'bt.sync', - /*! @constant CMD_VAR_SET internal command to perform a browser tab var set */ - CMD_VAR_SET : 'bt.varset', - /*! @constant CMD_VAR_SYNC internal command to perform a browser tab var sync */ - CMD_VAR_SYNC : 'bt.varsync', - /*! @constant CMD_ATTR_SYNC internal command to perform a dom sync attribute */ - CMD_ATTR_SYNC: 'bt.attr', - /*! @constant CMD_APPEND internal command to perform a dom append */ - CMD_APPEND : 'bt.dom.append', - /*! @constant CMD_PREPEND internal command to perform a dom append */ - CMD_PREPEND : 'bt.dom.prepend', - /*! @constant CMD_HTML internal command to perform a dom html */ - CMD_HTML : 'bt.dom.rewrite', - /*! @constant CMD_RELOAD internal command to perform a browser tab reload */ - CMD_RELOAD : 'bt.reload', - /*! @constant CMD_ZOMBKILL internal command to perform a browser tab zombies kill */ - CMD_ZOMBKILL : 'bt.zombkill', - /*! @constant CMD_DONTKILL internal command to perform a dontkill browser tab (CMD_ZOMBKILL reply) */ - CMD_DONTKILL : 'bt.dontkill', + setConstant : function(value, name) { + if (!name) { + if (this.UID == null) throw Error('UID is not define, you need to define $bt.UID or provide the "name" parameter'); + else if (this.HASH == null) { + this.HASH = this._getHash(this.UID); + } + return this.HASH+'.'+value; + } + return _getHash(name)+'.'+value; + }, /*! @var vars */ vars : [], /*! @var callbacks */ @@ -170,7 +156,13 @@ var $bt = { * @method init * @param string fn a function to call on initializing on dom ready */ - init : function(fn) { + init : function(uid, fn) { + if (!fn && $.isFunc(uid) || arguments.length==0) { + if (this.UID == null) throw Error('UID is not define, you need to define $bt.UID or provide the "uid" parameter'); + if (arguments.length > 0) fn = uid; + uid = this.UID; + } + this._initConstant(uid); this._init(fn); }, /*! @@ -389,6 +381,46 @@ var $bt = { if (i > -1) $bt.list.splice(i, 1); }, /*! @private */ + _getHash : function(name) { + name = window.location.host + '#' + name; + var uid = 0; + for (var i = 0, c = 0, lim = name.length; i < lim; i++) { + uid = ((uid<<5)-uid)+name.charCodeAt(i); + uid = uid & uid; // Convert to 32bit integer + } + return Math.abs(uid); + }, + /*! @private */ + _initConstant : function(name) { + var uid = this.HASH != null ? this.HASH : this._getHash(name); + /*! @constant LS_TABS localStorage key for browsertabs list */ + this.LS_TABS = uid+'.bt.list', + /*! @constant LS_CURTAB localStorage key for current browsertab */ + this.LS_CURTAB = uid+'.bt.current', + /*! @constant LS_CMD localStorage key command to interact with other tabs */ + this.LS_CMD = uid+'.bt.event', + /*! @constant CMD_SYNC internal command to perform a browser tab synchro */ + this.CMD_SYNC = uid+'.bt.sync', + /*! @constant CMD_VAR_SET internal command to perform a browser tab var set */ + this.CMD_VAR_SET = uid+'.bt.varset', + /*! @constant CMD_VAR_SYNC internal command to perform a browser tab var sync */ + this.CMD_VAR_SYNC = uid+'.bt.varsync', + /*! @constant CMD_ATTR_SYNC internal command to perform a dom sync attribute */ + this.CMD_ATTR_SYNC = uid+'.bt.attr', + /*! @constant CMD_APPEND internal command to perform a dom append */ + this.CMD_APPEND = uid+'.bt.dom.append', + /*! @constant CMD_PREPEND internal command to perform a dom append */ + this.CMD_PREPEND = uid+'.bt.dom.prepend', + /*! @constant CMD_HTML internal command to perform a dom html */ + this.CMD_HTML = uid+'.bt.dom.rewrite', + /*! @constant CMD_RELOAD internal command to perform a browser tab reload */ + this.CMD_RELOAD = uid+'.bt.reload', + /*! @constant CMD_ZOMBKILL internal command to perform a browser tab zombies kill */ + this.CMD_ZOMBKILL = uid+'.bt.zombkill', + /*! @constant CMD_DONTKILL internal command to perform a dontkill browser tab (CMD_ZOMBKILL reply) */ + this.CMD_DONTKILL = uid+'.bt.dontkill' + }, + /*! @private */ _init : function(fn) { $(window).on('beforeunload', $bt._unload); $(window).on('storage', $bt._cmd); @@ -450,8 +482,8 @@ var $bt = { var cmd = $j.obj(e.newValue); if (!cmd) return; if (cmd.to == "*" || cmd.to == $bt.id) { - $bt.log('RECEIVING cmd '+cmd.name+' : '); - $bt.log(cmd); + console.log('RECEIVING cmd '+cmd.name+' : '); + console.log(cmd); try { if (!$.isNone(cmd.context) && cmd.context!=null && !$.isNone(window.parent.frames[cmd.context])) { cmd.context = window.parent.frames[cmd.context].document; @@ -496,11 +528,11 @@ var $bt = { break; case $bt.CMD_VAR_SET : - $bt.vars[cmd.varName] = cmd.data; + $bt.vars[cmd.varName] = $j.obj(cmd.data); break; case $bt.CMD_VAR_SYNC : - $bt.varset(cmd.varName, $bt.vars[cmd.varName]); + if (!$.isNone($bt.vars[cmd.varName])) $bt.varset(cmd.varName, $bt.vars[cmd.varName]); break; case $bt.CMD_ATTR_SYNC :