sproutcore 1.6.0.rc.2-x86-mingw32 → 1.6.0.1-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +12 -0
 - data/VERSION.yml +1 -1
 - data/bin/sc-docs +6 -1
 - data/lib/buildtasks/target.rake +1 -1
 - data/lib/frameworks/sproutcore/Buildfile +5 -1
 - data/lib/frameworks/sproutcore/CHANGELOG.md +175 -1
 - data/lib/frameworks/sproutcore/apps/test_controls/controllers/select.js +12 -0
 - data/lib/frameworks/sproutcore/apps/test_controls/resources/select_page.js +19 -5
 - data/lib/frameworks/sproutcore/frameworks/ajax/system/request.js +28 -31
 - data/lib/frameworks/sproutcore/frameworks/ajax/system/response.js +9 -2
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/controllers/controller.js +21 -1
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/responder_context.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/template_helpers/checkbox_support.js +6 -1
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/template_helpers/text_field_support.js +26 -8
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/keyboard.js +2 -0
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/pane.js +12 -5
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/template.js +25 -9
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/system/locale.js +157 -5
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/system/render_context.js +7 -6
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +9 -3
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/system/sparse_array.js +8 -8
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/system/string.js +104 -4
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/system/theme.js +3 -56
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/system/utils.js +4 -2
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/controllers/object/content_destroyed.js +59 -0
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/mixins/string.js +41 -1
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/mixins/template_helpers/text_field_support.js +10 -2
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/panes/template.js +16 -1
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template/handlebars.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/clippingFrame.js +11 -0
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/didAppendToDocument.js +18 -2
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/insertBefore.js +10 -6
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/keyboard.js +18 -1
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/views/template_collection.js +9 -1
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view.js +9 -4
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/keyboard.js +15 -3
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/manipulation.js +14 -8
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/theming.js +8 -18
 - data/lib/frameworks/sproutcore/frameworks/datastore/data_sources/fixtures.js +12 -2
 - data/lib/frameworks/sproutcore/frameworks/datastore/mixins/relationship_support.js +296 -0
 - data/lib/frameworks/sproutcore/frameworks/datastore/models/child_record.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/datastore/models/record.js +330 -326
 - data/lib/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +22 -1
 - data/lib/frameworks/sproutcore/frameworks/datastore/system/nested_store.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/datastore/system/store.js +614 -614
 - data/lib/frameworks/sproutcore/frameworks/datastore/tests/data_sources/data_source.js +14 -1
 - data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record.js +3 -1
 - data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_array_complex.js +2 -0
 - data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_complex.js +2 -0
 - data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record/core_methods.js +20 -13
 - data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record_attribute.js +61 -46
 - data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/commitChangesFromNestedStore.js +30 -30
 - data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/commitChangesFromNestedStore.js +24 -24
 - data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/connectDataSource.js +31 -0
 - data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/pushRelationships.js +1177 -0
 - data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/localized/system/datetime.js +4 -63
 - data/lib/frameworks/sproutcore/frameworks/desktop/mixins/border.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/desktop/mixins/scrollable.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/desktop/panes/alert.js +7 -8
 - data/lib/frameworks/sproutcore/frameworks/desktop/panes/menu.js +18 -1
 - data/lib/frameworks/sproutcore/frameworks/desktop/panes/panel.js +9 -0
 - data/lib/frameworks/sproutcore/frameworks/desktop/protocols/drag_data_source.js +3 -3
 - data/lib/frameworks/sproutcore/frameworks/desktop/protocols/drop_target.js +3 -3
 - data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/button.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/checkbox.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/collection.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/disclosure.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/image_button.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/master_detail.js +3 -2
 - data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/menu.js +12 -2
 - data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/panel.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/picker.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/progress.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/radio.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/radio_group.js +2 -2
 - data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/segment.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/segmented.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/slider.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/toolbar.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/well.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/workspace.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/desktop/resources/segmented.css +1 -0
 - data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/alert/ui.js +33 -22
 - data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/panel/methods.js +20 -1
 - data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/checkbox/methods.js +10 -3
 - data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/date_field/methods.js +34 -7
 - data/lib/frameworks/sproutcore/frameworks/desktop/views/button.js +14 -15
 - data/lib/frameworks/sproutcore/frameworks/desktop/views/checkbox.js +40 -14
 - data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +699 -700
 - data/lib/frameworks/sproutcore/frameworks/desktop/views/list_item.js +2 -2
 - data/lib/frameworks/sproutcore/frameworks/desktop/views/master_detail.js +11 -1
 - data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_item.js +16 -6
 - data/lib/frameworks/sproutcore/frameworks/desktop/views/progress.js +0 -1
 - data/lib/frameworks/sproutcore/frameworks/desktop/views/radio.js +49 -7
 - data/lib/frameworks/sproutcore/frameworks/desktop/views/select_button.js +9 -0
 - data/lib/frameworks/sproutcore/frameworks/desktop/views/select_field.js +6 -2
 - data/lib/frameworks/sproutcore/frameworks/desktop/views/slider.js +4 -26
 - data/lib/frameworks/sproutcore/frameworks/desktop/views/web.js +20 -19
 - data/lib/frameworks/sproutcore/frameworks/experimental/Buildfile +2 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/designer/designers/view_designer.js +249 -249
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/mixins/edit_mode.js +13 -5
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/mixins/emptiness.js +53 -37
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/render_delegates/form.js +2 -1
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/render_delegates/form_row.js +3 -11
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/mixins/edit_mode.js +53 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/mixins/emptiness.js +114 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/views/form.js +174 -6
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/views/form_row.js +86 -6
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/views/form.js +80 -110
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/views/form_row.js +96 -97
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/polymorphism/README.md +2 -1
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/polymorphism/models/record.js +20 -36
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/ext/menu.js +121 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/ext/menu_item.js +90 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/mixins/select_view_menu.js +139 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/render_delegates/select_button.js +14 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/ext/menu_resizing.js +25 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/mixins/select_view_menu/bindings.js +43 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/mixins/select_view_menu/check_selected.js +32 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/views/popup_button/menu_setup.js +40 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/views/popup_button/show_menu.js +45 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/views/select/menu_width.js +49 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/views/select/selected_item.js +191 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/views/popup_button.js +264 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/views/select.js +450 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/mixins/split_child.js +14 -6
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/mixins/split_thumb.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/render_delegates/split.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/render_delegates/split_divider.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/views/split.js +9 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/views/thumb.js +3 -2
 - data/lib/frameworks/sproutcore/frameworks/foundation/mixins/auto_resize.js +7 -17
 - data/lib/frameworks/sproutcore/frameworks/foundation/mixins/content_value_support.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/foundation/mixins/flowed_layout.js +35 -8
 - data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inline_editable.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inline_editor.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inline_editor_delegate.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inner_frame.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/canvas_image.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/helpers/sizing.js +2 -0
 - data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/image.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/label.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/render_delegate.js +6 -6
 - data/lib/frameworks/sproutcore/frameworks/foundation/resources/images/favicon.ico +0 -0
 - data/lib/frameworks/sproutcore/frameworks/foundation/resources/text_field.css +0 -5
 - data/lib/frameworks/sproutcore/frameworks/foundation/system/exception_handler.js +4 -2
 - data/lib/frameworks/sproutcore/frameworks/foundation/system/math.js +2 -1
 - data/lib/frameworks/sproutcore/frameworks/foundation/system/module.js +13 -0
 - data/lib/frameworks/sproutcore/frameworks/foundation/system/utils/string_measurement.js +6 -9
 - data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/flowed_layout/tests.js +912 -0
 - data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/methods.js +36 -7
 - data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/ui.js +58 -4
 - data/lib/frameworks/sproutcore/frameworks/foundation/validators/validator.js +1 -3
 - data/lib/frameworks/sproutcore/frameworks/foundation/views/field.js +0 -15
 - data/lib/frameworks/sproutcore/frameworks/foundation/views/label.js +2 -2
 - data/lib/frameworks/sproutcore/frameworks/foundation/views/text_field.js +25 -14
 - data/lib/frameworks/sproutcore/frameworks/handlebars/handlebars.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/runtime/core.js +15 -9
 - data/lib/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/flatten.js +24 -0
 - data/lib/frameworks/sproutcore/frameworks/runtime/ext/array.js +2 -1
 - data/lib/frameworks/sproutcore/frameworks/runtime/ext/function.js +5 -5
 - data/lib/frameworks/sproutcore/frameworks/runtime/mixins/array.js +19 -0
 - data/lib/frameworks/sproutcore/frameworks/runtime/mixins/copyable.js +3 -2
 - data/lib/frameworks/sproutcore/frameworks/runtime/mixins/freezable.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/runtime/system/binding.js +14 -14
 - data/lib/frameworks/sproutcore/frameworks/runtime/system/error.js +3 -0
 - data/lib/frameworks/sproutcore/frameworks/runtime/system/logger.js +2 -2
 - data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +2 -2
 - data/lib/frameworks/sproutcore/frameworks/runtime/system/range_observer.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/runtime/system/run_loop.js +3 -3
 - data/lib/frameworks/sproutcore/frameworks/runtime/system/set.js +15 -16
 - data/lib/frameworks/sproutcore/frameworks/runtime/tests/core/itemType.js +6 -2
 - data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/object/enhance.js +30 -0
 - data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/range_observer/create.js +17 -0
 - data/lib/frameworks/sproutcore/frameworks/statechart/system/state.js +9 -2
 - data/lib/frameworks/sproutcore/frameworks/statechart/system/statechart.js +3 -1
 - data/lib/frameworks/sproutcore/frameworks/testing/resources/runner.css +0 -1
 - data/lib/frameworks/sproutcore/frameworks/yuireset/resources/base.css +80 -0
 - data/lib/frameworks/sproutcore/frameworks/yuireset/resources/core.css +0 -4
 - data/lib/frameworks/sproutcore/lib/index.rhtml +2 -1
 - data/lib/frameworks/sproutcore/themes/ace/resources/collection/normal/list.css +3 -3
 - data/lib/frameworks/sproutcore/themes/ace/resources/collection/normal/list_item.css +2 -2
 - data/lib/frameworks/sproutcore/themes/ace/resources/form/form.css +9 -0
 - data/lib/frameworks/sproutcore/themes/ace/resources/menu/menu.css +3 -1
 - data/lib/frameworks/sproutcore/themes/ace/resources/picker/popover/picker.js +1 -1
 - data/lib/frameworks/sproutcore/themes/ace/resources/picker/popover/workspace.js +1 -1
 - data/lib/frameworks/sproutcore/themes/legacy_theme/render_delegates/button.js +1 -1
 - data/lib/frameworks/sproutcore/themes/legacy_theme/render_delegates/panel.js +1 -1
 - data/lib/frameworks/sproutcore/themes/legacy_theme/render_delegates/progress.js +2 -0
 - data/lib/frameworks/sproutcore/themes/legacy_theme/render_delegates/slider.js +1 -1
 - data/lib/frameworks/sproutcore/themes/legacy_theme/render_delegates/well.js +1 -1
 - data/lib/sproutcore/builders/base.rb +5 -1
 - data/lib/sproutcore/builders/handlebars.rb +12 -1
 - data/lib/sproutcore/models/target.rb +1 -9
 - data/lib/sproutcore/rack/proxy.rb +238 -92
 - data/lib/sproutcore/tools/docs.rb +1 -7
 - data/spec/fixtures/builder_tests/apps/handlebars_test/Buildfile +1 -0
 - data/spec/fixtures/builder_tests/apps/handlebars_test/{template.handlebars → templates/template.handlebars} +2 -0
 - data/spec/lib/builders/handlebars_spec.rb +10 -4
 - data/sproutcore.gemspec +3 -1
 - metadata +73 -44
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/english.lproj/default_styles.css +0 -5
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/english.lproj/strings.js +0 -15
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/views/form_checkbox_field.js +0 -17
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/views/form_field.js +0 -17
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/views/form_label.js +0 -17
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/views/form_radio_field.js +0 -17
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/views/form_text_field.js +0 -17
 
    
        data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/views/popup_button.js
    ADDED
    
    | 
         @@ -0,0 +1,264 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            // Copyright: ©2006-2010 Sprout Systems, Inc. and contributors.
         
     | 
