decouple code between bt and svan with refacto, manage frame context and callback - update version to 0.5

This commit is contained in:
a-Sansara 2015-12-17 00:32:36 +01:00
parent 25a7ed9648
commit 8a0613baae
5 changed files with 180 additions and 150 deletions

View File

@ -1,14 +1,19 @@
# bt # bt
manage communication between browser tabs
Manage commnunication between browser tabs.
this js lib can perform several actions on browser tabs like :
- append/rewrite/synchro node on all (other) tabs or a specific tab (and possibly on specific frame context) eventually with callback.
- reload all tabs or a specific tab with specified url or tab 's current url
- perform your custom actions on all tabs or specific tab
### require ### require
html5 localStorage html5 localStorage svan (pluie.org small vanilla jquery-like lib)
### Initialize ### Initialize
$v(document).ready(function() { $(document).ready(function() {
$bt.init(); $bt.init();
} }
@ -17,21 +22,30 @@ manage communication between browser tabs
// append data on node to other browser tabs // append data on node to other browser tabs
$bt.append('#test', "<b>it's cool to append</b>"); $bt.append('#test', "<b>it's cool to append</b>");
// rewrite content on node to other browser tabs // rewrite content on node to other browser tabs
$bt.html('#test', "<b>it's cool to rewrite</b>"); $bt.html('#test', "<b>it's cool to rewrite</b>");
// rewrite content to specific browser tabs // append content to specific browser tab
$bt.html('#test', "<b>it's cool to rewrite</b>", '1449974562012'); $bt.append('#test', "<b>it's cool to rewrite</b>", null, null, '1449974562012');
// rewrite content to specified browser tab with callback
$bt.html('#test', "<b>it's cool to rewrite</b>", null, function() { alert('callback'); }, '1449974562012');
// append content to specified browser tab on specific frame
$bt.append('#test', "<b>it's cool to rewrite</b>", 'frameName', null, '1449974562012');
// perform a node synchro to other browser tabs // perform a node synchro to other browser tabs
$bt.sync('#test'); $bt.sync('#test');
// perform a node synchro to specified browser tab on specific frame with callback
$bt.sync('#test', 'frameName', callback, '1449974562012');
// reload other browser tabs // reload other browser tabs
$bt.reload(); $bt.reload();
// reload other browser tabs to specific url // reload specific browser tab to specific url
$bt.reload(window.location.path+"?reloaded=1"); $bt.reload(window.location.path+"?reloaded=1", '1449974562012');
// get browser tab list // get browser tab list
$bt.list; $bt.list;
@ -61,11 +75,9 @@ manage communication between browser tabs
### Bonus ### Bonus
// alias localStorage : clear|rem|get|set // alias localStorage : clear|rem|get|set
$l; $l
// alias json : str|obj // alias json : str|obj
$j $j
// minimal vanilla jquery style : ready|on|html|append|attr|val|foreach
$v
### Demo ### Demo

View File

@ -19,8 +19,12 @@
<h2>pluie.org bt demo : </h2> <h2>pluie.org bt demo : </h2>
<span>author : a-sansara - version : 0.4</span> <span>author : a-sansara - version : 0.4</span>
<div> <div>
<p> <p> Manage commnunication between browser tabs.</p>
this js lib can perform several actions on browser tabs. <p> this js lib can perform several actions on browser tabs like :<br/>
<ul><li>append/rewrite/synchro node on all (other) tabs or a specific tab (and possibly on specific frame context) eventually with callback.</li>
<li>reload all tabs or a specific tab with specified url or tab 's current url</li>
<li>perform your custom actions on all tabs or specific tab</li>
</ul>
</p> </p>
<h3>Static actions</h3> <h3>Static actions</h3>
<button class="cmd-sta-append" title="$bt.append('#test', '<b>it\'s cool to append</b><br/>');">static dom append</button> <button class="cmd-sta-append" title="$bt.append('#test', '<b>it\'s cool to append</b><br/>');">static dom append</button>
@ -41,6 +45,7 @@ enter txt or html : <br/>
<h3>Target output</h3> <h3>Target output</h3>
<div id="test"></div> <div id="test"></div>
</div> </div>
<script type="text/javascript" src="src/svan-min.js"></script>
<script type="text/javascript" src="src/bt-min.js"></script> <script type="text/javascript" src="src/bt-min.js"></script>
<script type="text/javascript"> <script type="text/javascript">
// define a new custom cmd // define a new custom cmd
@ -56,42 +61,42 @@ $bt.on = function(cmd) {
} }
} }
// //
$v(document).ready(function() { $(document).ready(function() {
$bt.init(); $bt.init();
var bind = function(call) { var bind = function(call) {
var html = $v('#data').val(); var html = $('#data').val();
if (html.length > 0) call(html) if (html.length > 0) call(html)
else $v('#data').attr('placeholder', 'insert data first !'); else $('#data').attr('placeholder', 'insert data first !');
} }
$v('.cmd-append').on('click', function(){ $('.cmd-append').on('click', function(){
bind(function(data) { bind(function(data) {
$bt.append('#test', data); $bt.append('#test', data);
}); });
}); });
$v('.cmd-html').on('click', function(){ $('.cmd-html').on('click', function(){
bind(function(data) { bind(function(data) {
$bt.html('#test', data); $bt.html('#test', data);
}); });
}); });
$v('.cmd-custom').on('click', function(){ $('.cmd-custom').on('click', function(){
bind(function(data) { bind(function(data) {
$bt.send({ name : $bt.CMD_CUSTOM, customKey : data }); $bt.send({ name : $bt.CMD_CUSTOM, customKey : data });
}); });
}); });
$v('.cmd-sync').on('click', function(){ $('.cmd-sync').on('click', function(){
$v('h2').html('pluie.org bt demo (sync on '+(new Date).getTime()+') :'); $v('h2').html('pluie.org bt demo (sync on '+(new Date).getTime()+') :');
$bt.sync('h2'); $bt.sync('h2');
}); });
$v('.cmd-reload').on('click', function(){ $('.cmd-reload').on('click', function(){
$bt.reload(window.location.pathname+"?reload="+(new Date).getTime()); $bt.reload(window.location.pathname+"?reload="+(new Date).getTime());
}); });
$v('.cmd-tarsync').on('click', function(){ $('.cmd-tarsync').on('click', function(){
$bt.sync('#test'); $bt.sync('#test');
}); });
$v('.cmd-sta-append').on('click', function(){ $('.cmd-sta-append').on('click', function(){
eval(this.title); eval(this.title);
}); });
$v('.cmd-sta-html').on('click', function(){ $('.cmd-sta-html').on('click', function(){
eval(this.title); eval(this.title);
}); });
}); });

