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 sc_require('render_delegates/render_delegate');
  9 
 10 /**
 11   @class
 12   Renders and updates DOM representations of a label.
 13 
 14   Parameters
 15   --------------------------
 16   Expects these properties on the data source:
 17 
 18   - title
 19 
 20   If any of these are not present in the data source, the render delegate
 21   will throw an error.
 22 
 23   Optional Parameters:
 24   ---------------------------
 25   If present, these properties will be used.
 26 
 27   - icon: should be either a class name or a URL
 28   - hint: allows the label to display a hint value if its title is empty.
 29   - escapeHTML: whether the HTML should be escaped to prevent XSS attacks
 30     and the like.
 31   - textAlign
 32   - needsEllipsis: Whether an ellipsis (...) should be added after the title
 33     if the title is too long.
 34 */
 35 
 36 SC.BaseTheme.labelRenderDelegate = SC.RenderDelegate.create({
 37   className: 'label',
 38 
 39   render: function(dataSource, context) {
 40     var toolTip = dataSource.get('toolTip');
 41 
 42     this.addSizeClassName(dataSource, context);
 43 
 44     // Set the toolTip.
 45     if (toolTip) {
 46       context.setAttr('title', toolTip);
 47     }
 48 
 49     /*
 50       TODO [CC @ 1.5] These properties have been deprecated. We should remove them
 51             in the next release
 52     */
 53     context.addStyle({
 54       textAlign: dataSource.get('textAlign') || null
 55     });
 56 
 57     context.setClass('ellipsis', dataSource.get('needsEllipsis') || NO);
 58     context.setClass('icon', dataSource.get('icon') || NO);
 59 
 60     var html = this.htmlForTitleAndIcon(dataSource);
 61     context.push(html);
 62 
 63     // we could use didChangeFor, but in this case, checking the generated
 64     // HTML will probably be faster (and definitely be simpler)
 65     // because several properties are used.
 66     dataSource.get('renderState')._lastHTMLForTitleAndIcon = html;
 67   },
 68 
 69   update: function(dataSource, jquery) {
 70     var toolTip = dataSource.get('toolTip');
 71 
 72     this.updateSizeClassName(dataSource, jquery);
 73 
 74     /*
 75       TODO [CC @ 1.5] These properties have been deprecated. We should remove them
 76             in the next release
 77     */
 78     jquery.css({
 79       textAlign: dataSource.get('textAlign') || null
 80     });
 81 
 82     // Update the toolTip.
 83     if (toolTip) {
 84       jquery.attr('title', toolTip);
 85     } else {
 86       jquery.removeAttr('title');
 87     }
 88 
 89     jquery.setClass('ellipsis', dataSource.get('needsEllipsis') || NO);
 90 
 91     var html = this.htmlForTitleAndIcon(dataSource);
 92     if (dataSource.get('renderState')._lastHTMLForTitleAndIcon !== html) {
 93       jquery.html(html);
 94       dataSource.get('renderState')._lastHTMLForTitleAndIcon = html;
 95     }
 96   },
 97 
 98   /**
 99     Generates the HTML for the title and icon of the label. Render delegates can
100     override this to change how that HTML renders without affecting the rest of the
101     rendering of the label.
102 
103     @param dataSource The data source that provides the title and icon properties.
104     @return the html to use
105   */
106   htmlForTitleAndIcon: function(dataSource) {
107     var title = dataSource.get('title'),
108         hint = dataSource.get('hint'),
109         escapeHTML = dataSource.get('escapeHTML'),
110         icon = dataSource.get('icon') || '';
111 
112     // Escape the body if needed. This prevents potential XSS attacks.
113     if (title && escapeHTML) {
114       title = SC.RenderContext.escapeHTML(title) ;
115     }
116 
117     // Escape the hint if needed. This prevents potential XSS attacks.
118     if (hint && escapeHTML) { hint = SC.RenderContext.escapeHTML(hint); }
119     if (hint && !title) {
120       title = "<span class='sc-hint'>" + hint + "</span>";
121     }
122 
123     if (icon) {
124       // If the icon property is the path to an image, create an image tag
125       // that points to that URL.
126       if (icon.indexOf('/') >= 0) {
127         icon = '<img src="'+icon+'" alt="" class="icon" />';
128 
129       // Otherwise, the icon property is a class name that should be added
130       // to the image tag. Display a blank image so that the user can add
131       // background image using CSS.
132       } else {
133         icon = '<img src="'+SC.BLANK_IMAGE_URL+'" alt="" class="icon '+icon+'" />';
134       }
135     }
136 
137     return icon + (SC.none(title) ? '' : title);
138   }
139 
140 });
141