| 
      
 2 
     | 
    
         
            +
            //            Portions ©2008-2011 Apple Inc. All rights reserved.
         
     | 
| 
      
 3 
     | 
    
         
            +
            // License:   Licensed under MIT license (see license.js)
         
     | 
| 
      
 4 
     | 
    
         
            +
            // ==========================================================================
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            /**
         
     | 
| 
      
 7 
     | 
    
         
            +
             * @class
         
     | 
| 
      
 8 
     | 
    
         
            +
             * @extends SC.ButtonView
         
     | 
| 
      
 9 
     | 
    
         
            +
             * @version 1.6
         
     | 
| 
      
 10 
     | 
    
         
            +
             * @author Alex Iskander
         
     | 
| 
      
 11 
     | 
    
         
            +
             */
         
     | 
| 
      
 12 
     | 
    
         
            +
            SC.PopupButtonView = SC.ButtonView.extend({
         
     | 
| 
      
 13 
     | 
    
         
            +
              /** @scope SC.PopupButtonView.prototype */
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              /**
         
     | 
| 
      
 17 
     | 
    
         
            +
                The render delegate to use to render and update the HTML for the PopupButton.
         
     | 
| 
      
 18 
     | 
    
         
            +
                
         
     | 
| 
      
 19 
     | 
    
         
            +
                @type String
         
     | 
| 
      
 20 
     | 
    
         
            +
                @default 'popupButtonRenderDelegate'
         
     | 
| 
      
 21 
     | 
    
         
            +
              */
         
     | 
| 
      
 22 
     | 
    
         
            +
              renderDelegateName: 'popupButtonRenderDelegate',
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              /**
         
     | 
| 
      
 25 
     | 
    
         
            +
                The menu that will pop up when this button is clicked. This can be a class or
         
     | 
| 
      
 26 
     | 
    
         
            +
                an instance.
         
     | 
| 
      
 27 
     | 
    
         
            +
                
         
     | 
| 
      
 28 
     | 
    
         
            +
                @type {SC.MenuPane}
         
     | 
| 
      
 29 
     | 
    
         
            +
                @default SC.MenuPane
         
     | 
| 
      
 30 
     | 
    
         
            +
              */
         
     | 
| 
      
 31 
     | 
    
         
            +
              menu: SC.MenuPane,
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              /**
         
     | 
| 
      
 34 
     | 
    
         
            +
                If YES, a menu instantiation task will be placed in SproutCore's
         
     | 
| 
      
 35 
     | 
    
         
            +
                `SC.backgroundTaskQueue` so the menu will be instantiated before 
         
     | 
| 
      
 36 
     | 
    
         
            +
                the user taps the button, improving response time.
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                @type Boolean
         
     | 
| 
      
 39 
     | 
    
         
            +
                @default NO
         
     | 
| 
      
 40 
     | 
    
         
            +
                @property
         
     | 
| 
      
 41 
     | 
    
         
            +
              */
         
     | 
| 
      
 42 
     | 
    
         
            +
              shouldLoadInBackground: NO,
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
              /**
         
     | 
| 
      
 45 
     | 
    
         
            +
               * @private
         
     | 
| 
      
 46 
     | 
    
         
            +
               * If YES, the menu has been instantiated; if NO, the 'menu' property
         
     | 
| 
      
 47 
     | 
    
         
            +
               * still has a class instead of an instance.
         
     | 
| 
      
 48 
     | 
    
         
            +
              */
         
     | 
| 
      
 49 
     | 
    
         
            +
              _menuIsLoaded: NO,
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
              /** @private
         
     | 
| 
      
 52 
     | 
    
         
            +
                isActive is NO, but when the menu is instantiated, it is bound to the menu's isVisibleInWindow property.
         
     | 
| 
      
 53 
     | 
    
         
            +
              */
         
     | 
| 
      
 54 
     | 
    
         
            +
              isActive: NO,
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
              acceptsFirstResponder: YES,
         
     | 
| 
      
 57 
     | 
    
         
            +
              
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
              /**
         
     | 
| 
      
 60 
     | 
    
         
            +
                @private
         
     | 
| 
      
 61 
     | 
    
         
            +
              */
         
     | 
| 
      
 62 
     | 
    
         
            +
              init: function() {
         
     | 
| 
      
 63 
     | 
    
         
            +
                sc_super();
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                // keep track of the current instantiated menu separately from
         
     | 
| 
      
 66 
     | 
    
         
            +
                // our property. This allows us to destroy it when the property
         
     | 
| 
      
 67 
     | 
    
         
            +
                // changes, and to track if the property change was initiated by
         
     | 
| 
      
 68 
     | 
    
         
            +
                // us (since we set `menu` to the instantiated menu).
         
     | 
| 
      
 69 
     | 
    
         
            +
                this._currentMenu = null;
         
     | 
| 
      
 70 
     | 
    
         
            +
                this.invokeOnce('scheduleMenuSetupIfNeeded');
         
     | 
| 
      
 71 
     | 
    
         
            +
              },
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
              /**
         
     | 
| 
      
 74 
     | 
    
         
            +
                Adds menu instantiation to the background task queue if the menu
         
     | 
| 
      
 75 
     | 
    
         
            +
                is not already instantiated and if shouldLoadInBackground is YES.
         
     | 
| 
      
 76 
     | 
    
         
            +
                
         
     | 
| 
      
 77 
     | 
    
         
            +
                @method
         
     | 
| 
      
 78 
     | 
    
         
            +
                @private
         
     | 
| 
      
 79 
     | 
    
         
            +
               */
         
     | 
| 
      
 80 
     | 
    
         
            +
              scheduleMenuSetupIfNeeded: function() {
         
     | 
| 
      
 81 
     | 
    
         
            +
                var menu = this.get('menu');
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                if (menu && menu.isClass && this.get('shouldLoadInBackground')) {
         
     | 
| 
      
 84 
     | 
    
         
            +
                  SC.backgroundTaskQueue.push(SC.PopupButtonView.InstantiateMenuTask.create({ popupButton: this }));
         
     | 
| 
      
 85 
     | 
    
         
            +
                }
         
     | 
| 
      
 86 
     | 
    
         
            +
              },
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
              /** @private if the menu changes, it must be set up again. */
         
     | 
| 
      
 89 
     | 
    
         
            +
              menuDidChange: function() {
         
     | 
| 
      
 90 
     | 
    
         
            +
                // first, check if we are the ones who changed the property
         
     | 
| 
      
 91 
     | 
    
         
            +
                // by setting it to the instantiated menu
         
     | 
| 
      
 92 
     | 
    
         
            +
                var menu = this.get('menu');
         
     | 
| 
      
 93 
     | 
    
         
            +
                if (menu === this._currentMenu) { 
         
     | 
| 
      
 94 
     | 
    
         
            +
                  return;
         
     | 
| 
      
 95 
     | 
    
         
            +
                }
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                this.invokeOnce('scheduleMenuSetupIfNeeded');
         
     | 
| 
      
 98 
     | 
    
         
            +
              }.observes('menu'),
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
              /**
         
     | 
| 
      
 101 
     | 
    
         
            +
               Instantiates the menu if it exists and is not already instantiated.
         
     | 
| 
      
 102 
     | 
    
         
            +
               If another menu is already instantiated, it will be destroyed.
         
     | 
| 
      
 103 
     | 
    
         
            +
              */
         
     | 
| 
      
 104 
     | 
    
         
            +
              setupMenu: function() {
         
     | 
| 
      
 105 
     | 
    
         
            +
                var menu = this.get('menu');
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                // handle our existing menu, if any
         
     | 
| 
      
 108 
     | 
    
         
            +
                if (menu === this._currentMenu) { return; }
         
     | 
| 
      
 109 
     | 
    
         
            +
                if (this._currentMenu) {
         
     | 
| 
      
 110 
     | 
    
         
            +
                  this.isActiveBinding.disconnect();
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                  this._currentMenu.destroy();
         
     | 
| 
      
 113 
     | 
    
         
            +
                  this._currentMenu = null;
         
     | 
| 
      
 114 
     | 
    
         
            +
                }
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
                // do not do anything if there is nothing to do.
         
     | 
| 
      
 117 
     | 
    
         
            +
                if (menu && menu.isClass) {
         
     | 
| 
      
 118 
     | 
    
         
            +
                  menu = this.createMenu(menu);
         
     | 
| 
      
 119 
     | 
    
         
            +
                }
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                this._currentMenu = menu;
         
     | 
| 
      
 122 
     | 
    
         
            +
                this.set('menu', menu);
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
                this.isActiveBinding = this.bind('isActive', menu, 'isVisibleInWindow');
         
     | 
| 
      
 125 
     | 
    
         
            +
              },
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
              /**
         
     | 
| 
      
 128 
     | 
    
         
            +
                Called to instantiate a menu. You can override this to set properties
         
     | 
| 
      
 129 
     | 
    
         
            +
                such as the menu's width or the currently selected item.
         
     | 
| 
      
 130 
     | 
    
         
            +
                
         
     | 
| 
      
 131 
     | 
    
         
            +
                @param {SC.MenuPane} menu The MenuPane class to instantiate.
         
     | 
| 
      
 132 
     | 
    
         
            +
              */
         
     | 
| 
      
 133 
     | 
    
         
            +
              createMenu: function(menu) {
         
     | 
| 
      
 134 
     | 
    
         
            +
                return menu.create();
         
     | 
| 
      
 135 
     | 
    
         
            +
              },
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
              /**
         
     | 
| 
      
 139 
     | 
    
         
            +
                Shows the PopupButton's menu. You can call this to show it manually.
         
     | 
| 
      
 140 
     | 
    
         
            +
                
         
     | 
| 
      
 141 
     | 
    
         
            +
                NOTE: The menu will not be shown until the end of the Run Loop.
         
     | 
| 
      
 142 
     | 
    
         
            +
              */
         
     | 
| 
      
 143 
     | 
    
         
            +
              showMenu: function() {
         
     | 
| 
      
 144 
     | 
    
         
            +
                // problem: menu's bindings may not flush
         
     | 
| 
      
 145 
     | 
    
         
            +
                this.setupMenu();
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                // solution: pop up the menu later. Ugly-ish, but not too bad:
         
     | 
| 
      
 148 
     | 
    
         
            +
                this.invokeLast('_showMenu');
         
     | 
| 
      
 149 
     | 
    
         
            +
              },
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
              /**
         
     | 
| 
      
 152 
     | 
    
         
            +
                Hides the PopupButton's menu if it is currently showing.
         
     | 
| 
      
 153 
     | 
    
         
            +
              */
         
     | 
| 
      
 154 
     | 
    
         
            +
              hideMenu: function() {
         
     | 
| 
      
 155 
     | 
    
         
            +
                var menu = this.get('menu');
         
     | 
| 
      
 156 
     | 
    
         
            +
                if (menu && !menu.isClass) {
         
     | 
| 
      
 157 
     | 
    
         
            +
                  menu.remove();
         
     | 
| 
      
 158 
     | 
    
         
            +
                }
         
     | 
| 
      
 159 
     | 
    
         
            +
              },
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
              /**
         
     | 
| 
      
 162 
     | 
    
         
            +
                The prefer matrix (positioning information) to use to pop up the new menu.
         
     | 
| 
      
 163 
     | 
    
         
            +
                
         
     | 
| 
      
 164 
     | 
    
         
            +
                @property
         
     | 
| 
      
 165 
     | 
    
         
            +
                @type Array
         
     | 
| 
      
 166 
     | 
    
         
            +
                @default [0, 0, 0]
         
     | 
| 
      
 167 
     | 
    
         
            +
              */
         
     | 
| 
      
 168 
     | 
    
         
            +
              menuPreferMatrix: [0, 0, 0],
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
              /**
         
     | 
| 
      
 171 
     | 
    
         
            +
                @private
         
     | 
| 
      
 172 
     | 
    
         
            +
                The actual showing of the menu is delayed because bindings may need
         
     | 
| 
      
 173 
     | 
    
         
            +
                to flush.
         
     | 
| 
      
 174 
     | 
    
         
            +
              */
         
     | 
| 
      
 175 
     | 
    
         
            +
              _showMenu: function() {
         
     | 
| 
      
 176 
     | 
    
         
            +
                var menu = this.get('menu');
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
                menu.popup(this, this.get('menuPreferMatrix'));
         
     | 
| 
      
 179 
     | 
    
         
            +
              },
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
      
 181 
     | 
    
         
            +
              /** @private */
         
     | 
| 
      
 182 
     | 
    
         
            +
              mouseDown: function(evt) {
         
     | 
| 
      
 183 
     | 
    
         
            +
                // If disabled, handle mouse down but ignore it.
         
     | 
| 
      
 184 
     | 
    
         
            +
                if (!this.get('isEnabled')) return YES ;
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
                this.set('_mouseDown', YES);
         
     | 
| 
      
 187 
     | 
    
         
            +
             
     | 
| 
      
 188 
     | 
    
         
            +
                this.showMenu();
         
     | 
| 
      
 189 
     | 
    
         
            +
             
     | 
| 
      
 190 
     | 
    
         
            +
                this._mouseDownTimestamp = new Date().getTime();
         
     | 
| 
      
 191 
     | 
    
         
            +
                this.becomeFirstResponder();
         
     | 
| 
      
 192 
     | 
    
         
            +
             
     | 
| 
      
 193 
     | 
    
         
            +
                return YES;
         
     | 
| 
      
 194 
     | 
    
         
            +
              },
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
              /** @private */
         
     | 
| 
      
 197 
     | 
    
         
            +
              mouseUp: function(evt) {
         
     | 
| 
      
 198 
     | 
    
         
            +
                var menu = this.get('menu'), targetMenuItem, success;
         
     | 
| 
      
 199 
     | 
    
         
            +
             
     | 
| 
      
 200 
     | 
    
         
            +
                if (menu && this.get('_mouseDown')) {
         
     | 
| 
      
 201 
     | 
    
         
            +
                  targetMenuItem = menu.getPath('rootMenu.targetMenuItem');
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
      
 203 
     | 
    
         
            +
                  if (targetMenuItem && menu.get('mouseHasEntered')) {
         
     | 
| 
      
 204 
     | 
    
         
            +
                    // Have the menu item perform its action.
         
     | 
| 
      
 205 
     | 
    
         
            +
                    // If the menu returns NO, it had no action to
         
     | 
| 
      
 206 
     | 
    
         
            +
                    // perform, so we should close the menu immediately.
         
     | 
| 
      
 207 
     | 
    
         
            +
                    if (!targetMenuItem.performAction()) {
         
     | 
| 
      
 208 
     | 
    
         
            +
                      menu.remove();
         
     | 
| 
      
 209 
     | 
    
         
            +
                    }
         
     | 
| 
      
 210 
     | 
    
         
            +
                  } else {
         
     | 
| 
      
 211 
     | 
    
         
            +
                    // If the user waits more than 200ms between mouseDown and mouseUp,
         
     | 
| 
      
 212 
     | 
    
         
            +
                    // we can assume that they are clicking and dragging to the menu item,
         
     | 
| 
      
 213 
     | 
    
         
            +
                    // and we should close the menu if they mouseup anywhere not inside
         
     | 
| 
      
 214 
     | 
    
         
            +
                    // the menu.
         
     | 
| 
      
 215 
     | 
    
         
            +
                    if (this._mouseDownTimestamp && evt.timeStamp - this._mouseDownTimestamp > 400) {
         
     | 
| 
      
 216 
     | 
    
         
            +
                      menu.remove();
         
     | 
| 
      
 217 
     | 
    
         
            +
                    }
         
     | 
| 
      
 218 
     | 
    
         
            +
                  }
         
     | 
| 
      
 219 
     | 
    
         
            +
                }
         
     | 
| 
      
 220 
     | 
    
         
            +
             
     | 
| 
      
 221 
     | 
    
         
            +
                this._mouseDownTimestamp = undefined;
         
     | 
| 
      
 222 
     | 
    
         
            +
                return YES;
         
     | 
| 
      
 223 
     | 
    
         
            +
              },
         
     | 
| 
      
 224 
     | 
    
         
            +
             
     | 
| 
      
 225 
     | 
    
         
            +
              /**
         
     | 
| 
      
 226 
     | 
    
         
            +
                @private
         
     | 
| 
      
 227 
     | 
    
         
            +
                
         
     | 
| 
      
 228 
     | 
    
         
            +
                Shows the menu when the user presses Enter. Otherwise, hands it off to button
         
     | 
| 
      
 229 
     | 
    
         
            +
                to decide what to do.
         
     | 
| 
      
 230 
     | 
    
         
            +
              */
         
     | 
| 
      
 231 
     | 
    
         
            +
              keyDown: function(event) {
         
     | 
| 
      
 232 
     | 
    
         
            +
                if (event.which == 13) {
         
     | 
| 
      
 233 
     | 
    
         
            +
                  this.showMenu();
         
     | 
| 
      
 234 
     | 
    
         
            +
                  return YES;
         
     | 
| 
      
 235 
     | 
    
         
            +
                }
         
     | 
| 
      
 236 
     | 
    
         
            +
             
     | 
| 
      
 237 
     | 
    
         
            +
                return sc_super();
         
     | 
| 
      
 238 
     | 
    
         
            +
              }
         
     | 
| 
      
 239 
     | 
    
         
            +
            });
         
     | 