7
src/bt-min.js vendored
View File

@ -1,6 +1 @@
/* by a-sansara - https://github.com/pluie-org/bt */var $bt={TRACE:true&&typeof console!="undefined",LS_TABS:'bt.tabs',LS_CURTAB:'bt.ctab',LS_CMD:'bt.cmd',CMD_SYNC:'bt.sync',CMD_APPEND:'dom.append',CMD_HTML:'dom.html',CMD_RELOAD:'bt.reload',init:function(fn){this._init(fn);},on:function(cmd){this.log(cmd);},log:function(data){if(this.TRACE)console.log(data);},send:function(cmd){cmd.uid=this.id+Math.random();cmd.from=this.id;if(typeof cmd.to=="undefined")cmd.to="*";$l.set(this.LS_CMD,$j.str(cmd));$l.rem(this.LS_CMD);},append:function(selector,data,btid){this._dom(this.CMD_APPEND,selector,data,btid);},html:function(selector,data,btid){this._dom(this.CMD_HTML,selector,data,btid);},sync:function(selector,btid){this._dom(this.CMD_HTML,selector,$v(selector).html(),btid);},reload:function(url,btid){$bt.send({name:$bt.CMD_RELOAD,url:url,to:!btid?'*':btid});},_refresh:function(){$bt.list=$j.obj($l.get($bt.LS_TABS));},_broadcast:function(){$bt.send({name:$bt.CMD_SYNC});},_remove:function(id){if(!id)id=$bt.id;var i=$bt.list.indexOf(id);if(i>-1)$bt.list.splice(i,1);},_init:function(fn){$v(window).on('beforeunload',$bt._unload);$v(window).on('storage',$bt._cmd);$v(window).on('focus',$bt._focus);$bt.id=(new Date).getTime();var t=$l.get($bt.LS_TABS);$bt.list=t==null?[]:$j.obj(t);$bt.list.push($bt.id);$l.set($bt.LS_TABS,$j.str($bt.list));$bt._broadcast();$bt.log($bt.list);if(typeof fn=="function")fn();},_dom:function(n,s,d,id){$bt.send({name:n,selector:s,data:d,to:!id?'*':id});},_unload:function(e){$bt._refresh();$bt._remove();$l.set($bt.LS_TABS,$j.str($bt.list));$bt._broadcast();return null;},_focus:function(e){$l.set($bt.LS_CURTAB,$bt.id);},_cmd:function(e){if(e.key!=$bt.LS_CMD)return;var cmd=$j.obj(e.newValue);if(!cmd)return;if(cmd.to=="*"||cmd.to==$bt.id){$bt.log("do "+cmd.name);$bt.log(cmd);switch(cmd.name){case $bt.CMD_SYNC:$bt._refresh();$bt.log($bt.list);break;case $bt.CMD_APPEND:$v(cmd.selector).append(cmd.data);break;case $bt.CMD_HTML:$v(cmd.selector).html(cmd.data);break;case $bt.CMD_RELOAD:window.location=typeof cmd.url!="undefined"?cmd.url:window.location;break;default:if(typeof $bt.on=="function")$bt.on(cmd);}}}} /* by a-sansara - v 0.5 - https://github.com/pluie-org/bt */var $l=function(){var t=localStorage;return{clear:function(){return t.clear()},get:function(n){return t.getItem(n)},rem:function(n){return t.removeItem(n)},set:function(n,e){return t.setItem(n,e)}}}(),$j=function(){var t=JSON;return{str:function(n){return t.stringify(n)},obj:function(n){return t.parse(n)}}}(),$bt={VERSION:.5,TRACE:!0&&!$.isNone(console),LS_TABS:"bt.tabs",LS_CURTAB:"bt.ctab",LS_CMD:"bt.cmd",CMD_SYNC:"bt.sync",CMD_VAR_SET:"var.set",CMD_VAR_GET:"var.get",CMD_APPEND:"dom.append",CMD_HTML:"dom.html",CMD_RELOAD:"bt.reload",vars:[],init:function(t){this._init(t)},on:function(t){this.log(t)},log:function(t){this.TRACE&&console.log(t)},send:function(t){t.uid=this.id+Math.random(),t.from=this.id,$.isNone(t.to)&&(t.to="*"),t=$j.str(t),$bt.log("sending cmd : "+this.LS_CMD+" : "+t),$l.set(this.LS_CMD,t),$l.rem(this.LS_CMD)},append:function(t,n,e,o,c){this._dom(this.CMD_APPEND,e,t,n,o,c)},html:function(t,n,e,o,c){this._dom(this.CMD_HTML,e,t,n,o,c)},sync:function(t,n,e,o){var c=$.isNone(n)||null==n?document:parent.frames[n].document;this._dom(this.CMD_HTML,n,t,$(t,c).html(),e,o)},reload:function(t,n){$bt.send({name:$bt.CMD_RELOAD,url:t,to:n?n:"*"})},varset:function(t,n){$bt.vars[t]=n,$bt.send({name:$bt.CMD_VAR_SET,data:{k:t,v:n}})},varget:function(t){if($bt.list.length>1){var n=$bt.list[0]==$bt.id?$bt.list[1]:$bt.list[0];$bt.send({name:$bt.CMD_VAR_GET,data:{k:t},to:n})}return $bt.vars[t]},_refresh:function(){$bt.list=$j.obj($l.get($bt.LS_TABS))},_broadcast:function(){$bt.send({name:$bt.CMD_SYNC})},_remove:function(t){t||(t=$bt.id);var n=$bt.list.indexOf(t);n>-1&&$bt.list.splice(n,1)},_init:function(t){$(window).on("beforeunload",$bt._unload),$(window).on("storage",$bt._cmd),$(window).on("focus",$bt._focus),$bt.id=(new Date).getTime();var n=$l.get($bt.LS_TABS);$bt.list=null==n?[]:$j.obj(n),$bt.list.push($bt.id),$l.set($bt.LS_TABS,$j.str($bt.list)),$bt._broadcast(),$bt.log($bt.list),$.isFunc(t)&&t()},_dom:function(t,n,e,o,c,i){$bt.send({name:t,context:n,selector:e,data:o,fn:c,to:i?i:"*"})},_unload:function(){return $bt._refresh(),$bt._remove(),$l.set($bt.LS_TABS,$j.str($bt.list)),$bt._broadcast(),null},_focus:function(){$l.set($bt.LS_CURTAB,$bt.id)},_cmd:function(e){if($.isNone(e.originalEvent)||(e=e.originalEvent),e.key==$bt.LS_CMD){var cmd=$j.obj(e.newValue);if(cmd)if($bt.log("RECEIVING cmd "+cmd.name+" : "),"*"==cmd.to||cmd.to==$bt.id){$bt.log("do "+cmd.name),$bt.log(cmd);try{$.isNone(cmd.context)||($bt.log(cmd.context),cmd.context=window.parent.frames[cmd.context].document,$bt.log(cmd.context))}catch(e){$bt.log("bad context "+cmd.context+" : "+e.message)}switch(cmd.name){case $bt.CMD_SYNC:$bt._refresh(),$bt.log($bt.list);break;case $bt.CMD_APPEND:$(cmd.selector,cmd.context).append(cmd.data);break;case $bt.CMD_HTML:$(cmd.selector,cmd.context).html(cmd.data);break;case $bt.CMD_RELOAD:window.location=$.isNone(cmd.url)?window.location:cmd.url;break;case $bt.CMD_VAR_GET:$bt.varset(cmd.data.k,$bt.vars[cmd.data.k],cmd.from);break;case $bt.CMD_VAR_SET:$bt.vars[cmd.data.k]=cmd.data.v;break;default:$.isFunc($bt.on)&&$bt.on(cmd)}if($.isStr(cmd.fn)&&cmd.fn.length>0){$bt.log(cmd.fn);var f=eval("window."+cmd.fn);$.isFunc(f)&&f()}}else $bt.log("ignoring (not target)")}}};
var $v=function(p){var s=typeof p=="string";var c=s?document.querySelectorAll(p):null;var a=s?[].slice.call(c):[p];delete(s);if(p==localStorage){return{clear:function(){return p.clear();},get:function(k){return p.getItem(k);},rem:function(k){return p.removeItem(k);},set:function(k,v){return p.setItem(k,v);}};}
else if(p==JSON){return{str:function(o){return p.stringify(o);},obj:function(s){return p.parse(s);}};}
else{this.foreach=function(f){[].forEach.call(c,f);};this.html=function(d){if(arguments.length==0)return a[0].innerHTML;else a[0].innerHTML=d;};this.append=function(d){this.foreach(function(n){n.innerHTML+=d;});};this.on=function(t,f,u){if(c!=null){this.foreach(function(n){n.addEventListener(t,f,u===true);});}
else a[0].addEventListener(t,f,u===true);};this.val=function(d){if(arguments.length==0)return a[0].value;else a[0].value=d;};this.attr=function(k,v){if(arguments.length==1)return a[0].getAttribute(k);else a[0].setAttribute(k,v);};this.ready=function(f){document.addEventListener('DOMContentLoaded',f);};return this;}}
var $l=$v(localStorage);var $j=$v(JSON);

