1 // ========================================================================== 2 // Project: SproutCore - JavaScript Application Framework 3 // Copyright: ©2006-2009 Sprout Systems, Inc. and contributors. 4 // Portions ©2008-2011 Apple Inc. All rights reserved. 5 // License: Licensed under MIT license (see license.js) 6 // ========================================================================== 7 8 sc_require('render_delegates/render_delegate'); 9 10 SC.RenderDelegate.reopen({ 11 /** 12 A list of size names to look for when automatically determining 13 control size. By default, this has all of the SproutCore control sizes. 14 */ 15 sizes: [ 16 SC.TINY_CONTROL_SIZE, SC.SMALL_CONTROL_SIZE, 17 SC.REGULAR_CONTROL_SIZE, SC.LARGE_CONTROL_SIZE, 18 SC.HUGE_CONTROL_SIZE, SC.JUMBO_CONTROL_SIZE 19 ], 20 21 /** 22 Determines the correct size for the given data source, and returns the 23 hash, if any, representing it. 24 25 The hashes to choose from are properties on the render delegate. You define 26 them with the same name as you would use for styling. For example, 27 SC.REGULAR_CONTROL_SIZE uses a property name 'sc-regular-size': 28 29 SC.RenderDelegate.create({ 30 'sc-regular-size': { 31 // my properties here 32 } 33 34 If no matching size is found, the hash (if any) for SC.REGULAR_CONTROL_SIZE 35 will be returned. 36 37 @param {DataSource} dataSource The data source in which to find `controlSize` 38 or `frame` and to determine the size for. 39 40 @returns {Hash undefined} 41 */ 42 sizeFor: function(dataSource) { 43 var controlSize = dataSource.get('controlSize'), size, idx, len; 44 45 // if there is a control size set on the control 46 // then we need to use it, and give an error if we 47 // don't have it. 48 if (controlSize) { 49 if (!this[controlSize]) { 50 // create a hash for the control size 51 this[controlSize] = {}; 52 } 53 54 size = this[controlSize]; 55 56 // make sure there's a name on the size for use as class name 57 if (!size.name) { 58 size.name = controlSize; 59 } 60 61 return size; 62 } 63 64 // try to determine control size for the supplied frame 65 // TODO: cache this in dataSource.renderState 66 var frame = dataSource.get('frame'); 67 if (!frame) { 68 size = this['sc-regular-size']; 69 70 // create the size hash if needed 71 if (!size) { size = this['sc-regular-size'] = {}; } 72 if (!size.name) { size.name = 'sc-regular-size'; } 73 return size; 74 } 75 76 // loop to automatically find size 77 for (idx = 0; idx < len; idx++) { 78 key = sizes[idx]; 79 size = this[key]; 80 81 // when the size is not defined, skip it. 82 if (!size) { 83 continue; 84 } 85 86 if ( 87 // if no auto-size-selection params are supplied, then we cannot 88 // automatically select a size... 89 ( 90 size.width === undefined && size.height === undefined && 91 size.minHeight === undefined && size.minWidth === undefined && 92 size.maxHeight === undefined && size.maxWidth === undefined 93 ) || 94 95 // otherwise, if any are defined and are non-equal 96 (size.width !== undefined && frame.width !== size.width) || 97 (size.minWidth !== undefined && frame.width < size.minWidth) || 98 (size.maxWidth !== undefined && frame.width > size.maxWidth) || 99 100 (size.height !== undefined && frame.height !== size.height) || 101 (size.minHeight !== undefined && frame.height < size.minHeight) || 102 (size.maxHeight !== undefined && frame.height < size.maxHeight) 103 ) { 104 continue; 105 } 106 107 // the size needs a name to use as a class name. If one is not already 108 // present, set it to the key. 109 if (!size.name) { 110 size.name = key; 111 } 112 113 return size; 114 } 115 116 // hardcoded to return regular size if defined 117 size = this['sc-regular-size']; 118 119 // create the size hash if needed 120 if (!size) { size = this['sc-regular-size'] = {}; } 121 if (!size.name) { size.name = 'sc-regular-size'; } 122 123 124 return size; 125 }, 126 127 /** 128 Determines the proper size for the dataSource, and then renders the class 129 name corresponding to that size. 130 */ 131 addSizeClassName: function(dataSource, context) { 132 var size = this.sizeFor(dataSource); 133 if (size) { 134 context.addClass(size.name); 135 } 136 }, 137 138 /** 139 Determines the proper size for the dataSource, and then updates 140 the DOM to include that size's class name. 141 */ 142 updateSizeClassName: function(dataSource, jquery) { 143 var size = this.sizeFor(dataSource); 144 if (size) { 145 jquery.addClass(size.name); 146 } 147 }, 148 149 /** 150 Retrieves the given property for the specified data source. This property 151 may be static, or may be computed specifically for this data source. This 152 version fo `getPropertyFor` will check in your size hashes to see if any 153 properties have been overridden. 154 155 @param {DataSource} dataSource The data source to get the property 156 for. Some properties may differ based on the data source; for instance, 157 some may have different values depending on size. 158 @param {String} propertyName The name of the property to retrieve. 159 */ 160 getPropertyFor: function(dataSource, propertyName) { 161 var size = this.sizeFor(dataSource); 162 if (size) { 163 if (size[propertyName + 'For']) { 164 return size[propertyName + 'For'](dataSource, propertyName); 165 } else if (size[propertyName] !== undefined) { 166 return size[propertyName]; 167 } 168 } 169 170 if (this[propertyName + 'For']) { 171 return this[propertyName + 'For']; 172 } 173 174 return this[propertyName]; 175 } 176 }); 177