| 
      
 240 
     | 
    
         
            +
             
     | 
| 
      
 241 
     | 
    
         
            +
            /**
         
     | 
| 
      
 242 
     | 
    
         
            +
              @class
         
     | 
| 
      
 243 
     | 
    
         
            +
              
         
     | 
| 
      
 244 
     | 
    
         
            +
              An SC.Task that handles instantiating a PopupButtonView's menu. It is used
         
     | 
| 
      
 245 
     | 
    
         
            +
              by SC.PopupButtonView to instantiate the menu in the backgroundTaskQueue.
         
     | 
| 
      
 246 
     | 
    
         
            +
            */
         
     | 
| 
      
 247 
     | 
    
         
            +
            SC.PopupButtonView.InstantiateMenuTask = SC.Task.extend(
         
     | 
| 
      
 248 
     | 
    
         
            +
              /**@scope SC.PopupButtonView.InstantiateMenuTask.prototype */ {
         
     | 
| 
      
 249 
     | 
    
         
            +
                
         
     | 
| 
      
 250 
     | 
    
         
            +
              /**
         
     | 
| 
      
 251 
     | 
    
         
            +
                The popupButton whose menu should be instantiated.
         
     | 
| 
      
 252 
     | 
    
         
            +
                
         
     | 
| 
      
 253 
     | 
    
         
            +
                @property
         
     | 
| 
      
 254 
     | 
    
         
            +
                @type {SC.PopupButtonView}
         
     | 
| 
      
 255 
     | 
    
         
            +
                @default null
         
     | 
| 
      
 256 
     | 
    
         
            +
              */
         
     | 
| 
      
 257 
     | 
    
         
            +
              popupButton: null,
         
     | 
| 
      
 258 
     | 
    
         
            +
              
         
     | 
| 
      
 259 
     | 
    
         
            +
              /** Instantiates the menu. */
         
     | 
| 
      
 260 
     | 
    
         
            +
              run: function(queue) {
         
     | 
| 
      
 261 
     | 
    
         
            +
                this.popupButton.setupMenu();
         
     | 
| 
      
 262 
     | 
    
         
            +
              }
         
     | 
| 
      
 263 
     | 
    
         
            +
            });
         
     | 
