diff --git a/Upload/admin/jscripts/iconselect/arrow.png b/Upload/admin/jscripts/iconselect/arrow.png new file mode 100644 index 0000000..4917ceb Binary files /dev/null and b/Upload/admin/jscripts/iconselect/arrow.png differ diff --git a/Upload/admin/jscripts/iconselect/iconselect.css b/Upload/admin/jscripts/iconselect/iconselect.css new file mode 100644 index 0000000..990a574 --- /dev/null +++ b/Upload/admin/jscripts/iconselect/iconselect.css @@ -0,0 +1,131 @@ +/* +To change this license header, choose License Headers in Project Properties. +To change this template file, choose Tools | Templates +and open the template in the editor. +*/ +/* + Created on : Nov 28, 2013, 7:09:35 AM + Author : bugraozden +*/ + +.icon-select{ + width:0px; + } + + .icon-select .selected-box { + + position: relative; + margin: 0px; + padding: 0px; + width: 70px; /* sil */ + height: 60px; /* sil */ + border: 1px solid #999999; + + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + background-color: white; + + z-index: 1000; + + } + + .icon-select .selected-box:hover { + + position: relative; + margin: 0px; + padding: 0px; + width: 70px; /* sil */ + height: 60px; /* sil */ + border: 1px solid #000000; + background-color: #FFFFFF; + + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + + } + + .icon-select .selected-icon { + + position: absolute; + margin: 0px; + padding: 0px; + top:5px; + left:5px; + width: 48px; /* sil */ + height: 48px; /* sil */ + + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + + } + + .icon-select .component-icon{ + position: absolute; + bottom:5px; + right:4px; + } + + .icon-select .box { + + position: absolute; + top:0px; + left:71px; + margin: 0px; + padding: 0px; + width: 170px; /* sil */ + height: 170px; /* sil */ + border: 1px solid #EEEEEE; + background-color: #EEEEEE; + + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + + + overflow:auto; + /* + -webkit-overflow-scrolling: touch; + */ + + } + + .icon-select .icon { + position: relative; + margin: 5px 0px 0px 5px; + padding: 0px; + width: 48px; /* sil */ + height: 48px; /* sil */ + border: 1px solid #CCCCCC; + background-color: #FFFFFF; + + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + + overflow:hidden; + float: left; + } + + .icon-select .icon:hover { + border: 1px solid #000000; + } + + .icon-select .icon.selected { + position: relative; + margin: 5px 0px 0px 5px; + padding: 0px; + width: 48px; /* sil */ + height: 48px; /* sil */ + border: 1px solid #EEEEEE; + background-color: #EEEEEE; + + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + + overflow:hidden; + float: left; +} \ No newline at end of file diff --git a/Upload/admin/jscripts/iconselect/iconselect.js b/Upload/admin/jscripts/iconselect/iconselect.js new file mode 100644 index 0000000..ba789d2 --- /dev/null +++ b/Upload/admin/jscripts/iconselect/iconselect.js @@ -0,0 +1,320 @@ + +/** + * + * Created with NetBeans IDE + * + * Code : Icon Select JS + * Version : 1.0 + * + * User : Bugra OZDEN + * Site : http://www.bugraozden.com + * Mail : bugra.ozden@gmail.com + * + * Date : 10/30/13 + * Time : 01:10 PM + * + */ + +IconSelect.DEFAULT = {}; +IconSelect.DEFAULT.SELECTED_ICON_WIDTH = 48; +IconSelect.DEFAULT.SELECTED_ICON_HEIGHT = 48; +IconSelect.DEFAULT.SELECTED_BOX_PADDING = 1; +IconSelect.DEFAULT.SELECTED_BOX_PADDING_RIGHT = 12; +IconSelect.DEFAULT.ICONS_WIDTH = 32; +IconSelect.DEFAULT.ICONS_HEIGHT = 32; +IconSelect.DEFAULT.BOX_ICON_SPACE = 1; +IconSelect.DEFAULT.HORIZONTAL_ICON_NUMBER = 3; +IconSelect.DEFAULT.VECTORAL_ICON_NUMBER = 3; + +IconSelect.COMPONENT_ICON_FILE_PATH = "images/control/icon-select/arrow.png"; + +function IconSelect($$elementID, $$parameters) { + + var _icons = []; + var _selectedIndex = -1; + var _boxScroll; + + var _default = IconSelect.DEFAULT; + + function _init() { + + //parametreler boş gelirse + if(!$$parameters) $$parameters = {}; + //En üst elementi seç + if(_View.setIconSelectElement($$elementID)){ + + //set parameters + $$parameters = _Model.checkParameters($$parameters); + //create UI + var ui = _View.createUI($$parameters, $$elementID); + //basıldığında göster/gizle + _View.iconSelectElement.onclick = function(){ + _View.showBox(); + }; + + //Başlangıçta gizle + _View.showBox(false); + + //Nesneye basıldığında gizlemeyi iptal et. + _View.iconSelectElement.addEventListener('click', function($event){ + $event.stopPropagation(); + }); + + //dışarı basıldığında gizle. + window.addEventListener('click', function(){ + _View.showBox(false); + }); + + }else{ + alert("Element not found."); + } + + } + + //Tüm iconları yeniden yükle. + this.refresh = function($icons, $selected){ + if (typeof $selected === 'undefined') { + $selected = 0; + } + _icons = []; + + _View.clearIcons(); + + var setSelectedIndex = this.setSelectedIndex; + + for(var i = 0; i < $icons.length; i++){ + $icons[i].element = _View.createIcon($icons[i].iconFilePath, $icons[i].iconValue, i, $$parameters); + $icons[i].element.onclick = function(){setSelectedIndex(this.childNodes[0].getAttribute('icon-index'));}; + _icons.push($icons[i]); + + } + + var horizontalIconNumber = Math.round(($icons.length) / $$parameters.vectoralIconNumber); + + _View.boxElement.style.height = (($$parameters.iconsHeight + 2) * horizontalIconNumber) + ((horizontalIconNumber + 1) * $$parameters.boxIconSpace) + 'px'; + this.setSelectedIndex($selected); + + }; + + //icon listesini al. + this.getIcons = function(){ return _icons; }; + + //iconu seçili hale gelir. + this.setSelectedIndex = function($index){ + + var icon; + + if(_icons.length > $index) + icon = _icons[$index]; + + if(icon){ + //eski icondan seçilme özelliğini kaldır. + if(_selectedIndex != -1) _icons[_selectedIndex].element.setAttribute('class','icon'); + _selectedIndex = $index; + _View.selectedIconImgElement.setAttribute('src', icon.iconFilePath); + if(_selectedIndex != -1) _icons[_selectedIndex].element.setAttribute('class','icon selected'); + } + + _View.iconSelectElement.dispatchEvent(new Event('changed')); + + //_View.showBox(false); + + }; + + this.getSelectedIndex = function(){ return _selectedIndex; }; + this.getSelectedValue = function(){ return _icons[_selectedIndex].iconValue }; + this.getSelectedFilePath = function(){ return _icons[_selectedIndex].iconFilePath }; + + + + //### VIEW CLASS ### + + function _View(){} + + _View.iconSelectElement; + _View.boxElement; + _View.boxScrollElement; + _View.selectedIconImgElement; + _View.selectedIconElement; + + _View.showBox = function($isShown){ + + if($isShown == null) { + $isShown = (_View.boxElement.style.display == "none") ? true : false; + } + + if($isShown) { + _View.boxElement.style.display = "block"; + _View.boxScrollElement.style.display = "block"; + _boxScroll = (_boxScroll) ? _boxScroll : new iScroll($$elementID + "-box-scroll"); + }else{ + _View.boxElement.style.display = "none"; + _View.boxScrollElement.style.display = "none"; + } + + _View.boxElement.style.display = ($isShown) ? "block" : "none"; + + + + }; + + _View.setIconSelectElement = function($elementID){ + _View.iconSelectElement = document.getElementById($elementID); + return _View.iconSelectElement; + }; + + _View.clearUI = function(){ + _View.iconSelectElement.innerHTML = ""; + }; + + _View.clearIcons = function(){ + _View.boxElement.innerHTML = ""; + }; + + _View.createUI = function($parameters){ + + /* HTML MODEL + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + */ + + _View.clearUI(); + + _View.iconSelectElement.setAttribute('class', 'icon-select'); + + var selectedBoxElement = document.createElement('div'); + selectedBoxElement.setAttribute('class' ,'selected-box'); + + var selectedIconElement = document.createElement('div'); + selectedIconElement.setAttribute('class' ,'selected-icon'); + + _View.selectedIconImgElement = document.createElement('img'); + _View.selectedIconImgElement.setAttribute('src', ''); + selectedIconElement.appendChild(_View.selectedIconImgElement); + + var componentIconElement = document.createElement('div'); + componentIconElement.setAttribute('class', 'component-icon'); + + var componentIconImgElement = document.createElement('img'); + componentIconImgElement.setAttribute('src', $parameters.arrowImagePath ); + componentIconElement.appendChild(componentIconImgElement); + + _View.boxScrollElement = document.createElement('div'); + _View.boxScrollElement.setAttribute('id',$$elementID + "-box-scroll"); + _View.boxScrollElement.setAttribute('class', 'box'); + + _View.boxElement = document.createElement('div'); + + //_View.boxElement.setAttribute('class', 'box'); + _View.boxScrollElement.appendChild(_View.boxElement); + + _View.selectedIconImgElement.style.width = $parameters.selectedIconWidth + 'px'; + _View.selectedIconImgElement.style.height = $parameters.selectedIconHeight + 'px'; + selectedIconElement.style.minWidth = $parameters.selectedIconWidth + 'px'; + selectedIconElement.style.minHeight = $parameters.selectedIconHeight + 'px'; + selectedBoxElement.style.width = $parameters.selectedIconWidth + $parameters.selectedBoxPadding + $parameters.selectedBoxPaddingRight + 'px'; + selectedBoxElement.style.height = $parameters.selectedIconHeight + ($parameters.selectedBoxPadding * 2) + 'px'; + selectedIconElement.style.top = $parameters.selectedBoxPadding + 'px'; + selectedIconElement.style.left = $parameters.selectedBoxPadding + 'px'; + componentIconElement.style.bottom = 4 + $parameters.selectedBoxPadding + 'px'; + + _View.boxScrollElement.style.left = parseInt(selectedBoxElement.style.width) + 1 + 'px'; + + _View.boxScrollElement.style.width = (($parameters.iconsWidth + 2) * $parameters.vectoralIconNumber) + (($parameters.vectoralIconNumber + 1) * $parameters.boxIconSpace) + 'px'; + _View.boxScrollElement.style.height = (($parameters.iconsHeight + 2) * $parameters.horizontalIconNumber) + (($parameters.horizontalIconNumber + 1) * $parameters.boxIconSpace) + 'px'; + + _View.boxElement.style.left = _View.boxScrollElement.style.left + 'px'; + _View.boxElement.style.width = _View.boxScrollElement.style.width + 'px'; + + _View.iconSelectElement.appendChild(selectedBoxElement); + selectedBoxElement.appendChild(selectedIconElement); + selectedBoxElement.appendChild(componentIconElement); + selectedBoxElement.appendChild(_View.boxScrollElement); + + + var results = {}; + results['iconSelectElement'] = _View.iconSelectElement; + results['selectedBoxElement'] = selectedBoxElement; + results['selectedIconElement'] = selectedIconElement; + results['selectedIconImgElement'] = _View.selectedIconImgElement; + results['componentIconElement'] = componentIconElement; + results['componentIconImgElement'] = componentIconImgElement; + + return results; + + + //trigger: created ( run setValues ) + + }; + + _View.createIcon = function($iconFilePath, $iconValue, $index, $parameters){ + + /* HTML MODEL + +
+ + */ + + var iconElement = document.createElement('div'); + iconElement.setAttribute('class', 'icon'); + iconElement.style.minWidth = $parameters.iconsWidth + 'px'; + iconElement.style.minHeight = $parameters.iconsHeight + 'px'; + iconElement.style.marginLeft = $parameters.boxIconSpace + 'px'; + iconElement.style.marginTop = $parameters.boxIconSpace + 'px'; + + var iconImgElement = document.createElement('img'); + iconImgElement.setAttribute('src', $iconFilePath); + iconImgElement.setAttribute('icon-value', $iconValue); + iconImgElement.setAttribute('icon-index', $index); + iconImgElement.style.width = $parameters.iconsWidth + 'px'; + iconImgElement.style.height = $parameters.iconsHeight + 'px'; + + iconElement.appendChild(iconImgElement); + _View.boxElement.appendChild(iconElement); + + return iconElement; + + }; + + //### MODEL CLASS ### + + function _Model(){} + + //TODO: params değişkenini kaldır yeni oluştursun. + _Model.checkParameters = function($parameters){ + + $parameters.selectedIconWidth = ($parameters.selectedIconWidth) ? $parameters.selectedIconWidth : _default.SELECTED_ICON_WIDTH; + $parameters.selectedIconHeight = ($parameters.selectedIconHeight) ? $parameters.selectedIconHeight : _default.SELECTED_ICON_HEIGHT; + $parameters.selectedBoxPadding = ($parameters.selectedBoxPadding) ? $parameters.selectedBoxPadding : _default.SELECTED_BOX_PADDING; + $parameters.selectedBoxPaddingRight = ($parameters.selectedBoxPaddingRight) ? $parameters.selectedBoxPaddingRight : _default.SELECTED_BOX_PADDING_RIGHT; + $parameters.iconsWidth = ($parameters.iconsWidth) ? $parameters.iconsWidth : _default.ICONS_WIDTH; + $parameters.iconsHeight = ($parameters.iconsHeight) ? $parameters.iconsHeight : _default.ICONS_HEIGHT; + $parameters.boxIconSpace = ($parameters.boxIconSpace) ? $parameters.boxIconSpace : _default.BOX_ICON_SPACE; + $parameters.vectoralIconNumber = ($parameters.vectoralIconNumber) ? $parameters.vectoralIconNumber : _default.VECTORAL_ICON_NUMBER; + $parameters.horizontalIconNumber = ($parameters.horizontalIconNumber) ? $parameters.horizontalIconNumber : _default.HORIZONTAL_ICON_NUMBER; + + return $parameters; + + }; + + _init(); + +} \ No newline at end of file diff --git a/Upload/admin/jscripts/iconselect/iscroll.js b/Upload/admin/jscripts/iconselect/iscroll.js new file mode 100644 index 0000000..a64db7a --- /dev/null +++ b/Upload/admin/jscripts/iconselect/iscroll.js @@ -0,0 +1,1104 @@ +/*! + * iScroll v4.2.5 ~ Copyright (c) 2012 Matteo Spinelli, http://cubiq.org + * Released under MIT license, http://cubiq.org/license + */ +(function(window, doc){ +var m = Math, + dummyStyle = doc.createElement('div').style, + vendor = (function () { + var vendors = 't,webkitT,MozT,msT,OT'.split(','), + t, + i = 0, + l = vendors.length; + + for ( ; i < l; i++ ) { + t = vendors[i] + 'ransform'; + if ( t in dummyStyle ) { + return vendors[i].substr(0, vendors[i].length - 1); + } + } + + return false; + })(), + cssVendor = vendor ? '-' + vendor.toLowerCase() + '-' : '', + + // Style properties + transform = prefixStyle('transform'), + transitionProperty = prefixStyle('transitionProperty'), + transitionDuration = prefixStyle('transitionDuration'), + transformOrigin = prefixStyle('transformOrigin'), + transitionTimingFunction = prefixStyle('transitionTimingFunction'), + transitionDelay = prefixStyle('transitionDelay'), + + // Browser capabilities + isAndroid = (/android/gi).test(navigator.appVersion), + isIDevice = (/iphone|ipad/gi).test(navigator.appVersion), + isTouchPad = (/hp-tablet/gi).test(navigator.appVersion), + + has3d = prefixStyle('perspective') in dummyStyle, + hasTouch = 'ontouchstart' in window && !isTouchPad, + hasTransform = vendor !== false, + hasTransitionEnd = prefixStyle('transition') in dummyStyle, + + RESIZE_EV = 'onorientationchange' in window ? 'orientationchange' : 'resize', + START_EV = hasTouch ? 'touchstart' : 'mousedown', + MOVE_EV = hasTouch ? 'touchmove' : 'mousemove', + END_EV = hasTouch ? 'touchend' : 'mouseup', + CANCEL_EV = hasTouch ? 'touchcancel' : 'mouseup', + TRNEND_EV = (function () { + if ( vendor === false ) return false; + + var transitionEnd = { + '' : 'transitionend', + 'webkit' : 'webkitTransitionEnd', + 'Moz' : 'transitionend', + 'O' : 'otransitionend', + 'ms' : 'MSTransitionEnd' + }; + + return transitionEnd[vendor]; + })(), + + nextFrame = (function() { + return window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function(callback) { return setTimeout(callback, 1); }; + })(), + cancelFrame = (function () { + return window.cancelRequestAnimationFrame || + window.webkitCancelAnimationFrame || + window.webkitCancelRequestAnimationFrame || + window.mozCancelRequestAnimationFrame || + window.oCancelRequestAnimationFrame || + window.msCancelRequestAnimationFrame || + clearTimeout; + })(), + + // Helpers + translateZ = has3d ? ' translateZ(0)' : '', + + // Constructor + iScroll = function (el, options) { + var that = this, + i; + + that.wrapper = typeof el == 'object' ? el : doc.getElementById(el); + that.wrapper.style.overflow = 'hidden'; + that.scroller = that.wrapper.children[0]; + + // Default options + that.options = { + hScroll: true, + vScroll: true, + x: 0, + y: 0, + bounce: true, + bounceLock: false, + momentum: true, + lockDirection: true, + useTransform: true, + useTransition: false, + topOffset: 0, + checkDOMChanges: false, // Experimental + handleClick: true, + + // Scrollbar + hScrollbar: true, + vScrollbar: true, + fixedScrollbar: isAndroid, + hideScrollbar: isIDevice, + fadeScrollbar: isIDevice && has3d, + scrollbarClass: '', + + // Zoom + zoom: false, + zoomMin: 1, + zoomMax: 4, + doubleTapZoom: 2, + wheelAction: 'scroll', + + // Snap + snap: false, + snapThreshold: 1, + + // Events + onRefresh: null, + onBeforeScrollStart: function (e) { e.preventDefault(); }, + onScrollStart: null, + onBeforeScrollMove: null, + onScrollMove: null, + onBeforeScrollEnd: null, + onScrollEnd: null, + onTouchEnd: null, + onDestroy: null, + onZoomStart: null, + onZoom: null, + onZoomEnd: null + }; + + // User defined options + for (i in options) that.options[i] = options[i]; + + // Set starting position + that.x = that.options.x; + that.y = that.options.y; + + // Normalize options + that.options.useTransform = hasTransform && that.options.useTransform; + that.options.hScrollbar = that.options.hScroll && that.options.hScrollbar; + that.options.vScrollbar = that.options.vScroll && that.options.vScrollbar; + that.options.zoom = that.options.useTransform && that.options.zoom; + that.options.useTransition = hasTransitionEnd && that.options.useTransition; + + // Helpers FIX ANDROID BUG! + // translate3d and scale doesn't work together! + // Ignoring 3d ONLY WHEN YOU SET that.options.zoom + if ( that.options.zoom && isAndroid ){ + translateZ = ''; + } + + // Set some default styles + that.scroller.style[transitionProperty] = that.options.useTransform ? cssVendor + 'transform' : 'top left'; + that.scroller.style[transitionDuration] = '0'; + that.scroller.style[transformOrigin] = '0 0'; + if (that.options.useTransition) that.scroller.style[transitionTimingFunction] = 'cubic-bezier(0.33,0.66,0.66,1)'; + + if (that.options.useTransform) that.scroller.style[transform] = 'translate(' + that.x + 'px,' + that.y + 'px)' + translateZ; + else that.scroller.style.cssText += ';position:absolute;top:' + that.y + 'px;left:' + that.x + 'px'; + + if (that.options.useTransition) that.options.fixedScrollbar = true; + + that.refresh(); + + that._bind(RESIZE_EV, window); + that._bind(START_EV); + if (!hasTouch) { + if (that.options.wheelAction != 'none') { + that._bind('DOMMouseScroll'); + that._bind('mousewheel'); + } + } + + if (that.options.checkDOMChanges) that.checkDOMTime = setInterval(function () { + that._checkDOMChanges(); + }, 500); + }; + +// Prototype +iScroll.prototype = { + enabled: true, + x: 0, + y: 0, + steps: [], + scale: 1, + currPageX: 0, currPageY: 0, + pagesX: [], pagesY: [], + aniTime: null, + wheelZoomCount: 0, + + handleEvent: function (e) { + var that = this; + switch(e.type) { + case START_EV: + if (!hasTouch && e.button !== 0) return; + that._start(e); + break; + case MOVE_EV: that._move(e); break; + case END_EV: + case CANCEL_EV: that._end(e); break; + case RESIZE_EV: that._resize(); break; + case 'DOMMouseScroll': case 'mousewheel': that._wheel(e); break; + case TRNEND_EV: that._transitionEnd(e); break; + } + }, + + _checkDOMChanges: function () { + if (this.moved || this.zoomed || this.animating || + (this.scrollerW == this.scroller.offsetWidth * this.scale && this.scrollerH == this.scroller.offsetHeight * this.scale)) return; + + this.refresh(); + }, + + _scrollbar: function (dir) { + var that = this, + bar; + + if (!that[dir + 'Scrollbar']) { + if (that[dir + 'ScrollbarWrapper']) { + if (hasTransform) that[dir + 'ScrollbarIndicator'].style[transform] = ''; + that[dir + 'ScrollbarWrapper'].parentNode.removeChild(that[dir + 'ScrollbarWrapper']); + that[dir + 'ScrollbarWrapper'] = null; + that[dir + 'ScrollbarIndicator'] = null; + } + + return; + } + + if (!that[dir + 'ScrollbarWrapper']) { + // Create the scrollbar wrapper + bar = doc.createElement('div'); + + if (that.options.scrollbarClass) bar.className = that.options.scrollbarClass + dir.toUpperCase(); + else bar.style.cssText = 'position:absolute;z-index:100;' + (dir == 'h' ? 'height:7px;bottom:1px;left:2px;right:' + (that.vScrollbar ? '7' : '2') + 'px' : 'width:7px;bottom:' + (that.hScrollbar ? '7' : '2') + 'px;top:2px;right:1px'); + + bar.style.cssText += ';pointer-events:none;' + cssVendor + 'transition-property:opacity;' + cssVendor + 'transition-duration:' + (that.options.fadeScrollbar ? '350ms' : '0') + ';overflow:hidden;opacity:' + (that.options.hideScrollbar ? '0' : '1'); + + that.wrapper.appendChild(bar); + that[dir + 'ScrollbarWrapper'] = bar; + + // Create the scrollbar indicator + bar = doc.createElement('div'); + if (!that.options.scrollbarClass) { + bar.style.cssText = 'position:absolute;z-index:100;background:rgba(0,0,0,0.5);border:1px solid rgba(255,255,255,0.9);' + cssVendor + 'background-clip:padding-box;' + cssVendor + 'box-sizing:border-box;' + (dir == 'h' ? 'height:100%' : 'width:100%') + ';' + cssVendor + 'border-radius:3px;border-radius:3px'; + } + bar.style.cssText += ';pointer-events:none;' + cssVendor + 'transition-property:' + cssVendor + 'transform;' + cssVendor + 'transition-timing-function:cubic-bezier(0.33,0.66,0.66,1);' + cssVendor + 'transition-duration:0;' + cssVendor + 'transform: translate(0,0)' + translateZ; + if (that.options.useTransition) bar.style.cssText += ';' + cssVendor + 'transition-timing-function:cubic-bezier(0.33,0.66,0.66,1)'; + + that[dir + 'ScrollbarWrapper'].appendChild(bar); + that[dir + 'ScrollbarIndicator'] = bar; + } + + if (dir == 'h') { + that.hScrollbarSize = that.hScrollbarWrapper.clientWidth; + that.hScrollbarIndicatorSize = m.max(m.round(that.hScrollbarSize * that.hScrollbarSize / that.scrollerW), 8); + that.hScrollbarIndicator.style.width = that.hScrollbarIndicatorSize + 'px'; + that.hScrollbarMaxScroll = that.hScrollbarSize - that.hScrollbarIndicatorSize; + that.hScrollbarProp = that.hScrollbarMaxScroll / that.maxScrollX; + } else { + that.vScrollbarSize = that.vScrollbarWrapper.clientHeight; + that.vScrollbarIndicatorSize = m.max(m.round(that.vScrollbarSize * that.vScrollbarSize / that.scrollerH), 8); + that.vScrollbarIndicator.style.height = that.vScrollbarIndicatorSize + 'px'; + that.vScrollbarMaxScroll = that.vScrollbarSize - that.vScrollbarIndicatorSize; + that.vScrollbarProp = that.vScrollbarMaxScroll / that.maxScrollY; + } + + // Reset position + that._scrollbarPos(dir, true); + }, + + _resize: function () { + var that = this; + setTimeout(function () { that.refresh(); }, isAndroid ? 200 : 0); + }, + + _pos: function (x, y) { + if (this.zoomed) return; + + x = this.hScroll ? x : 0; + y = this.vScroll ? y : 0; + + if (this.options.useTransform) { + this.scroller.style[transform] = 'translate(' + x + 'px,' + y + 'px) scale(' + this.scale + ')' + translateZ; + } else { + x = m.round(x); + y = m.round(y); + this.scroller.style.left = x + 'px'; + this.scroller.style.top = y + 'px'; + } + + this.x = x; + this.y = y; + + this._scrollbarPos('h'); + this._scrollbarPos('v'); + }, + + _scrollbarPos: function (dir, hidden) { + var that = this, + pos = dir == 'h' ? that.x : that.y, + size; + + if (!that[dir + 'Scrollbar']) return; + + pos = that[dir + 'ScrollbarProp'] * pos; + + if (pos < 0) { + if (!that.options.fixedScrollbar) { + size = that[dir + 'ScrollbarIndicatorSize'] + m.round(pos * 3); + if (size < 8) size = 8; + that[dir + 'ScrollbarIndicator'].style[dir == 'h' ? 'width' : 'height'] = size + 'px'; + } + pos = 0; + } else if (pos > that[dir + 'ScrollbarMaxScroll']) { + if (!that.options.fixedScrollbar) { + size = that[dir + 'ScrollbarIndicatorSize'] - m.round((pos - that[dir + 'ScrollbarMaxScroll']) * 3); + if (size < 8) size = 8; + that[dir + 'ScrollbarIndicator'].style[dir == 'h' ? 'width' : 'height'] = size + 'px'; + pos = that[dir + 'ScrollbarMaxScroll'] + (that[dir + 'ScrollbarIndicatorSize'] - size); + } else { + pos = that[dir + 'ScrollbarMaxScroll']; + } + } + + that[dir + 'ScrollbarWrapper'].style[transitionDelay] = '0'; + that[dir + 'ScrollbarWrapper'].style.opacity = hidden && that.options.hideScrollbar ? '0' : '1'; + that[dir + 'ScrollbarIndicator'].style[transform] = 'translate(' + (dir == 'h' ? pos + 'px,0)' : '0,' + pos + 'px)') + translateZ; + }, + + _start: function (e) { + var that = this, + point = hasTouch ? e.touches[0] : e, + matrix, x, y, + c1, c2; + + if (!that.enabled) return; + + if (that.options.onBeforeScrollStart) that.options.onBeforeScrollStart.call(that, e); + + if (that.options.useTransition || that.options.zoom) that._transitionTime(0); + + that.moved = false; + that.animating = false; + that.zoomed = false; + that.distX = 0; + that.distY = 0; + that.absDistX = 0; + that.absDistY = 0; + that.dirX = 0; + that.dirY = 0; + + // Gesture start + if (that.options.zoom && hasTouch && e.touches.length > 1) { + c1 = m.abs(e.touches[0].pageX-e.touches[1].pageX); + c2 = m.abs(e.touches[0].pageY-e.touches[1].pageY); + that.touchesDistStart = m.sqrt(c1 * c1 + c2 * c2); + + that.originX = m.abs(e.touches[0].pageX + e.touches[1].pageX - that.wrapperOffsetLeft * 2) / 2 - that.x; + that.originY = m.abs(e.touches[0].pageY + e.touches[1].pageY - that.wrapperOffsetTop * 2) / 2 - that.y; + + if (that.options.onZoomStart) that.options.onZoomStart.call(that, e); + } + + if (that.options.momentum) { + if (that.options.useTransform) { + // Very lame general purpose alternative to CSSMatrix + matrix = getComputedStyle(that.scroller, null)[transform].replace(/[^0-9\-.,]/g, '').split(','); + x = +(matrix[12] || matrix[4]); + y = +(matrix[13] || matrix[5]); + } else { + x = +getComputedStyle(that.scroller, null).left.replace(/[^0-9-]/g, ''); + y = +getComputedStyle(that.scroller, null).top.replace(/[^0-9-]/g, ''); + } + + if (x != that.x || y != that.y) { + if (that.options.useTransition) that._unbind(TRNEND_EV); + else cancelFrame(that.aniTime); + that.steps = []; + that._pos(x, y); + if (that.options.onScrollEnd) that.options.onScrollEnd.call(that); + } + } + + that.absStartX = that.x; // Needed by snap threshold + that.absStartY = that.y; + + that.startX = that.x; + that.startY = that.y; + that.pointX = point.pageX; + that.pointY = point.pageY; + + that.startTime = e.timeStamp || Date.now(); + + if (that.options.onScrollStart) that.options.onScrollStart.call(that, e); + + that._bind(MOVE_EV, window); + that._bind(END_EV, window); + that._bind(CANCEL_EV, window); + }, + + _move: function (e) { + var that = this, + point = hasTouch ? e.touches[0] : e, + deltaX = point.pageX - that.pointX, + deltaY = point.pageY - that.pointY, + newX = that.x + deltaX, + newY = that.y + deltaY, + c1, c2, scale, + timestamp = e.timeStamp || Date.now(); + + if (that.options.onBeforeScrollMove) that.options.onBeforeScrollMove.call(that, e); + + // Zoom + if (that.options.zoom && hasTouch && e.touches.length > 1) { + c1 = m.abs(e.touches[0].pageX - e.touches[1].pageX); + c2 = m.abs(e.touches[0].pageY - e.touches[1].pageY); + that.touchesDist = m.sqrt(c1*c1+c2*c2); + + that.zoomed = true; + + scale = 1 / that.touchesDistStart * that.touchesDist * this.scale; + + if (scale < that.options.zoomMin) scale = 0.5 * that.options.zoomMin * Math.pow(2.0, scale / that.options.zoomMin); + else if (scale > that.options.zoomMax) scale = 2.0 * that.options.zoomMax * Math.pow(0.5, that.options.zoomMax / scale); + + that.lastScale = scale / this.scale; + + newX = this.originX - this.originX * that.lastScale + this.x; + newY = this.originY - this.originY * that.lastScale + this.y; + + this.scroller.style[transform] = 'translate(' + newX + 'px,' + newY + 'px) scale(' + scale + ')' + translateZ; + + if (that.options.onZoom) that.options.onZoom.call(that, e); + return; + } + + that.pointX = point.pageX; + that.pointY = point.pageY; + + // Slow down if outside of the boundaries + if (newX > 0 || newX < that.maxScrollX) { + newX = that.options.bounce ? that.x + (deltaX / 2) : newX >= 0 || that.maxScrollX >= 0 ? 0 : that.maxScrollX; + } + if (newY > that.minScrollY || newY < that.maxScrollY) { + newY = that.options.bounce ? that.y + (deltaY / 2) : newY >= that.minScrollY || that.maxScrollY >= 0 ? that.minScrollY : that.maxScrollY; + } + + that.distX += deltaX; + that.distY += deltaY; + that.absDistX = m.abs(that.distX); + that.absDistY = m.abs(that.distY); + + if (that.absDistX < 6 && that.absDistY < 6) { + return; + } + + // Lock direction + if (that.options.lockDirection) { + if (that.absDistX > that.absDistY + 5) { + newY = that.y; + deltaY = 0; + } else if (that.absDistY > that.absDistX + 5) { + newX = that.x; + deltaX = 0; + } + } + + that.moved = true; + that._pos(newX, newY); + that.dirX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0; + that.dirY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0; + + if (timestamp - that.startTime > 300) { + that.startTime = timestamp; + that.startX = that.x; + that.startY = that.y; + } + + if (that.options.onScrollMove) that.options.onScrollMove.call(that, e); + }, + + _end: function (e) { + if (hasTouch && e.touches.length !== 0) return; + + var that = this, + point = hasTouch ? e.changedTouches[0] : e, + target, ev, + momentumX = { dist:0, time:0 }, + momentumY = { dist:0, time:0 }, + duration = (e.timeStamp || Date.now()) - that.startTime, + newPosX = that.x, + newPosY = that.y, + distX, distY, + newDuration, + snap, + scale; + + that._unbind(MOVE_EV, window); + that._unbind(END_EV, window); + that._unbind(CANCEL_EV, window); + + if (that.options.onBeforeScrollEnd) that.options.onBeforeScrollEnd.call(that, e); + + if (that.zoomed) { + scale = that.scale * that.lastScale; + scale = Math.max(that.options.zoomMin, scale); + scale = Math.min(that.options.zoomMax, scale); + that.lastScale = scale / that.scale; + that.scale = scale; + + that.x = that.originX - that.originX * that.lastScale + that.x; + that.y = that.originY - that.originY * that.lastScale + that.y; + + that.scroller.style[transitionDuration] = '200ms'; + that.scroller.style[transform] = 'translate(' + that.x + 'px,' + that.y + 'px) scale(' + that.scale + ')' + translateZ; + + that.zoomed = false; + that.refresh(); + + if (that.options.onZoomEnd) that.options.onZoomEnd.call(that, e); + return; + } + + if (!that.moved) { + if (hasTouch) { + if (that.doubleTapTimer && that.options.zoom) { + // Double tapped + clearTimeout(that.doubleTapTimer); + that.doubleTapTimer = null; + if (that.options.onZoomStart) that.options.onZoomStart.call(that, e); + that.zoom(that.pointX, that.pointY, that.scale == 1 ? that.options.doubleTapZoom : 1); + if (that.options.onZoomEnd) { + setTimeout(function() { + that.options.onZoomEnd.call(that, e); + }, 200); // 200 is default zoom duration + } + } else if (this.options.handleClick) { + that.doubleTapTimer = setTimeout(function () { + that.doubleTapTimer = null; + + // Find the last touched element + target = point.target; + while (target.nodeType != 1) target = target.parentNode; + + if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA') { + ev = doc.createEvent('MouseEvents'); + ev.initMouseEvent('click', true, true, e.view, 1, + point.screenX, point.screenY, point.clientX, point.clientY, + e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, + 0, null); + ev._fake = true; + target.dispatchEvent(ev); + } + }, that.options.zoom ? 250 : 0); + } + } + + that._resetPos(400); + + if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e); + return; + } + + if (duration < 300 && that.options.momentum) { + momentumX = newPosX ? that._momentum(newPosX - that.startX, duration, -that.x, that.scrollerW - that.wrapperW + that.x, that.options.bounce ? that.wrapperW : 0) : momentumX; + momentumY = newPosY ? that._momentum(newPosY - that.startY, duration, -that.y, (that.maxScrollY < 0 ? that.scrollerH - that.wrapperH + that.y - that.minScrollY : 0), that.options.bounce ? that.wrapperH : 0) : momentumY; + + newPosX = that.x + momentumX.dist; + newPosY = that.y + momentumY.dist; + + if ((that.x > 0 && newPosX > 0) || (that.x < that.maxScrollX && newPosX < that.maxScrollX)) momentumX = { dist:0, time:0 }; + if ((that.y > that.minScrollY && newPosY > that.minScrollY) || (that.y < that.maxScrollY && newPosY < that.maxScrollY)) momentumY = { dist:0, time:0 }; + } + + if (momentumX.dist || momentumY.dist) { + newDuration = m.max(m.max(momentumX.time, momentumY.time), 10); + + // Do we need to snap? + if (that.options.snap) { + distX = newPosX - that.absStartX; + distY = newPosY - that.absStartY; + if (m.abs(distX) < that.options.snapThreshold && m.abs(distY) < that.options.snapThreshold) { that.scrollTo(that.absStartX, that.absStartY, 200); } + else { + snap = that._snap(newPosX, newPosY); + newPosX = snap.x; + newPosY = snap.y; + newDuration = m.max(snap.time, newDuration); + } + } + + that.scrollTo(m.round(newPosX), m.round(newPosY), newDuration); + + if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e); + return; + } + + // Do we need to snap? + if (that.options.snap) { + distX = newPosX - that.absStartX; + distY = newPosY - that.absStartY; + if (m.abs(distX) < that.options.snapThreshold && m.abs(distY) < that.options.snapThreshold) that.scrollTo(that.absStartX, that.absStartY, 200); + else { + snap = that._snap(that.x, that.y); + if (snap.x != that.x || snap.y != that.y) that.scrollTo(snap.x, snap.y, snap.time); + } + + if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e); + return; + } + + that._resetPos(200); + if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e); + }, + + _resetPos: function (time) { + var that = this, + resetX = that.x >= 0 ? 0 : that.x < that.maxScrollX ? that.maxScrollX : that.x, + resetY = that.y >= that.minScrollY || that.maxScrollY > 0 ? that.minScrollY : that.y < that.maxScrollY ? that.maxScrollY : that.y; + + if (resetX == that.x && resetY == that.y) { + if (that.moved) { + that.moved = false; + if (that.options.onScrollEnd) that.options.onScrollEnd.call(that); // Execute custom code on scroll end + } + + if (that.hScrollbar && that.options.hideScrollbar) { + if (vendor == 'webkit') that.hScrollbarWrapper.style[transitionDelay] = '300ms'; + that.hScrollbarWrapper.style.opacity = '0'; + } + if (that.vScrollbar && that.options.hideScrollbar) { + if (vendor == 'webkit') that.vScrollbarWrapper.style[transitionDelay] = '300ms'; + that.vScrollbarWrapper.style.opacity = '0'; + } + + return; + } + + that.scrollTo(resetX, resetY, time || 0); + }, + + _wheel: function (e) { + var that = this, + wheelDeltaX, wheelDeltaY, + deltaX, deltaY, + deltaScale; + + if ('wheelDeltaX' in e) { + wheelDeltaX = e.wheelDeltaX / 12; + wheelDeltaY = e.wheelDeltaY / 12; + } else if('wheelDelta' in e) { + wheelDeltaX = wheelDeltaY = e.wheelDelta / 12; + } else if ('detail' in e) { + wheelDeltaX = wheelDeltaY = -e.detail * 3; + } else { + return; + } + + if (that.options.wheelAction == 'zoom') { + deltaScale = that.scale * Math.pow(2, 1/3 * (wheelDeltaY ? wheelDeltaY / Math.abs(wheelDeltaY) : 0)); + if (deltaScale < that.options.zoomMin) deltaScale = that.options.zoomMin; + if (deltaScale > that.options.zoomMax) deltaScale = that.options.zoomMax; + + if (deltaScale != that.scale) { + if (!that.wheelZoomCount && that.options.onZoomStart) that.options.onZoomStart.call(that, e); + that.wheelZoomCount++; + + that.zoom(e.pageX, e.pageY, deltaScale, 400); + + setTimeout(function() { + that.wheelZoomCount--; + if (!that.wheelZoomCount && that.options.onZoomEnd) that.options.onZoomEnd.call(that, e); + }, 400); + } + + return; + } + + deltaX = that.x + wheelDeltaX; + deltaY = that.y + wheelDeltaY; + + if (deltaX > 0) deltaX = 0; + else if (deltaX < that.maxScrollX) deltaX = that.maxScrollX; + + if (deltaY > that.minScrollY) deltaY = that.minScrollY; + else if (deltaY < that.maxScrollY) deltaY = that.maxScrollY; + + if (that.maxScrollY < 0) { + that.scrollTo(deltaX, deltaY, 0); + } + }, + + _transitionEnd: function (e) { + var that = this; + + if (e.target != that.scroller) return; + + that._unbind(TRNEND_EV); + + that._startAni(); + }, + + + /** + * + * Utilities + * + */ + _startAni: function () { + var that = this, + startX = that.x, startY = that.y, + startTime = Date.now(), + step, easeOut, + animate; + + if (that.animating) return; + + if (!that.steps.length) { + that._resetPos(400); + return; + } + + step = that.steps.shift(); + + if (step.x == startX && step.y == startY) step.time = 0; + + that.animating = true; + that.moved = true; + + if (that.options.useTransition) { + that._transitionTime(step.time); + that._pos(step.x, step.y); + that.animating = false; + if (step.time) that._bind(TRNEND_EV); + else that._resetPos(0); + return; + } + + animate = function () { + var now = Date.now(), + newX, newY; + + if (now >= startTime + step.time) { + that._pos(step.x, step.y); + that.animating = false; + if (that.options.onAnimationEnd) that.options.onAnimationEnd.call(that); // Execute custom code on animation end + that._startAni(); + return; + } + + now = (now - startTime) / step.time - 1; + easeOut = m.sqrt(1 - now * now); + newX = (step.x - startX) * easeOut + startX; + newY = (step.y - startY) * easeOut + startY; + that._pos(newX, newY); + if (that.animating) that.aniTime = nextFrame(animate); + }; + + animate(); + }, + + _transitionTime: function (time) { + time += 'ms'; + this.scroller.style[transitionDuration] = time; + if (this.hScrollbar) this.hScrollbarIndicator.style[transitionDuration] = time; + if (this.vScrollbar) this.vScrollbarIndicator.style[transitionDuration] = time; + }, + + _momentum: function (dist, time, maxDistUpper, maxDistLower, size) { + var deceleration = 0.0006, + speed = m.abs(dist) / time, + newDist = (speed * speed) / (2 * deceleration), + newTime = 0, outsideDist = 0; + + // Proportinally reduce speed if we are outside of the boundaries + if (dist > 0 && newDist > maxDistUpper) { + outsideDist = size / (6 / (newDist / speed * deceleration)); + maxDistUpper = maxDistUpper + outsideDist; + speed = speed * maxDistUpper / newDist; + newDist = maxDistUpper; + } else if (dist < 0 && newDist > maxDistLower) { + outsideDist = size / (6 / (newDist / speed * deceleration)); + maxDistLower = maxDistLower + outsideDist; + speed = speed * maxDistLower / newDist; + newDist = maxDistLower; + } + + newDist = newDist * (dist < 0 ? -1 : 1); + newTime = speed / deceleration; + + return { dist: newDist, time: m.round(newTime) }; + }, + + _offset: function (el) { + var left = -el.offsetLeft, + top = -el.offsetTop; + + while (el = el.offsetParent) { + left -= el.offsetLeft; + top -= el.offsetTop; + } + + if (el != this.wrapper) { + left *= this.scale; + top *= this.scale; + } + + return { left: left, top: top }; + }, + + _snap: function (x, y) { + var that = this, + i, l, + page, time, + sizeX, sizeY; + + // Check page X + page = that.pagesX.length - 1; + for (i=0, l=that.pagesX.length; i= that.pagesX[i]) { + page = i; + break; + } + } + if (page == that.currPageX && page > 0 && that.dirX < 0) page--; + x = that.pagesX[page]; + sizeX = m.abs(x - that.pagesX[that.currPageX]); + sizeX = sizeX ? m.abs(that.x - x) / sizeX * 500 : 0; + that.currPageX = page; + + // Check page Y + page = that.pagesY.length-1; + for (i=0; i= that.pagesY[i]) { + page = i; + break; + } + } + if (page == that.currPageY && page > 0 && that.dirY < 0) page--; + y = that.pagesY[page]; + sizeY = m.abs(y - that.pagesY[that.currPageY]); + sizeY = sizeY ? m.abs(that.y - y) / sizeY * 500 : 0; + that.currPageY = page; + + // Snap with constant speed (proportional duration) + time = m.round(m.max(sizeX, sizeY)) || 200; + + return { x: x, y: y, time: time }; + }, + + _bind: function (type, el, bubble) { + (el || this.scroller).addEventListener(type, this, !!bubble); + }, + + _unbind: function (type, el, bubble) { + (el || this.scroller).removeEventListener(type, this, !!bubble); + }, + + + /** + * + * Public methods + * + */ + destroy: function () { + var that = this; + + that.scroller.style[transform] = ''; + + // Remove the scrollbars + that.hScrollbar = false; + that.vScrollbar = false; + that._scrollbar('h'); + that._scrollbar('v'); + + // Remove the event listeners + that._unbind(RESIZE_EV, window); + that._unbind(START_EV); + that._unbind(MOVE_EV, window); + that._unbind(END_EV, window); + that._unbind(CANCEL_EV, window); + + if (!that.options.hasTouch) { + that._unbind('DOMMouseScroll'); + that._unbind('mousewheel'); + } + + if (that.options.useTransition) that._unbind(TRNEND_EV); + + if (that.options.checkDOMChanges) clearInterval(that.checkDOMTime); + + if (that.options.onDestroy) that.options.onDestroy.call(that); + }, + + refresh: function () { + var that = this, + offset, + i, l, + els, + pos = 0, + page = 0; + + if (that.scale < that.options.zoomMin) that.scale = that.options.zoomMin; + that.wrapperW = that.wrapper.clientWidth || 1; + that.wrapperH = that.wrapper.clientHeight || 1; + + that.minScrollY = -that.options.topOffset || 0; + that.scrollerW = m.round(that.scroller.offsetWidth * that.scale); + that.scrollerH = m.round((that.scroller.offsetHeight + that.minScrollY) * that.scale); + that.maxScrollX = that.wrapperW - that.scrollerW; + that.maxScrollY = that.wrapperH - that.scrollerH + that.minScrollY; + that.dirX = 0; + that.dirY = 0; + + if (that.options.onRefresh) that.options.onRefresh.call(that); + + that.hScroll = that.options.hScroll && that.maxScrollX < 0; + that.vScroll = that.options.vScroll && (!that.options.bounceLock && !that.hScroll || that.scrollerH > that.wrapperH); + + that.hScrollbar = that.hScroll && that.options.hScrollbar; + that.vScrollbar = that.vScroll && that.options.vScrollbar && that.scrollerH > that.wrapperH; + + offset = that._offset(that.wrapper); + that.wrapperOffsetLeft = -offset.left; + that.wrapperOffsetTop = -offset.top; + + // Prepare snap + if (typeof that.options.snap == 'string') { + that.pagesX = []; + that.pagesY = []; + els = that.scroller.querySelectorAll(that.options.snap); + for (i=0, l=els.length; i= that.maxScrollX) { + that.pagesX[page] = pos; + pos = pos - that.wrapperW; + page++; + } + if (that.maxScrollX%that.wrapperW) that.pagesX[that.pagesX.length] = that.maxScrollX - that.pagesX[that.pagesX.length-1] + that.pagesX[that.pagesX.length-1]; + + pos = 0; + page = 0; + that.pagesY = []; + while (pos >= that.maxScrollY) { + that.pagesY[page] = pos; + pos = pos - that.wrapperH; + page++; + } + if (that.maxScrollY%that.wrapperH) that.pagesY[that.pagesY.length] = that.maxScrollY - that.pagesY[that.pagesY.length-1] + that.pagesY[that.pagesY.length-1]; + } + + // Prepare the scrollbars + that._scrollbar('h'); + that._scrollbar('v'); + + if (!that.zoomed) { + that.scroller.style[transitionDuration] = '0'; + that._resetPos(400); + } + }, + + scrollTo: function (x, y, time, relative) { + var that = this, + step = x, + i, l; + + that.stop(); + + if (!step.length) step = [{ x: x, y: y, time: time, relative: relative }]; + + for (i=0, l=step.length; i 0 ? 0 : pos.left < that.maxScrollX ? that.maxScrollX : pos.left; + pos.top = pos.top > that.minScrollY ? that.minScrollY : pos.top < that.maxScrollY ? that.maxScrollY : pos.top; + time = time === undefined ? m.max(m.abs(pos.left)*2, m.abs(pos.top)*2) : time; + + that.scrollTo(pos.left, pos.top, time); + }, + + scrollToPage: function (pageX, pageY, time) { + var that = this, x, y; + + time = time === undefined ? 400 : time; + + if (that.options.onScrollStart) that.options.onScrollStart.call(that); + + if (that.options.snap) { + pageX = pageX == 'next' ? that.currPageX+1 : pageX == 'prev' ? that.currPageX-1 : pageX; + pageY = pageY == 'next' ? that.currPageY+1 : pageY == 'prev' ? that.currPageY-1 : pageY; + + pageX = pageX < 0 ? 0 : pageX > that.pagesX.length-1 ? that.pagesX.length-1 : pageX; + pageY = pageY < 0 ? 0 : pageY > that.pagesY.length-1 ? that.pagesY.length-1 : pageY; + + that.currPageX = pageX; + that.currPageY = pageY; + x = that.pagesX[pageX]; + y = that.pagesY[pageY]; + } else { + x = -that.wrapperW * pageX; + y = -that.wrapperH * pageY; + if (x < that.maxScrollX) x = that.maxScrollX; + if (y < that.maxScrollY) y = that.maxScrollY; + } + + that.scrollTo(x, y, time); + }, + + disable: function () { + this.stop(); + this._resetPos(0); + this.enabled = false; + + // If disabled after touchstart we make sure that there are no left over events + this._unbind(MOVE_EV, window); + this._unbind(END_EV, window); + this._unbind(CANCEL_EV, window); + }, + + enable: function () { + this.enabled = true; + }, + + stop: function () { + if (this.options.useTransition) this._unbind(TRNEND_EV); + else cancelFrame(this.aniTime); + this.steps = []; + this.moved = false; + this.animating = false; + }, + + zoom: function (x, y, scale, time) { + var that = this, + relScale = scale / that.scale; + + if (!that.options.useTransform) return; + + that.zoomed = true; + time = time === undefined ? 200 : time; + x = x - that.wrapperOffsetLeft - that.x; + y = y - that.wrapperOffsetTop - that.y; + that.x = x - x * relScale + that.x; + that.y = y - y * relScale + that.y; + + that.scale = scale; + that.refresh(); + + that.x = that.x > 0 ? 0 : that.x < that.maxScrollX ? that.maxScrollX : that.x; + that.y = that.y > that.minScrollY ? that.minScrollY : that.y < that.maxScrollY ? that.maxScrollY : that.y; + + that.scroller.style[transitionDuration] = time + 'ms'; + that.scroller.style[transform] = 'translate(' + that.x + 'px,' + that.y + 'px) scale(' + scale + ')' + translateZ; + that.zoomed = false; + }, + + isReady: function () { + return !this.moved && !this.zoomed && !this.animating; + } +}; + +function prefixStyle (style) { + if ( vendor === '' ) return style; + + style = style.charAt(0).toUpperCase() + style.substr(1); + return vendor + style; +} + +dummyStyle = null; // for the sake of it + +if (typeof exports !== 'undefined') exports.iScroll = iScroll; +else window.iScroll = iScroll; + +})(window, document); \ No newline at end of file diff --git a/Upload/admin/modules/newpoints/awards.php b/Upload/admin/modules/newpoints/awards.php new file mode 100644 index 0000000..c4dbff0 --- /dev/null +++ b/Upload/admin/modules/newpoints/awards.php @@ -0,0 +1,259 @@ + + * @license https://creativecommons.org/licenses/by-nc/4.0/ CC BY-NC 4.0 + * @link http://www.chack1172.altervista.org/Projects/MyBB-18/Newpoints-Awards.html + */ + +if (!defined('IN_ADMINCP')) { + die('Direct initialization of this file is not allowed.'); +} + +include(MYBB_ROOT . 'inc/functions_newpoints_awards.php'); +if (!installed_ougc_awards()) { + flash_message($lang->newpoints_awards_plugin_missing, 'error'); + admin_redirect('index.php?module=newpoints'); +} +$awards = load_awards(); + +$sub_tabs['newpoints_awards'] = [ + 'title' => $lang->newpoints_awards, + 'link' => 'index.php?module=newpoints-awards', + 'description' => $lang->newpoints_awards_desc +]; +$sub_tabs['newpoints_awards_add'] = [ + 'title' => $lang->newpoints_awards_add, + 'link' => 'index.php?module=newpoints-awards&action=add', + 'description' => $lang->newpoints_awards_add_desc +]; + +$page->add_breadcrumb_item($lang->newpoints, 'index.php?module=newpoints'); +$page->add_breadcrumb_item($lang->newpoints_awards, 'index.php?module=newpoints-awards'); +if ($mybb->input['action'] == 'delete') { + $aid = (int) $mybb->input['aid']; + $page->add_breadcrumb_item($lang->newpoints_awards_delete, 'index.php?module=newpoints-awards&action=delete'); + if ($mybb->request_method == 'post') { + if ($mybb->input['no']) { + admin_redirect('index.php?module=newpoints-awards'); + } + $db->delete_query('newpoints_awards', 'aid='.$aid); + flash_message($lang->newpoints_awards_award_deleted, 'success'); + admin_redirect('index.php?module=newpoints-awards'); + } else { + $page->output_confirm_action( + 'index.php?module=newpoints-awards&action=delete&aid='.$aid, + $lang->newpoints_awards_confirm_deleteaward + ); + } +} elseif ($mybb->input['action'] == 'edit') { + $aid = (int) $mybb->input['aid']; + $query = $db->simple_select('newpoints_awards', '*', 'aid='.$aid); + if ($db->num_rows($query) == 0) { + admin_redirect('index.php?module=newpoints-awards&action=add&aid='.$aid); + } else { + $award = $db->fetch_array($query); + } + if ($mybb->request_method == 'post') { + $new_aid = (int) $mybb->input['award']; + $query = $db->simple_select('ougc_awards', '*', 'aid='.$new_aid); + if ($db->num_rows($query) == 0) { + $errors[] = $lang->newpoints_awards_invalid_award; + } elseif ($aid != $new_aid) { + $query = $db->simple_select('newpoints_awards', '*', 'aid='.$new_aid); + if ($db->num_rows($query) > 0) { + $errors[] = $lang->newpoints_awards_awardprice_exists; + } + } + if (empty($errors)) { + $db->update_query('newpoints_awards', [ + 'aid' => $new_aid, + 'price' => (float) $mybb->input['price'], + 'reason' => $db->escape_string(trim($mybb->input['reason'])), + 'visible' => (int) $mybb->input['visible'] + ], 'aid='.$aid); + flash_message($lang->newpoints_awards_award_edited, 'success'); + admin_redirect('index.php?module=newpoints-awards'); + } + } + $sub_tabs['newpoints_awards_edit'] = [ + 'title' => $lang->newpoints_awards_edit, + 'link' => 'index.php?module=newpoints-awards&action=edit&aid='.$aid, + 'description' => $lang->newpoints_awards_edit_desc + ]; + $page->add_breadcrumb_item($lang->newpoints_awards_edit, 'index.php?module=newpoints-awards&action=edit&aid='.$aid); + $page->output_header($lang->newpoints_awards_editaward); + $page->output_nav_tabs($sub_tabs, 'newpoints_awards_edit'); + if (count($awards) == 0) { + flash_message($lang->newpoints_awards_no_awards, 'error'); + admin_redirect('index.php?module=newpoints-awards'); + } + if (count($errors) > 0) { + $page->output_inline_error($errors); + } + $form = new Form('index.php?module=newpoints-awards&action=edit&aid='.$aid, 'post', 'newpoints_awards'); + $form_container = new FormContainer($lang->newpoints_awards_editaward); + $form_container->output_row( + $lang->newpoints_awards_award, + $lang->newpoints_awards_award_desc, + awards_select($awards, $aid) + ); + $form_container->output_row( + $lang->newpoints_awards_price, + $lang->newpoints_awards_price_desc, + $form->generate_text_box('price', $award['price']) + ); + $form_container->output_row( + $lang->newpoints_awards_reason, + $lang->newpoints_awards_reason_desc, + $form->generate_text_area('reason', $award['reason']) + ); + $form_container->output_row( + $lang->newpoints_awards_visible, + $lang->newpoints_awards_visible_desc, + $form->generate_yes_no_radio('visible', $award['visible']) + ); + $form_container->end(); + $form->output_submit_wrapper([ + $form->generate_submit_button($lang->newpoints_awards_submit), + $form->generate_reset_button($lang->newpoints_awards_reset), + ]); + $form->end(); + $page->output_footer(); +} elseif ($mybb->input['action'] == 'add') { + if ($mybb->request_method == 'post') { + $award = (int) $mybb->input['award']; + $query = $db->simple_select('ougc_awards', '*', 'aid='.$award); + if ($db->num_rows($query) == 0) { + $errors[] = $lang->newpoints_awards_invalid_award; + } else { + $query = $db->simple_select('newpoints_awards', '*', 'aid='.$award); + if ($db->num_rows($query) > 0) { + $errors[] = $lang->newpoints_awards_awardprice_exists; + } + } + if (empty($errors)) { + $db->insert_query('newpoints_awards', [ + 'aid' => $award, + 'price' => (float) $mybb->input['price'], + 'reason' => $db->escape_string(trim($mybb->input['reason'])), + 'visible' => (int) $mybb->input['visible'] + ]); + flash_message($lang->newpoints_awards_award_added, 'success'); + admin_redirect('index.php?module=newpoints-awards'); + } + } + if (count($awards) == 0) { + flash_message($lang->newpoints_awards_no_awards, 'error'); + admin_redirect('index.php?module=newpoints-awards'); + } + $aid = (int) $mybb->input['aid']; + $page->add_breadcrumb_item($lang->newpoints_awards_add, 'index.php?module=newpoints-awards&action=add'); + $page->output_header($lang->newpoints_awards_addaward); + $page->output_nav_tabs($sub_tabs, 'newpoints_awards_add'); + if (count($errors) > 0) { + $page->output_inline_error($errors); + } + $form = new Form('index.php?module=newpoints-awards&action=add', 'post', 'newpoints_awards'); + $form_container = new FormContainer($lang->newpoints_awards_addaward); + $form_container->output_row( + $lang->newpoints_awards_award, + $lang->newpoints_awards_award_desc, + awards_select($awards, $aid) + ); + $form_container->output_row( + $lang->newpoints_awards_price, + $lang->newpoints_awards_price_desc, + $form->generate_text_box('price', '0.00') + ); + $form_container->output_row( + $lang->newpoints_awards_reason, + $lang->newpoints_awards_reason_desc, + $form->generate_text_area('reason', '') + ); + $form_container->output_row( + $lang->newpoints_awards_visible, + $lang->newpoints_awards_visible_desc, + $form->generate_yes_no_radio('visible', '1') + ); + $form_container->end(); + $form->output_submit_wrapper([ + $form->generate_submit_button($lang->newpoints_awards_submit), + $form->generate_reset_button($lang->newpoints_awards_reset), + ]); + $form->end(); + $page->output_footer(); +} + +if (!$mybb->input['action']) { + $page->output_header($lang->newpoints_awards); + $page->output_nav_tabs($sub_tabs, 'newpoints_awards'); + + $table = new Table; + $table->construct_header( + $lang->newpoints_awards_award, + ['width' => '60%', 'colspan' => 2] + ); + $table->construct_header( + $lang->newpoints_awards_price, + ['width' => '20%', 'class' => 'align_center'] + ); + $table->construct_header( + $lang->controls, + ['width' => '20%', 'class' => 'align_center'] + ); + + $query = $db->simple_select('newpoints_awards', '*'); + while ($award = $db->fetch_array($query)) { + $extra = ''; + if (!isset($awards[$award['aid']])) { + $db->delete_query('newpoints_awards', 'aid='.$award['aid']); + continue; + } + if ($award['visible'] == 1) { + $status_img = 'bullet_on.png'; + $status_txt = $lang->newpoints_awards_alt_visible; + } else { + $status_img = 'bullet_off.png'; + $status_txt = $lang->newpoints_awards_alt_hidden; + } + $icon = '('.$status_txt.')'; + $table->construct_cell( + '', + ['width' => '1%', 'class' => 'align_center'] + ); + $table->construct_cell( + $icon.' '.$awards[$award['aid']]['name'], + ['width' => '59%'] + ); + $table->construct_cell( + newpoints_format_points($award['price']), + ['class' => 'align_center'] + ); + $popup = new PopupMenu('field_'.$award['aid'], $lang->options); + $popup->add_item($lang->edit, 'index.php?module=newpoints-awards&action=edit&aid='.$award['aid']); + $popup->add_item($lang->delete, 'index.php?module=newpoints-awards&action=delete&aid='.$award['aid']); + $table->construct_cell( + $popup->fetch(), + ['class' => 'align_center'] + ); + $table->construct_row(); + } + + if ($table->num_rows() == 0) { + $table->construct_cell( + $lang->newpoints_awards_no_awards_price, + ['colspan' => 4] + ); + $table->construct_row(); + } + + $table->output($lang->newpoints_awards); + + $page->output_footer(); +} diff --git a/Upload/inc/functions_newpoints_awards.php b/Upload/inc/functions_newpoints_awards.php new file mode 100644 index 0000000..6e0ea99 --- /dev/null +++ b/Upload/inc/functions_newpoints_awards.php @@ -0,0 +1,127 @@ + + * @license https://creativecommons.org/licenses/by-nc/4.0/ CC BY-NC 4.0 + * @link http://www.chack1172.altervista.org/Projects/MyBB-18/Newpoints-Awards.html + */ + +function load_awards() +{ + global $db; + $query = $db->simple_select('ougc_awards'); + $awards = []; + if ($db->num_rows($query) > 0) { + while ($award = $db->fetch_array($query)) { + $awards[$award['aid']] = parse_award($award); + } + } + return $awards; +} + +function parse_award($award) +{ + global $mybb, $theme; + $replaces = [ + '{bburl}' => $mybb->settings['bburl'], + '{homeurl}' => $mybb->settings['homeurl'], + '{imgdir}' => $theme['imgdir'] + ]; + if (is_array($award)) { + $award['image'] = str_replace( + array_keys($replaces), + array_values($replaces), + $award['image'] + ); + } + return $award; +} + +function activated_ougc_awards() +{ + global $cache; + $plugins = $cache->read('plugins'); + if (isset($plugins['active']['ougc_awards'])) { + return true; + } + return false; +} + +function installed_ougc_awards() +{ + global $db, $cache; + if (!$db->table_exists('ougc_awards')) { + newpoints_awards_deactivate(); + $plugins = $cache->read('newpoints_plugins'); + unset($plugins['active']['newpoints_awards']); + $cache->update('newpoints_plugins', $plugins); + return false; + } + return true; +} + +function awards_select($awards, $selected = 0) +{ + global $form; + $iconlist = ''; + $award_selected = $key = 0; + foreach ($awards as $award) { + $iconlist .= << 0 && $award['aid'] == $selected) { + $award_selected = $key; + } + $key++; + } + $award_list = []; + foreach ($awards as $award) { + $award_list[$award['aid']] = $award['name']; + } + $code = $form->generate_select_box('award', $award_list, $selected, ['id' => 'award']); + $code .= <<