<commit_before>// ========================================================================
// SproutCore
// copyright 2006-2008 Sprout Systems, Inc.
// ========================================================================

require('views/view') ;

/**
  @class
  
  This is a basic popup menu. You can show the popup menu by calling the 
  view's popup() method.  Pass in the root element and event so that is can
  be positioned.
  
  @extends SC.View
*/
SC.PopupMenuView = SC.View.extend({
  emptyElement: "<ul></ul>",
  
  acceptsFirstResponder: true,


  keyDown: function(evt)
  {
    return this.interpretKeyEvents(evt);
  },

  // interpretKeyEvents callbacks...
  cancel: function()
  {
    this.set('currentSelectedMenuItem', null);
    this.set('isVisible', false);
  },
  moveUp: function()
  {
    this.selectPreviousMenuItem();
  },
  moveDown: function()
  {
    this.selectNextMenuItem();
  },
  
  _currentSelectedMenuItem: null,
  currentSelectedMenuItem: function( key, value )
  {
    if (value !== undefined)
    {
      if (this._currentSelectedMenuItem) this._currentSelectedMenuItem.set('isDefault', false);
      this._currentSelectedMenuItem = value;
      if (this._currentSelectedMenuItem) this._currentSelectedMenuItem.set('isDefault', true);
    }
    return this._currentSelectedMenuItem;
  }.property(),
  
  selectPreviousMenuItem: function()
  {
    var item = this.previousValidMenuItem();
    if (!item) return false;
    this.set('currentSelectedMenuItem', item);
  },
  
  selectNextMenuItem: function()
  {
    var item = this.nextValidMenuItem();
    if (!item) return false;
    this.set('currentSelectedMenuItem', item);
  },
  
  previousValidMenuItem: function()
  {
    return this._validMenuItemInDirection('previousSibling', 'lastChild');
  },
  nextValidMenuItem: function()
  {
    return this._validMenuItemInDirection('nextSibling', 'firstChild');
  },
  _validMenuItemInDirection: function( direction, begin )
  {
    var curr = this.get('currentSelectedMenuItem');
    var view = curr ? curr.get(direction) : this.get(begin);
    if (!view) return null;
    do {
      if (view.get('isEnabled')) return view;
    } while (view = view.get(direction));
    return null;
  },
  
  
  _show: function()
  {
    // clear out any previously used selection value...
    this.set('currentSelectedMenuItem', null);

    var menuItems = this.get('childNodes');
    for (var i=0, n=menuItems.length; i < n; i++)
    {
      // for each menu item, get the action that it performs and the current target for that action
      var sender = menuItems[i];

      // old function style actions... skip validating and let them be
      if (sender._hasLegacyActionHandler()) continue;

      var action = sender.get('action');
      var target = SC.app.targetForAction(action, sender.get('target'), sender);
      
      //console.log( "action: %s, target: %o", action, target );
      
      // found a target and the target validates, menu item is enabled if the validator returns true
      if (target && target.respondsTo('validateMenuItem')) sender.set('isEnabled', target.validateMenuItem(sender));
      // found a target and it chooses not to validate, menu item is enabled
      if (target && !target.respondsTo('validateMenuItem')) sender.set('isEnabled', true);
      // unable to resolve a target for this action, therefor disable the menu item
      if (!target) sender.set('isEnabled', false);
    }
    // call the superclasses _show method to make the menu visible
    arguments.callee.base.apply(this, arguments);
  },
  
  resizeWithOldParentSize: function() {
    
    // loop through child views (which should be menu items), and get their
    // required widths.  Use the maximum returned width.
    var requiredWidth = 0;
    var child = this.get('firstChild') ;
    while(child) {
      var w = (child.computedRequiredWidth) ? child.computedRequiredWidth():0;
      if (w > requiredWidth) requiredWidth = w ;
      child = child.get('nextSibling') ;
    }
    
    // loop through children again, set their widths to the required with.
    var size = { width: requiredWidth } ;
    var child = this.get('firstChild') ;
    while(child) {
      child.set('size',size) ;
      child = child.get('nextSibling') ;
    }
    
    // set this view to the same size.
    this.set('size',size) ;
  }
  
});<commit_msg>Popup menu was setting the width on each of the child menu items in addition to itself. This had a huge performance impact with little actual benefit.  We will let CSS handle the sizing of the menu items so they inherit the width of the menu automatically.<commit_after>// ========================================================================
// SproutCore
// copyright 2006-2008 Sprout Systems, Inc.
// ========================================================================

