1 // ========================================================================== 2 // Project: SproutCore - JavaScript Application Framework 3 // Copyright: ©2006-2011 Strobe Inc. and contributors. 4 // Portions ©2008-2011 Apple Inc. All rights reserved. 5 // License: Licensed under MIT license (see license.js) 6 // ========================================================================== 7 8 // These are helpful utility functions for calculating range and rect values 9 sc_require('system/browser'); 10 11 SC.mixin( /** @scope SC */ { 12 13 /** 14 Takes a URL of any type and normalizes it into a fully qualified URL with 15 hostname. For example: 16 17 "some/path" => "http://localhost:4020/some/path" 18 "/some/path" => "http://localhost:4020/some/path" 19 "http://localhost:4020/some/path" => "http://localhost:4020/some/path" 20 21 @param url {String} the URL 22 @returns {String} the normalized URL 23 */ 24 normalizeURL: function(url) { 25 if (url.slice(0,1) == '/') { 26 url = window.location.protocol + '//' + window.location.host + url ; 27 } else if ((url.slice(0,5) == 'http:') || (url.slice(0,6) == 'https:')) { 28 // no change 29 } else { 30 url = window.location.href + '/' + url ; 31 } 32 return url ; 33 }, 34 35 /** Return true if the number is between 0 and 1 */ 36 isPercentage: function(val){ 37 return (val<1 && val>0); 38 }, 39 40 /** Return the left edge of the frame */ 41 minX: function(frame) { 42 return frame.x || 0; 43 }, 44 45 /** Return the right edge of the frame. */ 46 maxX: function(frame) { 47 return (frame.x || 0) + (frame.width || 0); 48 }, 49 50 /** Return the midpoint of the frame. */ 51 midX: function(frame) { 52 return (frame.x || 0) + ((frame.width || 0) / 2) ; 53 }, 54 55 /** Return the top edge of the frame */ 56 minY: function(frame) { 57 return frame.y || 0 ; 58 }, 59 60 /** Return the bottom edge of the frame */ 61 maxY: function(frame) { 62 return (frame.y || 0) + (frame.height || 0) ; 63 }, 64 65 /** Return the midpoint of the frame */ 66 midY: function(frame) { 67 return (frame.y || 0) + ((frame.height || 0) / 2) ; 68 }, 69 70 /** Returns the point that will center the frame X within the passed frame. */ 71 centerX: function(innerFrame, outerFrame) { 72 return (outerFrame.width - innerFrame.width) / 2 ; 73 }, 74 75 /** Return the point that will center the frame Y within the passed frame. */ 76 centerY: function(innerFrame, outerFrame) { 77 return (outerFrame.height - innerFrame.height) /2 ; 78 }, 79 80 /** 81 The offset of an element. 82 83 This function returns the left and top offset of an element with respect to either the document, the 84 viewport or the element's parent element. In standard SproutCore applications, the coordinates of the 85 viewport are equivalent to the document, but a HTML5 application that wishes to use this component 86 of SproutCore might need to properly distinguish between the two. 87 88 For a useful discussion on the concepts of offsets and coordinates, see: 89 http://www.quirksmode.org/mobile/viewports.html. 90 91 @param {DOMElement|jQuery|String} elem the element to find the offset of. 92 This is passed to `jQuery()`, so any value supported by `jQuery()` will work. 93 @param {String} relativeToFlag flag to determine which relative element to determine offset by. 94 One of either: 'document', 'viewport' or 'parent' (default: 'document'). 95 @returns {Object} the offset of the element as an Object (ie. Hash) in the form { x: value, y: value }. 96 */ 97 offset: function(elem, relativeToFlag) { 98 var userAgent, 99 index, 100 mobileBuildNumber, 101 result; 102 103 relativeToFlag = relativeToFlag || 'document'; 104 105 if (relativeToFlag === 'parent') { 106 result = jQuery(elem).position(); 107 } else { 108 result = jQuery(elem).offset(); 109 110 // jQuery does not workaround a problem with Mobile Safari versions prior to 4.1 that add the scroll 111 // offset to the results of getBoundingClientRect. 112 // 113 // See http://dev.jquery.it/ticket/6446 114 if (SC.browser.isMobileSafari) { 115 userAgent = navigator.userAgent; 116 index = userAgent.indexOf('Mobile/'); 117 mobileBuildNumber = userAgent.substring(index + 7, index + 9); 118 119 if (parseInt(SC.browser.mobileSafari, 0) <= 532 || (mobileBuildNumber <= "8A")) { 120 result.left -= window.pageXOffset; 121 result.top -= window.pageYOffset; 122 } 123 } 124 125 // Subtract the scroll offset for viewport coordinates 126 if (relativeToFlag === 'viewport') { 127 128 if(SC.browser.isIE8OrLower){ 129 result.left -= $(window).scrollLeft(); 130 result.top -= $(window).scrollTop(); 131 }else{ 132 result.left -= window.pageXOffset; 133 result.top -= window.pageYOffset; 134 } 135 } 136 } 137 138 // Translate 'left', 'top' to 'x', 'y' 139 140 try{ 141 result.x = result.left; 142 result.y = result.top; 143 } catch (e) { 144 // We need this for IE, when the element is detached, for some strange 145 // reason the object returned by element.getBoundingClientRect() 146 // is read-only 147 result = {x:result.left, y:result.top}; 148 } 149 delete result.left; 150 delete result.top; 151 152 return result; 153 }, 154 155 /** 156 @deprecated Use SC.offset instead. 157 158 SC.offset() is more accurate, more flexible in the value for the element parameter and 159 easier to understand. 160 161 @param el The DOM element 162 @returns {Point} A hash with x, y offsets. 163 */ 164 viewportOffset: function(el) { 165 //@if(debug) 166 SC.warn("Developer Warning: SC.viewportOffset() has been deprecated in favor of SC.offset(). Please use SC.offset() from here on."); 167 //@endif 168 var result = SC.offset(el, 'viewport'); 169 170 return {x: result.left, y: result.top}; 171 } 172 173 }) ; 174