/** * Magento * * NOTICE OF LICENSE * * This source file is subject to the Academic Free License (AFL 3.0) * that is bundled with this package in the file LICENSE_AFL.txt. * It is also available through the world-wide-web at this URL: * http://opensource.org/licenses/afl-3.0.php * If you did not receive a copy of the license and are unable to * obtain it through the world-wide-web, please send an email * to license@magentocommerce.com so we can send you a copy immediately. * * DISCLAIMER * * Do not edit or add to this file if you wish to upgrade Magento to newer * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. * * @category design * @package default_iphone * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ // webkitdragdrop.js v1.0, Mon May 15 2010 // // Copyright (c) 2010 Tommaso Buvoli (http://www.tommasobuvoli.com) // No Extra Libraries are required, simply download this file, add it to your pages! // // To See this library in action, grab an ipad and head over to http://www.gotproject.com // webkitdragdrop is freely distributable under the terms of an MIT-style license. //Description // Because this library was designed to run without requiring any other libraries, several basic helper functions were implemented // 6 helper functons in this webkit_tools class have been taked directly from Prototype 1.6.1 (http://prototypejs.org/) (c) 2005-2009 Sam Stephenson var webkit_tools = { //$ function - simply a more robust getElementById $:function(e) { if(typeof(e) == 'string') { return document.getElementById(e); } return e; }, //extend function - copies the values of b into a (Shallow copy) extend:function(a,b) { for (var key in b) { a[key] = b[key]; } return a; }, //empty function - used as defaut for events empty:function() { }, //remove null values from an array compact:function(a) { var b = [] var l = a.length; for(var i = 0; i < l; i ++) { if(a[i] !== null) { b.push(a[i]); } } return b; }, //DESCRIPTION // This function was taken from the internet (http://robertnyman.com/2006/04/24/get-the-rendered-style-of-an-element/) and returns // the computed style of an element independantly from the browser //INPUT // oELM (DOM ELEMENT) element whose style should be extracted // strCssRule element getCalculatedStyle:function(oElm, strCssRule) { var strValue = ""; if(document.defaultView && document.defaultView.getComputedStyle){ strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule); } else if(oElm.currentStyle){ strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){ return p1.toUpperCase(); }); strValue = oElm.currentStyle[strCssRule]; } return strValue; }, //bindAsEventListener function - used to bind events bindAsEventListener:function(f,object) { var __method = f; return function(event) { __method.call(object, event || window.event); }; }, //cumulative offset - courtesy of Prototype (http://www.prototypejs.org) cumulativeOffset:function(element) { var valueT = 0, valueL = 0; do { valueT += element.offsetTop || 0; valueL += element.offsetLeft || 0; if (element.offsetParent == document.body) if (element.style.position == 'absolute') break; element = element.offsetParent; } while (element); return {left : valueL, top : valueT}; }, //getDimensions - courtesy of Prototype (http://www.prototypejs.org) getDimensions: function(element) { var display = element.style.display; if (display != 'none' && display != null) // Safari bug return {width: element.offsetWidth, height: element.offsetHeight}; var els = element.style; var originalVisibility = els.visibility; var originalPosition = els.position; var originalDisplay = els.display; els.visibility = 'hidden'; if (originalPosition != 'fixed') // Switching fixed to absolute causes issues in Safari els.position = 'absolute'; els.display = 'block'; var originalWidth = element.clientWidth; var originalHeight = element.clientHeight; els.display = originalDisplay; els.position = originalPosition; els.visibility = originalVisibility; return {width: originalWidth, height: originalHeight}; }, //hasClassName - courtesy of Prototype (http://www.prototypejs.org) hasClassName: function(element, className) { var elementClassName = element.className; return (elementClassName.length > 0 && (elementClassName == className || new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName))); }, //addClassName - courtesy of Prototype (http://www.prototypejs.org) addClassName: function(element, className) { if (!this.hasClassName(element, className)) element.className += (element.className ? ' ' : '') + className; return element; }, //removeClassName - courtesy of Prototype (http://www.prototypejs.org) removeClassName: function(element, className) { element.className = this.strip(element.className.replace(new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ')); return element; }, //strip - courtesy of Prototype (http://www.prototypejs.org) strip:function(s) { return s.replace(/^\s+/, '').replace(/\s+$/, ''); } } //Description // Droppable fire events when a draggable is dropped on them var webkit_droppables = function() { this.initialize = function() { this.droppables = []; this.droppableRegions = []; } this.add = function(root, instance_props) { root = webkit_tools.$(root); var default_props = {accept : [], hoverClass : null, onDrop : webkit_tools.empty, onOver : webkit_tools.empty, onOut : webkit_tools.empty}; default_props = webkit_tools.extend(default_props, instance_props || {}); this.droppables.push({r : root, p : default_props}); } this.remove = function(root) { root = webkit_tools.$(root); var d = this.droppables; var i = d.length; while(i--) { if(d[i].r == root) { d[i] = null; this.droppables = webkit_tools.compact(d); return true; } } return false; } //calculate position and size of all droppables this.prepare = function() { var d = this.droppables; var i = d.length; var dR = []; var r = null; while(i--) { r = d[i].r; if(r.style.display != 'none') { dR.push({i : i, size : webkit_tools.getDimensions(r), offset : webkit_tools.cumulativeOffset(r)}) } } this.droppableRegions = dR; } this.finalize = function(x,y,r,e) { var indices = this.isOver(x,y); var index = this.maxZIndex(indices); var over = this.process(index,r); if(over) { this.drop(index, r,e); } this.process(-1,r); return over; } this.check = function(x,y,r,e) { var indices = this.isOver(x,y); var index = this.maxZIndex(indices); return this.process(index,r, e); } this.isOver = function(x, y) { var dR = this.droppableRegions; var i = dR.length; var active = []; var r = 0; var maxX = 0; var minX = 0; var maxY = 0; var minY = 0; while(i--) { r = dR[i]; minY = r.offset.top; maxY = minY + r.size.height; if((y > minY) && (y < maxY)) { minX = r.offset.left; maxX = minX + r.size.width; if((x > minX) && (x < maxX)) { active.push(r.i); } } } return active; } this.maxZIndex = function(indices) { var d = this.droppables; var l = indices.length; var index = -1; var maxZ = -100000000; var curZ = 0; while(l--) { curZ = parseInt(d[indices[l]].r.style.zIndex || 0); if(curZ > maxZ) { maxZ = curZ; index = indices[l]; } } return index; } this.process = function(index, draggableRoot, e) { //only perform update if a change has occured if(this.lastIndex != index) { //remove previous if(this.lastIndex != null) { var d = this.droppables[this.lastIndex] var p = d.p; var r = d.r; if(p.hoverClass) { webkit_tools.removeClassName(r,p.hoverClass); } p.onOut(draggableRoot, e); this.lastIndex = null; this.lastOutput = false; } //add new if(index != -1) { var d = this.droppables[index] var p = d.p; var r = d.r; if(this.hasClassNames(draggableRoot, p.accept)) { if(p.hoverClass) { webkit_tools.addClassName(r,p.hoverClass); } p.onOver(draggableRoot, e); this.lastIndex = index; this.lastOutput = true; } } } return this.lastOutput; } this.drop = function(index, r, e) { if(index != -1) { this.droppables[index].p.onDrop(r,e); } } this.hasClassNames = function(r, names) { var l = names.length; if(l == 0){return true} while(l--) { if(webkit_tools.hasClassName(r,names[l])) { return true; } } return false; } this.initialize(); } webkit_drop = new webkit_droppables(); //Description //webkit draggable - allows users to drag elements with their hands var webkit_draggable = function(r, ip) { this.ready = false; this.timeout = undefined; this.initialize = function(root, instance_props) { this.root = webkit_tools.$(root); var default_props = {scroll : false, revert : false, handle : this.root, zIndex : 1000, onStart : webkit_tools.empty, onEnd : webkit_tools.empty}; this.p = webkit_tools.extend(default_props, instance_props || {}); default_props.handle = webkit_tools.$(default_props.handle); this.prepare(); this.bindEvents(); } this.prepare = function() { var rs = this.root.style; //set position if(webkit_tools.getCalculatedStyle(this.root,'position') != 'absolute') { rs.position = 'relative'; } //set top, right, bottom, left rs.top = rs.top || '0px'; rs.left = rs.left || '0px'; rs.right = ""; rs.bottom = ""; //set zindex; rs.zIndex = rs.zIndex || '0'; } this.bindEvents = function() { var handle = this.p.handle; this.ts = webkit_tools.bindAsEventListener(this.touchStart, this); this.tm = webkit_tools.bindAsEventListener(this.touchMove, this); this.te = webkit_tools.bindAsEventListener(this.touchEnd, this); handle.addEventListener("touchstart", this.ts, false); handle.addEventListener("touchmove", this.tm, false); handle.addEventListener("touchend", this.te, false); } this.destroy = function() { var handle = this.p.handle; handle.removeEventListener("touchstart", this.ts); handle.removeEventListener("touchmove", this.tm); handle.removeEventListener("touchend", this.te); } this.set = function(key, value) { this.p[key] = value; } this.touchStart = function(event) { this.timeout = setTimeout(function () { //prepare needed variables var p = this.p; var r = this.root; var rs = r.style; var t = event.targetTouches[0]; //get position of touch touchX = t.pageX; touchY = t.pageY; //set base values for position of root rs.top = this.root.style.top || '0px'; rs.left = this.root.style.left || '0px'; rs.bottom = null; rs.right = null; var rootP = webkit_tools.cumulativeOffset(r); var cp = this.getPosition(); //save event properties p.rx = cp.x; p.ry = cp.y; p.tx = touchX; p.ty = touchY; p.z = parseInt(this.root.style.zIndex); //boost zIndex rs.zIndex = p.zIndex; webkit_drop.prepare(); p.onStart(r, event); this.ready = true; }.bind(this), 500); } this.touchMove = function(event) { if ( this.ready ) { event.preventDefault(); event.stopPropagation(); //prepare needed variables var p = this.p; var r = this.root; var rs = r.style; var t = event.targetTouches[0]; if(t == null){return} var curX = t.pageX; var curY = t.pageY; var delX = curX - p.tx; var delY = curY - p.ty; rs.webkitTransform = 'translate3d(' + (p.rx + delX) + 'px,' + (p.ry + delY) + 'px, 1px)'; //scroll window if(p.scroll) { s = this.getScroll(curX, curY); if((s[0] != 0) || (s[1] != 0)) { window.scrollTo(window.scrollX + s[0], window.scrollY + s[1]); } } //check droppables webkit_drop.check(curX, curY, r, event); //save position for touchEnd this.lastCurX = curX; this.lastCurY = curY; } } this.touchEnd = function(event) { clearTimeout(this.timeout); if ( this.ready ) { event.preventSwipe = true; var r = this.root; var p = this.p; var dropped = webkit_drop.finalize(this.lastCurX, this.lastCurY, r, event); if(((p.revert) && (!dropped)) || (p.revert === 'always')) { //revert root var rs = r.style; rs.webkitTransform = 'translate3d(' + p.rx + 'px,' + p.ry + 'px, 1px)'; //rs.top = (p.ry + 'px'); //rs.left = (p.rx + 'px'); } r.style.zIndex = this.p.z; this.p.onEnd(r, event); this.ready = false; } } this.getPosition = function() { var rs = this.root.style; return {x : parseInt(rs.left || 0), y : parseInt(rs.top || 0)} } this.getScroll = function(pX, pY) { //read window variables var sX = window.scrollX; var sY = window.scrollY; var wX = window.innerWidth; var wY = window.innerHeight; //set contants var scroll_amount = 10; //how many pixels to scroll var scroll_sensitivity = 100; //how many pixels from border to start scrolling from. var delX = 0; var delY = 0; //process vertical y scroll if(pY - sY < scroll_sensitivity) { delY = -scroll_amount; } else if((sY + wY) - pY < scroll_sensitivity) { delY = scroll_amount; } //process horizontal x scroll if(pX - sX < scroll_sensitivity) { delX = -scroll_amount; } else if((sX + wX) - pX < scroll_sensitivity) { delX = scroll_amount; } return [delX, delY] } //contructor this.initialize(r, ip); } //Description //webkit_click class. manages click events for draggables var webkit_click = function(r, ip) { this.initialize = function(root, instance_props) { var default_props = {onClick : webkit_tools.empty}; this.root = webkit_tools.$(root); this.p = webkit_tools.extend(default_props, instance_props || {}); this.bindEvents(); } this.bindEvents = function() { var root = this.root; //bind events to local scope this.ts = webkit_tools.bindAsEventListener(this.touchStart,this); this.tm = webkit_tools.bindAsEventListener(this.touchMove,this); this.te = webkit_tools.bindAsEventListener(this.touchEnd,this); //add Listeners root.addEventListener("touchstart", this.ts, false); root.addEventListener("touchmove", this.tm, false); root.addEventListener("touchend", this.te, false); this.bound = true; } this.touchStart = function() { this.moved = false; if(this.bound == false) { this.root.addEventListener("touchmove", this.tm, false); this.bound = true; } } this.touchMove = function() { this.moved = true; this.root.removeEventListener("touchmove", this.tm); this.bound = false; } this.touchEnd = function() {e.preventSwipe = true; if(this.moved == false) { this.p.onClick(); } } this.setEvent = function(f) { if(typeof(f) == 'function') { this.p.onClick = f; } } this.unbind = function() { var root = this.root; root.removeEventListener("touchstart", this.ts); root.removeEventListener("touchmove", this.tm); root.removeEventListener("touchend", this.te); } //call constructor this.initialize(r, ip); }