require('views/view') ;

/**
  @class
  
  This is a basic popup menu. You can show the popup menu by calling the 
  view's popup() method.  Pass in the root element and event so that is can
  be positioned.
  
  @extends SC.View
*/
SC.PopupMenuView = SC.View.extend({
  emptyElement: "<ul></ul>",
  
  acceptsFirstResponder: true,


  keyDown: function(evt)
  {
    return this.interpretKeyEvents(evt);
  },

  // interpretKeyEvents callbacks...
  cancel: function()
  {
    this.set('currentSelectedMenuItem', null);
    this.set('isVisible', false);
  },
  moveUp: function()
  {
    this.selectPreviousMenuItem();
  },
  moveDown: function()
  {
    this.selectNextMenuItem();
  },
  
  _currentSelectedMenuItem: null,
  currentSelectedMenuItem: function( key, value )
  {
    if (value !== undefined)
    {
      if (this._currentSelectedMenuItem) this._currentSelectedMenuItem.set('isDefault', false);
      this._currentSelectedMenuItem = value;
      if (this._currentSelectedMenuItem) this._currentSelectedMenuItem.set('isDefault', true);
    }
    return this._currentSelectedMenuItem;
  }.property(),
  
  selectPreviousMenuItem: function()
  {
    var item = this.previousValidMenuItem();
    if (!item) return false;
    this.set('currentSelectedMenuItem', item);
  },
  
  selectNextMenuItem: function()
  {
    var item = this.nextValidMenuItem();
    if (!item) return false;
    this.set('currentSelectedMenuItem', item);
  },
  
  previousValidMenuItem: function()
  {
    return this._validMenuItemInDirection('previousSibling', 'lastChild');
  },
  nextValidMenuItem: function()
  {
    return this._validMenuItemInDirection('nextSibling', 'firstChild');
  },
  _validMenuItemInDirection: function( direction, begin )
  {
    var curr = this.get('currentSelectedMenuItem');
    var view = curr ? curr.get(direction) : this.get(begin);
    if (!view) return null;
    do {
      if (view.get('isEnabled')) return view;
    } while (view = view.get(direction));
    return null;
  },
  
  
  _show: function()
  {
    // clear out any previously used selection value...
    this.set('currentSelectedMenuItem', null);

    var menuItems = this.get('childNodes');
    for (var i=0, n=menuItems.length; i < n; i++)
    {
      // for each menu item, get the action that it performs and the current target for that action
      var sender = menuItems[i];

      // old function style actions... skip validating and let them be
      if (sender._hasLegacyActionHandler()) continue;

      var action = sender.get('action');
      var target = SC.app.targetForAction(action, sender.get('target'), sender);
      
      //console.log( "action: %s, target: %o", action, target );
      
      // found a target and the target validates, menu item is enabled if the validator returns true
      if (target && target.respondsTo('validateMenuItem')) sender.set('isEnabled', target.validateMenuItem(sender));
      // found a target and it chooses not to validate, menu item is enabled
      if (target && !target.respondsTo('validateMenuItem')) sender.set('isEnabled', true);
      // unable to resolve a target for this action, therefor disable the menu item
      if (!target) sender.set('isEnabled', false);
    }
    // call the superclasses _show method to make the menu visible
    arguments.callee.base.apply(this, arguments);
  },
  
  resizeWithOldParentSize: function() {
    
    // loop through child views (which should be menu items), and get their
    // required widths.  Use the maximum returned width.
    var requiredWidth = 0;
    var child = this.get('firstChild') ;
    while(child) {
      var w = (child.computedRequiredWidth) ? child.computedRequiredWidth():0;
      if (w > requiredWidth) requiredWidth = w ;
      child = child.get('nextSibling') ;
    }
   var oldWidth = this.get("size").width;
   if(requiredWidth != oldWidth)
   {
     var size = { width: requiredWidth };
     // set this view to the same size.
     this.set('size',size) ;
   }
  }
  
});
{'fraction_non_alphanumeric': 0.14946297343131712, 'fraction_numerical': 0.00248728094968909, 'mean_word_length': 3.3025291828793772, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2315843', 'n_tokens_mistral': 2506, 'n_tokens_neox': 2458, 'n_words': 737}