UNPKG

com.cordova.admob

Version:

Google AdMob plugin for Cordova, Phonegap and Intel XDK ,support ios and android,support admob v1 and admob v2 ,Monetize your app with one javascript line.simple and easy to use api.build on admob ios 7.6 and admob android sdk 8 project home:https

1,332 lines (1,213 loc) 264 kB
/*! intel-appframework - v2.1.0 - 2014-03-26 */ /** * af.actionsheet - an actionsheet for html5 mobile apps * Copyright 2012 - Intel */ /* EXAMPLE You can pass in an HTML string that will get rendered $(document.body).actionsheet('<a >Back</a><a onclick="alert(\'hi\');" >Show Alert 3</a><a onclick="alert(\'goodbye\');">Show Alert 4</a>'); You can also use an arra of objects to show each item. There are three propertyes text - the text to display cssClasses - extra css classes handler - click handler function $(document.body).actionsheet( [{ text: 'back', cssClasses: 'red', handler: function () { $.ui.goBack(); } }, { text: 'show alert 5', cssClasses: 'blue', handler: function () { alert("hi"); } }, { text: 'show alert 6', cssClasses: '', handler: function () { alert("goodbye"); } }] ); */ /* global af*/ (function($) { "use strict"; $.fn.actionsheet = function(opts) { var tmp; for (var i = 0; i < this.length; i++) { tmp = new actionsheet(this[i], opts); } return this.length === 1 ? tmp : this; }; var actionsheet = (function() { var actionsheet = function(elID, opts) { if (typeof elID === "string" || elID instanceof String) { this.el = document.getElementById(elID); } else { this.el = elID; } if (!this.el) { window.alert("Could not find element for actionsheet " + elID); return; } if (this instanceof actionsheet) { if (typeof(opts) === "object") { for (var j in opts) { this[j] = opts[j]; } } } else { return new actionsheet(elID, opts); } // try { var that = this; var markStart = "<div id='af_actionsheet'><div style='width:100%'>"; var markEnd = "</div></div>"; var markup; var noop=function(){}; if (typeof opts === "string") { markup = $(markStart + opts + "<a href='javascript:;' class='cancel'>Cancel</a>" + markEnd); } else if (typeof opts === "object") { markup = $(markStart + markEnd); var container = $(markup.children().get(0)); opts.push({ text: "Cancel", cssClasses: "cancel" }); for (var i = 0; i < opts.length; i++) { var item = $("<a href='javascript:;'>" + (opts[i].text || "TEXT NOT ENTERED") + "</a>"); item[0].onclick = (opts[i].handler || noop); if (opts[i].cssClasses && opts[i].cssClasses.length > 0) item.addClass(opts[i].cssClasses); container.append(item); } } $(elID).find("#af_actionsheet").remove(); $(elID).find("#af_action_mask").remove(); $(elID).append(markup); markup.vendorCss("Transition", "all 0ms"); markup.cssTranslate("0,0"); markup.css("top", window.innerHeight + "px"); this.el.style.overflow = "hidden"; markup.on("click", "a", function() { that.hideSheet(); return false; }); this.activeSheet = markup; $(elID).append("<div id='af_action_mask' style='position:absolute;top:0px;left:0px;right:0px;bottom:0px;z-index:9998;background:rgba(0,0,0,.4)'/>"); setTimeout(function() { markup.vendorCss("Transition", "all 300ms"); markup.cssTranslate("0," + (-(markup.height())) + "px"); }, 10); $("#af_action_mask").bind("touchstart touchmove touchend click",function(e){ e.preventDefault(); e.stopPropagation(); }); }; actionsheet.prototype = { activeSheet: null, hideSheet: function() { var that = this; this.activeSheet.off("click", "a", function() { that.hideSheet(); }); $(this.el).find("#af_action_mask").unbind("click").remove(); this.activeSheet.vendorCss("Transition", "all 0ms"); var markup = this.activeSheet; var theEl = this.el; setTimeout(function() { markup.vendorCss("Transition", "all 300ms"); markup.cssTranslate("0,0px"); setTimeout(function() { markup.remove(); markup = null; theEl.style.overflow = "none"; }, 500); }, 10); } }; return actionsheet; })(); })(af); /** * af.css3animate - a css3 animation library that supports chaning/callbacks * Copyright 2013 - Intel */ /* EXAMPLE $("#animate").css3Animate({ width: "100px", height: "100px", x: "20%", y: "30%", time: "1000ms", opacity: .5, callback: function () { //execute when finished } }); //Chain animations $("#animate").css3Animate({ x: 20, y: 30, time: "300ms", callback: function () { $("#animate").css3Animate({ x: 20, y: 30, time: "500ms", previous: true, callback: function () { reset(); } }); } }); */ /* global af*/ /* global numOnly*/ (function($) { "use strict"; var cache = []; var objId = function(obj) { if (!obj.afCSS3AnimateId) obj.afCSS3AnimateId = $.uuid(); return obj.afCSS3AnimateId; }; var getEl = function(elID) { if (typeof elID === "string" || elID instanceof String) { return document.getElementById(elID); } else if ($.is$(elID)) { return elID[0]; } else { return elID; } }; var getCSS3Animate = function(obj, options) { var tmp, id, el = getEl(obj); //first one id = objId(el); if (cache[id]) { cache[id].animate(options); tmp = cache[id]; } else { tmp = css3Animate(el, options); cache[id] = tmp; } return tmp; }; $.fn.css3Animate = function(opts) { //keep old callback system - backwards compatibility - should be deprecated in future versions if (!opts.complete && opts.callback) opts.complete = opts.callback; //first on var tmp = getCSS3Animate(this[0], opts); opts.complete = null; opts.sucess = null; opts.failure = null; for (var i = 1; i < this.length; i++) { tmp.link(this[i], opts); } return tmp; }; $.css3AnimateQueue = function() { return new css3Animate.queue(); }; var translateOpen = $.feat.cssTransformStart; var translateClose = $.feat.cssTransformEnd; var transitionEnd = $.feat.cssPrefix.replace(/-/g, "") + "TransitionEnd"; transitionEnd = ($.os.fennec || $.feat.cssPrefix === "" || $.os.ie) ? "transitionend" : transitionEnd; transitionEnd = transitionEnd.replace(transitionEnd.charAt(0), transitionEnd.charAt(0).toLowerCase()); var css3Animate = (function() { var css3Animate = function(elID, options) { if (!(this instanceof css3Animate)) return new css3Animate(elID, options); //start doing stuff this.callbacksStack = []; this.activeEvent = null; this.countStack = 0; this.isActive = false; this.el = elID; this.linkFinishedProxy = $.proxy(this.linkFinished, this); if (!this.el) return; this.animate(options); var that = this; af(this.el).bind("destroy", function() { var id = that.el.afCSS3AnimateId; that.callbacksStack = []; if (cache[id]) delete cache[id]; }); }; css3Animate.prototype = { animate: function(options) { //cancel current active animation on this object if (this.isActive) this.cancel(); this.isActive = true; if (!options) { window.alert("Please provide configuration options for animation of " + this.el.id); return; } var classMode = !! options.addClass; var scale, time; var timeNum = numOnly(options.time); if (classMode) { //class defines properties being changed if (options.removeClass) { af(this.el).replaceClass(options.removeClass, options.addClass); } else { af(this.el).addClass(options.addClass); } } else { //property by property if (timeNum === 0) options.time = 0; if (!options.y) options.y = 0; if (!options.x) options.x = 0; if (options.previous) { var cssMatrix = new $.getCssMatrix(this.el); options.y += numOnly(cssMatrix.f); options.x += numOnly(cssMatrix.e); } if (!options.origin) options.origin = "0% 0%"; if (!options.scale) options.scale = "1"; if (!options.rotateY) options.rotateY = "0"; if (!options.rotateX) options.rotateX = "0"; if (!options.skewY) options.skewY = "0"; if (!options.skewX) options.skewX = "0"; if (!options.timingFunction) options.timingFunction = "linear"; //check for percent or numbers if (typeof(options.x) === "number" || (options.x.indexOf("%") === -1 && options.x.toLowerCase().indexOf("px") === -1 && options.x.toLowerCase().indexOf("deg") === -1)) options.x = parseInt(options.x, 10) + "px"; if (typeof(options.y) === "number" || (options.y.indexOf("%") === -1 && options.y.toLowerCase().indexOf("px") === -1 && options.y.toLowerCase().indexOf("deg") === -1)) options.y = parseInt(options.y, 10) + "px"; var trans = "translate" + translateOpen + (options.x) + "," + (options.y) + translateClose + " scale(" + parseFloat(options.scale) + ") rotate(" + options.rotateX + ")"; if (!$.os.opera) trans += " rotateY(" + options.rotateY + ")"; trans += " skew(" + options.skewX + "," + options.skewY + ")"; this.el.style[$.feat.cssPrefix + "Transform"] = trans; this.el.style[$.feat.cssPrefix + "BackfaceVisibility"] = "hidden"; var properties = $.feat.cssPrefix + "Transform"; if (options.opacity !== undefined) { this.el.style.opacity = options.opacity; properties += ", opacity"; } if (options.width) { this.el.style.width = options.width; properties = "all"; } if (options.height) { this.el.style.height = options.height; properties = "all"; } this.el.style[$.feat.cssPrefix + "TransitionProperty"] = "all"; if (("" + options.time).indexOf("s") === -1) { scale = "ms"; time = options.time + scale; } else if (options.time.indexOf("ms") !== -1) { scale = "ms"; time = options.time; } else { scale = "s"; time = options.time + scale; } if (options.delay) { this.el.style[$.feat.cssPrefix + "TransitionDelay"] = options.delay; } this.el.style[$.feat.cssPrefix + "TransitionDuration"] = time; this.el.style[$.feat.cssPrefix + "TransitionTimingFunction"] = options.timingFunction; this.el.style[$.feat.cssPrefix + "TransformOrigin"] = options.origin; } //add callback to the stack this.callbacksStack.push({ complete: options.complete, success: options.success, failure: options.failure }); this.countStack++; var that = this, duration; var style = window.getComputedStyle(this.el); if (classMode) { //get the duration duration = style[$.feat.cssPrefix + "TransitionDuration"]; timeNum = numOnly(duration); options.time = timeNum; if (duration.indexOf("ms") !== -1) { scale = "ms"; } else { scale = "s"; options.time *= 1000; } } //finish asap if (timeNum === 0 || (scale === "ms" && timeNum < 5) || style.display === "none") { //the duration is nearly 0 or the element is not displayed, finish immediatly $.asap($.proxy(this.finishAnimation, this, [false])); //this.finishAnimation(); //set transitionend event } else { //setup the event normally this.activeEvent = function(event) { clearTimeout(that.timeout); that.finishAnimation(event); that.el.removeEventListener(transitionEnd, that.activeEvent, false); }; that.timeout = setTimeout(this.activeEvent, numOnly(options.time) + 50); this.el.addEventListener(transitionEnd, this.activeEvent, false); } }, addCallbackHook: function(callback) { if (callback) this.callbacksStack.push(callback); this.countStack++; return this.linkFinishedProxy; }, linkFinished: function(canceled) { if (canceled) this.cancel(); else this.finishAnimation(); }, finishAnimation: function(event) { if (event && event.preventDefault) event.preventDefault(); if (!this.isActive) return; this.countStack--; if (this.countStack === 0) this.fireCallbacks(false); }, fireCallbacks: function(canceled) { this.clearEvents(); //keep callbacks after cleanup // (if any of the callbacks overrides this object, callbacks will keep on fire as expected) var callbacks = this.callbacksStack; //cleanup this.cleanup(); //fire all callbacks for (var i = 0; i < callbacks.length; i++) { var complete = callbacks[i].complete; var success = callbacks[i].success; var failure = callbacks[i].failure; //fire callbacks if (typeof(complete) === "function") complete(canceled); //success/failure if (canceled && typeof(failure) === "function") failure(); else if (typeof(success) === "function") success(); } }, cancel: function() { if (!this.isActive) return; this.fireCallbacks(true); //fire failure callbacks }, cleanup: function() { this.callbacksStack = []; this.isActive = false; this.countStack = 0; }, clearEvents: function() { if (this.activeEvent) { this.el.removeEventListener(transitionEnd, this.activeEvent, false); } this.activeEvent = null; }, link: function(elID, opts) { var callbacks = { complete: opts.complete, success: opts.success, failure: opts.failure }; opts.complete = this.addCallbackHook(callbacks); opts.success = null; opts.failure = null; //run the animation with the replaced callbacks getCSS3Animate(elID, opts); //set the old callback back in the obj to avoid strange stuff opts.complete = callbacks.complete; opts.success = callbacks.success; opts.failure = callbacks.failure; return this; } }; return css3Animate; })(); css3Animate.queue = function() { return { elements: [], push: function(el) { this.elements.push(el); }, pop: function() { return this.elements.pop(); }, run: function() { var that = this; if (this.elements.length === 0) return; if (typeof(this.elements[0]) === "function") { var func = this.shift(); func(); } if (this.elements.length === 0) return; var params = this.shift(); if (this.elements.length > 0) { params.complete = function(canceled) { if (!canceled) that.run(); }; } css3Animate(document.getElementById(params.id), params); }, shift: function() { return this.elements.shift(); } }; }; })(af); /** * @license MIT - https://github.com/darius/requestAnimationFrame/commit/4f27a5a21902a883330da4663bea953b2f96cb15#diff-9879d6db96fd29134fc802214163b95a http://paulirish.com/2011/requestanimationframe-for-smart-animating/ http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel MIT license Adapted from https://gist.github.com/paulirish/1579671 which derived from http://paulirish.com/2011/requestanimationframe-for-smart-animating/ http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating requestAnimationFrame polyfill by Erik Möller. Fixes from Paul Irish, Tino Zijdel, Andrew Mao, Klemen Slavič, Darius Bacon */ if (!Date.now) Date.now = function() { "use strict"; return new Date().getTime(); }; (function() { "use strict"; var vendors = ["webkit", "moz","ms"]; for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) { var vp = vendors[i]; window.requestAnimationFrame = window[vp+"RequestAnimationFrame"]; window.cancelAnimationFrame = (window[vp+"CancelAnimationFrame"] || window[vp+"CancelRequestAnimationFrame"]); } if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) || !window.requestAnimationFrame || !window.cancelAnimationFrame) { var lastTime = 0; window.requestAnimationFrame = function(callback) { var now = Date.now(); var nextTime = Math.max(lastTime + 16, now); return setTimeout(function() { callback(lastTime = nextTime); }, nextTime - now); }; window.cancelAnimationFrame = clearTimeout; } }()); /** * af.animate - an experimental animation library that uses matrices and requestAnimationFrame * Only supports x/y now and is used by the scroller library * Copyright 2013 - Intel */ (function($) { "use strict"; var cache = []; var objId = function(obj) { if (!obj.afAnimateId) obj.afAnimateId = $.uuid(); return obj.afAnimateId; }; var getEl = function(elID) { if (typeof elID === "string" || elID instanceof String) { return document.getElementById(elID); } else if ($.is$(elID)) { return elID[0]; } else { return elID; } }; var getAnimate = function(obj, options) { var tmp, id, el = getEl(obj); //first one id = objId(el); if (cache[id]) { if(options) cache[id].animate(options); tmp = cache[id]; } else { tmp = Animate(el, options); cache[id] = tmp; } return tmp; }; $.fn.animate = function(opts) { var tmp = getAnimate(this[0], opts); return tmp; }; var Animate = function(elID, options) { if (!(this instanceof Animate)) return new Animate(elID, options); this.el=elID; //start doing stuff if (!this.el) return; if(options) this.animate(options); var that = this; af(this.el).bind("destroy", function() { var id = that.el.afAnimateId; if (cache[id]) delete cache[id]; }); }; Animate.prototype = { animationTimer:null, isAnimating:false, startX:0, startY:0, runTime:0, endX:0, endY:0, currX:0, currY:0, animationStartTime:0, pauseTime:0, completeCB:null, easingFn:"linear", animateOpts:{}, updateCb:null, animate: function(options) { var that=this; if(that.isAnimating) return; that.isAnimating=true; window.cancelAnimationFrame(that.animationTimer); if (!options) { options={ x:0, y:0, duration:0 }; } this.easingFn=options.easing||"linear"; this.completeCB=options.complete||null; this.updateCB=options.update||null; this.runTime=numOnly(options.duration); options.complete&&(delete options.complete); this.animateOpts=options; this.startTime=Date.now(); this.startMatrix=$.getCssMatrix(this.el); if(this.runTime===0) this.doAnimate(); }, start:function(){ this.doAnimate(); }, doAnimate:function(){ var now = Date.now(), nextX, nextY,easeStep,that=this; if (this.runTime===0||(now >= this.startTime + this.runTime)) { that.setPosition(this.animateOpts.x,this.animateOpts.y); that.isAnimating = false; if(this.updateCB) this.updateCB({x:this.animateOpts.x,y:this.animateOpts.y}); if(this.completeCB) this.completeCB(); return; } now = (now - this.startTime) / this.runTime; now=now>1?1:now; easeStep = tweens[this.easingFn](now); nextX = (this.animateOpts.x - this.startMatrix.e) * easeStep + this.startMatrix.e; nextY = (this.animateOpts.y - this.startMatrix.f) * easeStep + this.startMatrix.f; this.setPosition(nextX,nextY); if(this.updateCB) this.updateCB({x:nextX,y:nextY}); if (this.isAnimating) this.animationTimer = window.requestAnimationFrame(function(){that.doAnimate();}); }, setPosition:function(x,y){ this.el.style[$.feat.cssPrefix+"Transform"]="matrix3d( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, "+x+", "+y+", 0, 1 )"; this.currX=x; this.currY=y; }, stop:function(){ this.isAnimating=false; window.cancelAnimationFrame(this.animationTimer); this.pauseTime=Date.now()-this.startTime; }, resume:function(){ this.isAnimating=true; this.startTime=Date.now()-this.pauseTime; this.doAnimate(); } }; var tweens = { linear:function (k) { return k; }, easeOutSine:function (k) { return Math.sin(k * Math.PI / 2 ); } }; })(af); /** * af.passwordBox - password box replacement for html5 mobile apps on android due to a bug with CSS3 translate3d * @copyright 2011 - Intel */ /* global af*/ (function ($) { "use strict"; $.passwordBox = function () { return new passwordBox(); }; var passwordBox = function () { this.oldPasswords = {}; }; passwordBox.prototype = { showPasswordPlainText: false, getOldPasswords: function (elID) { // if ($.os.android == false) return; - iOS users seem to want this too, so we'll let everyone join the party var container = elID && document.getElementById(elID) ? document.getElementById(elID) : document; if (!container) { window.alert("Could not find container element for passwordBox " + elID); return; } var sels = container.getElementsByTagName("input"); for (var i = 0; i < sels.length; i++) { if (sels[i].type !== "password") continue; if($.os.webkit){ sels[i].type = "text"; $(sels[i]).vendorCss("TextSecurity","disc"); } } }, changePasswordVisiblity: function (what, id) { what = parseInt(what,10); var theEl = document.getElementById(id); if (what === 1) { //show $(theEl).vendorCss("TextSecurity","none"); } else { $(theEl).vendorCss("TextSecurity","disc"); } if(!$.os.webkit) { if(what === 1) theEl.type="text"; else theEl.type="password"; } theEl = null; } }; })(af); /** * af.scroller * created by Intel with modifications by Carlos Ouro @ Badoo and Intel * Supports iOS native touch scrolling * Optimizations and bug improvements by Intel * @copyright Intel */ /* global numOnly*/ (function ($) { "use strict"; var HIDE_REFRESH_TIME = 325; // hide animation of pull2ref duration in ms var cache = []; var objId = function (obj) { if (!obj.afScrollerId) obj.afScrollerId = $.uuid(); return obj.afScrollerId; }; $.fn.scroller = function (opts) { var tmp, id; for (var i = 0; i < this.length; i++) { //cache system id = objId(this[i]); if (!cache[id]) { if (!opts) opts = {}; if (!$.feat.nativeTouchScroll) opts.useJsScroll = true; tmp = scroller(this[i], opts); cache[id] = tmp; } else { tmp = cache[id]; } } return this.length === 1 ? tmp : this; }; var boundTouchLayer = false; function checkConsistency(id) { if (!cache[id].el) { delete cache[id]; return false; } return true; } function bindTouchLayer() { //use a single bind for all scrollers if ($.os.android && !$.os.chrome && $.os.webkit) { var androidFixOn = false; //connect to touchLayer to detect editMode $.bind($.touchLayer, ["cancel-enter-edit", "exit-edit"], function () { if (androidFixOn) { androidFixOn = false; //dehactivate on scroller for (var el in cache) if (checkConsistency(el) && cache[el].androidFormsMode) cache[el].stopFormsMode(); } }); } boundTouchLayer = true; } var scroller = (function () { var jsScroller, nativeScroller; //initialize and js/native mode selector var scroller = function (elID, opts) { var el; if (!boundTouchLayer && $.touchLayer && $.isObject($.touchLayer)) bindTouchLayer(); else if (!$.touchLayer || !$.isObject($.touchLayer)) $.touchLayer = {}; if (typeof elID === "string" || elID instanceof String) { el = document.getElementById(elID); } else { el = elID; } if (!el) { window.alert("Could not find element for scroller " + elID); return; } var checkClassEl=$(el); if(opts.hasParent) checkClassEl=checkClassEl.parent(); if(checkClassEl.hasClass("x-scroll")) opts.horizontalScroll=true; if(checkClassEl.hasClass("y-scroll")) opts.verticalScroll=true; if ($.os.desktop) return new scrollerCore(el, opts); else if (opts.useJsScroll) return new jsScroller(el, opts); return new nativeScroller(el, opts); }; //parent abstract class (common functionality) var scrollerCore = function (el, opts) { this.el = el; this.afEl = $(this.el); for (var j in opts) { this[j] = opts[j]; } }; scrollerCore.prototype = { //core default properties refresh: false, refreshContent: "Pull to Refresh", refreshHangTimeout: 2000, refreshHeight: 60, refreshElement: null, refreshCancelCB: null, refreshRunning: false, scrollTop: 0, scrollLeft: 0, preventHideRefresh: true, verticalScroll: true, horizontalScroll: false, refreshTriggered: false, moved: false, eventsActive: false, rememberEventsActive: false, scrollingLocked: false, autoEnable: true, blockFormsFix: false, loggedPcentY: 0, loggedPcentX: 0, infinite: false, infiniteEndCheck: false, infiniteTriggered: false, scrollSkip: false, scrollTopInterval: null, scrollLeftInterval: null, bubbles:true, lockBounce:false, initScrollProgress:false, _scrollTo: function (params, time) { time = parseInt(time, 10); if (time === 0 || isNaN(time)) { this.el.scrollTop = Math.abs(params.y); this.el.scrollLeft = Math.abs(params.x); return; } var singleTick = 10; var distPerTick = (this.el.scrollTop - params.y) / Math.ceil(time / singleTick); var distLPerTick = (this.el.scrollLeft - params.x) / Math.ceil(time / singleTick); var self = this; var toRunY = Math.ceil(this.el.scrollTop - params.y) / distPerTick; var toRunX = Math.ceil(this.el.scrollLeft - params.x) / distPerTick; var xRun =0, yRun = 0; self.scrollTopInterval = window.setInterval(function () { self.el.scrollTop -= distPerTick; yRun++; if (yRun >= toRunY) { self.el.scrollTop = params.y; clearInterval(self.scrollTopInterval); } }, singleTick); self.scrollLeftInterval = window.setInterval(function () { self.el.scrollLeft -= distLPerTick; xRun++; if (xRun >= toRunX) { self.el.scrollLeft = params.x; clearInterval(self.scrollLeftInterval); } }, singleTick); }, enable: function () {}, disable: function () {}, hideScrollbars: function () {}, addPullToRefresh: function () {}, /** * We do step animations for "native" - iOS is acceptable and desktop browsers are fine * instead of css3 */ _scrollToTop: function (time) { this._scrollTo({ x: 0, y: 0 }, time); }, _scrollToBottom: function (time) { this._scrollTo({ x: 0, y: this.el.scrollHeight - this.el.offsetHeight }, time); }, scrollToBottom: function (time) { return this._scrollToBottom(time); }, scrollToTop: function (time) { return this._scrollToTop(time); }, //methods init: function (el, opts) { this.el = el; this.afEl = $(this.el); this.defaultProperties(); for (var j in opts) { this[j] = opts[j]; } //assign self destruct var that = this; var orientationChangeProxy = function (e) { //no need to readjust if disabled... if (that.eventsActive && !$.feat.nativeTouchScroll&&(!$.ui || ($.ui.activeDiv === that.container)) ) { that.adjustScroll(); } }; this.afEl.bind("destroy", function () { that.disable(true); //with destroy notice var id = that.el.afScrollerId; if (cache[id]) delete cache[id]; $.unbind($.touchLayer, "orientationchange-reshape", orientationChangeProxy); }); $.bind($.touchLayer, "orientationchange-reshape", orientationChangeProxy); $(window).bind("resize", orientationChangeProxy); }, needsFormsFix: function (focusEl) { return this.useJsScroll && this.isEnabled() && this.el.style.display !== "none" && $(focusEl).closest(this.afEl).size() > 0; }, handleEvent: function (e) { if (!this.scrollingLocked) { switch (e.type) { case "touchstart": clearInterval(this.scrollTopInterval); this.preventHideRefresh = !this.refreshRunning; // if it's not running why prevent it xD this.moved = false; this.onTouchStart(e); if(!this.bubbles) e.stopPropagation(); break; case "touchmove": this.onTouchMove(e); if(!this.bubbles) e.stopPropagation(); break; case "touchend": this.onTouchEnd(e); if(!this.bubbles) e.stopPropagation(); break; case "scroll": this.onScroll(e); break; } } }, coreAddPullToRefresh: function (rEl) { if (rEl) this.refreshElement = rEl; //Add the pull to refresh text. Not optimal but keeps from others overwriting the content and worrying about italics //add the refresh div var afEl; if (this.refreshElement === null) { var orginalEl = document.getElementById(this.container.id + "_pulldown"); if (orginalEl !== null) { afEl = $(orginalEl); } else { afEl = $("<div id='" + this.container.id + "_pulldown' class='afscroll_refresh' style='position:relative;height:60px;text-align:center;line-height:60px;font-weight:bold;'>" + this.refreshContent + "</div>"); } } else { afEl = $(this.refreshElement); } var el = afEl.get(0); this.refreshContainer = $("<div style='overflow:hidden;height:0;width:100%;display:none;background:inherit;-webkit-backface-visibility: hidden !important;'></div>"); $(this.el).prepend(this.refreshContainer.prepend(el)); this.refreshContainer = this.refreshContainer[0]; }, fireRefreshRelease: function (triggered) { if (!this.refresh || !triggered) return; this.setRefreshContent("Refreshing..."); var autoCancel = $.trigger(this, "refresh-release", [triggered]) !== false; this.preventHideRefresh = false; this.refreshRunning = true; if (autoCancel) { var that = this; if (this.refreshHangTimeout > 0) this.refreshCancelCB = setTimeout(function () { that.hideRefresh(); }, this.refreshHangTimeout); } }, setRefreshContent: function (content) { $(this.container).find(".afscroll_refresh").html(content); }, lock: function () { if (this.scrollingLocked) return; this.scrollingLocked = true; this.rememberEventsActive = this.eventsActive; if (this.eventsActive) { this.disable(); } }, unlock: function () { if (!this.scrollingLocked) return; this.scrollingLocked = false; if (this.rememberEventsActive) { this.enable(); } }, scrollToItem: function (el, where) { //TODO: add functionality for x position if (!$.is$(el)) el = $(el); var newTop,itemPos,panelTop,itemTop; if (where === "bottom") { itemPos = el.offset(); newTop = itemPos.top - this.afEl.offset().bottom + itemPos.height; newTop += 4; //add a small space } else { itemTop = el.offset().top; newTop = itemTop - document.body.scrollTop; panelTop = this.afEl.offset().top; if (document.body.scrollTop < panelTop) { newTop -= panelTop; } newTop -= 4; //add a small space } this.scrollBy({ y: newTop, x: 0 }, 0); }, setPaddings: function (top, bottom) { var el = $(this.el); var curTop = numOnly(el.css("paddingTop")); el.css("paddingTop", top + "px").css("paddingBottom", bottom + "px"); //don't let padding mess with scroll this.scrollBy({ y: top - curTop, x: 0 }); }, //freak of mathematics, but for our cases it works divide: function (a, b) { return b !== 0 ? a / b : 0; }, isEnabled: function () { return this.eventsActive; }, addInfinite: function () { this.infinite = true; }, clearInfinite: function () { this.infiniteTriggered = false; this.scrollSkip = true; }, scrollTo:function (pos, time) { return this._scrollTo(pos, time); }, updateP2rHackPosition:function(){} }; //extend to jsScroller and nativeScroller (constructs) jsScroller = function (el, opts) { this.init(el, opts); if(opts.hasParent) this.container = this.el.parentNode; else { //copy/etc var $div=$.create("div",{}); $div.append($(this.el).contents()); $(this.el).append($div); this.container=this.el; this.el=$div.get(0); } this.container.afScrollerId = el.afScrollerId; this.afEl = $(this.container); if (this.container.style.overflow !== "hidden") this.container.style.overflow = "hidden"; this.addPullToRefresh(null, true); if(opts.autoEnable) this.autoEnable=opts.autoEnable; if (this.autoEnable) this.enable(true); var scrollDiv; //create vertical scroll if (this.verticalScroll && this.verticalScroll === true && this.scrollBars === true) { scrollDiv = createScrollBar(5, 20); scrollDiv.style.top = "0px"; if (this.vScrollCSS) scrollDiv.className = this.vScrollCSS; //scrollDiv.style.opacity = "0"; scrollDiv.style.display="none"; this.container.appendChild(scrollDiv); this.vscrollBar = scrollDiv; scrollDiv = null; } //create horizontal scroll if (this.horizontalScroll && this.horizontalScroll === true && this.scrollBars === true) { scrollDiv = createScrollBar(20, 5); scrollDiv.style.bottom = "0px"; if (this.hScrollCSS) scrollDiv.className = this.hScrollCSS; //scrollDiv.style.opacity = "0"; scrollDiv.style.display="none"; this.container.appendChild(scrollDiv); this.hscrollBar = scrollDiv; scrollDiv = null; } if (this.horizontalScroll) this.el.style.cssFloat = "left"; this.el.hasScroller = true; }; nativeScroller = function (el, opts) { if(opts.nativeParent){ el=el.parentNode; } this.init(el, opts); var $el = $(el); if (opts.replaceParent === true) { var oldParent = $el.parent(); $el.css("height", oldParent.height()).css("width", oldParent.width()); $el.insertBefore($el.parent()); //$el.parent().parent().append($el); oldParent.remove(); } this.container = this.el; $el.css("-webkit-overflow-scrolling", "touch"); if(opts.autoEnable) this.autoEnable=opts.autoEnable; if(this.autoEnable) this.enable(); }; nativeScroller.prototype = new scrollerCore(); jsScroller.prototype = new scrollerCore(); ///Native scroller nativeScroller.prototype.defaultProperties = function () { this.refreshContainer = null; this.dY = this.cY = 0; this.dX = this.cX = 0; this.cancelPropagation = false; this.loggedPcentY = 0; this.loggedPcentX = 0; this.xReset=0; this.yReset=0; var that = this; this.adjustScrollOverflowProxy = function () { that.afEl.css("overflow", "auto"); that.afEl.parent().css("overflow","hidden"); }; }; nativeScroller.prototype.enable = function (firstExecution) { if (this.eventsActive) return; this.eventsActive = true; //unlock overflow this.el.style.overflow = "auto"; //this.el.parentNode.style.overflow="hidden"; //set current scroll if (!firstExecution) this.adjustScroll(); //set events this.el.addEventListener("touchstart", this, false); this.el.addEventListener("scroll", this, false); this.updateP2rHackPosition(); }; nativeScroller.prototype.disable = function (destroy) { if (!this.eventsActive) return; //log current scroll this.logPos(this.el.scrollLeft, this.el.scrollTop); //lock overflow if (!destroy&&!$.ui) { this.el.style.overflow = "hidden"; } //remove events this.el.removeEventListener("touchstart", this, false); this.el.removeEventListener("touchmove", this, false); this.el.removeEventListener("touchend", this, false); this.el.removeEventListener("scroll", this, false); this.eventsActive = false; }; nativeScroller.prototype.addPullToRefresh = function (el, leaveRefresh) { if (!leaveRefresh) this.refresh = true; if (this.refresh && this.refresh === true) { this.coreAddPullToRefresh(el); this.refreshContainer.style.position = "absolute"; this.refreshContainer.style.top = "-60px"; this.refreshContainer.style.height = "60px"; this.refreshContainer.style.display = "block"; this.updateP2rHackPosition(); } }; nativeScroller.prototype.updateP2rHackPosition=function(){ if(!this.refresh) return $(this.el).find(".p2rhack").remove(); var el=$(this.el).find(".p2rhack"); if(el.length === 0){ $(this.el).append("<div class='p2rhack' style='position:absolute;width:1px;height:1px;opacity:0;background:transparent;z-index:-1;-webkit-transform:translate3d(-1px,0,0);'></div>"); el=$(this.el).find(".p2rhack"); } el.css("top",this.el.scrollHeight+this.refreshHeight+1+"px"); }; nativeScroller.prototype.onTouchStart = function (e) { this.lastScrollInfo= { top:0 }; this.xReset=this.yReset=0; if(this.verticalScroll){ if(this.el.scrollTop===0&&this.refresh){ this.el.scrollTop=1; this.yReset=-1; } if(this.el.scrollTop===(this.el.scrollHeight - this.el.clientHeight)&&this.infinite){ this.el.scrollTop-=1; this.yReset=1; } } if(this.horizontalScroll){ if(this.el.scrollLeft===0){ this.el.scrollLeft=1; this.xReset=-1; } if(this.el.scrollLeft===(this.el.scrollWidth-this.el.clientWidth)){ this.el.scrollLeft-=1; this.xReset=1; } } if (this.refreshCancelCB) clearTimeout(this.refreshCancelCB); //get refresh ready if(this.refresh) this.el.addEventListener("touchend",this,false); this.el.addEventListener("touchmove", this,false); this.dY = e.touches[0].pageY; this.dX = e.touches[0].pageX; this.startTop=this.el.scrollTop; this.startLeft=this.el.scrollLeft; if (this.refresh || this.infinite) { if (this.refresh && this.dY < 0) { this.showRefresh(); } } }; nativeScroller.prototype.onTouchMove = function (e) { var newcY = e.touches[0].pageY - this.dY; var newcX = e.touches[0].pageX - this.dX; //var scorllTop var atTop=(this.el.scrollHeight-this.el.scrollTop)===this.el.clientHeight&&newcY<0; var atRight=(this.el.scrollWidth-this.el.scrollLeft)===this.el.clientWidth&&newcX<0; var preventDefault=e.target.tagName.toLowerCase()!=="input"; if(this.verticalScroll){ if(this.startTop===0&&this.el.scrollTop===0&&newcY>0) preventDefault&&e.preventDefault(); } if(this.horizontalScroll&&this.startTop===0&&this.el.scrollLeft===0&&newcX>0){ preventDefault&&e.preventDefault(); } if(this.verticalScroll&&atTop){ preventDefault&&e.preventDefault(); } if(this.horizontalScroll&&atRight){ preventDefault&&e.preventDefault(); } if (!this.moved) { $.trigger(this, "scrollstart", [this.el,{x:newcX,y:newcY}]); $.trigger($.touchLayer, "scrollst