1 // ========================================================================== 2 // Project: SproutCore - JavaScript Application Framework 3 // Copyright: ©2006-2011 Strobe Inc. and contributors. 4 // ©2008-2011 Apple Inc. All rights reserved. 5 // License: Licensed under MIT license (see license.js) 6 // ========================================================================== 7 8 SC.mixin( /** @scope SC */ { 9 _downloadFrames: 0, // count of download frames inserted into document 10 11 /** 12 Starts a download of the file at the named path. 13 14 Use this method when you want to cause a file to be downloaded to a users 15 desktop instead of having it display in the web browser. Note that your 16 server must return a header indicating that the file is intended for 17 download also. 18 */ 19 download: function(path) { 20 var tempDLIFrame=document.createElement('iframe'), 21 frameId = 'DownloadFrame_' + this._downloadFrames; 22 SC.$(tempDLIFrame).attr('id',frameId); 23 tempDLIFrame.style.border='10px'; 24 tempDLIFrame.style.width='0px'; 25 tempDLIFrame.style.height='0px'; 26 tempDLIFrame.style.position='absolute'; 27 tempDLIFrame.style.top='-10000px'; 28 tempDLIFrame.style.left='-10000px'; 29 // Don't set the iFrame content yet if this is Safari 30 if (!SC.browser.isSafari) { 31 SC.$(tempDLIFrame).attr('src',path); 32 } 33 document.getElementsByTagName('body')[0].appendChild(tempDLIFrame); 34 if (SC.browser.isSafari) { 35 SC.$(tempDLIFrame).attr('src',path); 36 } 37 this._downloadFrames = this._downloadFrames + 1; 38 if (!SC.browser.isSafari) { 39 var r = function() { 40 document.body.removeChild(document.getElementById(frameId)); 41 frameId = null; 42 } ; 43 r.invokeLater(null, 2000); 44 } 45 //remove possible IE7 leak 46 tempDLIFrame = null; 47 }, 48 49 // Get the computed style from specific element. Useful for cloning styles 50 getStyle: function(oElm, strCssRule){ 51 var strValue = ""; 52 if(document.defaultView && document.defaultView.getComputedStyle){ 53 strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule); 54 } 55 else if(oElm.currentStyle){ 56 strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){ 57 return p1.toUpperCase(); 58 }); 59 strValue = oElm.currentStyle[strCssRule]; 60 } 61 return strValue; 62 }, 63 64 // Convert double byte characters to standard Unicode. Considers only 65 // conversions from zenkaku to hankaky roomaji 66 uniJapaneseConvert: function (str){ 67 var nChar, cString= '', j, jLen; 68 //here we cycle through the characters in the current value 69 for (j=0, jLen = str.length; j<jLen; j++){ 70 nChar = str.charCodeAt(j); 71 72 //here we do the unicode conversion from zenkaku to hankaku roomaji 73 nChar = ((nChar>=65281 && nChar<=65392)?nChar-65248:nChar); 74 75 //MS IME seems to put this character in as the hyphen from keyboard but not numeric pad... 76 nChar = ( nChar===12540?45:nChar) ; 77 cString = cString + String.fromCharCode(nChar); 78 } 79 return cString; 80 }, 81 82 /** 83 Determines if the given point is within the given element. 84 85 The test rect will include the element's padding and can be configured to 86 optionally include the border or border and margin. 87 88 @param {Object} point the point as an Object (ie. Hash) in the form { x: value, y: value }. 89 @param {DOMElement|jQuery|String} elem the element to test inclusion within. 90 This is passed to `jQuery()`, so any value supported by `jQuery()` will work. 91 @param {String} includeFlag flag to determine the dimensions of the element to test within. 92 One of either: 'padding', 'border' or 'margin' (default: 'border'). 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 {Boolean} YES if the point is within the element; NO otherwise 96 */ 97 98 // Note: This method is the most correct way to test the inclusion of a point within a DOM element. 99 // First, it uses SC.offset which is a slightly improved version of jQuery's offset and much more reliable 100 // than writing your own offset determination code. 101 // Second, the offset must be adjusted to account for the element's left and top border 102 // if not including the border or to account for the left and top margins when including the margins. 103 pointInElement: function(point, elem, includeFlag, relativeToFlag) { 104 var offset, 105 width, 106 height, 107 rect; 108 109 elem = jQuery(elem); 110 includeFlag = includeFlag || 'border'; 111 112 // Find the offset 113 offset = SC.offset(elem, relativeToFlag); 114 115 // Find the dimensions 116 if (includeFlag === 'padding') { 117 width = elem.innerWidth(); 118 height = elem.innerHeight(); 119 120 // Adjust offset to account for top & left borders 121 offset.x += window.parseInt(elem.css('border-left-width').replace('px', '')); 122 offset.y += window.parseInt(elem.css('border-top-width').replace('px', '')); 123 } else { 124 width = elem.outerWidth(includeFlag === 'margin'); 125 height = elem.outerHeight(includeFlag === 'margin'); 126 127 if (includeFlag === 'margin') { 128 // Adjust offset to account for top & left margins 129 offset.x -= window.parseInt(elem.css('margin-left').replace('px', '')); 130 offset.y -= window.parseInt(elem.css('margin-top').replace('px', '')); 131 } 132 } 133 134 rect = { 135 x: offset.x, 136 y: offset.y, 137 width: width, 138 height: height 139 }; 140 141 return SC.pointInRect(point, rect); 142 }, 143 144 145 /** 146 Switch the scale of your app. Useful when visualizing apps not designed 147 for iphone. 148 */ 149 switchScale: function() { 150 $('head meta[name=viewport]').remove(); 151 if(window.innerWidth === window.screen.width){ 152 $('head').prepend('<meta name="viewport" content="width=device-width, initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=0" />'); 153 }else{ 154 $('head').prepend('<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=0" />'); 155 } 156 } 157 }); 158