1 // ==========================================================================
  2 // Project:   CoreTools.Target
  3 // Copyright: ©2011 Apple Inc.
  4 // ==========================================================================
  5 /*global CoreTools */
  6 
  7 /**
  8 
  9   Describes a target in the build system.
 10 
 11   @extends SC.Record
 12 */
 13 CoreTools.Target = SC.Record.extend(
 14 /** @scope CoreTools.Target.prototype */ {
 15 
 16   primaryKey: "name",
 17 
 18   /**
 19     Kind of target.
 20   */
 21   kind: SC.Record.attr(String),
 22 
 23   /**
 24     Name of target.  This is also the primary key.
 25   */
 26   name: SC.Record.attr(String),
 27 
 28   /**
 29     Parent of target.  Only non-null for nested targets.
 30   */
 31   parent: SC.Record.toOne("CoreTools.Target"),
 32 
 33   /**
 34     URL to use to load tests.
 35   */
 36   testsUrl: SC.Record.attr(String, { key: "link_tests" }),
 37 
 38   /**
 39     URL to use to load the app.  If no an app, returns null
 40   */
 41   appUrl: function () {
 42     return (this.get('kind') === 'app') ? CoreTools.attachUrlPrefix(this.get('name')) : null;
 43   }.property('kind', 'name').cacheable(),
 44 
 45   /**
 46     The isExpanded state.  Defaults to NO on load.
 47   */
 48   isExpanded: SC.Record.attr(Boolean, { defaultValue: NO }),
 49 
 50   /**
 51     Children of this target.  Computed by getting the loaded targets
 52   */
 53   children: function () {
 54     var store = this.get('store'),
 55       query = CoreTools.TARGETS_QUERY,
 56       ret = store.find(query).filterProperty('parent', this);
 57 
 58     if (ret) ret = ret.sortProperty('kind', 'displayName');
 59     return (ret && ret.get('length') > 0) ? ret : null;
 60   }.property().cacheable(),
 61 
 62   /**
 63     Display name for this target
 64   */
 65   displayName: function () {
 66     var name = (this.get('name') || '(unknown)').split('/');
 67     return name[name.length - 1];
 68   }.property('name').cacheable(),
 69 
 70   /**
 71     URL name for this target
 72   */
 73   urlName: function () {
 74     var name = (this.get('name') || '/unknown').slice(1).replace(/\//g, '-');
 75     return name;
 76   }.property('name').cacheable(),
 77 
 78   /**
 79     The icon to display.  Based on the type.
 80   */
 81   targetIcon: function () {
 82     var ret = 'sc-icon-document-16';
 83     switch (this.get('kind')) {
 84     case "framework":
 85       ret = 'sc-icon-folder-16';
 86       break;
 87 
 88     case "app":
 89       ret = this.get('sortKind') === 'sproutcore' ? 'sc-icon-options-16' : 'sc-icon-sproutcore-16';
 90       break;
 91     }
 92     return ret;
 93   }.property('sortKind').cacheable(),
 94 
 95   /**
 96     This is the group key used to display.  Will be the kind unless the item
 97     belongs to the sproutcore target.
 98   */
 99   sortKind: function () {
100     if (this.get('name') === '/sproutcore') return null;
101 
102     var parent = this.get('parent');
103     if (parent && parent.get('name') === '/sproutcore') {
104       // Lump all top-level SproutCore apps, frameworks and themes under SproutCore.
105       return 'sproutcore';
106     } else if (parent && parent.get('name').indexOf('/sproutcore') === 0) {
107       // The parent is a SproutCore framework, but we are not a top-level group.
108       return null;
109     } else {
110       return (this.get('kind') || 'unknown').toLowerCase();
111     }
112   }.property('kind', 'parent').cacheable(),
113 
114   testsQuery: function () {
115     return SC.Query.remote(CoreTools.Test, { url: this.get('testsUrl') });
116   }.property('testsUrl').cacheable(),
117 
118   /**
119     Returns all of the tests associated with this target by fetching the
120     testsUrl.
121   */
122   tests: function () {
123     return this.get('store').find(this.get('testsQuery'));
124   }.property('testsQuery').cacheable()
125 
126 });
127 
128 
129 CoreTools.TARGETS_QUERY = SC.Query.remote(CoreTools.Target);
130