1/* example usage */ 2/* 3// calling before above script is loaded 4var bsApi = window.bsApi || []; 5bsApi.push(['on', 'beforeInit']); 6bsApi.push(['on', 'beforeInit2']); 7 8// load bsApi from script from below 9// ie embed script tag or embed async script insert 10 11// after loaded 12bsApi.push(['on', 'afterInit']); 13bsApi.push(['on', 'afterInit2']); 14*/ 15 16 17// polyfill for array 18if (!Array.isArray) { 19 Array.isArray = function(arg) { 20 return Object.prototype.toString.call(arg) === '[object Array]'; 21 }; 22} 23 24class BsApi { 25 26 constructor(data) { 27 this._data = data; 28 this._loaded = false; 29 // this._init(); need to load after first "on" function call else we will end up triggering all triggers before we have a chance to bind 30 } 31 32 _init() { 33 if (this._data && Array.isArray(this._data)) { 34 while (this._data.length) { 35 this._processRow(this._data.shift()); 36 } 37 } 38 } 39 _processRow(arr) { 40 var funcName = arr.shift(); 41 if (Array.isArray(arr) && typeof this[funcName] !== 'undefined') { 42 if (arr.length) { 43 this[funcName](arr); 44 } else { 45 this[funcName](); 46 } 47 } 48 } 49 50 _createEventName(eventName) { 51 return 'bsApi_' + eventName.replace(/[^a-z0-9]/ig, '_') + '.bsApi'; 52 } 53 54 push(arr) { 55 this._processRow(arr); 56 } 57 58 on(arr) { 59 // auto-init here instead of on constuct 60 if (!this._loaded) { 61 this._loaded = -1; // prevent race condition where multiple on()'s might get called before setTimeout() triggers 62 var _this = this; 63 // must do in setTimeout() so we queue to run after all bsApi.push(['on',...]) statements are called, else we will initialize only after 1st one 64 // technically this is wrong if we do bsApi.push(['on',...]) from multiple places but at least we will get the main block 65 // later we can a option to disable auto init and then manully init after we are done binding 66 setTimeout(function () { 67 _this._loaded = true; // must be set before _init() else trigger will re-queue function and create an infinite loop 68 _this._init(); 69 }, 0); 70 } 71 if (Array.isArray(arr)) { 72 var eventName = arr.shift(); 73 eventName = this._createEventName(eventName); 74 var callback = arr.shift(); 75 $(window).on(eventName, function (evt, data) { 76 if (typeof data !== 'undefined') { 77 callback(data); 78 } else { 79 callback(); 80 } 81 }); 82 83 } 84 } 85 86 trigger(arr) { 87 // if we're not initialized yet then just re-queue the trigger, 88 // we should just do this in .push() function however that will be break the auto-init for .on() 89 // we must check against === true to prevent cases where trigger() gets called after auto-init but before it finishes calling the setTimeout() 90 if (this._loaded !== true) { 91 arr.unshift('trigger'); 92 this._data.push(arr); 93 } else { 94 var eventName = arr.shift(); 95 eventName = this._createEventName(eventName); 96 var data = arr; 97 $(window).trigger(eventName, data); 98 } 99 } 100} 101 102var bsApi = window.bsApi || []; 103if (!(bsApi instanceof BsApi)) { // prevent duplicate in case it gets called twice 104 bsApi = window.bsApi = new BsApi(bsApi); 105}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.