257
src/bt.js
View File

@ -3,19 +3,21 @@
* @contributors : * @contributors :
* @copyright : pluie.org * @copyright : pluie.org
* @date : 2015-12-10 22:22:34 * @date : 2015-12-10 22:22:34
* @version : 0.4 * @version : 0.5
* @license : MIT * @license : MIT
* @require : html5 localStorage * @require : html5 localStorage svan (small vanilla jquery-like lib)
* @desc : * @desc : manage communication between browser tabs
* *
* USAGE : * USAGE :
* *
* *
* Initialize * Initialize
* *
* $v(document).ready(function() { *
* $(document).ready(function() {
* $bt.init(); * $bt.init();
* } * });
*
* *
* *
* Internal Commands * Internal Commands
@ -26,17 +28,26 @@
* // rewrite content on node to other browser tabs * // rewrite content on node to other browser tabs
* $bt.html('#test', "<b>it's cool to rewrite</b>"); * $bt.html('#test', "<b>it's cool to rewrite</b>");
* *
* // rewrite content to specific browser tabs * // append content to specific browser tab
* $bt.html('#test', "<b>it's cool to rewrite</b>", '1449974562012'); * $bt.append('#test', "<b>it's cool to rewrite</b>", null, null, '1449974562012');
*
* // rewrite content to specified browser tab with callback
* $bt.html('#test', "<b>it's cool to rewrite</b>", null, function() { alert('callback'); }, '1449974562012');
*
* // append content to specified browser tab on specific frame
* $bt.append('#test', "<b>it's cool to rewrite</b>", 'frameName', null, '1449974562012');
* *
* // perform a node synchro to other browser tabs * // perform a node synchro to other browser tabs
* $bt.sync('#test'); * $bt.sync('#test');
* *
* // perform a node synchro to specified browser tab on specific frame with callback
* $bt.sync('#test', 'frameName', callback, '1449974562012');
*
* // reload other browser tabs * // reload other browser tabs
* $bt.reload(); * $bt.reload();
* *
* // reload other browser tabs to specific url * // reload specific browser tab to specific url
* $bt.reload(window.location.path+"?reloaded=1"); * $bt.reload(window.location.path+"?reloaded=1", '1449974562012');
* *
* // get browser tab list * // get browser tab list
* $bt.list; * $bt.list;
@ -68,34 +79,58 @@
* $l; * $l;
* // alias json : str|obj * // alias json : str|obj
* $j * $j
* // minimal vanilla jquery style : ready|on|html|append|attr|val|foreach
* $v
* *
* enjoy ! * enjoy !
*/ */
var $l = (function alias() {
var a = localStorage;
return {
clear : function() { return a.clear(); },
get : function(k) { return a.getItem(k); },
rem : function(k) { return a.removeItem(k); },
set : function(k, v) { return a.setItem(k, v); }
};
}());
var $j = (function alias() {
var a = JSON;
return {
str : function(o) { return a.stringify(o); },
obj : function(s) { return a.parse(s); }
};
}());
var $bt = { var $bt = {
TRACE : true && typeof console != "undefined", VERSION : 0.5,
TRACE : true && !$.isNone(console),
/*! @constant LS_TABS localStorage key for browsertabs list */ /*! @constant LS_TABS localStorage key for browsertabs list */
LS_TABS : 'bt.tabs', LS_TABS : 'bt.tabs',
/*! @constant LS_CURTAB localStorage key for current browsertab */ /*! @constant LS_CURTAB localStorage key for current browsertab */
LS_CURTAB : 'bt.ctab', LS_CURTAB : 'bt.ctab',
/*! @constant LS_CMD localStorage key command to interact with other tabs */ /*! @constant LS_CMD localStorage key command to interact with other tabs */
LS_CMD : 'bt.cmd', LS_CMD : 'bt.cmd',
/*! @constant CMD_SYNC internal command to perform a browser tab synchro */ /*! @constant CMD_SYNC internal command to perform a browser tab synchro */
CMD_SYNC : 'bt.sync', CMD_SYNC : 'bt.sync',
/*! @constant CMD_VAR_SET internal command to perform a browser tab var set */
CMD_VAR_SET : 'var.set',
/*! @constant CMD_VAR_GET internal command to perform a browser tab var get */
CMD_VAR_GET : 'var.get',
/*! @constant CMD_APPEND internal command to perform a dom append */ /*! @constant CMD_APPEND internal command to perform a dom append */
CMD_APPEND : 'dom.append', CMD_APPEND : 'dom.append',
/*! @constant CMD_HTML internal command to perform a dom html */ /*! @constant CMD_HTML internal command to perform a dom html */
CMD_HTML : 'dom.html', CMD_HTML : 'dom.html',
/*! @constant CMD_RELOAD internal command to perform a browser tab reload */ /*! @constant CMD_RELOAD internal command to perform a browser tab reload */
CMD_RELOAD : 'bt.reload', CMD_RELOAD : 'bt.reload',
/*! @var vars */
vars : [],
/*! /*!
* @desc initialize on dom ready * @desc initialize on dom ready
* @public * @public
* @method init * @method init
* @param string fn a function to call on initializing on dom ready * @param string fn a function to call on initializing on dom ready
*/ */
init : function(fn) { init : function(fn) {
this._init(fn); this._init(fn);
}, },
/*! /*!
@ -104,7 +139,7 @@ var $bt = {
* @method on * @method on
* @param string cmd a cmd to treat * @param string cmd a cmd to treat
*/ */
on : function(cmd) { on : function(cmd) {
// custom // custom
this.log(cmd); this.log(cmd);
}, },
@ -114,7 +149,7 @@ var $bt = {
* @method on * @method on
* @param mix data data to log * @param mix data data to log
*/ */
log : function(data) { log : function(data) {
if (this.TRACE) console.log(data); if (this.TRACE) console.log(data);
}, },
/*! /*!
@ -123,75 +158,93 @@ var $bt = {
* @method send * @method send
* @param object cmd the cmd to send * @param object cmd the cmd to send
*/ */
send : function(cmd) { send : function(cmd) {
cmd.uid = this.id+Math.random(); cmd.uid = this.id+Math.random();
cmd.from = this.id; cmd.from = this.id;
if (typeof cmd.to == "undefined") cmd.to = "*"; if ($.isNone(cmd.to)) cmd.to = "*";
$l.set(this.LS_CMD, $j.str(cmd)); cmd = $j.str(cmd);
$bt.log('sending cmd : '+this.LS_CMD+' : '+cmd);
$l.set(this.LS_CMD, cmd);
$l.rem(this.LS_CMD); $l.rem(this.LS_CMD);
}, },
/*! /*!
* @desc perform an dom append command on other tabs * @desc perform a dom append command on other tabs
* @public * @public
* @method append * @method append
* @param string selector the selector wich target the node(s) * @param string selector the selector wich target the node(s)
* @param string data the data to append * @param string data the data to append
* @param string ctx context name of selector (frame name relative to document wich match specified selector) or if not defined or null current document
* @param int btid target browser tab id (if not defined all target all tabs) * @param int btid target browser tab id (if not defined all target all tabs)
*/ */
append : function(selector, data, btid) { append : function(selector, data, ctx, fn, btid) {
this._dom(this.CMD_APPEND, selector, data, btid); this._dom(this.CMD_APPEND, ctx, selector, data, fn, btid);
}, },
/*! /*!
* @desc perform an dom html command on other tabs * @desc perform a dom html command on other tabs
* @public * @public
* @method append * @method append
* @param string selector the selector wich target the node(s) * @param string selector the selector wich target the node(s)
* @param string data the data to append * @param string data the data to append
* @param string ctx context name of selector (frame name relative to document wich match specified selector) or if not defined or null current document
* @param int btid target browser tab id (if not defined all target all tabs) * @param int btid target browser tab id (if not defined all target all tabs)
*/ */
html : function(selector, data, btid) { html : function(selector, data, ctx, fn, btid) {
this._dom(this.CMD_HTML, selector, data, btid); this._dom(this.CMD_HTML, ctx, selector, data, fn, btid);
}, },
/*! /*!
* @desc perform an dom synchro command on other tabs * @desc perform a dom synchro command on other tabs
* @public * @public
* @method sync * @method sync
* @param string selector the selector wich target the node(s) to synchro * @param string selector the selector wich target the node(s) to synchro
* @param string ctx context name of selector (frame name relative to document wich match specified selector) or if not defined or null current document
* @param int btid target browser tab id (if not defined all target all tabs) * @param int btid target browser tab id (if not defined all target all tabs)
*/ */
sync : function(selector, btid) { sync : function(selector, ctx, fn, btid) {
this._dom(this.CMD_HTML, selector, $v(selector).html(), btid); var c = !$.isNone(ctx) && ctx != null ? parent.frames[ctx].document : document;
this._dom(this.CMD_HTML, ctx, selector, $(selector, c).html(), fn, btid);
}, },
/*! /*!
* @desc perform an reload command on other tabs with specified url * @desc perform a reload command on other tabs with specified url
* @public * @public
* @method reload * @method reload
* @param string url the url to load (if not defined load current page) * @param string url the url to load (if not defined load current page)
* @param int btid target browser tab id (if not defined all target all tabs) * @param int btid target browser tab id (if not defined all target all tabs)
*/ */
reload : function(url, btid) { reload : function(url, btid) {
$bt.send({ name : $bt.CMD_RELOAD, url : url, to : !btid ? '*' : btid }); $bt.send({ name : $bt.CMD_RELOAD, url : url, to : !btid ? '*' : btid });
}, },
/*! */
varset : function(k, v) {
$bt.vars[k] = v;
$bt.send({ name : $bt.CMD_VAR_SET, data : { k : k, v : v } });
},
/*! */
varget : function(k) {
if ($bt.list.length >1) {
var to = $bt.list[0] == $bt.id ? $bt.list[1] : $bt.list[0];
$bt.send({ name : $bt.CMD_VAR_GET, data : { k : k }, to : to });
}
return $bt.vars[k];
},
/*! @private */ /*! @private */
_refresh : function() { _refresh : function() {
$bt.list = $j.obj($l.get($bt.LS_TABS)); $bt.list = $j.obj($l.get($bt.LS_TABS));
}, },
/*! @private */ /*! @private */
_broadcast : function() { _broadcast : function() {
$bt.send({ name : $bt.CMD_SYNC }); $bt.send({ name : $bt.CMD_SYNC });
}, },
/*! @private */ /*! @private */
_remove : function(id) { _remove : function(id) {
if (!id) id = $bt.id; if (!id) id = $bt.id;
var i = $bt.list.indexOf(id); var i = $bt.list.indexOf(id);
if (i > -1) $bt.list.splice(i, 1); if (i > -1) $bt.list.splice(i, 1);
}, },
/*! @private */ /*! @private */
_init : function(fn) { _init : function(fn) {
$v(window).on('beforeunload', $bt._unload); $(window).on('beforeunload', $bt._unload);
$v(window).on('storage', $bt._cmd); $(window).on('storage', $bt._cmd);
$v(window).on('focus', $bt._focus); $(window).on('focus', $bt._focus);
//~ $l.clear();
$bt.id = (new Date).getTime(); $bt.id = (new Date).getTime();
var t = $l.get($bt.LS_TABS); var t = $l.get($bt.LS_TABS);
$bt.list = t==null ? [] : $j.obj(t); $bt.list = t==null ? [] : $j.obj(t);
@ -199,14 +252,14 @@ var $bt = {
$l.set($bt.LS_TABS, $j.str($bt.list)); $l.set($bt.LS_TABS, $j.str($bt.list));
$bt._broadcast(); $bt._broadcast();
$bt.log($bt.list); $bt.log($bt.list);
if (typeof fn == "function") fn(); if ($.isFunc(fn)) fn();
}, },
/*! @private */ /*! @private */
_dom : function(n, s, d, id) { _dom : function(n, c, s, d, fn, id) {
$bt.send({ name : n, selector : s, data : d, to : !id ? '*' : id }); $bt.send({ name : n, context : c, selector : s, data : d, fn : fn, to : !id ? '*' : id });
}, },
/*! @private */ /*! @private */
_unload : function(e) { _unload : function(e) {
$bt._refresh(); $bt._refresh();
$bt._remove(); $bt._remove();
$l.set($bt.LS_TABS, $j.str($bt.list)); $l.set($bt.LS_TABS, $j.str($bt.list));
@ -214,17 +267,29 @@ var $bt = {
return null; return null;
}, },
/*! @private */ /*! @private */
_focus : function(e) { _focus : function(e) {
$l.set($bt.LS_CURTAB, $bt.id); $l.set($bt.LS_CURTAB, $bt.id);
}, },
/*! @private */ /*! @private */
_cmd : function(e) { _cmd : function(e) {
if (!$.isNone(e.originalEvent)) e = e.originalEvent;
if (e.key!=$bt.LS_CMD) return; if (e.key!=$bt.LS_CMD) return;
var cmd = $j.obj(e.newValue); var cmd = $j.obj(e.newValue);
if (!cmd) return; if (!cmd) return;
$bt.log('RECEIVING cmd '+cmd.name+' : ');
if (cmd.to == "*" || cmd.to == $bt.id) { if (cmd.to == "*" || cmd.to == $bt.id) {
$bt.log("do "+cmd.name); $bt.log("do "+cmd.name);
$bt.log(cmd); $bt.log(cmd);
try {
if (!$.isNone(cmd.context)) {
$bt.log(cmd.context);
cmd.context = window.parent.frames[cmd.context].document;
$bt.log(cmd.context);
}
}
catch(e) {
$bt.log("bad context "+cmd.context+" : "+e.message);
}
switch(cmd.name) { switch(cmd.name) {
case $bt.CMD_SYNC : case $bt.CMD_SYNC :
@ -233,87 +298,39 @@ var $bt = {
break; break;
case $bt.CMD_APPEND : case $bt.CMD_APPEND :
$v(cmd.selector).append(cmd.data); $(cmd.selector, cmd.context).append(cmd.data);
break; break;
case $bt.CMD_HTML : case $bt.CMD_HTML :
$v(cmd.selector).html(cmd.data); $(cmd.selector, cmd.context).html(cmd.data);
break; break;
case $bt.CMD_RELOAD : case $bt.CMD_RELOAD :
window.location = typeof cmd.url != "undefined" ? cmd.url : window.location; window.location = !$.isNone(cmd.url) ? cmd.url : window.location;
break;
case $bt.CMD_VAR_GET :
$bt.varset(cmd.data.k, $bt.vars[cmd.data.k], cmd.from);
break;
case $bt.CMD_VAR_SET :
$bt.vars[cmd.data.k] = cmd.data.v;
break; break;
default : default :
// do your stuff here // do your stuff here
if (typeof $bt.on == "function") $bt.on(cmd); if ($.isFunc($bt.on)) $bt.on(cmd);
} }
if ($.isStr(cmd.fn) && cmd.fn.length>0) {
$bt.log(cmd.fn);
var f = eval("window."+cmd.fn);
if ($.isFunc(f)) {
f();
}
}
}
else {
$bt.log("ignoring (not target)");
} }
} }
} }
// vanilla minimal jquery style
var $v = function(p) {
var s = typeof p == "string";
var c = s ? document.querySelectorAll(p) : null;
var a = s ? [].slice.call(c) : [p];
delete(s);
// alias
if (p==localStorage) {
return {
clear : function() { return p.clear(); },
get : function(k) { return p.getItem(k); },
rem : function(k) { return p.removeItem(k); },
set : function(k, v) { return p.setItem(k, v); }
};
}
// alias
else if (p==JSON) {
// alias JSON
return {
str : function(o) { return p.stringify(o); },
obj : function(s) { return p.parse(s); }
};
}
else {
this.foreach = function(f) {
[].forEach.call(c, f);
};
// assume uniq selector
// Living Standard cf https://w3c.github.io/DOM-Parsing/#innerhtml
this.html = function(d) {
if (arguments.length == 0) return a[0].innerHTML;
else a[0].innerHTML = d;
};
this.append = function(d) {
this.foreach(function(n) {
n.innerHTML += d;
});
};
this.on = function(t, f, u) {
if (c != null) {
this.foreach(function(n) {
n.addEventListener(t, f, u===true);
});
}
else a[0].addEventListener(t, f, u===true);
};
// assume uniq selector
this.val = function(d) {
if (arguments.length == 0) return a[0].value;
else a[0].value = d;
};
// assume uniq selector
this.attr = function(k, v) {
if (arguments.length == 1) return a[0].getAttribute(k);
else a[0].setAttribute(k, v);
};
this.ready = function(f) {
document.addEventListener('DOMContentLoaded', f);
};
return this;
}
}
// alias localStorage : clear|rem|get|set
var $l = $v(localStorage);
// alias json : str|obj
var $j = $v(JSON);

1
src/svan-min.js vendored Normal file
View File

@ -0,0 +1 @@
/* by a-sansara - v 0.3 - https://github.com/pluie-org/svan */!function(){{var t=function(t,n){return typeof t==n},n=function(t,i){return new n.init(t,i)},i=n.isNone=function(n){return t(n,"undefined")},o=n.isStr=function(n){return t(n,"string")},e=n.isFunc=function(n){return t(n,"function")},s=n.isObj=function(n){return t(n,"object")};n.isNode=function(t){return s(t)&&!i(t.nodeType)},n.isWin=function(t){return!i(t.window)&&t.window==t}}n.prototype={regsan:function(t){return t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")},first:function(){return this.found?this.list[0]:null},last:function(){return this.found?this.list[this.list.length-1]:b},index:function(t){return this.found&&t>0&&t<this.list.length?this.list[t]:b},all:function(){return this.list},find:function(t){return this.found?[].slice.call(this.list[0].querySelectorAll(t)):[]},foreach:function(t){this.found&&this.list.forEach(t)},html:function(t){return t?void this.foreach(function(n){n.innerHTML=t}):this.found?this.list[0].innerHTML:""},append:function(t){this.foreach(function(n){n.innerHTML+=t})},on:function(t,n,i){console.log("ON START "+t+" - capture ? "+i),console.log("node"),console.log(this.first()),console.log("context"),console.log(this.context),console.log("list"),console.log(this.list),console.log("found"),console.log(this.found),this.foreach(function(o){console.log("inside foreach loop"),o.addEventListener(t,n,i===!0)})},val:function(t){return t?void this.foreach(function(n){n.value=t}):this.found?this.list[0].value:null},attr:function(t,n){return 1==arguments.length?this.found?this.list[0].getAttribute(t):null:void this.foreach(function(i){i.setAttribute(t,n)})},toggle:function(t){this.foreach(function(n){n.classList.toggle(t)})},hasClass:function(t){return this.found?this.list[0].contains(t):this.found},removeClass:function(t){this.foreach(function(n){n.classList.contains(t)&&n.classList.toggle(t)})},addClass:function(t){this.foreach(function(n){n.classList.contains(t)||n.classList.toggle(t)})},fadeIn:function(t,n,i){if(this.found){t||(t=this.FADE_DURATION);var o=parseFloat(1/t*20),e=this.first();e.style.opacity=0,e.style.display=i||"block",function t(){var i=parseFloat(e.style.opacity);(i+=o)<1?(e.style.opacity=i,requestAnimationFrame(t)):"function"==typeof n&&n.call(e)}(t)}},fadeOut:function(t,n){if(this.found){t||(t=this.FADE_DURATION);var i=parseFloat(1/t*20),o=this.first();o.style.opacity=1,function t(){var e=parseFloat(o.style.opacity);(e-=i)<0?(o.style.display="none","function"==typeof n&&n.call(o)):(o.style.opacity=e,requestAnimationFrame(t))}(t)}},ready:function(t){this.context.addEventListener("DOMContentLoaded",t)}},n.eachObj=function(t,n,i){for(var o in t)t.hasOwnProperty(o)&&n.call(i,o,t[o])},n.ajax=function(t){this.eachObj(t,function(t,n){console.log(t),console.log(n)});var n=new XMLHttpRequest;n.onreadystatechange=function(n){4==this.readyState&&(200==this.status?e(t.done)&&t.done.call(t.context,n,this.responseText,this.statusText):e(t.fail)&&t.fail.call(t.context,n,this.responseText,this.statusText),e(t.always)&&t.always.call(t.context,n,this.responseText,this.statusText))},!i(t.timeout)&&t.async&&(n.timeout=t.timeout),e(t.before)&&t.before.call(n),n.open(t.method,t.url,t.async),n.setRequestHeader("Content-Type","application/x-www-form-urlencoded");var o="";s(t.data)&&this.eachObj(t.data,function(t,n){o+=t+"="+encodeURIComponent(n)}),n.send(o)};var c=n.init=function(t,e){return this.FADE_DURATION=700,this.VERSION=.3,this.context=i(e)?document:e,this.list=o(t)?[].slice.call(this.context.querySelectorAll(t)):n.isNode(t)||n.isWin(t)?[t]:[],this.found=this.list.length>0,this};c.prototype=n.prototype,window.Svan=n,i(window.$)&&(window.$=n)}();