diff options
author | Thomas Müller <thomas.mueller@tmit.eu> | 2014-06-06 11:27:04 +0200 |
---|---|---|
committer | Thomas Müller <thomas.mueller@tmit.eu> | 2014-06-06 11:27:04 +0200 |
commit | 289accc31bd2adb98833e470162483119924e2e9 (patch) | |
tree | a8547b7eb22d481f2752403b486ebe1e8636414a /core | |
parent | 3a7b30795c56f1debdb7a9dcd51578b711c2f622 (diff) | |
parent | b2bae9313d3467f945ef02a3091d8cbf52c1382a (diff) | |
download | nextcloud-server-289accc31bd2adb98833e470162483119924e2e9.tar.gz nextcloud-server-289accc31bd2adb98833e470162483119924e2e9.zip |
Merge pull request #8159 from owncloud/mobile-sidebar-swipe
Mobile sidebar swipe
Diffstat (limited to 'core')
-rw-r--r-- | core/css/apps.css | 23 | ||||
-rw-r--r-- | core/css/header.css | 4 | ||||
-rw-r--r-- | core/css/icons.css | 4 | ||||
-rw-r--r-- | core/css/mobile.css | 88 | ||||
-rw-r--r-- | core/css/styles.css | 18 | ||||
-rw-r--r-- | core/img/actions/menu.png | bin | 0 -> 106 bytes | |||
-rw-r--r-- | core/img/actions/menu.svg | 12 | ||||
-rw-r--r-- | core/js/js.js | 54 | ||||
-rwxr-xr-x | core/js/snap.js | 568 | ||||
-rw-r--r-- | core/js/tests/specHelper.js | 18 |
10 files changed, 774 insertions, 15 deletions
diff --git a/core/css/apps.css b/core/css/apps.css index 4bcf89c7ee4..ebb0c269000 100644 --- a/core/css/apps.css +++ b/core/css/apps.css @@ -1,4 +1,5 @@ -/* ---- APP STYLING ---- */ +/* APP STYLING -------------------------------------------------------------- */ + #app { height: 100%; @@ -8,15 +9,26 @@ -moz-box-sizing: border-box; box-sizing: border-box; } + + + + +/* APP-NAVIGATION ------------------------------------------------------------*/ + + /* Navigation: folder like structure */ #app-navigation { - width: 230px; + width: 250px; height: 100%; float: left; -moz-box-sizing: border-box; box-sizing: border-box; background-color: #f8f8f8; border-right: 1px solid #ccc; padding-bottom: 44px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } #app-navigation > ul { position: relative; @@ -166,6 +178,11 @@ + + +/* APP-CONTENT ---------------------------------------------------------------*/ + + /* Part where the content will be loaded into */ #app-content { position: relative; @@ -176,7 +193,7 @@ /* settings area */ #app-settings { position: fixed; - width: 229px; + width: 249px; bottom: 0; border-top: 1px solid #ccc; } diff --git a/core/css/header.css b/core/css/header.css index 83612c67445..d04895d27cf 100644 --- a/core/css/header.css +++ b/core/css/header.css @@ -122,10 +122,6 @@ /* NAVIGATION --------------------------------------------------------------- */ -#content-wrapper { - padding-left: 0; -} - #navigation { position: fixed; top: 45px; diff --git a/core/css/icons.css b/core/css/icons.css index 75d66a773a1..60f0b1b8c60 100644 --- a/core/css/icons.css +++ b/core/css/icons.css @@ -90,6 +90,10 @@ background-image: url('../img/actions/mail.svg'); } +.icon-menu { + background-image: url('../img/actions/menu.svg'); +} + .icon-more { background-image: url('../img/actions/more.svg'); } diff --git a/core/css/mobile.css b/core/css/mobile.css index 9cea0dddc8f..98033528210 100644 --- a/core/css/mobile.css +++ b/core/css/mobile.css @@ -60,4 +60,92 @@ box-sizing: border-box; } + +/* APP SIDEBAR TOGGLE and SWIPE ----------------------------------------------*/ + +/* prevent scrollbar when sidebar is open */ +.snapjs-left #content-wrapper { + overflow-x: hidden; +} + +#app-navigation, +#app-content { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + +#app-navigation { + width: 250px !important; +} + +#app-content { + width: 100% !important; + left: 0 !important; + background-color: #fff; + overflow-x: hidden !important; +} + +#app-navigation-toggle { + position: fixed; + display: inline-block !important; + top: 45px; + left: 0; + width: 44px; + height: 44px; + z-index: 149; + background-color: rgba(255, 255, 255, .7); + cursor: pointer; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; + filter: alpha(opacity=60); + opacity: .6; +} +#app-navigation-toggle:hover, +#app-navigation-toggle:focus { + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; + filter: alpha(opacity=100); + opacity: 1; +} + +/* fix controls bar for apps which don't use the standard */ +#body-user .app-files #controls, +#user-controls { + left: 0 !important; + padding-left: 44px !important; +} +/* .viewer-mode is when text editor, PDF viewer, etc is open */ +#body-user .app-files.viewer-mode #controls { + padding-left: 0 !important; +} +.app-files.viewer-mode #app-navigation-toggle { + display: none !important; +} + +table.multiselect thead { + left: 0 !important; +} + +/* shorten elements for mobile */ +#uploadprogresswrapper { + width: 50px; +} + + +/* fix controls bar jumping when navigation is slid out */ +.snapjs-left #app-navigation-toggle { + top: 0; +} +.snapjs-left .app-files #controls, +.snapjs-left #user-controls { + top: 0; +} +.snapjs-left table.multiselect thead { + top: 44px; +} + + + +/* end of media query */ } diff --git a/core/css/styles.css b/core/css/styles.css index 9b8a9cc660c..5ad9796137d 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -253,6 +253,10 @@ input[type="submit"].enabled { background: #eee; border-bottom: 1px solid #e7e7e7; z-index: 50; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } #controls .button, #controls button, @@ -272,14 +276,22 @@ input[type="submit"].enabled { display: none; } -#content { position:relative; height:100%; width:100%; } +#content { + position: relative; + height: 100%; + width: 100%; +} #content .hascontrols { position: relative; top: 45px; } #content-wrapper { - position:absolute; height:100%; width:100%; padding-left:80px; padding-top: 45px; - -moz-box-sizing:border-box; box-sizing:border-box; + position: absolute; + height: 100%; + width: 100%; + padding-top: 45px; + -moz-box-sizing:border-box; + box-sizing:border-box; } #emptycontent { diff --git a/core/img/actions/menu.png b/core/img/actions/menu.png Binary files differnew file mode 100644 index 00000000000..583ce319175 --- /dev/null +++ b/core/img/actions/menu.png diff --git a/core/img/actions/menu.svg b/core/img/actions/menu.svg new file mode 100644 index 00000000000..f0e33df3737 --- /dev/null +++ b/core/img/actions/menu.svg @@ -0,0 +1,12 @@ +<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/"> + <metadata> + <rdf:RDF> + <cc:Work rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> + <dc:title/> + </cc:Work> + </rdf:RDF> + </metadata> + <path d="m2,2,0,2,12,0,0-2zm0,5,0,2,12,0,0-2zm0,5,0,2,12,0,0-2z"/> +</svg> diff --git a/core/js/js.js b/core/js/js.js index b3cefa83bee..d02dc6445f2 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -1131,6 +1131,60 @@ function initCore() { } setupMainMenu(); + + // just add snapper for logged in users + if($('#body-login, #body-public').length === 0) { + + // App sidebar on mobile + var snapper = new Snap({ + element: document.getElementById('app-content'), + disable: 'right', + maxPosition: 250 + }); + $('#app-content').prepend('<div id="app-navigation-toggle" class="icon-menu" style="display:none;"></div>'); + $('#app-navigation-toggle').click(function(){ + if(snapper.state().state == 'left'){ + snapper.close(); + } else { + snapper.open('left'); + } + }); + // close sidebar when switching navigation entry + var $appNavigation = $('#app-navigation'); + $appNavigation.delegate('a', 'click', function(event) { + var $target = $(event.target); + // don't hide navigation when changing settings or adding things + if($target.is('.app-navigation-noclose') || + $target.closest('.app-navigation-noclose').length) { + return; + } + if($target.is('.add-new') || + $target.closest('.add-new').length) { + return; + } + if($target.is('#app-settings') || + $target.closest('#app-settings').length) { + return; + } + snapper.close(); + }); + + var toggleSnapperOnSize = function() { + if($(window).width() > 768) { + snapper.close(); + snapper.disable(); + } else { + snapper.enable(); + } + }; + + $(window).resize(_.debounce(toggleSnapperOnSize, 250)); + + // initial call + toggleSnapperOnSize(); + + } + } $(document).ready(initCore); diff --git a/core/js/snap.js b/core/js/snap.js new file mode 100755 index 00000000000..0bbefe44203 --- /dev/null +++ b/core/js/snap.js @@ -0,0 +1,568 @@ +/* + * Snap.js + * + * Copyright 2013, Jacob Kelley - http://jakiestfu.com/ + * Released under the MIT Licence + * http://opensource.org/licenses/MIT + * + * Github: http://github.com/jakiestfu/Snap.js/ + * Version: 1.9.3 + */ +/*jslint browser: true*/ +/*global define, module, ender*/ +(function(win, doc) { + 'use strict'; + var Snap = Snap || function(userOpts) { + var settings = { + element: null, + dragger: null, + disable: 'none', + addBodyClasses: true, + hyperextensible: true, + resistance: 0.5, + flickThreshold: 50, + transitionSpeed: 0.3, + easing: 'ease', + maxPosition: 266, + minPosition: -266, + tapToClose: true, + touchToDrag: true, + slideIntent: 40, // degrees + minDragDistance: 5 + }, + cache = { + simpleStates: { + opening: null, + towards: null, + hyperExtending: null, + halfway: null, + flick: null, + translation: { + absolute: 0, + relative: 0, + sinceDirectionChange: 0, + percentage: 0 + } + } + }, + eventList = {}, + utils = { + hasTouch: ('ontouchstart' in doc.documentElement || win.navigator.msPointerEnabled), + eventType: function(action) { + var eventTypes = { + down: (utils.hasTouch ? 'touchstart' : 'mousedown'), + move: (utils.hasTouch ? 'touchmove' : 'mousemove'), + up: (utils.hasTouch ? 'touchend' : 'mouseup'), + out: (utils.hasTouch ? 'touchcancel' : 'mouseout') + }; + return eventTypes[action]; + }, + page: function(t, e){ + return (utils.hasTouch && e.touches.length && e.touches[0]) ? e.touches[0]['page'+t] : e['page'+t]; + }, + klass: { + has: function(el, name){ + return (el.className).indexOf(name) !== -1; + }, + add: function(el, name){ + if(!utils.klass.has(el, name) && settings.addBodyClasses){ + el.className += " "+name; + } + }, + remove: function(el, name){ + if(settings.addBodyClasses){ + el.className = (el.className).replace(name, "").replace(/^\s+|\s+$/g, ''); + } + } + }, + dispatchEvent: function(type) { + if (typeof eventList[type] === 'function') { + return eventList[type].call(); + } + }, + vendor: function(){ + var tmp = doc.createElement("div"), + prefixes = 'webkit Moz O ms'.split(' '), + i; + for (i in prefixes) { + if (typeof tmp.style[prefixes[i] + 'Transition'] !== 'undefined') { + return prefixes[i]; + } + } + }, + transitionCallback: function(){ + return (cache.vendor==='Moz' || cache.vendor==='ms') ? 'transitionend' : cache.vendor+'TransitionEnd'; + }, + canTransform: function(){ + return typeof settings.element.style[cache.vendor+'Transform'] !== 'undefined'; + }, + deepExtend: function(destination, source) { + var property; + for (property in source) { + if (source[property] && source[property].constructor && source[property].constructor === Object) { + destination[property] = destination[property] || {}; + utils.deepExtend(destination[property], source[property]); + } else { + destination[property] = source[property]; + } + } + return destination; + }, + angleOfDrag: function(x, y) { + var degrees, theta; + // Calc Theta + theta = Math.atan2(-(cache.startDragY - y), (cache.startDragX - x)); + if (theta < 0) { + theta += 2 * Math.PI; + } + // Calc Degrees + degrees = Math.floor(theta * (180 / Math.PI) - 180); + if (degrees < 0 && degrees > -180) { + degrees = 360 - Math.abs(degrees); + } + return Math.abs(degrees); + }, + events: { + addEvent: function addEvent(element, eventName, func) { + if (element.addEventListener) { + return element.addEventListener(eventName, func, false); + } else if (element.attachEvent) { + return element.attachEvent("on" + eventName, func); + } + }, + removeEvent: function addEvent(element, eventName, func) { + if (element.addEventListener) { + return element.removeEventListener(eventName, func, false); + } else if (element.attachEvent) { + return element.detachEvent("on" + eventName, func); + } + }, + prevent: function(e) { + if (e.preventDefault) { + e.preventDefault(); + } else { + e.returnValue = false; + } + } + }, + parentUntil: function(el, attr) { + var isStr = typeof attr === 'string'; + while (el.parentNode) { + if (isStr && el.getAttribute && el.getAttribute(attr)){ + return el; + } else if(!isStr && el === attr){ + return el; + } + el = el.parentNode; + } + return null; + } + }, + action = { + translate: { + get: { + matrix: function(index) { + + if( !utils.canTransform() ){ + return parseInt(settings.element.style.left, 10); + } else { + var matrix = win.getComputedStyle(settings.element)[cache.vendor+'Transform'].match(/\((.*)\)/), + ieOffset = 8; + if (matrix) { + matrix = matrix[1].split(','); + if(matrix.length===16){ + index+=ieOffset; + } + return parseInt(matrix[index], 10); + } + return 0; + } + } + }, + easeCallback: function(){ + settings.element.style[cache.vendor+'Transition'] = ''; + cache.translation = action.translate.get.matrix(4); + cache.easing = false; + clearInterval(cache.animatingInterval); + + if(cache.easingTo===0){ + utils.klass.remove(doc.body, 'snapjs-right'); + utils.klass.remove(doc.body, 'snapjs-left'); + } + + utils.dispatchEvent('animated'); + utils.events.removeEvent(settings.element, utils.transitionCallback(), action.translate.easeCallback); + }, + easeTo: function(n) { + + if( !utils.canTransform() ){ + cache.translation = n; + action.translate.x(n); + } else { + cache.easing = true; + cache.easingTo = n; + + settings.element.style[cache.vendor+'Transition'] = 'all ' + settings.transitionSpeed + 's ' + settings.easing; + + cache.animatingInterval = setInterval(function() { + utils.dispatchEvent('animating'); + }, 1); + + utils.events.addEvent(settings.element, utils.transitionCallback(), action.translate.easeCallback); + action.translate.x(n); + } + if(n===0){ + settings.element.style[cache.vendor+'Transform'] = ''; + } + }, + x: function(n) { + if( (settings.disable==='left' && n>0) || + (settings.disable==='right' && n<0) + ){ return; } + + if( !settings.hyperextensible ){ + if( n===settings.maxPosition || n>settings.maxPosition ){ + n=settings.maxPosition; + } else if( n===settings.minPosition || n<settings.minPosition ){ + n=settings.minPosition; + } + } + + n = parseInt(n, 10); + if(isNaN(n)){ + n = 0; + } + + if( utils.canTransform() ){ + var theTranslate = 'translate3d(' + n + 'px, 0,0)'; + settings.element.style[cache.vendor+'Transform'] = theTranslate; + } else { + settings.element.style.width = (win.innerWidth || doc.documentElement.clientWidth)+'px'; + + settings.element.style.left = n+'px'; + settings.element.style.right = ''; + } + } + }, + drag: { + listen: function() { + cache.translation = 0; + cache.easing = false; + utils.events.addEvent(settings.element, utils.eventType('down'), action.drag.startDrag); + utils.events.addEvent(settings.element, utils.eventType('move'), action.drag.dragging); + utils.events.addEvent(settings.element, utils.eventType('up'), action.drag.endDrag); + }, + stopListening: function() { + utils.events.removeEvent(settings.element, utils.eventType('down'), action.drag.startDrag); + utils.events.removeEvent(settings.element, utils.eventType('move'), action.drag.dragging); + utils.events.removeEvent(settings.element, utils.eventType('up'), action.drag.endDrag); + }, + startDrag: function(e) { + // No drag on ignored elements + var target = e.target ? e.target : e.srcElement, + ignoreParent = utils.parentUntil(target, 'data-snap-ignore'); + + if (ignoreParent) { + utils.dispatchEvent('ignore'); + return; + } + + + if(settings.dragger){ + var dragParent = utils.parentUntil(target, settings.dragger); + + // Only use dragger if we're in a closed state + if( !dragParent && + (cache.translation !== settings.minPosition && + cache.translation !== settings.maxPosition + )){ + return; + } + } + + utils.dispatchEvent('start'); + settings.element.style[cache.vendor+'Transition'] = ''; + cache.isDragging = true; + cache.hasIntent = null; + cache.intentChecked = false; + cache.startDragX = utils.page('X', e); + cache.startDragY = utils.page('Y', e); + cache.dragWatchers = { + current: 0, + last: 0, + hold: 0, + state: '' + }; + cache.simpleStates = { + opening: null, + towards: null, + hyperExtending: null, + halfway: null, + flick: null, + translation: { + absolute: 0, + relative: 0, + sinceDirectionChange: 0, + percentage: 0 + } + }; + }, + dragging: function(e) { + if (cache.isDragging && settings.touchToDrag) { + + var thePageX = utils.page('X', e), + thePageY = utils.page('Y', e), + translated = cache.translation, + absoluteTranslation = action.translate.get.matrix(4), + whileDragX = thePageX - cache.startDragX, + openingLeft = absoluteTranslation > 0, + translateTo = whileDragX, + diff; + + // Shown no intent already + if((cache.intentChecked && !cache.hasIntent)){ + return; + } + + if(settings.addBodyClasses){ + if((absoluteTranslation)>0){ + utils.klass.add(doc.body, 'snapjs-left'); + utils.klass.remove(doc.body, 'snapjs-right'); + } else if((absoluteTranslation)<0){ + utils.klass.add(doc.body, 'snapjs-right'); + utils.klass.remove(doc.body, 'snapjs-left'); + } + } + + if (cache.hasIntent === false || cache.hasIntent === null) { + var deg = utils.angleOfDrag(thePageX, thePageY), + inRightRange = (deg >= 0 && deg <= settings.slideIntent) || (deg <= 360 && deg > (360 - settings.slideIntent)), + inLeftRange = (deg >= 180 && deg <= (180 + settings.slideIntent)) || (deg <= 180 && deg >= (180 - settings.slideIntent)); + if (!inLeftRange && !inRightRange) { + cache.hasIntent = false; + } else { + cache.hasIntent = true; + } + cache.intentChecked = true; + } + + if ( + (settings.minDragDistance>=Math.abs(thePageX-cache.startDragX)) || // Has user met minimum drag distance? + (cache.hasIntent === false) + ) { + return; + } + + utils.events.prevent(e); + utils.dispatchEvent('drag'); + + cache.dragWatchers.current = thePageX; + // Determine which direction we are going + if (cache.dragWatchers.last > thePageX) { + if (cache.dragWatchers.state !== 'left') { + cache.dragWatchers.state = 'left'; + cache.dragWatchers.hold = thePageX; + } + cache.dragWatchers.last = thePageX; + } else if (cache.dragWatchers.last < thePageX) { + if (cache.dragWatchers.state !== 'right') { + cache.dragWatchers.state = 'right'; + cache.dragWatchers.hold = thePageX; + } + cache.dragWatchers.last = thePageX; + } + if (openingLeft) { + // Pulling too far to the right + if (settings.maxPosition < absoluteTranslation) { + diff = (absoluteTranslation - settings.maxPosition) * settings.resistance; + translateTo = whileDragX - diff; + } + cache.simpleStates = { + opening: 'left', + towards: cache.dragWatchers.state, + hyperExtending: settings.maxPosition < absoluteTranslation, + halfway: absoluteTranslation > (settings.maxPosition / 2), + flick: Math.abs(cache.dragWatchers.current - cache.dragWatchers.hold) > settings.flickThreshold, + translation: { + absolute: absoluteTranslation, + relative: whileDragX, + sinceDirectionChange: (cache.dragWatchers.current - cache.dragWatchers.hold), + percentage: (absoluteTranslation/settings.maxPosition)*100 + } + }; + } else { + // Pulling too far to the left + if (settings.minPosition > absoluteTranslation) { + diff = (absoluteTranslation - settings.minPosition) * settings.resistance; + translateTo = whileDragX - diff; + } + cache.simpleStates = { + opening: 'right', + towards: cache.dragWatchers.state, + hyperExtending: settings.minPosition > absoluteTranslation, + halfway: absoluteTranslation < (settings.minPosition / 2), + flick: Math.abs(cache.dragWatchers.current - cache.dragWatchers.hold) > settings.flickThreshold, + translation: { + absolute: absoluteTranslation, + relative: whileDragX, + sinceDirectionChange: (cache.dragWatchers.current - cache.dragWatchers.hold), + percentage: (absoluteTranslation/settings.minPosition)*100 + } + }; + } + action.translate.x(translateTo + translated); + } + }, + endDrag: function(e) { + if (cache.isDragging) { + utils.dispatchEvent('end'); + var translated = action.translate.get.matrix(4); + + // Tap Close + if (cache.dragWatchers.current === 0 && translated !== 0 && settings.tapToClose) { + utils.dispatchEvent('close'); + utils.events.prevent(e); + action.translate.easeTo(0); + cache.isDragging = false; + cache.startDragX = 0; + return; + } + + // Revealing Left + if (cache.simpleStates.opening === 'left') { + // Halfway, Flicking, or Too Far Out + if ((cache.simpleStates.halfway || cache.simpleStates.hyperExtending || cache.simpleStates.flick)) { + if (cache.simpleStates.flick && cache.simpleStates.towards === 'left') { // Flicking Closed + action.translate.easeTo(0); + } else if ( + (cache.simpleStates.flick && cache.simpleStates.towards === 'right') || // Flicking Open OR + (cache.simpleStates.halfway || cache.simpleStates.hyperExtending) // At least halfway open OR hyperextending + ) { + action.translate.easeTo(settings.maxPosition); // Open Left + } + } else { + action.translate.easeTo(0); // Close Left + } + // Revealing Right + } else if (cache.simpleStates.opening === 'right') { + // Halfway, Flicking, or Too Far Out + if ((cache.simpleStates.halfway || cache.simpleStates.hyperExtending || cache.simpleStates.flick)) { + if (cache.simpleStates.flick && cache.simpleStates.towards === 'right') { // Flicking Closed + action.translate.easeTo(0); + } else if ( + (cache.simpleStates.flick && cache.simpleStates.towards === 'left') || // Flicking Open OR + (cache.simpleStates.halfway || cache.simpleStates.hyperExtending) // At least halfway open OR hyperextending + ) { + action.translate.easeTo(settings.minPosition); // Open Right + } + } else { + action.translate.easeTo(0); // Close Right + } + } + cache.isDragging = false; + cache.startDragX = utils.page('X', e); + } + } + } + }, + init = function(opts) { + if (opts.element) { + utils.deepExtend(settings, opts); + cache.vendor = utils.vendor(); + action.drag.listen(); + } + }; + /* + * Public + */ + this.open = function(side) { + utils.dispatchEvent('open'); + utils.klass.remove(doc.body, 'snapjs-expand-left'); + utils.klass.remove(doc.body, 'snapjs-expand-right'); + + if (side === 'left') { + cache.simpleStates.opening = 'left'; + cache.simpleStates.towards = 'right'; + utils.klass.add(doc.body, 'snapjs-left'); + utils.klass.remove(doc.body, 'snapjs-right'); + action.translate.easeTo(settings.maxPosition); + } else if (side === 'right') { + cache.simpleStates.opening = 'right'; + cache.simpleStates.towards = 'left'; + utils.klass.remove(doc.body, 'snapjs-left'); + utils.klass.add(doc.body, 'snapjs-right'); + action.translate.easeTo(settings.minPosition); + } + }; + this.close = function() { + utils.dispatchEvent('close'); + action.translate.easeTo(0); + }; + this.expand = function(side){ + var to = win.innerWidth || doc.documentElement.clientWidth; + + if(side==='left'){ + utils.dispatchEvent('expandLeft'); + utils.klass.add(doc.body, 'snapjs-expand-left'); + utils.klass.remove(doc.body, 'snapjs-expand-right'); + } else { + utils.dispatchEvent('expandRight'); + utils.klass.add(doc.body, 'snapjs-expand-right'); + utils.klass.remove(doc.body, 'snapjs-expand-left'); + to *= -1; + } + action.translate.easeTo(to); + }; + + this.on = function(evt, fn) { + eventList[evt] = fn; + return this; + }; + this.off = function(evt) { + if (eventList[evt]) { + eventList[evt] = false; + } + }; + + this.enable = function() { + utils.dispatchEvent('enable'); + action.drag.listen(); + }; + this.disable = function() { + utils.dispatchEvent('disable'); + action.drag.stopListening(); + }; + + this.settings = function(opts){ + utils.deepExtend(settings, opts); + }; + + this.state = function() { + var state, + fromLeft = action.translate.get.matrix(4); + if (fromLeft === settings.maxPosition) { + state = 'left'; + } else if (fromLeft === settings.minPosition) { + state = 'right'; + } else { + state = 'closed'; + } + return { + state: state, + info: cache.simpleStates + }; + }; + init(userOpts); + }; + if ((typeof module !== 'undefined') && module.exports) { + module.exports = Snap; + } + if (typeof ender === 'undefined') { + this.Snap = Snap; + } + if ((typeof define === "function") && define.amd) { + define("snap", [], function() { + return Snap; + }); + } +}).call(this, window, document); diff --git a/core/js/tests/specHelper.js b/core/js/tests/specHelper.js index fc5043c2f49..2af3497051c 100644 --- a/core/js/tests/specHelper.js +++ b/core/js/tests/specHelper.js @@ -19,15 +19,12 @@ * */ -/* global OC */ - /** * Simulate the variables that are normally set by PHP code */ // from core/js/config.php window.TESTING = true; -window.oc_debug = true; window.datepickerFormatDate = 'MM d, yy'; window.dayNames = [ 'Sunday', @@ -55,6 +52,8 @@ window.monthNames = [ window.firstDay = 0; // setup dummy webroots +/* jshint camelcase: false */ +window.oc_debug = true; window.oc_webroot = location.href + '/'; window.oc_appswebroots = { "files": window.oc_webroot + '/apps/files/' @@ -68,11 +67,20 @@ window.oc_appconfig = { }; window.oc_defaults = {}; +/* jshint camelcase: true */ + +// mock for Snap.js plugin +window.Snap = function() {}; +window.Snap.prototype = { + enable: function() {}, + disable: function() {}, + close: function() {} +}; + // global setup for all tests (function setupTests() { var fakeServer = null, - $testArea = null, - routesRequestStub; + $testArea = null; beforeEach(function() { // test area for elements that need absolute selector access or measure widths/heights |