sproutcore 1.5.0.pre.3 → 1.5.0.pre.4
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/.rspec +1 -0
- data/CHANGELOG +42 -0
- data/README.txt +25 -0
- data/VERSION.yml +1 -1
- data/bin/sc-build +1 -1
- data/bin/sc-build-number +1 -1
- data/bin/sc-docs +1 -1
- data/bin/sc-gen +1 -1
- data/bin/sc-init +1 -1
- data/bin/sc-manifest +1 -1
- data/bin/sc-server +1 -1
- data/bin/sproutcore +1 -1
- data/lib/buildtasks/build.rake +5 -0
- data/lib/buildtasks/manifest.rake +20 -1
- data/lib/frameworks/sproutcore/Buildfile +12 -9
- data/lib/frameworks/sproutcore/CHANGELOG.md +48 -0
- data/lib/frameworks/sproutcore/apps/greenhouse/README +2 -9
- data/lib/frameworks/sproutcore/apps/greenhouse/TODO +11 -27
- data/lib/frameworks/sproutcore/apps/greenhouse/controllers/library.js +3 -10
- data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/css/main-page.css +4 -31
- data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/dialogs.js +5 -4
- data/lib/frameworks/sproutcore/apps/greenhouse/models/dir.js +3 -3
- data/lib/frameworks/sproutcore/apps/greenhouse/models/file.js +2 -2
- data/lib/frameworks/sproutcore/apps/greenhouse/states/main.js +31 -14
- data/lib/frameworks/sproutcore/apps/greenhouse/states/modals.js +2 -1
- data/lib/frameworks/sproutcore/apps/greenhouse/states/ready.js +27 -1
- data/lib/frameworks/sproutcore/apps/greenhouse/tests/views/list_item.js +1 -0
- data/lib/frameworks/sproutcore/apps/greenhouse/tests/views/plist_item.js +20 -0
- data/lib/frameworks/sproutcore/apps/greenhouse/theme.js +25 -0
- data/lib/frameworks/sproutcore/apps/greenhouse/views/plist_item.js +161 -24
- data/lib/frameworks/sproutcore/apps/greenhouse/views/tear_off_picker.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/bootstrap/system/browser.js +37 -25
- data/lib/frameworks/sproutcore/frameworks/bootstrap/tests/system/browser.js +135 -26
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/controllers/array.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/controllers/controller.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/controllers/object.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/core.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/ext/object.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/ext/run_loop.js +1 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/mixins/delegate_support.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/mixins/responder_context.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/mixins/selection_support.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/mixins/string.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/keyboard.js +68 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/layout.js +108 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/panes/main.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/manipulation.js +27 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/panes/pane.js +215 -505
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/template.js +24 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/visibility.js +11 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/protocols/observable_protocol.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/protocols/sparse_array_delegate.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/resources/core.css +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/resources/view.css +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/application.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/browser.js +1 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/builder.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/core_query.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/cursor.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/device.js +210 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/event.js +5 -5
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/json.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/locale.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/page.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/platform.js +31 -5
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/ready.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/render_context.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/responder.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/root_responder.js +83 -110
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/selection_set.js +7 -4
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/sparse_array.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/theme.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/timer.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/utils/rect.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/utils.js +151 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/array/array_case.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/array/enum_case.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/array/null_case.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/array/selection_support.js +26 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/array/single_case.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/object/empty_case.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/object/multiple_case.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/object/single_case.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/object/single_enumerable_case.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/mixins/responder_context.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/mixins/string.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/panes/template.js +14 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/builder.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/core_query/within.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/json.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/locale.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/begin.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/element.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/end.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/get.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/helpers_attr.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/helpers_basic.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/helpers_className.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/helpers_style.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/init.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/join.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/push_text.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/tag.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/update.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/root_responder/makeKeyPane.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/root_responder/makeMainPane.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/root_responder/makeMenuPane.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/root_responder/root_responder.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/root_responder/targetForAction.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/selection_set/add.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/selection_set/copy.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/selection_set/indexSetForSource.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/selection_set/isEqual.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/selection_set/remove.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/sparse_array.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/theme.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/timer/invalidate.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/timer/invokeLater.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/timer/isPaused.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/timer/performAction.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/timer/schedule.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/utils/normalizeURL.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/utils/offset.js +268 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/utils/rect.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/main_pane.js +43 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/pane/append_remove.js +107 -18
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/pane/child_view.js +20 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/pane/firstResponder.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/pane/keyPane.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/pane/layout.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/pane/sendEvent.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template/checkbox_support.js +32 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template/text_field_support.js +73 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template_view/collection.js +65 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template_view/core.js +67 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template_view/handlebars.js +295 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/animation.js +19 -18
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/build.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/build_children.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/clippingFrame.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/convertFrames.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/convertLayouts.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/createChildViews.js +18 -15
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/createLayer.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/destroyLayer.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/didAppendToDocument.js +11 -8
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/findLayerInParentLayer.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/init.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/insertBefore.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/isVisible.js +28 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/isVisibleInWindow.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/keyboard.js +22 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/layer.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/layoutChildViews.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutDidChange.js +180 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutStyle.js +640 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/parentViewDidChange.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/prepareContext.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/removeChild.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/render.js +125 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/render_delegate_support.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/replaceChild.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/static_layout.js +21 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/theme.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/updateLayer.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/updateLayerLocation.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/view.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/viewDidResize.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/template/checkbox_support.js +20 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/template/collection.js +99 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/template/text_field_support.js +35 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/template.js +77 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/animation.js +187 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/base.js +1 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/cursor.js +41 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/enabled.js +57 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/keyboard.js +223 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout.js +1150 -0
- data/lib/frameworks/sproutcore/frameworks/{amber/views → core_foundation/views/view}/layout_style.js +93 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/manipulation.js +489 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/theming.js +362 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/touch.js +67 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/visibility.js +113 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view.js +1280 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/models/child_attribute.js +27 -53
- data/lib/frameworks/sproutcore/frameworks/datastore/models/children_attribute.js +13 -19
- data/lib/frameworks/sproutcore/frameworks/datastore/models/many_attribute.js +1 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/models/record.js +183 -71
- data/lib/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +1 -2
- data/lib/frameworks/sproutcore/frameworks/datastore/system/child_array.js +26 -46
- data/lib/frameworks/sproutcore/frameworks/datastore/system/nested_store.js +25 -4
- data/lib/frameworks/sproutcore/frameworks/datastore/system/store.js +139 -21
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/data_sources/fixtures.js +6 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/integration/cyclical_relationship.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/{parentless.js → data_store.js} +62 -16
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record.js +51 -17
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_array.js +36 -10
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_array_complex.js +11 -11
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_complex.js +8 -8
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record/normalize.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/{foundation/english.lproj → datetime/resources}/strings.js +1 -0
- data/lib/frameworks/sproutcore/frameworks/{foundation → datetime}/system/datetime.js +5 -37
- data/lib/frameworks/sproutcore/frameworks/{foundation → datetime}/tests/system/datetime.js +1 -0
- data/lib/frameworks/sproutcore/frameworks/debug/core.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/designer/controllers/designs.js +1 -2
- data/lib/frameworks/sproutcore/frameworks/designer/designers/object_designer.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/designer/designers/view_designer.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/designer/views/designer_drop_target.js +9 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/english.lproj/segmented.css +71 -70
- data/lib/frameworks/sproutcore/frameworks/desktop/mixins/collection_row_delegate.js +10 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/segment.js +4 -19
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/segmented.js +33 -14
- data/lib/frameworks/sproutcore/frameworks/desktop/system/drag.js +25 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/date_field/ui.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/methods.js +25 -103
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/ui.js +102 -92
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/tab/ui.js +22 -25
- data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +38 -25
- data/lib/frameworks/sproutcore/frameworks/desktop/views/date_field.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/views/segment.js +42 -22
- data/lib/frameworks/sproutcore/frameworks/desktop/views/segmented.js +513 -230
- data/lib/frameworks/sproutcore/frameworks/desktop/views/select_field.js +0 -2
- data/lib/frameworks/sproutcore/frameworks/experimental/README.md +23 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/device_motion/README.md +11 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/device_motion/device.js +215 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/device_motion/platform.js +67 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/polymorphism/README.md +34 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/polymorphism/models/polymorphic_single_attribute.js +183 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/polymorphism/models/record.js +23 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/polymorphism/tests/models/polymorphic/single.js +124 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/auto_resize.js +0 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inner_frame.js +151 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/canvas_image.js +27 -17
- data/lib/frameworks/sproutcore/frameworks/foundation/system/image_queue.js +6 -3
- data/lib/frameworks/sproutcore/frameworks/foundation/system/logger.js +163 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/system/user_defaults.js +6 -3
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_text_field/beginEditing.js +1 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/system/logger.js +44 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/image/ui.js +200 -167
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/ui.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/views/image.js +52 -137
- data/lib/frameworks/sproutcore/frameworks/foundation/views/text_field.js +7 -11
- data/lib/frameworks/sproutcore/frameworks/handlebars/extensions.js +138 -0
- data/lib/frameworks/sproutcore/frameworks/handlebars/handlebars.js +1338 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/core.js +32 -26
- data/lib/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/base.js +162 -3
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/array.js +10 -5
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/enumerable.js +123 -3
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +12 -5
- data/lib/frameworks/sproutcore/frameworks/runtime/private/chain_observer.js +50 -13
- data/lib/frameworks/sproutcore/frameworks/runtime/system/logger.js +163 -333
- data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +58 -8
- data/lib/frameworks/sproutcore/frameworks/runtime/system/run_loop.js +2 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/core/itemType.js +9 -6
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/core/makeArray.js +15 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/array.js +2 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/chained.js +31 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/observable.js +18 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/logger.js +31 -143
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/object/concatenated_properties.js +71 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/object/enhance.js +177 -0
- data/lib/frameworks/sproutcore/frameworks/table/views/table.js +5 -4
- data/lib/frameworks/sproutcore/frameworks/table/views/table_header.js +5 -3
- data/lib/frameworks/sproutcore/themes/ace/resources/button/button.js +8 -2
- data/lib/frameworks/sproutcore/themes/ace/resources/menu/menu.css +2 -3
- data/lib/frameworks/sproutcore/themes/ace/resources/segmented/18px/segmented.css +1 -1
- data/lib/frameworks/sproutcore/themes/ace/resources/segmented/24px/segmented.css +1 -1
- data/lib/frameworks/sproutcore/themes/ace/resources/segmented/30px/segmented.css +1 -1
- data/lib/frameworks/sproutcore/themes/ace/resources/segmented/44px/segmented.css +1 -1
- data/lib/frameworks/sproutcore/themes/ace/resources/segmented/segmented.css +2 -2
- data/lib/frameworks/sproutcore/themes/standard_theme/english.lproj/segmented.css +62 -62
- data/lib/gen/html_app/Buildfile +36 -0
- data/lib/gen/html_app/README +1 -0
- data/lib/gen/html_app/USAGE +15 -0
- data/lib/gen/html_app/templates/apps/@target_name@/@target_name@.js +14 -0
- data/lib/gen/html_app/templates/apps/@target_name@/resources/images/.gitkeep +0 -0
- data/lib/gen/html_app/templates/apps/@target_name@/resources/stylesheets/@target_name@.css +0 -0
- data/lib/gen/html_app/templates/apps/@target_name@/resources/templates/@target_name@.handlebars +1 -0
- data/lib/gen/html_project/Buildfile +45 -0
- data/lib/gen/html_project/INIT +3 -0
- data/lib/gen/html_project/README +1 -0
- data/lib/gen/html_project/USAGE +2 -0
- data/lib/gen/html_project/templates/@filename@/Buildfile +8 -0
- data/lib/gen/html_project/templates/@filename@/README +7 -0
- data/lib/sproutcore/builders/handlebars.rb +30 -0
- data/lib/sproutcore/builders.rb +1 -1
- data/lib/sproutcore/helpers/static_helper.rb +3 -3
- data/lib/sproutcore/tools/init.rb +25 -9
- data/spec/buildtasks/manifest/prepare_build_tasks/handlebars_spec.rb +39 -0
- data/spec/fixtures/builder_tests/apps/handlebars_test/template.handlebars +5 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/templates/demo.handlebars +4 -0
- data/spec/lib/builders/handlebars_spec.rb +29 -0
- data/vendor/chance/lib/chance/imagers/data_url.rb +20 -7
- data/vendor/chance/lib/chance/instance.rb +4 -1
- data/vendor/chance/lib/chance/parser.rb +31 -31
- data/vendor/chance/lib/chance/slicing.rb +38 -8
- metadata +195 -225
- data/lib/frameworks/sproutcore/frameworks/amber/system/device.js +0 -143
- data/lib/frameworks/sproutcore/frameworks/amber/system/utils.js +0 -174
- data/lib/frameworks/sproutcore/frameworks/amber/tests/views/main_pane.js +0 -31
- data/lib/frameworks/sproutcore/frameworks/amber/tests/views/pane/sendTouchEvent.js +0 -267
- data/lib/frameworks/sproutcore/frameworks/amber/tests/views/view/layoutDidChange.js +0 -149
- data/lib/frameworks/sproutcore/frameworks/amber/tests/views/view/layoutStyle.js +0 -602
- data/lib/frameworks/sproutcore/frameworks/amber/tests/views/view/render.js +0 -115
- data/lib/frameworks/sproutcore/frameworks/amber/views/base.js +0 -1
- data/lib/frameworks/sproutcore/frameworks/amber/views/view.js +0 -4003
- data/lib/frameworks/sproutcore/frameworks/datastore/models/child_record.js +0 -105
|
@@ -10,24 +10,24 @@
|
|
|
10
10
|
|
|
11
11
|
SegmentedView is a special type of button that can display multiple
|
|
12
12
|
segments. Each segment has a value assigned to it. When the user clicks
|
|
13
|
-
on the segment, the value of that segment will become the new value of
|
|
13
|
+
on the segment, the value of that segment will become the new value of
|
|
14
14
|
the control.
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
You can also optionally configure a target/action that will fire whenever
|
|
17
17
|
the user clicks on an item. This will give your code an opportunity to take
|
|
18
18
|
some action depending on the new value. (of course, you can always bind to
|
|
19
19
|
the value as well, which is generally the preferred approach.)
|
|
20
|
-
|
|
20
|
+
|
|
21
21
|
h1. Defining Your Segments
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
You define your segments by providing a items array, much like you provide
|
|
24
|
-
to a RadioView. Your items array can be as simple as an array of strings
|
|
24
|
+
to a RadioView. Your items array can be as simple as an array of strings
|
|
25
25
|
or as complex as full model objects. Based on how you configure your
|
|
26
|
-
itemKey properties, the segmented view will read the properties it needs
|
|
26
|
+
itemKey properties, the segmented view will read the properties it needs
|
|
27
27
|
from the array and construct the button.
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
You can define the following properties on objects you pass in:
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
| *itemTitleKey* | the title of the button |
|
|
32
32
|
| *itemValueKey* | the value of the button |
|
|
33
33
|
| *itemWidthKey* | the preferred width. if omitted, it autodetects |
|
|
@@ -40,19 +40,19 @@
|
|
|
40
40
|
*/
|
|
41
41
|
SC.SegmentedView = SC.View.extend(SC.Control,
|
|
42
42
|
/** @scope SC.SegmentedView.prototype */ {
|
|
43
|
-
|
|
43
|
+
|
|
44
44
|
classNames: ['sc-segmented-view'],
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
theme: 'square',
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
/**
|
|
49
49
|
The value of the segmented view.
|
|
50
|
-
|
|
50
|
+
|
|
51
51
|
The SegmentedView's value will always be the value of the currently
|
|
52
|
-
selected button. Setting this value will change the selected button.
|
|
52
|
+
selected button. Setting this value will change the selected button.
|
|
53
53
|
If you set this value to something that has no matching button, then
|
|
54
54
|
no buttons will be selected.
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
@field {Object}
|
|
57
57
|
*/
|
|
58
58
|
value: null,
|
|
@@ -60,14 +60,14 @@ SC.SegmentedView = SC.View.extend(SC.Control,
|
|
|
60
60
|
/**
|
|
61
61
|
Set to YES to enabled the segmented view, NO to disabled it.
|
|
62
62
|
*/
|
|
63
|
-
isEnabled: YES,
|
|
63
|
+
isEnabled: YES,
|
|
64
64
|
|
|
65
65
|
/**
|
|
66
66
|
If YES, clicking a selected button again will deselect it, setting the
|
|
67
67
|
segmented views value to null. Defaults to NO.
|
|
68
68
|
*/
|
|
69
|
-
allowsEmptySelection: NO,
|
|
70
|
-
|
|
69
|
+
allowsEmptySelection: NO,
|
|
70
|
+
|
|
71
71
|
/**
|
|
72
72
|
If YES, then clicking on a tab will not deselect the other segments, it
|
|
73
73
|
will simply add or remove it from the selection.
|
|
@@ -78,124 +78,163 @@ SC.SegmentedView = SC.View.extend(SC.Control,
|
|
|
78
78
|
If YES, titles will be localized before display.
|
|
79
79
|
*/
|
|
80
80
|
localize: YES,
|
|
81
|
-
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
Aligns the segments of the segmented view within its frame horizontally.
|
|
84
|
+
*/
|
|
82
85
|
align: SC.ALIGN_CENTER,
|
|
83
|
-
|
|
86
|
+
|
|
84
87
|
/**
|
|
85
88
|
Change the layout direction to make this a vertical set of tabs instead
|
|
86
89
|
of horizontal ones.
|
|
87
90
|
*/
|
|
88
91
|
layoutDirection: SC.LAYOUT_HORIZONTAL,
|
|
89
|
-
|
|
92
|
+
|
|
90
93
|
// ..........................................................
|
|
91
94
|
// SEGMENT DEFINITION
|
|
92
95
|
//
|
|
93
|
-
|
|
96
|
+
|
|
94
97
|
/**
|
|
95
98
|
The array of items to display. This may be a simple array of strings, objects
|
|
96
99
|
or SC.Objects. If you pass objects or SC.Objects, you must also set the
|
|
97
100
|
various itemKey properties to tell the SegmentedView how to extract the
|
|
98
101
|
information it needs.
|
|
99
|
-
|
|
100
|
-
Note: only SC.Object items support key-value coding and therefore
|
|
101
|
-
|
|
102
|
+
|
|
103
|
+
Note: only SC.Object items support key-value coding and therefore may be
|
|
104
|
+
observed by the view for changes to titles, values, icons, widths,
|
|
102
105
|
isEnabled values & tooltips.
|
|
103
|
-
|
|
104
|
-
TODO: explain how to notify the view of changes to String & Object items
|
|
105
|
-
|
|
106
|
+
|
|
106
107
|
@property {Array}
|
|
107
108
|
*/
|
|
108
109
|
items: null,
|
|
109
110
|
|
|
110
|
-
/**
|
|
111
|
+
/**
|
|
111
112
|
The key that contains the title for each item.
|
|
112
|
-
|
|
113
|
+
|
|
113
114
|
@property {String}
|
|
114
115
|
*/
|
|
115
116
|
itemTitleKey: null,
|
|
116
|
-
|
|
117
|
-
/**
|
|
117
|
+
|
|
118
|
+
/**
|
|
118
119
|
The key that contains the value for each item.
|
|
119
|
-
|
|
120
|
+
|
|
120
121
|
@property {String}
|
|
121
122
|
*/
|
|
122
123
|
itemValueKey: null,
|
|
123
|
-
|
|
124
|
-
/**
|
|
124
|
+
|
|
125
|
+
/**
|
|
125
126
|
A key that determines if this item in particular is enabled. Note if the
|
|
126
127
|
control in general is not enabled, no items will be enabled, even if the
|
|
127
128
|
item's enabled property returns YES.
|
|
128
|
-
|
|
129
|
+
|
|
129
130
|
@property {String}
|
|
130
131
|
*/
|
|
131
132
|
itemIsEnabledKey: null,
|
|
132
133
|
|
|
133
|
-
/**
|
|
134
|
+
/**
|
|
134
135
|
The key that contains the icon for each item. If omitted, no icons will
|
|
135
136
|
be displayed.
|
|
136
|
-
|
|
137
|
+
|
|
137
138
|
@property {String}
|
|
138
139
|
*/
|
|
139
140
|
itemIconKey: null,
|
|
140
141
|
|
|
141
|
-
/**
|
|
142
|
+
/**
|
|
142
143
|
The key that contains the desired width for each item. If omitted, the
|
|
143
144
|
width will autosize.
|
|
144
|
-
|
|
145
|
+
|
|
145
146
|
@property {String}
|
|
146
147
|
*/
|
|
147
148
|
itemWidthKey: null,
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
The key that contains the action for this item. If defined, then
|
|
151
|
-
selecting this item will fire the action in addition to changing the
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
The key that contains the action for this item. If defined, then
|
|
152
|
+
selecting this item will fire the action in addition to changing the
|
|
152
153
|
value. See also itemTargetKey.
|
|
153
|
-
|
|
154
|
+
|
|
154
155
|
@property {String}
|
|
155
156
|
*/
|
|
156
157
|
itemActionKey: null,
|
|
157
158
|
|
|
158
|
-
/**
|
|
159
|
+
/**
|
|
159
160
|
The key that contains the target for this item. If this and itemActionKey
|
|
160
|
-
are defined, then this will be the target of the action fired.
|
|
161
|
-
|
|
161
|
+
are defined, then this will be the target of the action fired.
|
|
162
|
+
|
|
162
163
|
@property {String}
|
|
163
164
|
*/
|
|
164
165
|
itemTargetKey: null,
|
|
165
166
|
|
|
166
|
-
/**
|
|
167
|
+
/**
|
|
167
168
|
The key that contains the key equivalent for each item. If defined then
|
|
168
|
-
pressing that key equivalent will be like selecting the tab. Also,
|
|
169
|
-
pressing the Alt or Option key for 3 seconds will display the key
|
|
169
|
+
pressing that key equivalent will be like selecting the tab. Also,
|
|
170
|
+
pressing the Alt or Option key for 3 seconds will display the key
|
|
170
171
|
equivalent in the tab.
|
|
171
172
|
*/
|
|
172
173
|
itemKeyEquivalentKey: null,
|
|
173
|
-
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
The title to use for the overflow segment if it appears.
|
|
177
|
+
|
|
178
|
+
@property {String}
|
|
179
|
+
*/
|
|
180
|
+
overflowTitle: '»',
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
The toolTip to use for the overflow segment if it appears.
|
|
184
|
+
|
|
185
|
+
@property {String}
|
|
186
|
+
*/
|
|
187
|
+
overflowToolTip: 'More…',
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
The icon to use for the overflow segment if it appears.
|
|
191
|
+
|
|
192
|
+
@property {String}
|
|
193
|
+
*/
|
|
194
|
+
overflowIcon: null,
|
|
195
|
+
|
|
174
196
|
/** @private
|
|
175
197
|
The following properties are used to map items to child views. Item keys
|
|
176
|
-
are looked up on the item based on this view's value for each 'itemKey'.
|
|
198
|
+
are looked up on the item based on this view's value for each 'itemKey'.
|
|
177
199
|
If a value in the item is found, then that value is mapped to a child
|
|
178
200
|
view using the matching viewKey.
|
|
179
|
-
|
|
201
|
+
|
|
180
202
|
@property {Array}
|
|
181
203
|
*/
|
|
182
204
|
itemKeys: 'itemTitleKey itemValueKey itemIsEnabledKey itemIconKey itemWidthKey itemToolTipKey itemKeyEquivalentKey'.w(),
|
|
183
205
|
viewKeys: 'title value isEnabled icon width toolTip keyEquivalent'.w(),
|
|
184
|
-
|
|
206
|
+
|
|
185
207
|
/**
|
|
186
208
|
Call itemsDidChange once to initialize segment child views for the items that exist at
|
|
187
209
|
creation time.
|
|
188
210
|
*/
|
|
189
211
|
init: function() {
|
|
190
212
|
sc_super();
|
|
191
|
-
|
|
213
|
+
|
|
214
|
+
var title = this.get('overflowTitle'),
|
|
215
|
+
toolTip = this.get('overflowToolTip'),
|
|
216
|
+
icon = this.get('overflowIcon'),
|
|
217
|
+
overflowView;
|
|
218
|
+
|
|
219
|
+
overflowView = SC.SegmentView.create({
|
|
220
|
+
controlSize: this.get('controlSize'),
|
|
221
|
+
localize: this.get('localize'),
|
|
222
|
+
title: title,
|
|
223
|
+
toolTip: toolTip,
|
|
224
|
+
icon: icon,
|
|
225
|
+
isLastSegment: YES,
|
|
226
|
+
isOverflowSegment: YES
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
this.appendChild(overflowView);
|
|
230
|
+
|
|
192
231
|
this.itemsDidChange();
|
|
193
232
|
},
|
|
194
|
-
|
|
233
|
+
|
|
195
234
|
/**
|
|
196
235
|
Called whenever the number of items changes. This method populates SegmentedView's childViews, taking
|
|
197
236
|
care to re-use existing childViews if possible.
|
|
198
|
-
|
|
237
|
+
|
|
199
238
|
*/
|
|
200
239
|
itemsDidChange: function() {
|
|
201
240
|
var items = this.get('items') || [],
|
|
@@ -203,21 +242,22 @@ SC.SegmentedView = SC.View.extend(SC.Control,
|
|
|
203
242
|
localItem, // Used to avoid altering the original items
|
|
204
243
|
childViews = this.get('childViews'),
|
|
205
244
|
childView,
|
|
245
|
+
overflowView = childViews.lastObject(),
|
|
206
246
|
value = this.get('value'), // The value can change if items that were once selected are removed
|
|
207
247
|
isSelected,
|
|
208
248
|
itemKeys = this.get('itemKeys'),
|
|
209
|
-
itemKey,
|
|
249
|
+
itemKey,
|
|
210
250
|
viewKeys = this.get('viewKeys'),
|
|
211
251
|
viewKey,
|
|
212
252
|
i, j;
|
|
213
|
-
|
|
214
|
-
// Update childViews
|
|
215
|
-
if (childViews.get('length') > items.get('length')) { // We've lost segments (ie. childViews)
|
|
216
|
-
|
|
253
|
+
|
|
254
|
+
// Update childViews
|
|
255
|
+
if (childViews.get('length') - 1 > items.get('length')) { // We've lost segments (ie. childViews)
|
|
256
|
+
|
|
217
257
|
// Remove unneeded segments from the end back
|
|
218
|
-
for (i = childViews.get('length') -
|
|
258
|
+
for (i = childViews.get('length') - 2; i >= items.get('length'); i--) {
|
|
219
259
|
childView = childViews.objectAt(i);
|
|
220
|
-
|
|
260
|
+
|
|
221
261
|
// If a selected childView has been removed then update our value
|
|
222
262
|
if (SC.isArray(value)) {
|
|
223
263
|
value.removeObject(childView.get('value'));
|
|
@@ -227,58 +267,58 @@ SC.SegmentedView = SC.View.extend(SC.Control,
|
|
|
227
267
|
|
|
228
268
|
this.removeChild(childView);
|
|
229
269
|
}
|
|
230
|
-
|
|
270
|
+
|
|
231
271
|
// Update our value which may have changed
|
|
232
272
|
this.set('value', value);
|
|
233
|
-
|
|
234
|
-
} else if (childViews.get('length') < items.get('length')) { // We've gained segments
|
|
273
|
+
|
|
274
|
+
} else if (childViews.get('length') - 1 < items.get('length')) { // We've gained segments
|
|
235
275
|
|
|
236
276
|
// Create the new segments
|
|
237
|
-
for (i = childViews.get('length'); i < items.get('length'); i++) {
|
|
238
|
-
|
|
277
|
+
for (i = childViews.get('length') - 1; i < items.get('length'); i++) {
|
|
278
|
+
|
|
239
279
|
// We create a default SC.ButtonView-like object for each segment
|
|
240
280
|
childView = SC.SegmentView.create({
|
|
241
281
|
controlSize: this.get('controlSize'),
|
|
242
282
|
localize: this.get('localize')
|
|
243
283
|
});
|
|
244
|
-
|
|
284
|
+
|
|
245
285
|
// Attach the child
|
|
246
|
-
this.
|
|
247
|
-
}
|
|
286
|
+
this.insertBefore(childView, overflowView);
|
|
287
|
+
}
|
|
248
288
|
}
|
|
249
|
-
|
|
250
|
-
// Because the items array can be altered with insertAt or removeAt, we can't be sure that the items
|
|
251
|
-
// continue to match 1-to-1 the existing views, so once we have the correct number of childViews,
|
|
289
|
+
|
|
290
|
+
// Because the items array can be altered with insertAt or removeAt, we can't be sure that the items
|
|
291
|
+
// continue to match 1-to-1 the existing views, so once we have the correct number of childViews,
|
|
252
292
|
// simply update them all
|
|
253
293
|
childViews = this.get('childViews');
|
|
254
|
-
|
|
294
|
+
|
|
255
295
|
for (i = 0; i < items.get('length'); i++) {
|
|
256
296
|
localItem = items.objectAt(i);
|
|
257
297
|
childView = childViews.objectAt(i);
|
|
258
|
-
|
|
298
|
+
|
|
259
299
|
// Skip null/undefined items (but don't skip empty strings)
|
|
260
300
|
if (SC.none(localItem)) continue;
|
|
261
|
-
|
|
301
|
+
|
|
262
302
|
// Normalize the item (may be a String, Object or SC.Object)
|
|
263
303
|
if (SC.typeOf(localItem) === SC.T_STRING) {
|
|
264
|
-
|
|
304
|
+
|
|
265
305
|
localItem = SC.Object.create({
|
|
266
306
|
'title': localItem.humanize().titleize(),
|
|
267
307
|
'value': localItem
|
|
268
308
|
});
|
|
269
|
-
|
|
309
|
+
|
|
270
310
|
// Update our keys accordingly
|
|
271
311
|
this.set('itemTitleKey', 'title');
|
|
272
312
|
this.set('itemValueKey', 'value');
|
|
273
313
|
} else if (SC.typeOf(localItem) === SC.T_HASH) {
|
|
274
|
-
|
|
314
|
+
|
|
275
315
|
localItem = SC.Object.create(localItem);
|
|
276
316
|
} else if (localItem instanceof SC.Object) {
|
|
277
|
-
|
|
317
|
+
|
|
278
318
|
// We don't need to make any changes to SC.Object items, but we can observe them
|
|
279
319
|
for (j = itemKeys.get('length') - 1; j >= 0; j--) {
|
|
280
320
|
itemKey = this.get(itemKeys.objectAt(j));
|
|
281
|
-
|
|
321
|
+
|
|
282
322
|
if (itemKey) {
|
|
283
323
|
localItem.removeObserver(itemKey, this, this.itemContentDidChange);
|
|
284
324
|
localItem.addObserver(itemKey, this, this.itemContentDidChange, i);
|
|
@@ -287,26 +327,33 @@ SC.SegmentedView = SC.View.extend(SC.Control,
|
|
|
287
327
|
} else {
|
|
288
328
|
SC.Logger.error('SC.SegmentedView items may be Strings, Objects (ie. Hashes) or SC.Objects only');
|
|
289
329
|
}
|
|
290
|
-
|
|
330
|
+
|
|
291
331
|
// Determine whether this segment is selected based on the view's existing value(s)
|
|
292
332
|
isSelected = NO;
|
|
293
333
|
if (SC.isArray(value) ? value.indexOf(localItem.get(this.get('itemValueKey'))) >= 0 : value === localItem.get(this.get('itemValueKey'))) {
|
|
294
334
|
isSelected = YES;
|
|
295
335
|
}
|
|
296
336
|
childView.set('isSelected', isSelected);
|
|
297
|
-
|
|
337
|
+
|
|
298
338
|
// Assign segment specific properties based on position
|
|
299
339
|
childView.set('index', i);
|
|
300
340
|
childView.set('isFirstSegment', i === 0);
|
|
301
341
|
childView.set('isMiddleSegment', i < items.get('length') - 1 && i > 0);
|
|
302
342
|
childView.set('isLastSegment', i === items.get('length') - 1);
|
|
303
|
-
|
|
343
|
+
|
|
304
344
|
// Be sure to update the view's properties for the (possibly new) matched item
|
|
305
345
|
childView.updateItem(this, localItem);
|
|
306
346
|
}
|
|
307
|
-
|
|
347
|
+
|
|
348
|
+
// Force a segment remeasure to check overflow
|
|
349
|
+
this.invokeLast(this.remeasure);
|
|
308
350
|
}.observes('*items.[]'),
|
|
309
|
-
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
This observer method is called whenever any of the relevant properties of an item change. This only applies
|
|
354
|
+
to SC.Object based items that may be observed.
|
|
355
|
+
|
|
356
|
+
*/
|
|
310
357
|
itemContentDidChange: function(item, key, alwaysNull, index) {
|
|
311
358
|
var items = this.get('items'),
|
|
312
359
|
childViews = this.get('childViews'),
|
|
@@ -314,27 +361,136 @@ SC.SegmentedView = SC.View.extend(SC.Control,
|
|
|
314
361
|
|
|
315
362
|
childView = childViews.objectAt(index);
|
|
316
363
|
if (childView) {
|
|
317
|
-
|
|
364
|
+
|
|
318
365
|
// Update the childView
|
|
319
366
|
childView.updateItem(this, item);
|
|
320
367
|
} else {
|
|
321
368
|
SC.Logger.warn("Item content change was observed on item without matching segment child view.");
|
|
322
369
|
}
|
|
370
|
+
|
|
371
|
+
// Reset our measurements (which depend on width or title) and adjust visible views
|
|
372
|
+
this.invokeLast(this.remeasure);
|
|
373
|
+
},
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
Whenever the view resizes, we need to check to see if we're overflowing.
|
|
377
|
+
|
|
378
|
+
*/
|
|
379
|
+
viewDidResize: function() {
|
|
380
|
+
var visibleWidth = this.$().width();
|
|
381
|
+
|
|
382
|
+
// Only overflow if we've gone below the minimum width required to fit all the segments
|
|
383
|
+
if (this.isOverflowing || visibleWidth <= this.cachedMinimumWidth) this.adjustOverflow();
|
|
323
384
|
},
|
|
324
|
-
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
Whenever visibility changes, we need to check to see if we're overflowing.
|
|
388
|
+
|
|
389
|
+
*/
|
|
390
|
+
isVisibleInWindowDidChange: function() {
|
|
391
|
+
this.invokeLast(this.remeasure);
|
|
392
|
+
}.observes('isVisibleInWindow'),
|
|
393
|
+
|
|
394
|
+
/** @private
|
|
395
|
+
Calling this method forces the segments to be remeasured and will also adjust the
|
|
396
|
+
segments for overflow if necessary.
|
|
397
|
+
|
|
398
|
+
*/
|
|
399
|
+
remeasure: function() {
|
|
400
|
+
var renderDelegate = this.get('renderDelegate'),
|
|
401
|
+
childViews = this.get('childViews'),
|
|
402
|
+
overflowView;
|
|
403
|
+
|
|
404
|
+
if (this.get('isVisibleInWindow')) {
|
|
405
|
+
// Make all the views visible so that they can be measured
|
|
406
|
+
overflowView = childViews.lastObject();
|
|
407
|
+
overflowView.set('isVisible', YES);
|
|
408
|
+
|
|
409
|
+
for (var i = childViews.get('length') - 1; i >= 0; i--){
|
|
410
|
+
childViews.objectAt(i).set('isVisible', YES);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
this.cachedWidths = renderDelegate.segmentWidths(this);
|
|
414
|
+
this.cachedOverflowWidth = renderDelegate.overflowSegmentWidth(this);
|
|
415
|
+
|
|
416
|
+
this.adjustOverflow();
|
|
417
|
+
}
|
|
418
|
+
},
|
|
419
|
+
|
|
420
|
+
/** @private
|
|
421
|
+
This method is called to adjust the segment views for overflow.
|
|
422
|
+
|
|
423
|
+
*/
|
|
424
|
+
adjustOverflow: function() {
|
|
425
|
+
var childViews = this.get('childViews'),
|
|
426
|
+
childView,
|
|
427
|
+
value = this.get('value'),
|
|
428
|
+
overflowView = childViews.lastObject(),
|
|
429
|
+
visibleWidth = this.$().width(), // The inner width of the div
|
|
430
|
+
curElementsWidth = 0,
|
|
431
|
+
widthToFit,
|
|
432
|
+
length, i;
|
|
433
|
+
|
|
434
|
+
// This variable is useful to optimize when we are overflowing
|
|
435
|
+
this.isOverflowing = NO;
|
|
436
|
+
overflowView.set('isSelected', NO);
|
|
437
|
+
|
|
438
|
+
// Clear out the overflow items (these are the items not currently visible)
|
|
439
|
+
this.overflowItems = [];
|
|
440
|
+
|
|
441
|
+
length = this.cachedWidths.length;
|
|
442
|
+
for (i=0; i < length; i++) {
|
|
443
|
+
childView = childViews.objectAt(i);
|
|
444
|
+
curElementsWidth += this.cachedWidths[i];
|
|
445
|
+
|
|
446
|
+
// check for an overflow (leave room for the overflow segment except for with the last segment)
|
|
447
|
+
widthToFit = (i === length - 1) ? curElementsWidth : curElementsWidth + this.cachedOverflowWidth;
|
|
448
|
+
|
|
449
|
+
if (widthToFit > visibleWidth) {
|
|
450
|
+
// Add the localItem to the overflowItems
|
|
451
|
+
this.overflowItems.pushObject(childView.get('localItem'));
|
|
452
|
+
|
|
453
|
+
// Record that we're now overflowing
|
|
454
|
+
this.isOverflowing = YES;
|
|
455
|
+
|
|
456
|
+
childView.set('isVisible', NO);
|
|
457
|
+
|
|
458
|
+
// If the first item is already overflowed, make the overflowView first segment
|
|
459
|
+
if (i === 0) overflowView.set('isFirstSegment', YES);
|
|
460
|
+
|
|
461
|
+
// If the overflowed segment was selected, show the overflowView as selected instead
|
|
462
|
+
if (SC.isArray(value) ? value.indexOf(childView.get('value')) >= 0 : value === childView.get('value')) {
|
|
463
|
+
overflowView.set('isSelected', YES);
|
|
464
|
+
}
|
|
465
|
+
} else {
|
|
466
|
+
childView.set('isVisible', YES);
|
|
467
|
+
|
|
468
|
+
// If the first item is not overflowed, don't make the overflowView first segment
|
|
469
|
+
if (i === 0) overflowView.set('isFirstSegment', NO);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// Show/hide the overflow view if we have overflowed
|
|
474
|
+
if (this.isOverflowing) overflowView.set('isVisible', YES);
|
|
475
|
+
else overflowView.set('isVisible', NO);
|
|
476
|
+
|
|
477
|
+
// Store the minimum width before overflow
|
|
478
|
+
this.cachedMinimumWidth = curElementsWidth + this.cachedOverflowWidth;
|
|
479
|
+
},
|
|
480
|
+
|
|
325
481
|
// ..........................................................
|
|
326
482
|
// RENDERING/DISPLAY SUPPORT
|
|
327
|
-
//
|
|
328
|
-
|
|
483
|
+
//
|
|
484
|
+
|
|
329
485
|
displayProperties: ['align'],
|
|
330
|
-
|
|
486
|
+
|
|
331
487
|
renderDelegateName: 'segmentedRenderDelegate',
|
|
332
|
-
|
|
488
|
+
|
|
333
489
|
// ..........................................................
|
|
334
490
|
// EVENT HANDLING
|
|
335
|
-
//
|
|
336
|
-
|
|
337
|
-
/**
|
|
491
|
+
//
|
|
492
|
+
|
|
493
|
+
/**
|
|
338
494
|
Determines the index into the displayItems array where the passed mouse
|
|
339
495
|
event occurred.
|
|
340
496
|
*/
|
|
@@ -345,186 +501,224 @@ SC.SegmentedView = SC.View.extend(SC.Control,
|
|
|
345
501
|
return renderDelegate.indexForClientPosition(this, evt.clientX, evt.clientY);
|
|
346
502
|
}
|
|
347
503
|
},
|
|
348
|
-
|
|
504
|
+
|
|
349
505
|
keyDown: function(evt) {
|
|
506
|
+
var childViews,
|
|
507
|
+
childView,
|
|
508
|
+
i, length,
|
|
509
|
+
value, isArray;
|
|
510
|
+
|
|
350
511
|
// handle tab key
|
|
351
|
-
var i, item, items, len, value, isArray;
|
|
352
512
|
if (evt.which === 9 || evt.keyCode === 9) {
|
|
353
513
|
var view = evt.shiftKey ? this.get('previousValidKeyView') : this.get('nextValidKeyView');
|
|
354
514
|
if(view) view.becomeFirstResponder();
|
|
355
515
|
else evt.allowDefault();
|
|
356
516
|
return YES ; // handled
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// handle arrow keys
|
|
520
|
+
if (!this.get('allowsMultipleSelection')) {
|
|
521
|
+
childViews = this.get('childViews');
|
|
522
|
+
|
|
523
|
+
length = childViews.get('length');
|
|
362
524
|
value = this.get('value');
|
|
363
525
|
isArray = SC.isArray(value);
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
526
|
+
|
|
527
|
+
// Select from the left to the right
|
|
528
|
+
if (evt.which === 39 || evt.which === 40) {
|
|
529
|
+
|
|
530
|
+
if (value) {
|
|
531
|
+
for(i = 0; i < length - 2; i++){
|
|
532
|
+
childView = childViews.objectAt(i);
|
|
533
|
+
if ( isArray ? (value.indexOf(childView.get('value'))>=0) : (childView.get('value')===value)){
|
|
534
|
+
this.triggerItemAtIndex(i + 1);
|
|
535
|
+
}
|
|
369
536
|
}
|
|
537
|
+
} else {
|
|
538
|
+
this.triggerItemAtIndex(0);
|
|
370
539
|
}
|
|
371
540
|
return YES ; // handled
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
541
|
+
|
|
542
|
+
// Select from the right to the left
|
|
543
|
+
} else if (evt.which === 37 || evt.which === 38) {
|
|
544
|
+
|
|
545
|
+
if (value) {
|
|
546
|
+
for(i = 1; i < length - 1; i++) {
|
|
547
|
+
childView = childViews.objectAt(i);
|
|
548
|
+
if ( isArray ? (value.indexOf(childView.get('value'))>=0) : (childView.get('value')===value)){
|
|
549
|
+
this.triggerItemAtIndex(i - 1);
|
|
550
|
+
}
|
|
378
551
|
}
|
|
552
|
+
} else {
|
|
553
|
+
this.triggerItemAtIndex(length - 2);
|
|
379
554
|
}
|
|
380
|
-
|
|
555
|
+
|
|
556
|
+
return YES; // handled
|
|
381
557
|
}
|
|
382
558
|
}
|
|
383
|
-
|
|
559
|
+
|
|
560
|
+
return NO;
|
|
384
561
|
},
|
|
385
|
-
|
|
562
|
+
|
|
386
563
|
mouseDown: function(evt) {
|
|
387
564
|
var childViews = this.get('childViews'),
|
|
388
565
|
childView,
|
|
566
|
+
overflowIndex = childViews.get('length') - 1,
|
|
389
567
|
index;
|
|
390
|
-
|
|
568
|
+
|
|
391
569
|
if (!this.get('isEnabled')) return YES; // nothing to do
|
|
392
|
-
|
|
570
|
+
|
|
393
571
|
index = this.displayItemIndexForEvent(evt);
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
childView = childViews
|
|
572
|
+
|
|
573
|
+
if (index >= 0) {
|
|
574
|
+
childView = childViews.objectAt(index);
|
|
397
575
|
childView.set('isActive', YES);
|
|
398
|
-
|
|
399
576
|
this.activeChildView = childView;
|
|
400
|
-
|
|
401
|
-
// if mouse was pressed on
|
|
402
|
-
this.
|
|
577
|
+
|
|
578
|
+
// if mouse was pressed on the overflow segment, popup the menu
|
|
579
|
+
if (index === overflowIndex) this.showOverflowMenu();
|
|
580
|
+
else this._isMouseDown = YES;
|
|
403
581
|
}
|
|
404
|
-
|
|
405
|
-
return YES
|
|
582
|
+
|
|
583
|
+
return YES;
|
|
406
584
|
},
|
|
407
|
-
|
|
585
|
+
|
|
408
586
|
mouseUp: function(evt) {
|
|
409
587
|
var activeChildView,
|
|
410
588
|
index;
|
|
411
|
-
|
|
589
|
+
|
|
412
590
|
index = this.displayItemIndexForEvent(evt);
|
|
413
|
-
|
|
591
|
+
|
|
414
592
|
if (this._isMouseDown && (index >= 0)) {
|
|
415
|
-
|
|
416
|
-
// Clean up
|
|
593
|
+
|
|
417
594
|
this.triggerItemAtIndex(index);
|
|
418
|
-
|
|
595
|
+
|
|
596
|
+
// Clean up
|
|
419
597
|
activeChildView = this.activeChildView;
|
|
420
598
|
activeChildView.set('isActive', NO);
|
|
421
599
|
this.activeChildView = null;
|
|
422
|
-
|
|
600
|
+
|
|
423
601
|
this._isMouseDown = NO;
|
|
424
602
|
}
|
|
425
|
-
|
|
426
|
-
return YES
|
|
603
|
+
|
|
604
|
+
return YES;
|
|
427
605
|
},
|
|
428
|
-
|
|
606
|
+
|
|
429
607
|
mouseMoved: function(evt) {
|
|
430
608
|
var childViews = this.get('childViews'),
|
|
609
|
+
overflowIndex = childViews.get('length') - 1,
|
|
431
610
|
activeChildView,
|
|
432
611
|
childView,
|
|
433
612
|
index;
|
|
434
|
-
|
|
613
|
+
|
|
435
614
|
if (this._isMouseDown) {
|
|
436
615
|
// Update the last segment
|
|
437
616
|
index = this.displayItemIndexForEvent(evt);
|
|
438
|
-
|
|
617
|
+
|
|
439
618
|
activeChildView = this.activeChildView;
|
|
440
|
-
childView = childViews
|
|
441
|
-
|
|
619
|
+
childView = childViews.objectAt(index);
|
|
620
|
+
|
|
442
621
|
if (childView && childView !== activeChildView) {
|
|
443
622
|
// Changed
|
|
444
623
|
if (activeChildView) activeChildView.set('isActive', NO);
|
|
445
624
|
childView.set('isActive', YES);
|
|
446
|
-
|
|
625
|
+
|
|
447
626
|
this.activeChildView = childView;
|
|
627
|
+
|
|
628
|
+
if (index === overflowIndex) {
|
|
629
|
+
this.showOverflowMenu();
|
|
630
|
+
this._isMouseDown = NO;
|
|
631
|
+
}
|
|
448
632
|
}
|
|
449
633
|
}
|
|
450
634
|
return YES;
|
|
451
635
|
},
|
|
452
|
-
|
|
636
|
+
|
|
453
637
|
mouseEntered: function(evt) {
|
|
454
638
|
var childViews = this.get('childViews'),
|
|
455
639
|
childView,
|
|
640
|
+
overflowIndex = childViews.get('length') - 1,
|
|
456
641
|
index;
|
|
457
|
-
|
|
642
|
+
|
|
458
643
|
// if mouse was pressed down initially, start detection again
|
|
459
644
|
if (this._isMouseDown) {
|
|
460
645
|
index = this.displayItemIndexForEvent(evt);
|
|
461
|
-
|
|
462
|
-
if
|
|
463
|
-
|
|
646
|
+
|
|
647
|
+
// if mouse was pressed on the overflow segment, popup the menu
|
|
648
|
+
if (index === overflowIndex) {
|
|
649
|
+
this.showOverflowMenu();
|
|
650
|
+
this._isMouseDown = NO;
|
|
651
|
+
} else if (index >= 0) {
|
|
652
|
+
childView = childViews.objectAt(index);
|
|
464
653
|
childView.set('isActive', YES);
|
|
465
|
-
|
|
654
|
+
|
|
466
655
|
this.activeChildView = childView;
|
|
467
656
|
}
|
|
468
657
|
}
|
|
469
658
|
return YES;
|
|
470
659
|
},
|
|
471
|
-
|
|
660
|
+
|
|
472
661
|
mouseExited: function(evt) {
|
|
473
662
|
var activeChildView;
|
|
474
|
-
|
|
663
|
+
|
|
475
664
|
// if mouse was down, hide active index
|
|
476
665
|
if (this._isMouseDown) {
|
|
477
666
|
activeChildView = this.activeChildView;
|
|
478
667
|
if (activeChildView) activeChildView.set('isActive', NO);
|
|
479
|
-
|
|
668
|
+
|
|
480
669
|
this.activeChildView = null;
|
|
481
670
|
}
|
|
482
|
-
|
|
671
|
+
|
|
483
672
|
return YES;
|
|
484
673
|
},
|
|
485
|
-
|
|
674
|
+
|
|
486
675
|
touchStart: function(touch) {
|
|
487
676
|
var childViews = this.get('childViews'),
|
|
488
677
|
childView,
|
|
678
|
+
overflowIndex = childViews.get('length') - 1,
|
|
489
679
|
index;
|
|
490
|
-
|
|
680
|
+
|
|
491
681
|
if (!this.get('isEnabled')) return YES; // nothing to do
|
|
492
|
-
|
|
682
|
+
|
|
493
683
|
index = this.displayItemIndexForEvent(touch);
|
|
494
|
-
|
|
495
|
-
if (index >= 0) {
|
|
496
|
-
childView = childViews
|
|
684
|
+
|
|
685
|
+
if (index >= 0) {
|
|
686
|
+
childView = childViews.objectAt(index);
|
|
497
687
|
childView.set('isActive', YES);
|
|
498
688
|
this.activeChildView = childView;
|
|
499
|
-
|
|
500
|
-
|
|
689
|
+
|
|
690
|
+
// if touch was on the overflow segment, popup the menu
|
|
691
|
+
if (index === overflowIndex) this.showOverflowMenu();
|
|
692
|
+
else this._isTouching = YES;
|
|
501
693
|
}
|
|
502
|
-
|
|
694
|
+
|
|
503
695
|
return YES ;
|
|
504
696
|
},
|
|
505
|
-
|
|
697
|
+
|
|
506
698
|
touchEnd: function(touch) {
|
|
507
699
|
var activeChildView,
|
|
508
700
|
index;
|
|
509
|
-
|
|
701
|
+
|
|
510
702
|
index = this.displayItemIndexForEvent(touch);
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
703
|
+
|
|
704
|
+
if (this._isTouching && (index >= 0)) {
|
|
705
|
+
this.triggerItemAtIndex(index);
|
|
706
|
+
|
|
707
|
+
// Clean up
|
|
708
|
+
activeChildView = this.activeChildView;
|
|
709
|
+
activeChildView.set('isActive', NO);
|
|
710
|
+
this.activeChildView = null;
|
|
711
|
+
|
|
712
|
+
this._isTouching = NO;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
return YES;
|
|
523
716
|
},
|
|
524
|
-
|
|
717
|
+
|
|
525
718
|
touchesDragged: function(evt, touches) {
|
|
526
719
|
var isTouching = this.touchIsInBoundary(evt),
|
|
527
720
|
childViews = this.get('childViews'),
|
|
721
|
+
overflowIndex = childViews.get('length') - 1,
|
|
528
722
|
activeChildView,
|
|
529
723
|
childView,
|
|
530
724
|
index;
|
|
@@ -534,53 +728,64 @@ SC.SegmentedView = SC.View.extend(SC.Control,
|
|
|
534
728
|
this._touchDidEnter(evt);
|
|
535
729
|
}
|
|
536
730
|
index = this.displayItemIndexForEvent(evt);
|
|
537
|
-
|
|
731
|
+
|
|
538
732
|
activeChildView = this.activeChildView;
|
|
539
733
|
childView = childViews[index];
|
|
540
|
-
|
|
734
|
+
|
|
541
735
|
if (childView && childView !== activeChildView) {
|
|
542
736
|
// Changed
|
|
543
737
|
if (activeChildView) activeChildView.set('isActive', NO);
|
|
544
738
|
childView.set('isActive', YES);
|
|
545
|
-
|
|
739
|
+
|
|
546
740
|
this.activeChildView = childView;
|
|
741
|
+
|
|
742
|
+
if (index === overflowIndex) {
|
|
743
|
+
this.showOverflowMenu();
|
|
744
|
+
this._isMouseDown = NO;
|
|
745
|
+
}
|
|
547
746
|
}
|
|
548
747
|
} else {
|
|
549
748
|
if (this._isTouching) this._touchDidExit(evt);
|
|
550
749
|
}
|
|
551
|
-
|
|
750
|
+
|
|
552
751
|
this._isTouching = isTouching;
|
|
553
|
-
|
|
752
|
+
|
|
554
753
|
return YES;
|
|
555
754
|
},
|
|
556
|
-
|
|
755
|
+
|
|
557
756
|
_touchDidExit: function(evt) {
|
|
558
757
|
var activeChildView;
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
758
|
+
|
|
759
|
+
if (this.isTouching) {
|
|
760
|
+
activeChildView = this.activeChildView;
|
|
761
|
+
activeChildView.set('isActive', NO);
|
|
762
|
+
this.activeChildView = null;
|
|
763
|
+
}
|
|
563
764
|
|
|
564
765
|
return YES;
|
|
565
766
|
},
|
|
566
|
-
|
|
767
|
+
|
|
567
768
|
_touchDidEnter: function(evt) {
|
|
568
769
|
var childViews = this.get('childViews'),
|
|
569
770
|
childView,
|
|
771
|
+
overflowIndex = childViews.get('length') - 1,
|
|
570
772
|
index;
|
|
571
|
-
|
|
773
|
+
|
|
572
774
|
index = this.displayItemIndexForEvent(evt);
|
|
573
|
-
|
|
574
|
-
if (index
|
|
575
|
-
|
|
775
|
+
|
|
776
|
+
if (index === overflowIndex) {
|
|
777
|
+
this.showOverflowMenu();
|
|
778
|
+
this._isTouching = NO;
|
|
779
|
+
} else if (index >= 0) {
|
|
780
|
+
childView = childViews.objectAt(index);
|
|
576
781
|
childView.set('isActive', YES);
|
|
577
782
|
this.activeChildView = childView;
|
|
578
783
|
}
|
|
579
|
-
|
|
784
|
+
|
|
580
785
|
return YES;
|
|
581
786
|
},
|
|
582
787
|
|
|
583
|
-
/**
|
|
788
|
+
/**
|
|
584
789
|
Simulates the user clicking on the segment at the specified index. This
|
|
585
790
|
will update the value if possible and fire the action.
|
|
586
791
|
*/
|
|
@@ -588,25 +793,24 @@ SC.SegmentedView = SC.View.extend(SC.Control,
|
|
|
588
793
|
var childViews = this.get('childViews'),
|
|
589
794
|
childView,
|
|
590
795
|
sel, value, val, empty, mult;
|
|
591
|
-
|
|
592
|
-
childView = childViews
|
|
593
|
-
|
|
796
|
+
|
|
797
|
+
childView = childViews.objectAt(index);
|
|
798
|
+
|
|
594
799
|
if (!childView.get('isEnabled')) return this; // nothing to do!
|
|
595
800
|
|
|
596
801
|
empty = this.get('allowsEmptySelection');
|
|
597
802
|
mult = this.get('allowsMultipleSelection');
|
|
598
|
-
|
|
599
|
-
|
|
803
|
+
|
|
600
804
|
// get new value... bail if not enabled. Also save original for later.
|
|
601
805
|
sel = childView.get('value');
|
|
602
806
|
value = val = this.get('value') ;
|
|
603
|
-
|
|
807
|
+
|
|
604
808
|
if (SC.empty(value)) {
|
|
605
809
|
value = [];
|
|
606
810
|
} else if (!SC.isArray(value)) {
|
|
607
811
|
value = [value]; // force to array
|
|
608
812
|
}
|
|
609
|
-
|
|
813
|
+
|
|
610
814
|
// if we do not allow multiple selection, either replace the current
|
|
611
815
|
// selection or deselect it
|
|
612
816
|
if (!mult) {
|
|
@@ -614,10 +818,10 @@ SC.SegmentedView = SC.View.extend(SC.Control,
|
|
|
614
818
|
// the selected value, then deselect it.
|
|
615
819
|
if (empty && (value.get('length')===1) && (value.objectAt(0)===sel)) {
|
|
616
820
|
value = [];
|
|
617
|
-
|
|
821
|
+
|
|
618
822
|
// otherwise, simply replace the value.
|
|
619
823
|
} else value = [sel] ;
|
|
620
|
-
|
|
824
|
+
|
|
621
825
|
// if we do allow multiple selection, then add or remove item to the array.
|
|
622
826
|
} else {
|
|
623
827
|
if (value.indexOf(sel) >= 0) {
|
|
@@ -626,7 +830,7 @@ SC.SegmentedView = SC.View.extend(SC.Control,
|
|
|
626
830
|
}
|
|
627
831
|
} else value = value.concat([sel]) ;
|
|
628
832
|
}
|
|
629
|
-
|
|
833
|
+
|
|
630
834
|
// normalize back to non-array form
|
|
631
835
|
switch(value.get('length')) {
|
|
632
836
|
case 0:
|
|
@@ -638,7 +842,7 @@ SC.SegmentedView = SC.View.extend(SC.Control,
|
|
|
638
842
|
default:
|
|
639
843
|
break;
|
|
640
844
|
}
|
|
641
|
-
|
|
845
|
+
|
|
642
846
|
// also, trigger target if needed.
|
|
643
847
|
var actionKey = this.get('itemActionKey'),
|
|
644
848
|
targetKey = this.get('itemTargetKey'),
|
|
@@ -646,7 +850,7 @@ SC.SegmentedView = SC.View.extend(SC.Control,
|
|
|
646
850
|
resp = this.getPath('pane.rootResponder'),
|
|
647
851
|
item;
|
|
648
852
|
|
|
649
|
-
if (actionKey && (item = this.get('items').objectAt(
|
|
853
|
+
if (actionKey && (item = this.get('items').objectAt(index))) {
|
|
650
854
|
// get the source item from the item array. use the index stored...
|
|
651
855
|
action = item.get ? item.get(actionKey) : item[actionKey];
|
|
652
856
|
if (targetKey) {
|
|
@@ -659,51 +863,130 @@ SC.SegmentedView = SC.View.extend(SC.Control,
|
|
|
659
863
|
if(!action && val !== undefined) {
|
|
660
864
|
this.set('value', value);
|
|
661
865
|
}
|
|
662
|
-
|
|
866
|
+
|
|
663
867
|
// if an action/target is defined on self use that also
|
|
664
868
|
action =this.get('action');
|
|
665
869
|
if (action && resp) {
|
|
666
870
|
resp.sendAction(action, this.get('target'), this, this.get('pane'));
|
|
667
871
|
}
|
|
668
872
|
},
|
|
669
|
-
|
|
873
|
+
|
|
874
|
+
/** @private
|
|
875
|
+
Invoked whenever an item is selected in the overflow menu.
|
|
876
|
+
*/
|
|
877
|
+
selectOverflowItem: function(menu) {
|
|
878
|
+
var item = menu.get('selectedItem');
|
|
879
|
+
|
|
880
|
+
this.triggerItemAtIndex(item.get('index'));
|
|
881
|
+
|
|
882
|
+
// Cleanup
|
|
883
|
+
menu.removeObserver('selectedItem', this, 'selectOverflowItem');
|
|
884
|
+
|
|
885
|
+
this.activeChildView.set('isActive', NO);
|
|
886
|
+
this.activeChildView = null;
|
|
887
|
+
},
|
|
888
|
+
|
|
889
|
+
/** @private
|
|
890
|
+
Presents the popup menu containing overflowed segments.
|
|
891
|
+
*/
|
|
892
|
+
showOverflowMenu: function() {
|
|
893
|
+
var childViews = this.get('childViews'),
|
|
894
|
+
overflowViewIndex = childViews.get('length') - 1,
|
|
895
|
+
overflowItems = this.overflowItems,
|
|
896
|
+
overflowItemsLength,
|
|
897
|
+
startIndex,
|
|
898
|
+
isArray, value;
|
|
899
|
+
|
|
900
|
+
// Check the currently selected item if it is in overflowItems
|
|
901
|
+
overflowItemsLength = overflowItems.get('length');
|
|
902
|
+
startIndex = childViews.get('length') - 1 - overflowItemsLength;
|
|
903
|
+
|
|
904
|
+
value = this.get('value');
|
|
905
|
+
isArray = SC.isArray(value);
|
|
906
|
+
for (var i = 0; i < overflowItemsLength; i++) {
|
|
907
|
+
var item = overflowItems.objectAt(i),
|
|
908
|
+
itemValueKey = this.get('itemValueKey');
|
|
909
|
+
|
|
910
|
+
if (isArray ? value.indexOf(item.get(itemValueKey)) >= 0 : value === item.get(itemValueKey)) {
|
|
911
|
+
item.set('isChecked', YES);
|
|
912
|
+
} else {
|
|
913
|
+
item.set('isChecked', NO);
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
// Track the matching segment index
|
|
917
|
+
item.set('index', startIndex + i);
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
// TODO: we can't pass a shortcut key to the menu, because it isn't a property of SegmentedView (yet?)
|
|
921
|
+
var self = this;
|
|
922
|
+
|
|
923
|
+
var menu = SC.MenuPane.create({
|
|
924
|
+
layout: { width: 200 },
|
|
925
|
+
items: overflowItems,
|
|
926
|
+
itemTitleKey: this.get('itemTitleKey'),
|
|
927
|
+
itemIconKey: this.get('itemIconKey'),
|
|
928
|
+
itemIsEnabledKey: this.get('itemIsEnabledKey'),
|
|
929
|
+
itemKeyEquivalentKey: this.get('itemKeyEquivalentKey'),
|
|
930
|
+
itemCheckboxKey: 'isChecked',
|
|
931
|
+
|
|
932
|
+
// We need to be able to update our overflow segment even if the user clicks outside of the menu. Since
|
|
933
|
+
// there is no callback method or observable property when the menu closes, override modalPaneDidClick().
|
|
934
|
+
modalPaneDidClick: function() {
|
|
935
|
+
sc_super();
|
|
936
|
+
|
|
937
|
+
// Cleanup
|
|
938
|
+
this.removeObserver('selectedItem', self, 'selectOverflowItem');
|
|
939
|
+
|
|
940
|
+
self.activeChildView.set('isActive', NO);
|
|
941
|
+
self.activeChildView = null;
|
|
942
|
+
}
|
|
943
|
+
});
|
|
944
|
+
|
|
945
|
+
var layer = this.get('layer');
|
|
946
|
+
var overflowElement = layer.childNodes[layer.childNodes.length - 1];
|
|
947
|
+
menu.popup(overflowElement);
|
|
948
|
+
|
|
949
|
+
menu.addObserver("selectedItem", this, 'selectOverflowItem');
|
|
950
|
+
},
|
|
951
|
+
|
|
670
952
|
/** @private
|
|
671
953
|
Whenever the value changes, update the segments accordingly.
|
|
672
954
|
*/
|
|
673
955
|
valueDidChange: function() {
|
|
674
956
|
var value = this.get('value'),
|
|
957
|
+
overflowItemsLength,
|
|
675
958
|
childViews = this.get('childViews'),
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
959
|
+
overflowIndex = Infinity,
|
|
960
|
+
overflowView = childViews.lastObject(),
|
|
961
|
+
childView,
|
|
962
|
+
isSelected;
|
|
963
|
+
|
|
964
|
+
// The index where childViews are all overflowed
|
|
965
|
+
if (this.overflowItems) {
|
|
966
|
+
overflowItemsLength = this.overflowItems.get('length');
|
|
967
|
+
overflowIndex = childViews.get('length') - 1 - overflowItemsLength;
|
|
968
|
+
|
|
969
|
+
// Clear out the selected value of the overflowView (if it's set)
|
|
970
|
+
overflowView.set('isSelected', NO);
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
for (var i = childViews.get('length') - 2; i >= 0; i--) {
|
|
679
974
|
childView = childViews.objectAt(i);
|
|
680
975
|
if (SC.isArray(value) ? value.indexOf(childView.get('value')) >= 0 : value === childView.get('value')) {
|
|
681
976
|
childView.set('isSelected', YES);
|
|
977
|
+
|
|
978
|
+
// If we've gone over the overflow index, the child view is represented in overflow items
|
|
979
|
+
if (i >= overflowIndex) overflowView.set('isSelected', YES);
|
|
682
980
|
} else {
|
|
683
981
|
childView.set('isSelected', NO);
|
|
684
982
|
}
|
|
685
983
|
}
|
|
686
984
|
}.observes('value'),
|
|
687
|
-
|
|
985
|
+
|
|
688
986
|
/** tied to the isEnabled state */
|
|
689
987
|
acceptsFirstResponder: function() {
|
|
690
988
|
if(!SC.SAFARI_FOCUS_BEHAVIOR) return this.get('isEnabled');
|
|
691
989
|
else return NO;
|
|
692
|
-
}.property('isEnabled')
|
|
693
|
-
|
|
694
|
-
willBecomeKeyResponderFrom: function(keyView) {
|
|
695
|
-
// focus the text field.
|
|
696
|
-
if (!this._isFocused) {
|
|
697
|
-
this._isFocused = YES ;
|
|
698
|
-
this.becomeFirstResponder();
|
|
699
|
-
if (this.get('isVisibleInWindow')) {
|
|
700
|
-
this.$()[0].focus();
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
},
|
|
704
|
-
|
|
705
|
-
willLoseKeyResponderTo: function(responder) {
|
|
706
|
-
if (this._isFocused) this._isFocused = NO ;
|
|
707
|
-
}
|
|
708
|
-
|
|
990
|
+
}.property('isEnabled').cacheable()
|
|
991
|
+
|
|
709
992
|
});
|