| 
      
 264 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,450 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            // Copyright: ©2006-2010 Sprout Systems, Inc. and contributors.
         
     | 
| 
      
 2 
     | 
    
         
            +
            //            Portions ©2008-2011 Apple Inc. All rights reserved.
         
     | 
| 
      
 3 
     | 
    
         
            +
            // License:   Licensed under MIT license (see license.js)
         
     | 
| 
      
 4 
     | 
    
         
            +
            // ==========================================================================
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            sc_require('views/popup_button');
         
     | 
| 
      
 7 
     | 
    
         
            +
            sc_require('mixins/select_view_menu');
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            /**
         
     | 
| 
      
 10 
     | 
    
         
            +
             * @class
         
     | 
| 
      
 11 
     | 
    
         
            +
             * @extends SC.PopupButtonView
         
     | 
| 
      
 12 
     | 
    
         
            +
             * @version 2.0
         
     | 
| 
      
 13 
     | 
    
         
            +
             * @author Alex Iskander
         
     | 
| 
      
 14 
     | 
    
         
            +
             */
         
     | 
| 
      
 15 
     | 
    
         
            +
            SC.SelectView = SC.PopupButtonView.extend({
         
     | 
| 
      
 16 
     | 
    
         
            +
              /** @scope SC.SelectView.prototype */
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              //
         
     | 
| 
      
 19 
     | 
    
         
            +
              // Properties
         
     | 
| 
      
 20 
     | 
    
         
            +
              //
         
     | 
| 
      
 21 
     | 
    
         
            +
              theme: 'popup',
         
     | 
| 
      
 22 
     | 
    
         
            +
              renderDelegateName: 'selectRenderDelegate',
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              /**
         
     | 
| 
      
 25 
     | 
    
         
            +
                The array of items to populate the menu. This can be a simple array of strings,
         
     | 
| 
      
 26 
     | 
    
         
            +
                objects or hashes. If you pass objects or hashes, you can also set the
         
     | 
| 
      
 27 
     | 
    
         
            +
                various itemKey properties to tell the menu how to extract the information
         
     | 
| 
      
 28 
     | 
    
         
            +
                it needs.
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                @property {Array}
         
     | 
| 
      
 31 
     | 
    
         
            +
                @default []
         
     | 
| 
      
 32 
     | 
    
         
            +
              */
         
     | 
| 
      
 33 
     | 
    
         
            +
              items: null,
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              /**
         
     | 
| 
      
 36 
     | 
    
         
            +
                Binding default for an array of items
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                @property
         
     | 
| 
      
 39 
     | 
    
         
            +
                @default SC.Binding.multiple()
         
     | 
| 
      
 40 
     | 
    
         
            +
              */
         
     | 
| 
      
 41 
     | 
    
         
            +
              itemsBindingDefault: SC.Binding.multiple(),
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
              /**
         
     | 
| 
      
 44 
     | 
    
         
            +
                They key in the items which maps to the title.
         
     | 
| 
      
 45 
     | 
    
         
            +
                This only applies for items that are hashes or SC.Objects.
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                @property
         
     | 
| 
      
 48 
     | 
    
         
            +
                @type {String}
         
     | 
| 
      
 49 
     | 
    
         
            +
                @default 'title'
         
     | 
| 
      
 50 
     | 
    
         
            +
              */
         
     | 
| 
      
 51 
     | 
    
         
            +
              itemTitleKey: 'title',
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
              /**
         
     | 
| 
      
 54 
     | 
    
         
            +
                If you set this to a non-null value, then the value of this key will
         
     | 
| 
      
 55 
     | 
    
         
            +
                be used to sort the items.  If this is not set, then itemTitleKey will
         
     | 
| 
      
 56 
     | 
    
         
            +
                be used.
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                @property
         
     | 
| 
      
 59 
     | 
    
         
            +
                @type: {String}
         
     | 
| 
      
 60 
     | 
    
         
            +
                @default null
         
     | 
| 
      
 61 
     | 
    
         
            +
              */
         
     | 
| 
      
 62 
     | 
    
         
            +
              itemSortKey: null,
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
              /**
         
     | 
| 
      
 65 
     | 
    
         
            +
                They key in the items which maps to the value.
         
     | 
| 
      
 66 
     | 
    
         
            +
                This only applies for items that are hashes or SC.Objects.
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                 @property
         
     | 
| 
      
 69 
     | 
    
         
            +
                 @type {String}
         
     | 
| 
      
 70 
     | 
    
         
            +
                 @default 'value'
         
     | 
| 
      
 71 
     | 
    
         
            +
              */
         
     | 
| 
      
 72 
     | 
    
         
            +
              itemValueKey: 'value',
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
              /**
         
     | 
| 
      
 75 
     | 
    
         
            +
                 Key used to extract icons from the items array.
         
     | 
| 
      
 76 
     | 
    
         
            +
                 
         
     | 
| 
      
 77 
     | 
    
         
            +
                 @property
         
     | 
| 
      
 78 
     | 
    
         
            +
                 @type {String}
         
     | 
| 
      
 79 
     | 
    
         
            +
                 @default null
         
     | 
| 
      
 80 
     | 
    
         
            +
              */
         
     | 
| 
      
 81 
     | 
    
         
            +
              itemIconKey: null,
         
     | 
| 
      
 82 
     | 
    
         
            +
              
         
     | 
| 
      
 83 
     | 
    
         
            +
              /**
         
     | 
| 
      
 84 
     | 
    
         
            +
                Key to use to identify separators.
         
     | 
| 
      
 85 
     | 
    
         
            +
                
         
     | 
| 
      
 86 
     | 
    
         
            +
                Items that have this property set to YES will be drawn as separators.
         
     | 
| 
      
 87 
     | 
    
         
            +
                
         
     | 
| 
      
 88 
     | 
    
         
            +
                @property
         
     | 
| 
      
 89 
     | 
    
         
            +
                @type {String}
         
     | 
| 
      
 90 
     | 
    
         
            +
                @default null
         
     | 
| 
      
 91 
     | 
    
         
            +
              */
         
     | 
| 
      
 92 
     | 
    
         
            +
              itemSeparatorKey: "separator",
         
     | 
| 
      
 93 
     | 
    
         
            +
              
         
     | 
| 
      
 94 
     | 
    
         
            +
              /**
         
     | 
| 
      
 95 
     | 
    
         
            +
                Key used to indicate if the item is to be enabled.
         
     | 
| 
      
 96 
     | 
    
         
            +
                
         
     | 
| 
      
 97 
     | 
    
         
            +
                @property
         
     | 
| 
      
 98 
     | 
    
         
            +
                @type {String}
         
     | 
| 
      
 99 
     | 
    
         
            +
                @default null
         
     | 
| 
      
 100 
     | 
    
         
            +
              */
         
     | 
| 
      
 101 
     | 
    
         
            +
              itemIsEnabledKey: "isEnabled",
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
              /**
         
     | 
| 
      
 105 
     | 
    
         
            +
               The menu that will pop up when this button is clicked.
         
     | 
| 
      
 106 
     | 
    
         
            +
               
         
     | 
| 
      
 107 
     | 
    
         
            +
               The default menu has its properties bound to the SC.SelectView,
         
     | 
| 
      
 108 
     | 
    
         
            +
               meaning that it will get all its items from the SelectView.
         
     | 
| 
      
 109 
     | 
    
         
            +
               You may override the menu entirely with one of your own; if you
         
     | 
| 
      
 110 
     | 
    
         
            +
               mix in SC.SelectViewMenu, it'll get the bindings and the extended
         
     | 
| 
      
 111 
     | 
    
         
            +
               MenuItemView that draws its checkbox when it is the selected item.
         
     | 
| 
      
 112 
     | 
    
         
            +
               
         
     | 
| 
      
 113 
     | 
    
         
            +
               @property
         
     | 
| 
      
 114 
     | 
    
         
            +
               @type {SC.MenuPane}
         
     | 
| 
      
 115 
     | 
    
         
            +
               @default SC.MenuPane.extend(SC.SelectViewMenu)
         
     | 
| 
      
 116 
     | 
    
         
            +
              */
         
     | 
| 
      
 117 
     | 
    
         
            +
              menu: SC.MenuPane.extend(SC.SelectViewMenu),
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
              /**
         
     | 
| 
      
 120 
     | 
    
         
            +
                The currently selected item. If no item is selected, `null`.
         
     | 
| 
      
 121 
     | 
    
         
            +
                
         
     | 
| 
      
 122 
     | 
    
         
            +
                @private
         
     | 
| 
      
 123 
     | 
    
         
            +
                @property {SC.Object}
         
     | 
| 
      
 124 
     | 
    
         
            +
                @default null
         
     | 
| 
      
 125 
     | 
    
         
            +
                @isReadOnly
         
     | 
| 
      
 126 
     | 
    
         
            +
               */
         
     | 
| 
      
 127 
     | 
    
         
            +
              selectedItem: null,
         
     | 
| 
      
 128 
     | 
    
         
            +
              selectedItemBinding: '*menu.rootMenu.selectedItem',
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
              /**
         
     | 
| 
      
 132 
     | 
    
         
            +
                This is a property to enable/disable focus rings in buttons. 
         
     | 
| 
      
 133 
     | 
    
         
            +
                For SelectView, it is a default.
         
     | 
| 
      
 134 
     | 
    
         
            +
                
         
     | 
| 
      
 135 
     | 
    
         
            +
                @property
         
     | 
| 
      
 136 
     | 
    
         
            +
                @type {Boolean}
         
     | 
| 
      
 137 
     | 
    
         
            +
                @default YES
         
     | 
| 
      
 138 
     | 
    
         
            +
              */
         
     | 
| 
      
 139 
     | 
    
         
            +
              supportsFocusRing: YES,
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
              /**
         
     | 
| 
      
 143 
     | 
    
         
            +
                * @private
         
     | 
| 
      
 144 
     | 
    
         
            +
              */
         
     | 
| 
      
 145 
     | 
    
         
            +
              init: function() {
         
     | 
| 
      
 146 
     | 
    
         
            +
                sc_super();
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                // call valueDidChange to get the initial item, if any
         
     | 
| 
      
 149 
     | 
    
         
            +
                this._scsv_valueDidChange();
         
     | 
| 
      
 150 
     | 
    
         
            +
              },
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
              /**
         
     | 
| 
      
 153 
     | 
    
         
            +
                @private
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
                This gets the value for a specific menu item. This function allows a few different
         
     | 
| 
      
 156 
     | 
    
         
            +
                forms of input:
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
                - A string: returns the string.
         
     | 
| 
      
 159 
     | 
    
         
            +
                - A hash: returns hash[itemValueKey], using 'value' for the key if necessary.
         
     | 
| 
      
 160 
     | 
    
         
            +
                - An SC.Object: returns object.get(itemValueKey), using 'value' for the key if needed.
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
                This method therefore accepts both the menu items as created for the menupane's displayItems
         
     | 
| 
      
 163 
     | 
    
         
            +
                AND the raw items provided by the developer in `items`.
         
     | 
| 
      
 164 
     | 
    
         
            +
              */
         
     | 
| 
      
 165 
     | 
    
         
            +
              _scsv_getValueForMenuItem: function(item) {
         
     | 
| 
      
 166 
     | 
    
         
            +
                var valueKey = this.get('itemValueKey') || 'value';
         
     | 
| 
      
 167 
     | 
    
         
            +
             
     | 
| 
      
 168 
     | 
    
         
            +
                if (SC.typeOf(item) === SC.T_STRING) {
         
     | 
| 
      
 169 
     | 
    
         
            +
                  return item;
         
     | 
| 
      
 170 
     | 
    
         
            +
                } else if (item.get) {
         
     | 
| 
      
 171 
     | 
    
         
            +
                  return item.get(valueKey);
         
     | 
| 
      
 172 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 173 
     | 
    
         
            +
                  return item[valueKey];
         
     | 
| 
      
 174 
     | 
    
         
            +
                }
         
     | 
| 
      
 175 
     | 
    
         
            +
              },
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
              /**
         
     | 
| 
      
 178 
     | 
    
         
            +
                * When the selected item changes, we need to update our value.
         
     | 
| 
      
 179 
     | 
    
         
            +
                * @private
         
     | 
| 
      
 180 
     | 
    
         
            +
              */
         
     | 
| 
      
 181 
     | 
    
         
            +
              _scsv_selectedItemDidChange: function() {
         
     | 
| 
      
 182 
     | 
    
         
            +
                var sel = this.get('selectedItem'),
         
     | 
| 
      
 183 
     | 
    
         
            +
                    last = this._scsv_lastSelection,
         
     | 
| 
      
 184 
     | 
    
         
            +
                    titleKey = this.get('itemTitleKey') || 'title',
         
     | 
| 
      
 185 
     | 
    
         
            +
                    valueKey = this.get('itemValueKey') || 'value';
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
                // selected item could be a menu item from SC.MenuPane's displayItems, or it could
         
     | 
| 
      
 188 
     | 
    
         
            +
                // be a raw item. So, we have to use _scsv_getValueForMenuItem to resolve it.
         
     | 
| 
      
 189 
     | 
    
         
            +
                if(sel) {
         
     | 
| 
      
 190 
     | 
    
         
            +
                  this.setIfChanged('value', this._scsv_getValueForMenuItem(sel));
         
     | 
| 
      
 191 
     | 
    
         
            +
                }
         
     | 
| 
      
 192 
     | 
    
         
            +
             
     | 
| 
      
 193 
     | 
    
         
            +
                // add/remove observers for the title and value so we can invalidate.
         
     | 
| 
      
 194 
     | 
    
         
            +
                if (last && last.addObserver && sel !== last) {
         
     | 
| 
      
 195 
     | 
    
         
            +
                  last.removeObserver(titleKey, this, this._scsv_selectedItemPropertyDidChange);
         
     | 
| 
      
 196 
     | 
    
         
            +
                  last.removeObserver(valueKey, this, this._scsv_selectedItemPropertyDidChange);
         
     | 
| 
      
 197 
     | 
    
         
            +
                }
         
     | 
| 
      
 198 
     | 
    
         
            +
                
         
     | 
| 
      
 199 
     | 
    
         
            +
                if (sel && sel.addObserver && sel !== last) {
         
     | 
| 
      
 200 
     | 
    
         
            +
                  sel.addObserver(titleKey, this, this._scsv_selectedItemPropertyDidChange);
         
     | 
| 
      
 201 
     | 
    
         
            +
                  sel.addObserver(valueKey, this, this._scsv_selectedItemPropertyDidChange);
         
     | 
| 
      
 202 
     | 
    
         
            +
                }
         
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
      
 204 
     | 
    
         
            +
                this._scsv_lastSelection = sel;
         
     | 
| 
      
 205 
     | 
    
         
            +
              }.observes('selectedItem'),
         
     | 
| 
      
 206 
     | 
    
         
            +
             
     | 
| 
      
 207 
     | 
    
         
            +
              // called when either title or value changes on the selected item
         
     | 
| 
      
 208 
     | 
    
         
            +
              _scsv_selectedItemPropertyDidChange: function(item) {
         
     | 
| 
      
 209 
     | 
    
         
            +
                this.notifyPropertyChange('title');
         
     | 
| 
      
 210 
     | 
    
         
            +
                this.set('value', item.get(this.get('itemValueKey') || 'value'));
         
     | 
| 
      
 211 
     | 
    
         
            +
              },
         
     | 
| 
      
 212 
     | 
    
         
            +
             
     | 
| 
      
 213 
     | 
    
         
            +
              /**
         
     | 
| 
      
 214 
     | 
    
         
            +
                The title to show when no item is selected.
         
     | 
| 
      
 215 
     | 
    
         
            +
             
     | 
| 
      
 216 
     | 
    
         
            +
                @property
         
     | 
| 
      
 217 
     | 
    
         
            +
                @type String
         
     | 
| 
      
 218 
     | 
    
         
            +
                @default ""
         
     | 
| 
      
 219 
     | 
    
         
            +
              */
         
     | 
| 
      
 220 
     | 
    
         
            +
              defaultTitle: "",
         
     | 
| 
      
 221 
     | 
    
         
            +
             
     | 
| 
      
 222 
     | 
    
         
            +
              /**
         
     | 
| 
      
 223 
     | 
    
         
            +
                The title of the button, derived from the selected item.
         
     | 
| 
      
 224 
     | 
    
         
            +
              */
         
     | 
| 
      
 225 
     | 
    
         
            +
              title: function() {
         
     | 
| 
      
 226 
     | 
    
         
            +
                var sel = this.get('selectedItem');
         
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
      
 228 
     | 
    
         
            +
                if (!sel) {
         
     | 
| 
      
 229 
     | 
    
         
            +
                  return this.get('defaultTitle');
         
     | 
| 
      
 230 
     | 
    
         
            +
                } else if (sel.get) {
         
     | 
| 
      
 231 
     | 
    
         
            +
                  return sel.get(this.get('itemTitleKey') || 'title');
         
     | 
| 
      
 232 
     | 
    
         
            +
                } else if (SC.typeOf(sel) == SC.T_HASH) {
         
     | 
| 
      
 233 
     | 
    
         
            +
                  return sel[this.get('itemTitleKey') || 'title'];
         
     | 
| 
      
 234 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 235 
     | 
    
         
            +
                  return sel;
         
     | 
| 
      
 236 
     | 
    
         
            +
                }
         
     | 
| 
      
 237 
     | 
    
         
            +
              }.property('selectedItem').cacheable(),
         
     | 
| 
      
 238 
     | 
    
         
            +
             
     | 
| 
      
 239 
     | 
    
         
            +
              /**
         
     | 
| 
      
 240 
     | 
    
         
            +
                * When the value changes, we need to update selectedItem.
         
     | 
| 
      
 241 
     | 
    
         
            +
                * @private
         
     | 
| 
      
 242 
     | 
    
         
            +
              */
         
     | 
| 
      
 243 
     | 
    
         
            +
              _scsv_valueDidChange: function() {
         
     | 
| 
      
 244 
     | 
    
         
            +
                var value = this.get('value');
         
     | 
| 
      
 245 
     | 
    
         
            +
             
     | 
| 
      
 246 
     | 
    
         
            +
                if (!this.get('items')) {
         
     | 
| 
      
 247 
     | 
    
         
            +
                  return;
         
     | 
| 
      
 248 
     | 
    
         
            +
                }
         
     | 
| 
      
 249 
     | 
    
         
            +
             
     | 
| 
      
 250 
     | 
    
         
            +
                var items = this.get('items'), len = items.length, idx;
         
     | 
| 
      
 251 
     | 
    
         
            +
                for (idx = 0; idx < len; idx++) {
         
     | 
| 
      
 252 
     | 
    
         
            +
                  if (this._scsv_getValueForMenuItem(items[idx]) === value) {
         
     | 
| 
      
 253 
     | 
    
         
            +
                    this.setIfChanged('selectedItem', items[idx]);
         
     | 
| 
      
 254 
     | 
    
         
            +
                    return;
         
     | 
| 
      
 255 
     | 
    
         
            +
                  }
         
     | 
| 
      
 256 
     | 
    
         
            +
                }
         
     | 
| 
      
 257 
     | 
    
         
            +
             
     | 
| 
      
 258 
     | 
    
         
            +
                // if we got here, this means no item is selected
         
     | 
| 
      
 259 
     | 
    
         
            +
                this.setIfChanged('selectedItem', null);
         
     | 
| 
      
 260 
     | 
    
         
            +
              }.observes('value'),
         
     | 
| 
      
 261 
     | 
    
         
            +
             
     | 
| 
      
 262 
     | 
    
         
            +
              /**
         
     | 
| 
      
 263 
     | 
    
         
            +
                SelectView must set the selectView property on the menu so that the menu's
         
     | 
| 
      
 264 
     | 
    
         
            +
                properties get bound to the SelectView's. The bindings get set up by 
         
     | 
| 
      
 265 
     | 
    
         
            +
                the SelectViewMenu mixin, which should be mixed in to any SelectView menu.
         
     | 
| 
      
 266 
     | 
    
         
            +
             
     | 
| 
      
 267 
     | 
    
         
            +
                In addition, the initial selected item and the initial minimum menu width are set.
         
     | 
| 
      
 268 
     | 
    
         
            +
                @private
         
     | 
| 
      
 269 
     | 
    
         
            +
              */
         
     | 
| 
      
 270 
     | 
    
         
            +
              createMenu: function(klass) {
         
     | 
| 
      
 271 
     | 
    
         
            +
                var attrs = {
         
     | 
| 
      
 272 
     | 
    
         
            +
                  selectView: this,
         
     | 
| 
      
 273 
     | 
    
         
            +
                  selectedItem: this.get('selectedItem'),
         
     | 
| 
      
 274 
     | 
    
         
            +
                  minimumMenuWidth: this.get('minimumMenuWidth')
         
     | 
| 
      
 275 
     | 
    
         
            +
                };
         
     | 
| 
      
 276 
     | 
    
         
            +
             
     | 
| 
      
 277 
     | 
    
         
            +
                return klass.create(attrs);
         
     | 
| 
      
 278 
     | 
    
         
            +
              },
         
     | 
| 
      
 279 
     | 
    
         
            +
             
     | 
| 
      
 280 
     | 
    
         
            +
              /**
         
     | 
| 
      
 281 
     | 
    
         
            +
                The amount by which to offset the menu's left position when displaying it.
         
     | 
| 
      
 282 
     | 
    
         
            +
                This can be used to make sure the selected menu item is directly on top of
         
     | 
| 
      
 283 
     | 
    
         
            +
                the label in the SelectView.
         
     | 
| 
      
 284 
     | 
    
         
            +
             
     | 
| 
      
 285 
     | 
    
         
            +
                By default, this comes from the render delegate's menuLeftOffset property. 
         
     | 
| 
      
 286 
     | 
    
         
            +
                If you are writing a theme, you should set the value there.
         
     | 
| 
      
 287 
     | 
    
         
            +
                
         
     | 
| 
      
 288 
     | 
    
         
            +
                @property
         
     | 
| 
      
 289 
     | 
    
         
            +
                @type Number
         
     | 
| 
      
 290 
     | 
    
         
            +
                @default 'menuLeftOffset' from render delegate if present, or 0.
         
     | 
| 
      
 291 
     | 
    
         
            +
              */
         
     | 
| 
      
 292 
     | 
    
         
            +
              menuLeftOffset: SC.propertyFromRenderDelegate('menuLeftOffset', 0),
         
     | 
| 
      
 293 
     | 
    
         
            +
             
     | 
| 
      
 294 
     | 
    
         
            +
              /**
         
     | 
| 
      
 295 
     | 
    
         
            +
                The amount by which to offset the menu's top position when displaying it.
         
     | 
| 
      
 296 
     | 
    
         
            +
                This is added to any amount calculated based on the 'top' of a menu item.
         
     | 
| 
      
 297 
     | 
    
         
            +
             
     | 
| 
      
 298 
     | 
    
         
            +
                This can be used to make sure the selected menu item's label is directly on
         
     | 
| 
      
 299 
     | 
    
         
            +
                top of the SelectView's label.
         
     | 
| 
      
 300 
     | 
    
         
            +
             
     | 
| 
      
 301 
     | 
    
         
            +
                By default, this comes from the render delegate's menuTopOffset property.
         
     | 
| 
      
 302 
     | 
    
         
            +
                If you are writing a theme, you should set the value there.
         
     | 
| 
      
 303 
     | 
    
         
            +
             
     | 
| 
      
 304 
     | 
    
         
            +
                @property
         
     | 
| 
      
 305 
     | 
    
         
            +
                @type Number
         
     | 
| 
      
 306 
     | 
    
         
            +
                @default 'menuTopOffset' from render delegate if present, or 0.
         
     | 
| 
      
 307 
     | 
    
         
            +
              */
         
     | 
| 
      
 308 
     | 
    
         
            +
              menuTopOffset: SC.propertyFromRenderDelegate('menuTopOffset', 0),
         
     | 
| 
      
 309 
     | 
    
         
            +
             
     | 
| 
      
 310 
     | 
    
         
            +
              /**
         
     | 
| 
      
 311 
     | 
    
         
            +
                An amount to add to the menu's minimum width. For instance, this could be
         
     | 
| 
      
 312 
     | 
    
         
            +
                set to a negative value to let arrows on the side of the SelectView be visible.
         
     | 
| 
      
 313 
     | 
    
         
            +
             
     | 
| 
      
 314 
     | 
    
         
            +
                By default, this comes from the render delegate's menuMinimumWidthOffset property.
         
     | 
| 
      
 315 
     | 
    
         
            +
                If you are writing a theme, you should set the value there.
         
     | 
| 
      
 316 
     | 
    
         
            +
             
     | 
| 
      
 317 
     | 
    
         
            +
                @property
         
     | 
| 
      
 318 
     | 
    
         
            +
                @type Number
         
     | 
| 
      
 319 
     | 
    
         
            +
                @default 'menuWidthOffset' from render delegate if present, or 0.
         
     | 
| 
      
 320 
     | 
    
         
            +
              */
         
     | 
| 
      
 321 
     | 
    
         
            +
              menuMinimumWidthOffset: SC.propertyFromRenderDelegate('menuMinimumWidthOffset', 0),
         
     | 
| 
      
 322 
     | 
    
         
            +
             
     | 
| 
      
 323 
     | 
    
         
            +
              /**
         
     | 
| 
      
 324 
     | 
    
         
            +
                The prefer matrix for menu positioning. It is calculated so that the selected
         
     | 
| 
      
 325 
     | 
    
         
            +
                menu item is positioned directly over the SelectView.
         
     | 
| 
      
 326 
     | 
    
         
            +
                
         
     | 
| 
      
 327 
     | 
    
         
            +
                @property
         
     | 
| 
      
 328 
     | 
    
         
            +
                @type Array
         
     | 
| 
      
 329 
     | 
    
         
            +
                @private
         
     | 
| 
      
 330 
     | 
    
         
            +
              */
         
     | 
| 
      
 331 
     | 
    
         
            +
              menuPreferMatrix: function() {
         
     | 
| 
      
 332 
     | 
    
         
            +
                var menu = this.get('menu'),
         
     | 
| 
      
 333 
     | 
    
         
            +
                    leftPosition = this.get('menuLeftOffset'),
         
     | 
| 
      
 334 
     | 
    
         
            +
                    topPosition = this.get('menuTopOffset');
         
     | 
| 
      
 335 
     | 
    
         
            +
             
     | 
| 
      
 336 
     | 
    
         
            +
                if (!menu) {
         
     | 
| 
      
 337 
     | 
    
         
            +
                  return [leftPosition, topPosition, 2];
         
     | 
| 
      
 338 
     | 
    
         
            +
                }
         
     | 
| 
      
 339 
     | 
    
         
            +
             
     | 
| 
      
 340 
     | 
    
         
            +
                var idx = this.get('_selectedItemIndex'), itemViews = menu.get('menuItemViews');
         
     | 
| 
      
 341 
     | 
    
         
            +
                if (idx > -1) {
         
     | 
| 
      
 342 
     | 
    
         
            +
                  return [leftPosition, topPosition - itemViews[idx].get('layout').top, 2];
         
     | 
| 
      
 343 
     | 
    
         
            +
                }
         
     | 
| 
      
 344 
     | 
    
         
            +
             
     | 
| 
      
 345 
     | 
    
         
            +
                return [leftPosition, topPosition, 2];
         
     | 
| 
      
 346 
     | 
    
         
            +
             
     | 
| 
      
 347 
     | 
    
         
            +
              }.property('value', 'menu').cacheable(),
         
     | 
| 
      
 348 
     | 
    
         
            +
             
     | 
| 
      
 349 
     | 
    
         
            +
              /**
         
     | 
| 
      
 350 
     | 
    
         
            +
                Used to calculate things like the menu's top position.
         
     | 
| 
      
 351 
     | 
    
         
            +
             
     | 
| 
      
 352 
     | 
    
         
            +
                @private
         
     | 
| 
      
 353 
     | 
    
         
            +
              */
         
     | 
| 
      
 354 
     | 
    
         
            +
              _selectedItemIndex: function() {
         
     | 
| 
      
 355 
     | 
    
         
            +
                var menu = this.get('menu');
         
     | 
| 
      
 356 
     | 
    
         
            +
                if (!menu) {
         
     | 
| 
      
 357 
     | 
    
         
            +
                  return -1;
         
     | 
| 
      
 358 
     | 
    
         
            +
                }
         
     | 
| 
      
 359 
     | 
    
         
            +
             
     | 
| 
      
 360 
     | 
    
         
            +
                // We have to find the selected item, and then get its 'top' position so we
         
     | 
| 
      
 361 
     | 
    
         
            +
                // can position the menu correctly.
         
     | 
| 
      
 362 
     | 
    
         
            +
                var itemViews = menu.get('menuItemViews'), idx, len = itemViews.length, view;
         
     | 
| 
      
 363 
     | 
    
         
            +
                for (idx = 0; idx < len; idx++) {
         
     | 
| 
      
 364 
     | 
    
         
            +
                  view = itemViews[idx];
         
     | 
| 
      
 365 
     | 
    
         
            +
             
     | 
| 
      
 366 
     | 
    
         
            +
                  // we have to compare via value
         
     | 
| 
      
 367 
     | 
    
         
            +
                  var value = view.get('content').get(this.get('itemValueKey'));
         
     | 
| 
      
 368 
     | 
    
         
            +
                  if (value === this.get('value')) {
         
     | 
| 
      
 369 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 370 
     | 
    
         
            +
                  }
         
     | 
| 
      
 371 
     | 
    
         
            +
                }
         
     | 
| 
      
 372 
     | 
    
         
            +
             
     | 
| 
      
 373 
     | 
    
         
            +
                if (idx < len) {
         
     | 
| 
      
 374 
     | 
    
         
            +
                  return idx;
         
     | 
| 
      
 375 
     | 
    
         
            +
                }
         
     | 
| 
      
 376 
     | 
    
         
            +
             
     | 
| 
      
 377 
     | 
    
         
            +
                return -1;
         
     | 
| 
      
 378 
     | 
    
         
            +
              }.property('value', 'menu').cacheable(),
         
     | 
| 
      
 379 
     | 
    
         
            +
             
     | 
| 
      
 380 
     | 
    
         
            +
             
     | 
| 
      
 381 
     | 
    
         
            +
              /*
         
     | 
| 
      
 382 
     | 
    
         
            +
                Documented in base class; supplying documentation here will break the argument list.
         
     | 
| 
      
 383 
     | 
    
         
            +
              */
         
     | 
| 
      
 384 
     | 
    
         
            +
              showMenu: function(orig) {
         
     | 
| 
      
 385 
     | 
    
         
            +
                orig();
         
     | 
| 
      
 386 
     | 
    
         
            +
             
     | 
| 
      
 387 
     | 
    
         
            +
                var menu = this.get('menu'), itemViews = menu.get('menuItemViews');
         
     | 
| 
      
 388 
     | 
    
         
            +
              }.enhance(),
         
     | 
| 
      
 389 
     | 
    
         
            +
             
     | 
| 
      
 390 
     | 
    
         
            +
              /**
         
     | 
| 
      
 391 
     | 
    
         
            +
                The minimum width for the child menu. For instance, this property can make the
         
     | 
| 
      
 392 
     | 
    
         
            +
                menu always cover the entire SelectView--or, alternatively, cover all but the
         
     | 
| 
      
 393 
     | 
    
         
            +
                arrows on the side.
         
     | 
| 
      
 394 
     | 
    
         
            +
             
     | 
| 
      
 395 
     | 
    
         
            +
                By default, it is calculated by adding the menuMinimumWidthOffset to the view's 
         
     | 
| 
      
 396 
     | 
    
         
            +
                width. If you are writing a theme and want to change the width so the menu covers
         
     | 
| 
      
 397 
     | 
    
         
            +
                a specific part of the select view, change your render delegate's menuMinimumWidthOffset
         
     | 
| 
      
 398 
     | 
    
         
            +
                property.
         
     | 
| 
      
 399 
     | 
    
         
            +
             
     | 
| 
      
 400 
     | 
    
         
            +
                @type Number
         
     | 
| 
      
 401 
     | 
    
         
            +
                @property
         
     | 
| 
      
 402 
     | 
    
         
            +
              */
         
     | 
| 
      
 403 
     | 
    
         
            +
              minimumMenuWidth: function() {
         
     | 
| 
      
 404 
     | 
    
         
            +
                return this.get('frame').width + this.get('menuMinimumWidthOffset');
         
     | 
| 
      
 405 
     | 
    
         
            +
              }.property('frame', 'menuMinimumWidthOffset').cacheable(),
         
     | 
| 
      
 406 
     | 
    
         
            +
             
     | 
| 
      
 407 
     | 
    
         
            +
              //
         
     | 
| 
      
 408 
     | 
    
         
            +
              // KEY HANDLING
         
     | 
| 
      
 409 
     | 
    
         
            +
              //
         
     | 
| 
      
 410 
     | 
    
         
            +
              /**
         
     | 
| 
      
 411 
     | 
    
         
            +
                @private
         
     | 
| 
      
 412 
     | 
    
         
            +
             
     | 
| 
      
 413 
     | 
    
         
            +
                Handle Key event - Down arrow key
         
     | 
| 
      
 414 
     | 
    
         
            +
              */
         
     | 
| 
      
 415 
     | 
    
         
            +
              keyDown: function(event) {
         
     | 
| 
      
 416 
     | 
    
         
            +
                if ( this.interpretKeyEvents(event) ) {
         
     | 
| 
      
 417 
     | 
    
         
            +
                  return YES;
         
     | 
| 
      
 418 
     | 
    
         
            +
                }
         
     | 
| 
      
 419 
     | 
    
         
            +
                else {
         
     | 
| 
      
 420 
     | 
    
         
            +
                  sc_super();
         
     | 
| 
      
 421 
     | 
    
         
            +
                }
         
     | 
| 
      
 422 
     | 
    
         
            +
              },
         
     | 
| 
      
 423 
     | 
    
         
            +
             
     | 
| 
      
 424 
     | 
    
         
            +
              /**
         
     | 
| 
      
 425 
     | 
    
         
            +
                @private
         
     | 
| 
      
 426 
     | 
    
         
            +
             
     | 
| 
      
 427 
     | 
    
         
            +
                Pressing the Up or Down arrow key should display the menu pane
         
     | 
| 
      
 428 
     | 
    
         
            +
              */
         
     | 
| 
      
 429 
     | 
    
         
            +
              interpretKeyEvents: function(event) {
         
     | 
| 
      
 430 
     | 
    
         
            +
                if (event) {
         
     | 
| 
      
 431 
     | 
    
         
            +
                  if ((event.keyCode === 38 || event.keyCode === 40)) {
         
     | 
| 
      
 432 
     | 
    
         
            +
                    this.showMenu();
         
     | 
| 
      
 433 
     | 
    
         
            +
                    return YES;
         
     | 
| 
      
 434 
     | 
    
         
            +
                  }
         
     | 
| 
      
 435 
     | 
    
         
            +
                  else if (event.keyCode === 27) {
         
     | 
| 
      
 436 
     | 
    
         
            +
                    this.resignFirstResponder() ;
         
     | 
| 
      
 437 
     | 
    
         
            +
                    return YES;
         
     | 
| 
      
 438 
     | 
    
         
            +
                  }
         
     | 
| 
      
 439 
     | 
    
         
            +
                }
         
     | 
| 
      
 440 
     | 
    
         
            +
                return sc_super();
         
     | 
| 
      
 441 
     | 
    
         
            +
              },
         
     | 
| 
      
 442 
     | 
    
         
            +
             
     | 
| 
      
 443 
     | 
    
         
            +
              /** @private
         
     | 
| 
      
 444 
     | 
    
         
            +
               Function overridden - tied to the isEnabled state 
         
     | 
| 
      
 445 
     | 
    
         
            +
              */
         
     | 
| 
      
 446 
     | 
    
         
            +
              acceptsFirstResponder: function() {
         
     | 
| 
      
 447 
     | 
    
         
            +
                return this.get('isEnabled');
         
     | 
| 
      
 448 
     | 
    
         
            +
              }.property('isEnabled').cacheable()
         
     | 
| 
      
 449 
     | 
    
         
            +
             
     | 
| 
      
 450 
     | 
    
         
            +
            });
         
     |