sproutcore 1.7.1.beta → 1.8.0
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 +44 -0
- data/README.rdoc +20 -20
- data/VERSION.yml +3 -3
- data/lib/Buildfile +1 -1
- data/lib/buildtasks/build.rake +5 -0
- data/lib/buildtasks/manifest.rake +19 -1
- data/lib/frameworks/sproutcore/Buildfile +19 -17
- data/lib/frameworks/sproutcore/CHANGELOG.md +163 -29
- data/lib/frameworks/sproutcore/README.md +29 -8
- data/lib/frameworks/sproutcore/apps/statechart_routing/Buildfile +12 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/controllers/login_controller.js +11 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/controllers/main_controller.js +7 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/controllers/statechart_controller.js +17 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/core.js +25 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/main.js +15 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/resources/_theme.css +18 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/resources/bar_page.js +14 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/resources/foo_page.js +14 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/resources/loading.rhtml +9 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/resources/login_page.js +61 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/resources/main_page.js +46 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/statechart.js +76 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/theme.js +27 -0
- data/lib/frameworks/sproutcore/apps/tests/controllers/targets.js +1 -1
- data/lib/frameworks/sproutcore/apps/tests/states/no_targets.js +1 -1
- data/lib/frameworks/sproutcore/apps/tests/states/ready_detail.js +1 -1
- data/lib/frameworks/sproutcore/apps/tests/states/ready_empty.js +1 -1
- data/lib/frameworks/sproutcore/apps/tests/states/ready_list.js +1 -1
- data/lib/frameworks/sproutcore/apps/tests/states/ready_no_tests.js +1 -1
- data/lib/frameworks/sproutcore/apps/welcome/controllers/targets.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/ajax/system/request.js +14 -1
- data/lib/frameworks/sproutcore/frameworks/ajax/system/response.js +15 -15
- data/lib/frameworks/sproutcore/frameworks/ajax/tests/system/request.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/animation/core.js +8 -5
- data/lib/frameworks/sproutcore/frameworks/bootstrap/system/browser.js +302 -70
- data/lib/frameworks/sproutcore/frameworks/bootstrap/system/loader.js +19 -14
- data/lib/frameworks/sproutcore/frameworks/bootstrap/tests/system/browser.js +471 -149
- data/lib/frameworks/sproutcore/frameworks/core_foundation/controllers/array.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/core_foundation/ext/object.js +42 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/ext/run_loop.js +3 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/ext/string.js +7 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/action_support.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/delegate_support.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/responder_context.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/selection_support.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/body_overflow.js +63 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/keyboard.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/layout.js +37 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/main.js +28 -6
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/pane.js +10 -3
- data/lib/frameworks/sproutcore/frameworks/core_foundation/protocols/sparse_array_delegate.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/browser.js +66 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/builder.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/cursor.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/event.js +58 -57
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/locale.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/locale.js.orig +445 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/platform.js +51 -31
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/ready.js +5 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/render_context.js +53 -69
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/responder.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +98 -72
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/string.js +37 -3
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/timer.js +7 -4
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/controllers/array/array_case.js +21 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/controllers/object/content_destroyed.js +7 -7
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/mixins/string.js +23 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/browser.js +66 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/event.js +22 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/locale.js +11 -11
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/render_context/end.js +4 -4
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/render_context/escape_html.js +41 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/render_context/helpers_className.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/render_context/helpers_style.js +8 -8
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/render_context/update.js +17 -16
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/selection_set/remove.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/build_children.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/class_name_bindings_test.js +15 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/createChildViews.js +5 -5
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view.js +50 -30
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/acceleration.js +46 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/animation.js +1 -43
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/keyboard.js +8 -34
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout.js +3 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout_style.js +10 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/manipulation.js +6 -5
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/theming.js +22 -2
- data/lib/frameworks/sproutcore/frameworks/datastore/data_sources/data_source.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/datastore/mixins/relationship_support.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/models/child_attribute.js +0 -2
- data/lib/frameworks/sproutcore/frameworks/datastore/models/children_attribute.js +35 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/models/record.js +46 -19
- data/lib/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +23 -9
- data/lib/frameworks/sproutcore/frameworks/datastore/models/single_attribute.js +2 -3
- data/lib/frameworks/sproutcore/frameworks/datastore/system/many_array.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/system/nested_store.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/datastore/system/query.js +294 -302
- data/lib/frameworks/sproutcore/frameworks/datastore/system/query.js.orig +1531 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/system/record_array.js +4 -2
- data/lib/frameworks/sproutcore/frameworks/datastore/system/store.js +14 -11
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/integration/many_array.js +63 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/many_attribute.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record.js +4 -4
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_array.js +50 -10
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_array_complex.js +4 -4
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_complex.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record/destroy.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record/refresh.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record_attribute.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/single_attribute.js +114 -67
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/commitChangesFromNestedStore.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/readDataHash.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/query/compare.js +54 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/query/evaluation.js +29 -9
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/query/parse.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/record_array/core_methods.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/record_array/flush.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/cancelRecord.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/commitChangesFromNestedStore.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/commitRecord.js +37 -45
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/find.js +127 -127
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/pushChanges.js +16 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/pushRelationships.js +42 -4
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/readDataHash.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/core/system/datetime.js +13 -7
- data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/core/tests/system/datetime.js +8 -0
- data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/localized/resources/strings.js +2 -1
- data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/localized/system/datetime.js +1 -0
- data/lib/frameworks/sproutcore/frameworks/debug/core.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/core.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/mixins/collection_row_delegate.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/mixins/collection_view_delegate.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/alert.js +1 -4
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/menu.js +19 -6
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/modal.js +30 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/palette.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/panel.js +24 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/picker.js +121 -28
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/sheet.js +15 -15
- data/lib/frameworks/sproutcore/frameworks/desktop/protocols/drag_data_source.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/protocols/drop_target.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/protocols/responder.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/button.js +39 -15
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/collection.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/disclosure.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/image_button.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/panel.js +14 -6
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/popup_button.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/progress.js +11 -11
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/segment.js +4 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/segmented.js +1 -51
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/slider.js +11 -16
- data/lib/frameworks/sproutcore/frameworks/desktop/resources/images/icons/sc-icon-error-48.png +0 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/resources/slider.css +0 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/system/drag.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/system/undo_manager.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/alert/ui.js +9 -9
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/button/content.js +11 -11
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/button/ui.js +2 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/collection/reload.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/date_field/ui.js +107 -81
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/list/rowDelegate.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/progress/ui.js +68 -60
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/radio/methods.js +57 -12
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/scroll/integration.js +21 -19
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/scroller.js +5 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/ui.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/select/ui.js +32 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/split/methods.js +12 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/stacked/ui_comments.js +12 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/tab/methods.js +0 -8
- data/lib/frameworks/sproutcore/frameworks/desktop/views/button.js +77 -132
- data/lib/frameworks/sproutcore/frameworks/desktop/views/checkbox.js +5 -6
- data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +16 -15
- data/lib/frameworks/sproutcore/frameworks/desktop/views/date_field.js +52 -52
- data/lib/frameworks/sproutcore/frameworks/desktop/views/disclosure.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/views/grid.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/views/list.js +147 -147
- data/lib/frameworks/sproutcore/frameworks/desktop/views/list_item.js +11 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_item.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_scroll.js +5 -5
- data/lib/frameworks/sproutcore/frameworks/desktop/views/popup_button.js +22 -12
- data/lib/frameworks/sproutcore/frameworks/desktop/views/radio.js +13 -7
- data/lib/frameworks/sproutcore/frameworks/desktop/views/scene.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll.js +462 -441
- data/lib/frameworks/sproutcore/frameworks/desktop/views/scroller.js +48 -62
- data/lib/frameworks/sproutcore/frameworks/desktop/views/segment.js +22 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/views/segmented.js +150 -32
- data/lib/frameworks/sproutcore/frameworks/desktop/views/select.js +104 -45
- data/lib/frameworks/sproutcore/frameworks/desktop/views/select_button.js +42 -20
- data/lib/frameworks/sproutcore/frameworks/desktop/views/slider.js +24 -24
- data/lib/frameworks/sproutcore/frameworks/desktop/views/split.js +148 -154
- data/lib/frameworks/sproutcore/frameworks/desktop/views/stacked.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/views/static_content.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/views/tab.js +8 -7
- data/lib/frameworks/sproutcore/frameworks/desktop/views/web.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/experimental/Buildfile +2 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/apps/greenhouse/controllers/files.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/apps/greenhouse/controllers/library.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/apps/greenhouse/controllers/targets.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/apps/greenhouse/controllers/view_configs.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/apps/greenhouse/mixins/drop_down.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/apps/greenhouse/states/ready.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/apps/greenhouse/views/plist_item.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/apps/greenhouse/views/web.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/designer/controllers/page_design.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/designer/css/css_style_sheet.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/designer/designers/object_designer.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/designer/designers/view_designer.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/designer/mixins/snap_lines.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/designer/views/designer_drop_target.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/designer/views/drawing.js +21 -21
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/designer/views/page_item_view.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/views/form.js +59 -53
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/menu/views/menu/scroll.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/polymorphism/tests/models/polymorphism/simple.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/core_scroll.js +6 -6
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/desktop/scroll.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/touch/scroll.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/ext/menu.js +14 -10
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/ext/menu_item.js +17 -6
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/views/popup_button.js +38 -14
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/views/select.js +5 -13
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/mixins/split_child.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/mixins/split_thumb.js +5 -3
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/tests/children.js +19 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/tests/methods.js +20 -2
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/tests/split_thumb.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/views/split.js +35 -12
- data/lib/frameworks/sproutcore/frameworks/formatters/README +6 -0
- data/lib/frameworks/sproutcore/frameworks/formatters/english.lproj/strings.js +174 -0
- data/lib/frameworks/sproutcore/frameworks/formatters/formatters/date_formatter.js +351 -0
- data/lib/frameworks/sproutcore/frameworks/formatters/tests/date_formatter.js +517 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/core.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/auto_resize.js +345 -138
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/button.js +5 -3
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/content_value_support.js +176 -42
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/editable.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/flowed_layout.js +137 -105
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/gestureable.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inline_editable.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inline_editor.js +16 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/static_layout.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/validatable.js +47 -47
- data/lib/frameworks/sproutcore/frameworks/foundation/private/tree_item_observer.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/helpers/sizing.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/label.js +28 -6
- data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/render_delegate.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/resources/benchmark.css +0 -5
- data/lib/frameworks/sproutcore/frameworks/foundation/resources/bootstrap.rhtml +34 -19
- data/lib/frameworks/sproutcore/frameworks/foundation/resources/button_view.css +0 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/resources/label.css +1 -5
- data/lib/frameworks/sproutcore/frameworks/foundation/resources/text_field.css +8 -9
- data/lib/frameworks/sproutcore/frameworks/foundation/system/benchmark.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/system/module.js +179 -47
- data/lib/frameworks/sproutcore/frameworks/foundation/system/task_queue.js +34 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/system/text_selection.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/system/user_defaults.js +26 -12
- data/lib/frameworks/sproutcore/frameworks/foundation/system/utils/misc.js +7 -7
- data/lib/frameworks/sproutcore/frameworks/foundation/system/utils/string_measurement.js +12 -4
- data/lib/frameworks/sproutcore/frameworks/foundation/system/utils/string_metric_optimization.js +202 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/content_value_support/content.js +77 -8
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/flowed_layout/tests.js +1 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_editable/beginEditing.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_editable/commitEditing.js +4 -3
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_editable/discardEditing.js +4 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_editor/beginEditing.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_editor/commitEditing.js +4 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_editor/discardEditing.js +4 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/system/utils/pointInElement.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/label/ui.js +0 -8
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/ui.js +163 -149
- data/lib/frameworks/sproutcore/frameworks/foundation/validators/credit_card.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/validators/date.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/validators/date_time.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/validators/password.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/validators/validator.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/foundation/views/field.js +16 -43
- data/lib/frameworks/sproutcore/frameworks/foundation/views/image.js +4 -3
- data/lib/frameworks/sproutcore/frameworks/foundation/views/inline_text_field.js +67 -54
- data/lib/frameworks/sproutcore/frameworks/foundation/views/label.js +49 -38
- data/lib/frameworks/sproutcore/frameworks/foundation/views/text_field.js +285 -242
- data/lib/frameworks/sproutcore/frameworks/jquery/jquery-buffer.js +13 -13
- data/lib/frameworks/sproutcore/frameworks/jquery/jquery-buffered.js +19 -22
- data/lib/frameworks/sproutcore/frameworks/jquery/jquery-sc.js +9 -3
- data/lib/frameworks/sproutcore/frameworks/jquery/jquery.js +231 -186
- data/lib/frameworks/sproutcore/frameworks/media/views/audio.js +145 -143
- data/lib/frameworks/sproutcore/frameworks/media/views/video.js +156 -154
- data/lib/frameworks/sproutcore/frameworks/qunit/qunit/qunit.js +5 -5
- data/lib/frameworks/sproutcore/frameworks/routing/system/routes.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/routing/system/routes.js.orig +540 -0
- data/lib/frameworks/sproutcore/frameworks/routing/tests/system/routes.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/core.js +15 -8
- data/lib/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/base.js +5 -5
- data/lib/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/replace.js +12 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/ext/function.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/array.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/copyable.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/enumerable.js +7 -7
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +98 -32
- data/lib/frameworks/sproutcore/frameworks/runtime/private/chain_observer.js +7 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/private/observer_queue.js +14 -3
- data/lib/frameworks/sproutcore/frameworks/runtime/private/observer_set.js +98 -13
- data/lib/frameworks/sproutcore/frameworks/runtime/system/binding.js +8 -14
- data/lib/frameworks/sproutcore/frameworks/runtime/system/enumerator.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/system/error.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/system/index_set.js +23 -6
- data/lib/frameworks/sproutcore/frameworks/runtime/system/logger.js +69 -18
- data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +57 -31
- data/lib/frameworks/sproutcore/frameworks/runtime/system/run_loop.js +189 -14
- data/lib/frameworks/sproutcore/frameworks/runtime/system/string.js +82 -22
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/chained.js +20 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/observable.js +125 -4
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/private/observer_queue.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/binding.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/index_set/rangeStartForIndex.js +37 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/index_set/remove.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/logger.js +16 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/run_loop.js +75 -4
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/string.js +41 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/mixins/statechart_delegate.js +113 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/private/state_path_matcher.js +312 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/system/async.js +18 -22
- data/lib/frameworks/sproutcore/frameworks/statechart/system/state.js +508 -131
- data/lib/frameworks/sproutcore/frameworks/statechart/system/state_route_handler_context.js +78 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/system/statechart.js +265 -44
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/event_handling/basic/with_concurrent_states.js +16 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/event_handling/responder/responder_chain.js +11 -3
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/private/state_path_matcher.js +116 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/state/methods/add_substate.js +108 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/state/methods/find_first_relative_current_state/with_concurrent.js +179 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/state/methods/find_first_relative_current_state/without_concurrent.js +74 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/state/methods/get_state.js +141 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/state/methods/get_substate.js +340 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/state/methods/route_triggered.js +161 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/state/methods/try_to_handle_event.js +288 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/state_transitioning/history_state/standard/without_concurrent_states/context.js +5 -33
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/state_transitioning/routing/with_concurrent_states/basic.js +213 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/state_transitioning/routing/without_concurrent_states/basic.js +212 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/state_transitioning/standard/without_concurrent_states/core.js +8 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/{state/namespacing.js → statechart/methods/get_state.js} +3 -41
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/statechart/{invoke_state_method.js → methods/invoke_state_method.js} +1 -1
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/{event_handling/advanced → statechart}/respond_to_event.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/system/state_route_handler_context/methods/retry.js +64 -0
- data/lib/frameworks/sproutcore/frameworks/table/core.js +2 -0
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/controls/button.js +0 -1
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/ext/handlebars.js +29 -5
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/ext/handlebars/bind.js +4 -3
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/ext/handlebars/collection.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/ext/handlebars/localization.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/ext/handlebars/view.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{handlebars → template_view}/handlebars.js +493 -357
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/mixins/template_helpers/checkbox_support.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/mixins/template_helpers/text_field_support.js +13 -2
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/panes/template.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/tests/controls/button.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/tests/mixins/template_helpers/checkbox_support.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/tests/mixins/template_helpers/text_field_support.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/tests/panes/template.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/tests/views/template/collection.js +39 -14
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/tests/views/template/core.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/tests/views/template/handlebars.js +57 -6
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/views/bindable_span.js +21 -6
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/views/template.js +9 -3
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/views/template_collection.js +55 -26
- data/lib/frameworks/sproutcore/frameworks/testing/system/equiv.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/testing/system/plan.js +122 -122
- data/lib/frameworks/sproutcore/frameworks/testing/system/runner.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/testing/system/suite.js +4 -4
- data/lib/frameworks/sproutcore/frameworks/yuireset/resources/base.css +1 -1
- data/lib/frameworks/sproutcore/frameworks/yuireset/resources/reset.css +0 -1
- data/lib/frameworks/sproutcore/frameworks/yuireset/resources/view.css +4 -4
- data/lib/frameworks/sproutcore/lib/index.rhtml +55 -32
- data/lib/frameworks/sproutcore/license.js +2 -4
- data/lib/frameworks/sproutcore/themes/ace/resources/body.css +5 -1
- data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/18px/button.css +2 -2
- data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/24px/button.css +21 -13
- data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/30px/button.css +17 -10
- data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/44px/button.css +4 -3
- data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/24px/button.css +20 -12
- data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/30px/button.css +16 -8
- data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/jumbo/button.css +17 -0
- data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/small/button.css +17 -0
- data/lib/frameworks/sproutcore/themes/ace/resources/disclosure/ace/disclosure.css +2 -2
- data/lib/frameworks/sproutcore/themes/ace/resources/master-detail/master-detail.css +2 -2
- data/lib/frameworks/sproutcore/themes/ace/resources/picker/popover/popover.css +5 -3
- data/lib/frameworks/sproutcore/themes/iphone_theme/english.lproj/core.css +1 -1
- data/lib/frameworks/sproutcore/themes/legacy_theme/english.lproj/toolbar.css +1 -1
- data/lib/gen/app/USAGE +17 -4
- data/lib/gen/language/Buildfile +4 -4
- data/lib/gen/language/USAGE +4 -4
- data/lib/gen/page/templates/pages/@target_name@/Buildfile +7 -7
- data/lib/gen/{html_app → statechart_app}/Buildfile +0 -0
- data/lib/gen/{html_app → statechart_app}/README +0 -0
- data/lib/gen/statechart_app/USAGE +21 -0
- data/lib/gen/statechart_app/templates/apps/@target_name@/Buildfile +9 -0
- data/lib/gen/statechart_app/templates/apps/@target_name@/core.js +24 -0
- data/lib/gen/statechart_app/templates/apps/@target_name@/main.js +26 -0
- data/lib/gen/statechart_app/templates/apps/@target_name@/resources/_theme.css +18 -0
- data/lib/gen/statechart_app/templates/apps/@target_name@/resources/loading.rhtml +9 -0
- data/lib/gen/statechart_app/templates/apps/@target_name@/resources/main_page.js +21 -0
- data/lib/gen/statechart_app/templates/apps/@target_name@/statechart.js +8 -0
- data/lib/gen/statechart_app/templates/apps/@target_name@/states/ready_state.js +12 -0
- data/lib/gen/statechart_app/templates/apps/@target_name@/theme.js +24 -0
- data/lib/sproutcore/builders.rb +1 -0
- data/lib/sproutcore/builders/base.rb +19 -1
- data/lib/sproutcore/builders/chance_file.rb +6 -1
- data/lib/sproutcore/builders/handlebars.rb +1 -9
- data/lib/sproutcore/builders/javascript.rb +1 -10
- data/lib/sproutcore/builders/json.rb +25 -0
- data/lib/sproutcore/builders/less.rb +1 -1
- data/lib/sproutcore/builders/sass.rb +1 -1
- data/lib/sproutcore/builders/stylesheet.rb +1 -9
- data/lib/sproutcore/helpers/html5_manifest.rb +1 -1
- data/lib/sproutcore/helpers/static_helper.rb +42 -0
- data/lib/sproutcore/rack/proxy.rb +21 -3
- data/lib/sproutcore/rack/service.rb +3 -2
- data/lib/sproutcore/tools.rb +18 -25
- data/lib/sproutcore/tools/gen.rb +10 -3
- data/lib/sproutcore/tools/init.rb +11 -10
- data/spec/buildtasks/manifest/prepare_build_tasks/json_spec.rb +62 -0
- data/spec/fixtures/builder_tests/apps/handlebars_test/Buildfile +1 -1
- data/spec/fixtures/builder_tests/apps/json_test/sc_static.json +2 -0
- data/spec/lib/builders/json_spec.rb +53 -0
- data/sproutcore.gemspec +2 -2
- data/vendor/chance/lib/chance/parser.rb +1 -1
- metadata +222 -177
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/datetime.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/debug/invoke_once_last_debugging.js +0 -259
- data/lib/frameworks/sproutcore/frameworks/documentation/core.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/system/chance.js +0 -69
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/editable/ui.js +0 -44
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_text_field/ui.js +0 -64
- data/lib/frameworks/sproutcore/frameworks/mini/license.js +0 -30
- data/lib/gen/html_app/USAGE +0 -15
- data/lib/gen/html_app/templates/apps/@target_name@/@target_name@.js +0 -11
- 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 -6
- data/lib/gen/html_app/templates/apps/@target_name@/resources/templates/@target_name@.handlebars +0 -1
- data/lib/gen/html_project/Buildfile +0 -45
- data/lib/gen/html_project/INIT +0 -3
- data/lib/gen/html_project/README +0 -1
- data/lib/gen/html_project/USAGE +0 -2
- data/lib/gen/html_project/templates/@filename@/Buildfile +0 -5
- data/lib/gen/html_project/templates/@filename@/README +0 -4
|
@@ -250,6 +250,15 @@ SC.ListItemView = SC.View.extend(SC.InlineEditable, SC.Control,
|
|
|
250
250
|
*/
|
|
251
251
|
validator: null,
|
|
252
252
|
|
|
253
|
+
contentKeys: {
|
|
254
|
+
contentValueKey: 'title',
|
|
255
|
+
contentCheckboxKey: 'checkbox',
|
|
256
|
+
contentIconKey: 'icon',
|
|
257
|
+
contentRightIconKey: 'rightIcon',
|
|
258
|
+
contentUnreadCountKey: 'count',
|
|
259
|
+
contentIsBranchKey: 'branch'
|
|
260
|
+
},
|
|
261
|
+
|
|
253
262
|
/** @private */
|
|
254
263
|
contentPropertyDidChange: function() {
|
|
255
264
|
//if (this.get('isEditing')) this.discardEditing() ;
|
|
@@ -292,7 +301,7 @@ SC.ListItemView = SC.View.extend(SC.InlineEditable, SC.Control,
|
|
|
292
301
|
},
|
|
293
302
|
|
|
294
303
|
/** @private
|
|
295
|
-
Determines if the event
|
|
304
|
+
Determines if the event occurred inside an element with the specified
|
|
296
305
|
classname or not.
|
|
297
306
|
*/
|
|
298
307
|
_isInsideElementWithClassName: function(className, evt) {
|
|
@@ -393,7 +402,7 @@ SC.ListItemView = SC.View.extend(SC.InlineEditable, SC.Control,
|
|
|
393
402
|
this._removeCheckboxActiveState() ;
|
|
394
403
|
ret = YES ;
|
|
395
404
|
|
|
396
|
-
// if mouse as down on disclosure -- handle
|
|
405
|
+
// if mouse as down on disclosure -- handle mouse up. otherwise pass on
|
|
397
406
|
// to parent.
|
|
398
407
|
} else if (this._isMouseDownOnDisclosure) {
|
|
399
408
|
if (this._isInsideDisclosure(evt)) {
|
|
@@ -56,7 +56,7 @@ SC.MenuItemView = SC.View.extend(SC.ContentDisplay,
|
|
|
56
56
|
acceptsFirstResponder: YES,
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
|
-
IE only attribute to block
|
|
59
|
+
IE only attribute to block blurring of other controls
|
|
60
60
|
|
|
61
61
|
@type Boolean
|
|
62
62
|
@default YES
|
|
@@ -289,7 +289,7 @@ SC.MenuItemView = SC.View.extend(SC.ContentDisplay,
|
|
|
289
289
|
|
|
290
290
|
/**
|
|
291
291
|
This method will check whether the current Menu Item is still
|
|
292
|
-
selected and then create a submenu
|
|
292
|
+
selected and then create a submenu accordingly.
|
|
293
293
|
*/
|
|
294
294
|
showSubMenu: function() {
|
|
295
295
|
var subMenu = this.get('subMenu') ;
|
|
@@ -189,7 +189,7 @@ SC.MenuScrollerView = SC.ScrollerView.extend(
|
|
|
189
189
|
/**
|
|
190
190
|
This function overrides the default function in SC.Scroller.
|
|
191
191
|
SC.MenuScroller and SC.MenuScroll use valueBinding so this function is
|
|
192
|
-
not
|
|
192
|
+
not necessary.
|
|
193
193
|
*/
|
|
194
194
|
_sc_scroller_valueDidChange: function() {}.observes('value'),
|
|
195
195
|
|
|
@@ -258,7 +258,7 @@ SC.MenuScrollerView = SC.ScrollerView.extend(
|
|
|
258
258
|
_invokeScrollOnMouseOver: function(){
|
|
259
259
|
this._scrollMenu();
|
|
260
260
|
if(this.get('isMouseOver')){
|
|
261
|
-
this.invokeLater(this._invokeScrollOnMouseOver,
|
|
261
|
+
this.invokeLater(this._invokeScrollOnMouseOver, 50);
|
|
262
262
|
}
|
|
263
263
|
}
|
|
264
264
|
|
|
@@ -394,7 +394,7 @@ SC.MenuScrollView = SC.ScrollView.extend(
|
|
|
394
394
|
autohidesHorizontalScroller: NO,
|
|
395
395
|
|
|
396
396
|
/**
|
|
397
|
-
YES if the view
|
|
397
|
+
YES if the view should maintain a vertical scroller. This property must
|
|
398
398
|
be set when the view is created.
|
|
399
399
|
|
|
400
400
|
@type Boolean
|
|
@@ -647,7 +647,7 @@ SC.MenuScrollView = SC.ScrollView.extend(
|
|
|
647
647
|
|
|
648
648
|
/** @private
|
|
649
649
|
Invoked whenever the contentView's frame changes. This will update the
|
|
650
|
-
scroller
|
|
650
|
+
scroller maximum and optionally update the scroller visibility if the
|
|
651
651
|
size of the contentView changes. We don't care about the origin since
|
|
652
652
|
that is tracked separately from the offset values.
|
|
653
653
|
*/
|
|
@@ -695,7 +695,7 @@ SC.MenuScrollView = SC.ScrollView.extend(
|
|
|
695
695
|
|
|
696
696
|
// update the offset for the contentView...
|
|
697
697
|
var contentView = this.get('contentView');
|
|
698
|
-
if (contentView) contentView.
|
|
698
|
+
if (contentView) contentView.$().css('top', (0-offset) + "px");
|
|
699
699
|
|
|
700
700
|
}.observes('verticalScrollOffset')
|
|
701
701
|
|
|
@@ -188,28 +188,34 @@ SC.PopupButtonView = SC.ButtonView.extend(
|
|
|
188
188
|
|
|
189
189
|
this._action() ;
|
|
190
190
|
|
|
191
|
-
// Store the current timestamp. We register the timestamp
|
|
192
|
-
//
|
|
191
|
+
// Store the current timestamp. We register the timestamp after a setTimeout
|
|
192
|
+
// so that the menu has been rendered, in case that operation
|
|
193
193
|
// takes more than a few hundred milliseconds.
|
|
194
194
|
|
|
195
195
|
// One mouseUp, we'll use this value to determine how long the mouse was
|
|
196
196
|
// pressed.
|
|
197
|
-
|
|
197
|
+
|
|
198
|
+
// we need to keep track that we opened it just now in case we get the
|
|
199
|
+
// mouseUp before render finishes. If it is 0, then we know we have not
|
|
200
|
+
// waited long enough.
|
|
201
|
+
this._menuRenderedTimestamp = 0;
|
|
202
|
+
|
|
203
|
+
var self = this;
|
|
204
|
+
|
|
205
|
+
// setTimeout guarantees that all rendering is done. The browser will even
|
|
206
|
+
// have rendered by this point.
|
|
207
|
+
setTimeout(function() {
|
|
208
|
+
SC.run(function(){
|
|
209
|
+
// a run loop might be overkill here but what if Date.now fails?
|
|
210
|
+
self._menuRenderedTimestamp = Date.now();
|
|
211
|
+
});
|
|
212
|
+
}, 1);
|
|
198
213
|
|
|
199
214
|
this.becomeFirstResponder();
|
|
200
215
|
|
|
201
216
|
return YES ;
|
|
202
217
|
},
|
|
203
218
|
|
|
204
|
-
/** @private
|
|
205
|
-
Records the current timestamp. This is invoked at the end of the runloop
|
|
206
|
-
by mouseDown. We use this value to determine the delay between mouseDown
|
|
207
|
-
and mouseUp.
|
|
208
|
-
*/
|
|
209
|
-
_recordMouseDownTimestamp: function() {
|
|
210
|
-
this._menuRenderedTimestamp = new Date().getTime();
|
|
211
|
-
},
|
|
212
|
-
|
|
213
219
|
/** @private
|
|
214
220
|
Because we responded YES to the mouseDown event, we have responsibility
|
|
215
221
|
for handling the corresponding mouseUp event.
|
|
@@ -232,6 +238,10 @@ SC.PopupButtonView = SC.ButtonView.extend(
|
|
|
232
238
|
menu = this.get('instantiatedMenu'),
|
|
233
239
|
touch = SC.platform.touch,
|
|
234
240
|
targetMenuItem;
|
|
241
|
+
|
|
242
|
+
// normalize the previousTimestamp: if it is 0, it might as well be now.
|
|
243
|
+
// 0 means that we have not even triggered the nearly-immediate saving of timestamp.
|
|
244
|
+
if (previousTimestamp === 0) previousTimestamp = Date.now();
|
|
235
245
|
|
|
236
246
|
if (menu) {
|
|
237
247
|
// Get the menu item the user is currently hovering their mouse over
|
|
@@ -180,7 +180,7 @@ SC.RadioView = SC.View.extend(SC.Control,
|
|
|
180
180
|
/**
|
|
181
181
|
If items property is a hash, specify which property will function as
|
|
182
182
|
the item width with this itemWidthKey property. This is only used when
|
|
183
|
-
layoutDirection is set to SC.
|
|
183
|
+
layoutDirection is set to SC.LAYOUT_HORIZONTAL and can be used to override
|
|
184
184
|
the default value provided by the framework or theme CSS.
|
|
185
185
|
|
|
186
186
|
@type String
|
|
@@ -304,7 +304,7 @@ SC.RadioView = SC.View.extend(SC.Control,
|
|
|
304
304
|
ariaLabel = item.get ? item.get(ariaLabelKey) : item[ariaLabelKey];
|
|
305
305
|
} else ariaLabel = null;
|
|
306
306
|
|
|
307
|
-
// if item is nil, use
|
|
307
|
+
// if item is nil, use some defaults...
|
|
308
308
|
} else {
|
|
309
309
|
title = value = icon = null;
|
|
310
310
|
isEnabled = NO;
|
|
@@ -356,8 +356,11 @@ SC.RadioView = SC.View.extend(SC.Control,
|
|
|
356
356
|
this._activeRadioButton = index;
|
|
357
357
|
|
|
358
358
|
if (index !== undefined) {
|
|
359
|
-
this.get('displayItems')[index]
|
|
360
|
-
|
|
359
|
+
var item = this.get('displayItems')[index];
|
|
360
|
+
if (item.get('isEnabled')) {
|
|
361
|
+
item.set('isActive', YES);
|
|
362
|
+
delegate.updateRadioAtIndex(proxy, elem, index);
|
|
363
|
+
}
|
|
361
364
|
}
|
|
362
365
|
|
|
363
366
|
// even if radiobuttons are not set to get firstResponder, allow default
|
|
@@ -387,9 +390,12 @@ SC.RadioView = SC.View.extend(SC.Control,
|
|
|
387
390
|
this._activeRadioButton = undefined;
|
|
388
391
|
|
|
389
392
|
if (index !== undefined) {
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
+
var item = this.get('displayItems')[index];
|
|
394
|
+
if (item.get('isEnabled')) {
|
|
395
|
+
item.set('isActive', NO);
|
|
396
|
+
delegate.updateRadioAtIndex(proxy, elem, index);
|
|
397
|
+
this.set('value', item.value);
|
|
398
|
+
}
|
|
393
399
|
}
|
|
394
400
|
|
|
395
401
|
evt.allowDefault();
|
|
@@ -34,7 +34,7 @@ SC.SceneView = SC.ContainerView.extend(
|
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
36
|
Array of scene names. Scenes will slide on and off screen in the order
|
|
37
|
-
that you
|
|
37
|
+
that you specify them here. That is, if you shift from a scene at index
|
|
38
38
|
2 to a scene at index 1, the scenes will animation backwards. If you
|
|
39
39
|
shift to a scene at index 3, the scenes will animate forwards.
|
|
40
40
|
|
|
@@ -46,7 +46,7 @@ SC.SceneView = SC.ContainerView.extend(
|
|
|
46
46
|
/**
|
|
47
47
|
The currently showing scene. Changing this property will cause the
|
|
48
48
|
scene view to transition to the new scene. If you set this property to
|
|
49
|
-
null, an empty string, or a non-
|
|
49
|
+
null, an empty string, or a non-existent scene, then the scene will appear
|
|
50
50
|
empty.
|
|
51
51
|
|
|
52
52
|
@type String
|
|
@@ -24,14 +24,14 @@ SC.FAST_SCROLL_DECELERATION = 0.85;
|
|
|
24
24
|
/** @class
|
|
25
25
|
Implements a complete scroll view. This class uses a manual implementation
|
|
26
26
|
of scrollers in order to properly support clipping frames.
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
Important Events:
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
- contentView frame size changes (to autoshow/hide scrollbar - adjust scrollbar size)
|
|
31
31
|
- horizontalScrollOffset change
|
|
32
32
|
- verticalScrollOffsetChanges
|
|
33
33
|
- scroll wheel events
|
|
34
|
-
|
|
34
|
+
|
|
35
35
|
@extends SC.View
|
|
36
36
|
@since SproutCore 1.0
|
|
37
37
|
*/
|
|
@@ -47,44 +47,44 @@ SC.ScrollView = SC.View.extend({
|
|
|
47
47
|
|
|
48
48
|
// ..........................................................
|
|
49
49
|
// PROPERTIES
|
|
50
|
-
//
|
|
51
|
-
|
|
50
|
+
//
|
|
51
|
+
|
|
52
52
|
/**
|
|
53
53
|
Walk like a duck
|
|
54
|
-
|
|
54
|
+
|
|
55
55
|
@type Boolean
|
|
56
56
|
@default YES
|
|
57
57
|
@readOnly
|
|
58
58
|
*/
|
|
59
59
|
isScrollable: YES,
|
|
60
|
-
|
|
61
|
-
/**
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
62
|
The content view you want the scroll view to manage. This will be assigned to the contentView of the clipView also.
|
|
63
|
-
|
|
63
|
+
|
|
64
64
|
@type SC.View
|
|
65
65
|
@default null
|
|
66
66
|
*/
|
|
67
67
|
contentView: null,
|
|
68
|
-
|
|
68
|
+
|
|
69
69
|
/**
|
|
70
70
|
The horizontal alignment for non-filling content inside of the ScrollView. Possible values:
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
- SC.ALIGN_LEFT
|
|
73
73
|
- SC.ALIGN_RIGHT
|
|
74
74
|
- SC.ALIGN_CENTER
|
|
75
|
-
|
|
75
|
+
|
|
76
76
|
@type String
|
|
77
77
|
@default SC.ALIGN_LEFT
|
|
78
78
|
*/
|
|
79
79
|
horizontalAlign: SC.ALIGN_LEFT,
|
|
80
|
-
|
|
80
|
+
|
|
81
81
|
/**
|
|
82
82
|
The vertical alignment for non-filling content inside of the ScrollView. Possible values:
|
|
83
|
-
|
|
83
|
+
|
|
84
84
|
- SC.ALIGN_TOP
|
|
85
85
|
- SC.ALIGN_BOTTOM
|
|
86
86
|
- SC.ALIGN_MIDDLE
|
|
87
|
-
|
|
87
|
+
|
|
88
88
|
@type String
|
|
89
89
|
@default SC.ALIGN_TOP
|
|
90
90
|
*/
|
|
@@ -92,7 +92,7 @@ SC.ScrollView = SC.View.extend({
|
|
|
92
92
|
|
|
93
93
|
/**
|
|
94
94
|
The current horizontal scroll offset. Changing this value will update both the contentView and the horizontal scroller, if there is one.
|
|
95
|
-
|
|
95
|
+
|
|
96
96
|
@field
|
|
97
97
|
@type Number
|
|
98
98
|
@default 0
|
|
@@ -106,10 +106,10 @@ SC.ScrollView = SC.View.extend({
|
|
|
106
106
|
|
|
107
107
|
return this._scroll_horizontalScrollOffset||0;
|
|
108
108
|
}.property().cacheable(),
|
|
109
|
-
|
|
109
|
+
|
|
110
110
|
/**
|
|
111
111
|
The current vertical scroll offset. Changing this value will update both the contentView and the vertical scroller, if there is one.
|
|
112
|
-
|
|
112
|
+
|
|
113
113
|
@field
|
|
114
114
|
@type Number
|
|
115
115
|
@default 0
|
|
@@ -123,7 +123,7 @@ SC.ScrollView = SC.View.extend({
|
|
|
123
123
|
|
|
124
124
|
return this._scroll_verticalScrollOffset||0;
|
|
125
125
|
}.property().cacheable(),
|
|
126
|
-
|
|
126
|
+
|
|
127
127
|
/** @private
|
|
128
128
|
Calculates the maximum offset given content and container sizes, and the
|
|
129
129
|
alignment.
|
|
@@ -133,7 +133,7 @@ SC.ScrollView = SC.View.extend({
|
|
|
133
133
|
// simple to calculate the answer. Otherwise, we need to do some fancy-pants
|
|
134
134
|
// alignment logic (read: simple math)
|
|
135
135
|
if (contentSize >= containerSize) return contentSize - containerSize;
|
|
136
|
-
|
|
136
|
+
|
|
137
137
|
// alignment, yeah
|
|
138
138
|
if (align === SC.ALIGN_LEFT || align === SC.ALIGN_TOP) {
|
|
139
139
|
// if we left-align something, and it is smaller than the view, does that not mean
|
|
@@ -147,7 +147,7 @@ SC.ScrollView = SC.View.extend({
|
|
|
147
147
|
return 0 - (containerSize - contentSize);
|
|
148
148
|
}
|
|
149
149
|
},
|
|
150
|
-
|
|
150
|
+
|
|
151
151
|
/** @private
|
|
152
152
|
Calculates the minimum offset given content and container sizes, and the
|
|
153
153
|
alignment.
|
|
@@ -156,7 +156,7 @@ SC.ScrollView = SC.View.extend({
|
|
|
156
156
|
// if the content is larger than the container, we have no need to change the minimum
|
|
157
157
|
// away from the natural 0 position.
|
|
158
158
|
if (contentSize > containerSize) return 0;
|
|
159
|
-
|
|
159
|
+
|
|
160
160
|
// alignment, yeah
|
|
161
161
|
if (align === SC.ALIGN_LEFT || align === SC.ALIGN_TOP) {
|
|
162
162
|
// if we left-align something, and it is smaller than the view, does that not mean
|
|
@@ -170,12 +170,12 @@ SC.ScrollView = SC.View.extend({
|
|
|
170
170
|
return 0 - (containerSize - contentSize);
|
|
171
171
|
}
|
|
172
172
|
},
|
|
173
|
-
|
|
173
|
+
|
|
174
174
|
/**
|
|
175
|
-
The maximum horizontal scroll offset allowed given the current contentView
|
|
176
|
-
size and the size of the scroll view. If horizontal scrolling is
|
|
175
|
+
The maximum horizontal scroll offset allowed given the current contentView
|
|
176
|
+
size and the size of the scroll view. If horizontal scrolling is
|
|
177
177
|
disabled, this will always return 0.
|
|
178
|
-
|
|
178
|
+
|
|
179
179
|
@field
|
|
180
180
|
@type Number
|
|
181
181
|
@default 0
|
|
@@ -184,27 +184,27 @@ SC.ScrollView = SC.View.extend({
|
|
|
184
184
|
var view = this.get('contentView') ;
|
|
185
185
|
var contentWidth = view ? view.get('frame').width : 0,
|
|
186
186
|
calculatedWidth = view ? view.get('calculatedWidth') : 0;
|
|
187
|
-
|
|
187
|
+
|
|
188
188
|
// The following code checks if there is a calculatedWidth (collections)
|
|
189
189
|
// to avoid looking at the incorrect value calculated by frame.
|
|
190
190
|
if (calculatedWidth) {
|
|
191
|
-
contentWidth = view.calculatedWidth;
|
|
191
|
+
contentWidth = view.calculatedWidth;
|
|
192
192
|
}
|
|
193
193
|
contentWidth *= this._scale;
|
|
194
|
-
|
|
194
|
+
|
|
195
195
|
var containerWidth = this.get('containerView').get('frame').width ;
|
|
196
|
-
|
|
196
|
+
|
|
197
197
|
// we still must go through minimumScrollOffset even if we can't scroll
|
|
198
198
|
// because we need to adjust for alignment. So, just make sure it won't allow scrolling.
|
|
199
199
|
if (!this.get('canScrollHorizontal')) contentWidth = Math.min(contentWidth, containerWidth);
|
|
200
200
|
return this.maximumScrollOffset(contentWidth, containerWidth, this.get("horizontalAlign"));
|
|
201
201
|
}.property(),
|
|
202
|
-
|
|
202
|
+
|
|
203
203
|
/**
|
|
204
|
-
The maximum vertical scroll offset allowed given the current contentView
|
|
204
|
+
The maximum vertical scroll offset allowed given the current contentView
|
|
205
205
|
size and the size of the scroll view. If vertical scrolling is disabled,
|
|
206
206
|
this will always return 0 (or whatever alignment dictates).
|
|
207
|
-
|
|
207
|
+
|
|
208
208
|
@field
|
|
209
209
|
@type Number
|
|
210
210
|
@default 0
|
|
@@ -213,28 +213,28 @@ SC.ScrollView = SC.View.extend({
|
|
|
213
213
|
var view = this.get('contentView'),
|
|
214
214
|
contentHeight = (view && view.get('frame')) ? view.get('frame').height : 0,
|
|
215
215
|
calculatedHeight = view ? view.get('calculatedHeight') : 0;
|
|
216
|
-
|
|
216
|
+
|
|
217
217
|
// The following code checks if there is a calculatedWidth (collections)
|
|
218
218
|
// to avoid looking at the incorrect value calculated by frame.
|
|
219
219
|
if(calculatedHeight){
|
|
220
|
-
contentHeight = calculatedHeight;
|
|
220
|
+
contentHeight = calculatedHeight;
|
|
221
221
|
}
|
|
222
222
|
contentHeight *= this._scale;
|
|
223
|
-
|
|
223
|
+
|
|
224
224
|
var containerHeight = this.get('containerView').get('frame').height ;
|
|
225
|
-
|
|
225
|
+
|
|
226
226
|
// we still must go through minimumScrollOffset even if we can't scroll
|
|
227
227
|
// because we need to adjust for alignment. So, just make sure it won't allow scrolling.
|
|
228
228
|
if (!this.get('canScrollVertical')) contentHeight = Math.min(contentHeight, containerHeight);
|
|
229
229
|
return this.maximumScrollOffset(contentHeight, containerHeight, this.get("verticalAlign"));
|
|
230
230
|
}.property(),
|
|
231
|
-
|
|
232
|
-
|
|
231
|
+
|
|
232
|
+
|
|
233
233
|
/**
|
|
234
|
-
The minimum horizontal scroll offset allowed given the current contentView
|
|
235
|
-
size and the size of the scroll view. If horizontal scrolling is
|
|
234
|
+
The minimum horizontal scroll offset allowed given the current contentView
|
|
235
|
+
size and the size of the scroll view. If horizontal scrolling is
|
|
236
236
|
disabled, this will always return 0 (or whatever alignment dictates).
|
|
237
|
-
|
|
237
|
+
|
|
238
238
|
@field
|
|
239
239
|
@type Number
|
|
240
240
|
@default 0
|
|
@@ -246,23 +246,23 @@ SC.ScrollView = SC.View.extend({
|
|
|
246
246
|
// The following code checks if there is a calculatedWidth (collections)
|
|
247
247
|
// to avoid looking at the incorrect value calculated by frame.
|
|
248
248
|
if(calculatedWidth){
|
|
249
|
-
contentWidth = calculatedWidth;
|
|
249
|
+
contentWidth = calculatedWidth;
|
|
250
250
|
}
|
|
251
251
|
contentWidth *= this._scale;
|
|
252
|
-
|
|
252
|
+
|
|
253
253
|
var containerWidth = this.get('containerView').get('frame').width ;
|
|
254
|
-
|
|
254
|
+
|
|
255
255
|
// we still must go through minimumScrollOffset even if we can't scroll
|
|
256
256
|
// because we need to adjust for alignment. So, just make sure it won't allow scrolling.
|
|
257
257
|
if (!this.get('canScrollHorizontal')) contentWidth = Math.min(contentWidth, containerWidth);
|
|
258
258
|
return this.minimumScrollOffset(contentWidth, containerWidth, this.get("horizontalAlign"));
|
|
259
259
|
}.property(),
|
|
260
|
-
|
|
260
|
+
|
|
261
261
|
/**
|
|
262
|
-
The minimum vertical scroll offset allowed given the current contentView
|
|
262
|
+
The minimum vertical scroll offset allowed given the current contentView
|
|
263
263
|
size and the size of the scroll view. If vertical scrolling is disabled,
|
|
264
264
|
this will always return 0 (or whatever alignment dictates).
|
|
265
|
-
|
|
265
|
+
|
|
266
266
|
@field
|
|
267
267
|
@type Number
|
|
268
268
|
@default 0
|
|
@@ -271,49 +271,49 @@ SC.ScrollView = SC.View.extend({
|
|
|
271
271
|
var view = this.get('contentView') ;
|
|
272
272
|
var contentHeight = (view && view.get('frame')) ? view.get('frame').height : 0,
|
|
273
273
|
calculatedHeight = view ? view.get('calculatedHeight') : 0;
|
|
274
|
-
|
|
274
|
+
|
|
275
275
|
// The following code checks if there is a calculatedWidth (collections)
|
|
276
276
|
// to avoid looking at the incorrect value calculated by frame.
|
|
277
277
|
if(calculatedHeight){
|
|
278
|
-
contentHeight = view.calculatedHeight;
|
|
278
|
+
contentHeight = view.calculatedHeight;
|
|
279
279
|
}
|
|
280
280
|
contentHeight *= this._scale;
|
|
281
|
-
|
|
281
|
+
|
|
282
282
|
var containerHeight = this.get('containerView').get('frame').height ;
|
|
283
|
-
|
|
283
|
+
|
|
284
284
|
// we still must go through minimumScrollOffset even if we can't scroll
|
|
285
285
|
// because we need to adjust for alignment. So, just make sure it won't allow scrolling.
|
|
286
286
|
if (!this.get('canScrollVertical')) contentHeight = Math.min(contentHeight, containerHeight);
|
|
287
287
|
return this.minimumScrollOffset(contentHeight, containerHeight, this.get("verticalAlign"));
|
|
288
288
|
}.property(),
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
/**
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
292
|
Amount to scroll one vertical line.
|
|
293
|
-
|
|
293
|
+
|
|
294
294
|
Used by the default implementation of scrollDownLine() and scrollUpLine().
|
|
295
|
-
|
|
295
|
+
|
|
296
296
|
@type Number
|
|
297
297
|
@default 20
|
|
298
298
|
*/
|
|
299
299
|
verticalLineScroll: 20,
|
|
300
|
-
|
|
300
|
+
|
|
301
301
|
/**
|
|
302
302
|
Amount to scroll one horizontal line.
|
|
303
|
-
|
|
304
|
-
Used by the default implementation of scrollLeftLine() and
|
|
303
|
+
|
|
304
|
+
Used by the default implementation of scrollLeftLine() and
|
|
305
305
|
scrollRightLine().
|
|
306
|
-
|
|
306
|
+
|
|
307
307
|
@type Number
|
|
308
308
|
@default 20
|
|
309
309
|
*/
|
|
310
310
|
horizontalLineScroll: 20,
|
|
311
|
-
|
|
311
|
+
|
|
312
312
|
/**
|
|
313
313
|
Amount to scroll one vertical page.
|
|
314
|
-
|
|
314
|
+
|
|
315
315
|
Used by the default implementation of scrollUpPage() and scrollDownPage().
|
|
316
|
-
|
|
316
|
+
|
|
317
317
|
@field
|
|
318
318
|
@type Number
|
|
319
319
|
@default value of frame.height
|
|
@@ -322,13 +322,13 @@ SC.ScrollView = SC.View.extend({
|
|
|
322
322
|
verticalPageScroll: function() {
|
|
323
323
|
return this.get('frame').height;
|
|
324
324
|
}.property('frame'),
|
|
325
|
-
|
|
325
|
+
|
|
326
326
|
/**
|
|
327
327
|
Amount to scroll one horizontal page.
|
|
328
|
-
|
|
329
|
-
Used by the default implementation of scrollLeftPage() and
|
|
328
|
+
|
|
329
|
+
Used by the default implementation of scrollLeftPage() and
|
|
330
330
|
scrollRightPage().
|
|
331
|
-
|
|
331
|
+
|
|
332
332
|
@field
|
|
333
333
|
@type Number
|
|
334
334
|
@default value of frame.width
|
|
@@ -337,48 +337,48 @@ SC.ScrollView = SC.View.extend({
|
|
|
337
337
|
horizontalPageScroll: function() {
|
|
338
338
|
return this.get('frame').width;
|
|
339
339
|
}.property('frame'),
|
|
340
|
-
|
|
341
|
-
|
|
340
|
+
|
|
341
|
+
|
|
342
342
|
// ..........................................................
|
|
343
343
|
// SCROLLERS
|
|
344
|
-
//
|
|
345
|
-
|
|
346
|
-
/**
|
|
347
|
-
YES if the view should maintain a horizontal scroller. This property
|
|
344
|
+
//
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
YES if the view should maintain a horizontal scroller. This property
|
|
348
348
|
must be set when the view is created.
|
|
349
|
-
|
|
349
|
+
|
|
350
350
|
@type Boolean
|
|
351
351
|
@default YES
|
|
352
352
|
*/
|
|
353
353
|
hasHorizontalScroller: YES,
|
|
354
|
-
|
|
354
|
+
|
|
355
355
|
/**
|
|
356
|
-
The horizontal scroller view class. This will be replaced with a view
|
|
357
|
-
instance when the ScrollView is created unless hasHorizontalScroller is
|
|
356
|
+
The horizontal scroller view class. This will be replaced with a view
|
|
357
|
+
instance when the ScrollView is created unless hasHorizontalScroller is
|
|
358
358
|
NO.
|
|
359
|
-
|
|
359
|
+
|
|
360
360
|
@type SC.View
|
|
361
361
|
@default SC.ScrollerView
|
|
362
362
|
*/
|
|
363
363
|
horizontalScrollerView: SC.ScrollerView,
|
|
364
|
-
|
|
364
|
+
|
|
365
365
|
/**
|
|
366
366
|
The horizontal scroller view for touch. This will be replaced with a view
|
|
367
|
-
instance when touch is enabled when the ScrollView is created unless
|
|
367
|
+
instance when touch is enabled when the ScrollView is created unless
|
|
368
368
|
hasHorizontalScroller is NO.
|
|
369
|
-
|
|
369
|
+
|
|
370
370
|
@type SC.View
|
|
371
371
|
@default SC.TouchScrollerView
|
|
372
372
|
*/
|
|
373
373
|
horizontalTouchScrollerView: SC.TouchScrollerView,
|
|
374
|
-
|
|
374
|
+
|
|
375
375
|
/**
|
|
376
|
-
YES if the horizontal scroller should be visible. You can change this
|
|
377
|
-
property value anytime to show or hide the horizontal scroller. If you
|
|
378
|
-
do not want to use a horizontal scroller at all, you should instead set
|
|
379
|
-
hasHorizontalScroller to NO to avoid creating a scroller view in the
|
|
376
|
+
YES if the horizontal scroller should be visible. You can change this
|
|
377
|
+
property value anytime to show or hide the horizontal scroller. If you
|
|
378
|
+
do not want to use a horizontal scroller at all, you should instead set
|
|
379
|
+
hasHorizontalScroller to NO to avoid creating a scroller view in the
|
|
380
380
|
first place.
|
|
381
|
-
|
|
381
|
+
|
|
382
382
|
@type Boolean
|
|
383
383
|
@default YES
|
|
384
384
|
*/
|
|
@@ -387,61 +387,61 @@ SC.ScrollView = SC.View.extend({
|
|
|
387
387
|
/**
|
|
388
388
|
Returns YES if the view both has a horizontal scroller, the scroller is
|
|
389
389
|
visible.
|
|
390
|
-
|
|
390
|
+
|
|
391
391
|
@field
|
|
392
392
|
@type Boolean
|
|
393
393
|
@default YES
|
|
394
394
|
*/
|
|
395
395
|
canScrollHorizontal: function() {
|
|
396
|
-
return !!(this.get('hasHorizontalScroller') &&
|
|
397
|
-
this.get('horizontalScrollerView') &&
|
|
396
|
+
return !!(this.get('hasHorizontalScroller') &&
|
|
397
|
+
this.get('horizontalScrollerView') &&
|
|
398
398
|
this.get('isHorizontalScrollerVisible')) ;
|
|
399
399
|
}.property('isHorizontalScrollerVisible').cacheable(),
|
|
400
|
-
|
|
400
|
+
|
|
401
401
|
/**
|
|
402
402
|
If YES, the horizontal scroller will autohide if the contentView is
|
|
403
|
-
smaller than the visible area. You must set hasHorizontalScroller to YES
|
|
403
|
+
smaller than the visible area. You must set hasHorizontalScroller to YES
|
|
404
404
|
for this property to have any effect.
|
|
405
|
-
|
|
405
|
+
|
|
406
406
|
@type Boolean
|
|
407
407
|
@default YES
|
|
408
408
|
*/
|
|
409
409
|
autohidesHorizontalScroller: YES,
|
|
410
|
-
|
|
411
|
-
/**
|
|
412
|
-
YES if the view
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
YES if the view should maintain a vertical scroller. This property must
|
|
413
413
|
be set when the view is created.
|
|
414
|
-
|
|
414
|
+
|
|
415
415
|
@type Boolean
|
|
416
416
|
@default YES
|
|
417
417
|
*/
|
|
418
418
|
hasVerticalScroller: YES,
|
|
419
|
-
|
|
419
|
+
|
|
420
420
|
/**
|
|
421
|
-
The vertical scroller view class. This will be replaced with a view
|
|
421
|
+
The vertical scroller view class. This will be replaced with a view
|
|
422
422
|
instance when the ScrollView is created unless hasVerticalScroller is NO.
|
|
423
|
-
|
|
423
|
+
|
|
424
424
|
@type SC.View
|
|
425
425
|
@default SC.ScrollerView
|
|
426
426
|
*/
|
|
427
427
|
verticalScrollerView: SC.ScrollerView,
|
|
428
|
-
|
|
428
|
+
|
|
429
429
|
/**
|
|
430
430
|
The vertical touch scroller view class. This will be replaced with a view
|
|
431
431
|
instance when the ScrollView is created.
|
|
432
|
-
|
|
432
|
+
|
|
433
433
|
@type SC.View
|
|
434
434
|
@default SC.TouchScrollerView
|
|
435
435
|
*/
|
|
436
436
|
verticalTouchScrollerView: SC.TouchScrollerView,
|
|
437
|
-
|
|
437
|
+
|
|
438
438
|
/**
|
|
439
|
-
YES if the vertical scroller should be visible. You can change this
|
|
440
|
-
property value anytime to show or hide the vertical scroller. If you do
|
|
441
|
-
not want to use a vertical scroller at all, you should instead set
|
|
442
|
-
hasVerticalScroller to NO to avoid creating a scroller view in the first
|
|
439
|
+
YES if the vertical scroller should be visible. You can change this
|
|
440
|
+
property value anytime to show or hide the vertical scroller. If you do
|
|
441
|
+
not want to use a vertical scroller at all, you should instead set
|
|
442
|
+
hasVerticalScroller to NO to avoid creating a scroller view in the first
|
|
443
443
|
place.
|
|
444
|
-
|
|
444
|
+
|
|
445
445
|
@type Boolean
|
|
446
446
|
@default YES
|
|
447
447
|
*/
|
|
@@ -450,43 +450,43 @@ SC.ScrollView = SC.View.extend({
|
|
|
450
450
|
/**
|
|
451
451
|
Returns YES if the view both has a horizontal scroller, the scroller is
|
|
452
452
|
visible.
|
|
453
|
-
|
|
453
|
+
|
|
454
454
|
@field
|
|
455
455
|
@type Boolean
|
|
456
456
|
@default YES
|
|
457
457
|
*/
|
|
458
458
|
canScrollVertical: function() {
|
|
459
|
-
return !!(this.get('hasVerticalScroller') &&
|
|
460
|
-
this.get('verticalScrollerView') &&
|
|
459
|
+
return !!(this.get('hasVerticalScroller') &&
|
|
460
|
+
this.get('verticalScrollerView') &&
|
|
461
461
|
this.get('isVerticalScrollerVisible')) ;
|
|
462
462
|
}.property('isVerticalScrollerVisible').cacheable(),
|
|
463
463
|
|
|
464
464
|
/**
|
|
465
465
|
If YES, the vertical scroller will autohide if the contentView is
|
|
466
|
-
smaller than the visible area. You must set hasVerticalScroller to YES
|
|
466
|
+
smaller than the visible area. You must set hasVerticalScroller to YES
|
|
467
467
|
for this property to have any effect.
|
|
468
|
-
|
|
468
|
+
|
|
469
469
|
@type Boolean
|
|
470
470
|
@default YES
|
|
471
471
|
*/
|
|
472
472
|
autohidesVerticalScroller: YES,
|
|
473
|
-
|
|
473
|
+
|
|
474
474
|
/**
|
|
475
|
-
Use this property to set the 'bottom' offset of your vertical scroller,
|
|
475
|
+
Use this property to set the 'bottom' offset of your vertical scroller,
|
|
476
476
|
to make room for a thumb view or other accessory view. Default is 0.
|
|
477
|
-
|
|
477
|
+
|
|
478
478
|
@type Number
|
|
479
479
|
@default 0
|
|
480
480
|
*/
|
|
481
481
|
verticalScrollerBottom: 0,
|
|
482
|
-
|
|
482
|
+
|
|
483
483
|
/**
|
|
484
484
|
Use this to overlay the vertical scroller.
|
|
485
|
-
|
|
486
|
-
This ensures that the container frame will not resize to
|
|
487
|
-
vertical scroller, hence overlaying the scroller on top of
|
|
485
|
+
|
|
486
|
+
This ensures that the container frame will not resize to accommodate the
|
|
487
|
+
vertical scroller, hence overlaying the scroller on top of
|
|
488
488
|
the container.
|
|
489
|
-
|
|
489
|
+
|
|
490
490
|
@field
|
|
491
491
|
@type Boolean
|
|
492
492
|
@default NO
|
|
@@ -495,14 +495,14 @@ SC.ScrollView = SC.View.extend({
|
|
|
495
495
|
if (SC.platform.touch) return YES;
|
|
496
496
|
return NO;
|
|
497
497
|
}.property().cacheable(),
|
|
498
|
-
|
|
498
|
+
|
|
499
499
|
/**
|
|
500
500
|
Use this to overlay the horizontal scroller.
|
|
501
|
-
|
|
502
|
-
This ensures that the container frame will not resize to
|
|
503
|
-
horizontal scroller, hence overlaying the scroller on top of
|
|
501
|
+
|
|
502
|
+
This ensures that the container frame will not resize to accommodate the
|
|
503
|
+
horizontal scroller, hence overlaying the scroller on top of
|
|
504
504
|
the container
|
|
505
|
-
|
|
505
|
+
|
|
506
506
|
@field
|
|
507
507
|
@type Boolean
|
|
508
508
|
@default NO
|
|
@@ -511,71 +511,71 @@ SC.ScrollView = SC.View.extend({
|
|
|
511
511
|
if (SC.platform.touch) return YES;
|
|
512
512
|
return NO;
|
|
513
513
|
}.property().cacheable(),
|
|
514
|
-
|
|
514
|
+
|
|
515
515
|
/**
|
|
516
516
|
Use to control the positioning of the vertical scroller. If you do not
|
|
517
517
|
set 'verticalOverlay' to YES, then the content view will be automatically
|
|
518
518
|
sized to meet the left edge of the vertical scroller, wherever it may be.
|
|
519
519
|
This allows you to easily, for example, have “one pixel higher and one
|
|
520
520
|
pixel lower” scroll bars that blend into their parent views.
|
|
521
|
-
|
|
521
|
+
|
|
522
522
|
If you do set 'verticalOverlay' to YES, then the scroller view will
|
|
523
523
|
“float on top” of the content view.
|
|
524
|
-
|
|
524
|
+
|
|
525
525
|
Example: { top: -1, bottom: -1, right: 0 }
|
|
526
|
-
|
|
526
|
+
|
|
527
527
|
@type Hash
|
|
528
528
|
@default null
|
|
529
529
|
*/
|
|
530
530
|
verticalScrollerLayout: null,
|
|
531
|
-
|
|
531
|
+
|
|
532
532
|
/**
|
|
533
533
|
Use to control the positioning of the horizontal scroller. If you do not
|
|
534
534
|
set 'horizontalOverlay' to YES, then the content view will be
|
|
535
535
|
automatically sized to meet the top edge of the horizontal scroller,
|
|
536
536
|
wherever it may be.
|
|
537
|
-
|
|
537
|
+
|
|
538
538
|
If you do set 'horizontalOverlay' to YES, then the scroller view will
|
|
539
539
|
“float on top” of the content view.
|
|
540
|
-
|
|
540
|
+
|
|
541
541
|
Example: { left: 0, bottom: 0, right: 0 }
|
|
542
|
-
|
|
542
|
+
|
|
543
543
|
@type Hash
|
|
544
544
|
@default null
|
|
545
545
|
*/
|
|
546
546
|
horizontalScrollerLayout: null,
|
|
547
|
-
|
|
547
|
+
|
|
548
548
|
// ..........................................................
|
|
549
549
|
// CUSTOM VIEWS
|
|
550
|
-
//
|
|
551
|
-
|
|
550
|
+
//
|
|
551
|
+
|
|
552
552
|
/**
|
|
553
|
-
The container view that will contain your main content view. You can
|
|
553
|
+
The container view that will contain your main content view. You can
|
|
554
554
|
replace this property with your own custom subclass if you prefer.
|
|
555
|
-
|
|
555
|
+
|
|
556
556
|
@type SC.ContainerView
|
|
557
557
|
@default SC.ConainerView
|
|
558
558
|
*/
|
|
559
559
|
containerView: SC.ContainerView.extend({}),
|
|
560
|
-
|
|
561
|
-
|
|
560
|
+
|
|
561
|
+
|
|
562
562
|
// ..........................................................
|
|
563
563
|
// METHODS
|
|
564
|
-
//
|
|
565
|
-
|
|
564
|
+
//
|
|
565
|
+
|
|
566
566
|
/**
|
|
567
567
|
Scrolls the receiver to the specified x,y coordinate. This should be the
|
|
568
568
|
offset into the contentView you want to appear at the top-left corner of
|
|
569
569
|
the scroll view.
|
|
570
|
-
|
|
571
|
-
This method will
|
|
570
|
+
|
|
571
|
+
This method will contain the actual scroll based on whether the view
|
|
572
572
|
can scroll in the named direction and the maximum distance it can
|
|
573
573
|
scroll.
|
|
574
|
-
|
|
575
|
-
If you only want to scroll in one direction, pass null for the other
|
|
576
|
-
direction. You can also optionally pass a Hash for the first parameter
|
|
574
|
+
|
|
575
|
+
If you only want to scroll in one direction, pass null for the other
|
|
576
|
+
direction. You can also optionally pass a Hash for the first parameter
|
|
577
577
|
with x and y coordinates.
|
|
578
|
-
|
|
578
|
+
|
|
579
579
|
@param {Number} x the x scroll location
|
|
580
580
|
@param {Number} y the y scroll location
|
|
581
581
|
@returns {SC.ScrollView} receiver
|
|
@@ -585,27 +585,27 @@ SC.ScrollView = SC.View.extend({
|
|
|
585
585
|
if (y===undefined && SC.typeOf(x) === SC.T_HASH) {
|
|
586
586
|
y = x.y; x = x.x;
|
|
587
587
|
}
|
|
588
|
-
|
|
588
|
+
|
|
589
589
|
if (!SC.none(x)) {
|
|
590
590
|
this.set('horizontalScrollOffset', x) ;
|
|
591
591
|
}
|
|
592
|
-
|
|
592
|
+
|
|
593
593
|
if (!SC.none(y)) {
|
|
594
594
|
this.set('verticalScrollOffset', y) ;
|
|
595
595
|
}
|
|
596
|
-
|
|
596
|
+
|
|
597
597
|
return this ;
|
|
598
598
|
},
|
|
599
|
-
|
|
599
|
+
|
|
600
600
|
/**
|
|
601
|
-
Scrolls the receiver in the horizontal and vertical directions by the
|
|
602
|
-
amount specified, if allowed. The actual scroll amount will be
|
|
601
|
+
Scrolls the receiver in the horizontal and vertical directions by the
|
|
602
|
+
amount specified, if allowed. The actual scroll amount will be
|
|
603
603
|
constrained by the current scroll view settings.
|
|
604
|
-
|
|
605
|
-
If you only want to scroll in one direction, pass null or 0 for the other
|
|
606
|
-
direction. You can also optionally pass a Hash for the first parameter
|
|
604
|
+
|
|
605
|
+
If you only want to scroll in one direction, pass null or 0 for the other
|
|
606
|
+
direction. You can also optionally pass a Hash for the first parameter
|
|
607
607
|
with x and y coordinates.
|
|
608
|
-
|
|
608
|
+
|
|
609
609
|
@param {Number} x change in the x direction (or hash)
|
|
610
610
|
@param {Number} y change in the y direction
|
|
611
611
|
@returns {SC.ScrollView} receiver
|
|
@@ -615,41 +615,41 @@ SC.ScrollView = SC.View.extend({
|
|
|
615
615
|
if (y===undefined && SC.typeOf(x) === SC.T_HASH) {
|
|
616
616
|
y = x.y; x = x.x;
|
|
617
617
|
}
|
|
618
|
-
|
|
618
|
+
|
|
619
619
|
// if null, undefined, or 0, pass null; otherwise just add current offset
|
|
620
620
|
x = (x) ? this.get('horizontalScrollOffset')+x : null ;
|
|
621
621
|
y = (y) ? this.get('verticalScrollOffset')+y : null ;
|
|
622
622
|
return this.scrollTo(x,y) ;
|
|
623
623
|
},
|
|
624
|
-
|
|
624
|
+
|
|
625
625
|
/**
|
|
626
626
|
Scroll the view to make the view's frame visible. For this to make sense,
|
|
627
627
|
the view should be a subview of the contentView. Otherwise the results
|
|
628
628
|
will be undefined.
|
|
629
|
-
|
|
629
|
+
|
|
630
630
|
@param {SC.View} view view to scroll or null to scroll receiver visible
|
|
631
631
|
@returns {Boolean} YES if scroll position was changed
|
|
632
632
|
*/
|
|
633
633
|
scrollToVisible: function(view) {
|
|
634
|
-
|
|
634
|
+
|
|
635
635
|
// if no view is passed, do default
|
|
636
|
-
if (arguments.length === 0) return sc_super();
|
|
637
|
-
|
|
636
|
+
if (arguments.length === 0) return sc_super();
|
|
637
|
+
|
|
638
638
|
var contentView = this.get('contentView') ;
|
|
639
639
|
if (!contentView) return NO; // nothing to do if no contentView.
|
|
640
640
|
|
|
641
|
-
// get the frame for the view - should work even for views with static
|
|
641
|
+
// get the frame for the view - should work even for views with static
|
|
642
642
|
// layout, assuming it has been added to the screen.
|
|
643
643
|
var vf = view.get('frame');
|
|
644
644
|
if (!vf) return NO; // nothing to do
|
|
645
|
-
|
|
645
|
+
|
|
646
646
|
// convert view's frame to an offset from the contentView origin. This
|
|
647
647
|
// will become the new scroll offset after some adjustment.
|
|
648
648
|
vf = contentView.convertFrameFromView(vf, view.get('parentView')) ;
|
|
649
|
-
|
|
649
|
+
|
|
650
650
|
return this.scrollToRect(vf);
|
|
651
651
|
},
|
|
652
|
-
|
|
652
|
+
|
|
653
653
|
/**
|
|
654
654
|
Scroll to the supplied rectangle.
|
|
655
655
|
@param {Rect} rect Rectangle to scroll to.
|
|
@@ -658,32 +658,32 @@ SC.ScrollView = SC.View.extend({
|
|
|
658
658
|
scrollToRect: function(rect) {
|
|
659
659
|
// find current visible frame.
|
|
660
660
|
var vo = SC.cloneRect(this.get('containerView').get('frame')) ;
|
|
661
|
-
|
|
661
|
+
|
|
662
662
|
vo.x = this.get('horizontalScrollOffset') ;
|
|
663
663
|
vo.y = this.get('verticalScrollOffset') ;
|
|
664
664
|
|
|
665
665
|
var origX = vo.x, origY = vo.y;
|
|
666
|
-
|
|
666
|
+
|
|
667
667
|
// if top edge is not visible, shift origin
|
|
668
668
|
vo.y -= Math.max(0, SC.minY(vo) - SC.minY(rect)) ;
|
|
669
669
|
vo.x -= Math.max(0, SC.minX(vo) - SC.minX(rect)) ;
|
|
670
|
-
|
|
670
|
+
|
|
671
671
|
// if bottom edge is not visible, shift origin
|
|
672
672
|
vo.y += Math.max(0, SC.maxY(rect) - SC.maxY(vo)) ;
|
|
673
673
|
vo.x += Math.max(0, SC.maxX(rect) - SC.maxX(vo)) ;
|
|
674
|
-
|
|
674
|
+
|
|
675
675
|
// scroll to that origin.
|
|
676
676
|
if ((origX !== vo.x) || (origY !== vo.y)) {
|
|
677
677
|
this.scrollTo(vo.x, vo.y);
|
|
678
678
|
return YES ;
|
|
679
679
|
} else return NO;
|
|
680
680
|
},
|
|
681
|
-
|
|
682
|
-
|
|
681
|
+
|
|
682
|
+
|
|
683
683
|
/**
|
|
684
684
|
Scrolls the receiver down one or more lines if allowed. If number of
|
|
685
685
|
lines is not specified, scrolls one line.
|
|
686
|
-
|
|
686
|
+
|
|
687
687
|
@param {Number} lines number of lines
|
|
688
688
|
@returns {SC.ScrollView} receiver
|
|
689
689
|
*/
|
|
@@ -691,11 +691,11 @@ SC.ScrollView = SC.View.extend({
|
|
|
691
691
|
if (lines === undefined) lines = 1 ;
|
|
692
692
|
return this.scrollBy(null, this.get('verticalLineScroll')*lines) ;
|
|
693
693
|
},
|
|
694
|
-
|
|
694
|
+
|
|
695
695
|
/**
|
|
696
696
|
Scrolls the receiver up one or more lines if allowed. If number of
|
|
697
697
|
lines is not specified, scrolls one line.
|
|
698
|
-
|
|
698
|
+
|
|
699
699
|
@param {Number} lines number of lines
|
|
700
700
|
@returns {SC.ScrollView} receiver
|
|
701
701
|
*/
|
|
@@ -703,11 +703,11 @@ SC.ScrollView = SC.View.extend({
|
|
|
703
703
|
if (lines === undefined) lines = 1 ;
|
|
704
704
|
return this.scrollBy(null, 0-this.get('verticalLineScroll')*lines) ;
|
|
705
705
|
},
|
|
706
|
-
|
|
706
|
+
|
|
707
707
|
/**
|
|
708
708
|
Scrolls the receiver right one or more lines if allowed. If number of
|
|
709
709
|
lines is not specified, scrolls one line.
|
|
710
|
-
|
|
710
|
+
|
|
711
711
|
@param {Number} lines number of lines
|
|
712
712
|
@returns {SC.ScrollView} receiver
|
|
713
713
|
*/
|
|
@@ -715,11 +715,11 @@ SC.ScrollView = SC.View.extend({
|
|
|
715
715
|
if (lines === undefined) lines = 1 ;
|
|
716
716
|
return this.scrollTo(this.get('horizontalLineScroll')*lines, null) ;
|
|
717
717
|
},
|
|
718
|
-
|
|
718
|
+
|
|
719
719
|
/**
|
|
720
720
|
Scrolls the receiver left one or more lines if allowed. If number of
|
|
721
721
|
lines is not specified, scrolls one line.
|
|
722
|
-
|
|
722
|
+
|
|
723
723
|
@param {Number} lines number of lines
|
|
724
724
|
@returns {SC.ScrollView} receiver
|
|
725
725
|
*/
|
|
@@ -727,13 +727,13 @@ SC.ScrollView = SC.View.extend({
|
|
|
727
727
|
if (lines === undefined) lines = 1 ;
|
|
728
728
|
return this.scrollTo(0-this.get('horizontalLineScroll')*lines, null) ;
|
|
729
729
|
},
|
|
730
|
-
|
|
730
|
+
|
|
731
731
|
/**
|
|
732
732
|
Scrolls the receiver down one or more page if allowed. If number of
|
|
733
733
|
pages is not specified, scrolls one page. The page size is determined by
|
|
734
734
|
the verticalPageScroll value. By default this is the size of the current
|
|
735
735
|
scrollable area.
|
|
736
|
-
|
|
736
|
+
|
|
737
737
|
@param {Number} pages number of lines
|
|
738
738
|
@returns {SC.ScrollView} receiver
|
|
739
739
|
*/
|
|
@@ -741,13 +741,13 @@ SC.ScrollView = SC.View.extend({
|
|
|
741
741
|
if (pages === undefined) pages = 1 ;
|
|
742
742
|
return this.scrollBy(null, this.get('verticalPageScroll')*pages) ;
|
|
743
743
|
},
|
|
744
|
-
|
|
744
|
+
|
|
745
745
|
/**
|
|
746
746
|
Scrolls the receiver up one or more page if allowed. If number of
|
|
747
747
|
pages is not specified, scrolls one page. The page size is determined by
|
|
748
748
|
the verticalPageScroll value. By default this is the size of the current
|
|
749
749
|
scrollable area.
|
|
750
|
-
|
|
750
|
+
|
|
751
751
|
@param {Number} pages number of lines
|
|
752
752
|
@returns {SC.ScrollView} receiver
|
|
753
753
|
*/
|
|
@@ -755,13 +755,13 @@ SC.ScrollView = SC.View.extend({
|
|
|
755
755
|
if (pages === undefined) pages = 1 ;
|
|
756
756
|
return this.scrollBy(null, 0-(this.get('verticalPageScroll')*pages)) ;
|
|
757
757
|
},
|
|
758
|
-
|
|
758
|
+
|
|
759
759
|
/**
|
|
760
760
|
Scrolls the receiver right one or more page if allowed. If number of
|
|
761
761
|
pages is not specified, scrolls one page. The page size is determined by
|
|
762
762
|
the verticalPageScroll value. By default this is the size of the current
|
|
763
763
|
scrollable area.
|
|
764
|
-
|
|
764
|
+
|
|
765
765
|
@param {Number} pages number of lines
|
|
766
766
|
@returns {SC.ScrollView} receiver
|
|
767
767
|
*/
|
|
@@ -769,13 +769,13 @@ SC.ScrollView = SC.View.extend({
|
|
|
769
769
|
if (pages === undefined) pages = 1 ;
|
|
770
770
|
return this.scrollBy(this.get('horizontalPageScroll')*pages, null) ;
|
|
771
771
|
},
|
|
772
|
-
|
|
772
|
+
|
|
773
773
|
/**
|
|
774
774
|
Scrolls the receiver left one or more page if allowed. If number of
|
|
775
775
|
pages is not specified, scrolls one page. The page size is determined by
|
|
776
776
|
the verticalPageScroll value. By default this is the size of the current
|
|
777
777
|
scrollable area.
|
|
778
|
-
|
|
778
|
+
|
|
779
779
|
@param {Number} pages number of lines
|
|
780
780
|
@returns {SC.ScrollView} receiver
|
|
781
781
|
*/
|
|
@@ -783,12 +783,12 @@ SC.ScrollView = SC.View.extend({
|
|
|
783
783
|
if (pages === undefined) pages = 1 ;
|
|
784
784
|
return this.scrollBy(0-(this.get('horizontalPageScroll')*pages), null) ;
|
|
785
785
|
},
|
|
786
|
-
|
|
786
|
+
|
|
787
787
|
/** @private
|
|
788
788
|
Adjusts the layout for the various internal views. This method is called
|
|
789
789
|
once when the scroll view is first configured and then anytime a scroller
|
|
790
790
|
is shown or hidden. You can call this method yourself as well to retile.
|
|
791
|
-
|
|
791
|
+
|
|
792
792
|
You may also want to override this method to handle layout for any
|
|
793
793
|
additional controls you have added to the view.
|
|
794
794
|
*/
|
|
@@ -796,26 +796,26 @@ SC.ScrollView = SC.View.extend({
|
|
|
796
796
|
// get horizontal scroller/determine if we should have a scroller
|
|
797
797
|
var hscroll = this.get('hasHorizontalScroller') ? this.get('horizontalScrollerView') : null ;
|
|
798
798
|
var hasHorizontal = hscroll && this.get('isHorizontalScrollerVisible');
|
|
799
|
-
|
|
799
|
+
|
|
800
800
|
// get vertical scroller/determine if we should have a scroller
|
|
801
801
|
var vscroll = this.get('hasVerticalScroller') ? this.get('verticalScrollerView') : null ;
|
|
802
802
|
var hasVertical = vscroll && this.get('isVerticalScrollerVisible') ;
|
|
803
|
-
|
|
803
|
+
|
|
804
804
|
// get the containerView
|
|
805
805
|
var clip = this.get('containerView') ;
|
|
806
806
|
var clipLayout = { left: 0, top: 0 } ;
|
|
807
807
|
var t, layout, vo, ho, vl, hl;
|
|
808
|
-
|
|
808
|
+
|
|
809
809
|
var ht = ((hasHorizontal) ? hscroll.get('scrollbarThickness') : 0) ;
|
|
810
810
|
var vt = (hasVertical) ? vscroll.get('scrollbarThickness') : 0 ;
|
|
811
|
-
|
|
811
|
+
|
|
812
812
|
if (hasHorizontal) {
|
|
813
813
|
hl = this.get('horizontalScrollerLayout');
|
|
814
|
-
layout = {
|
|
815
|
-
left: (hl ? hl.left : 0),
|
|
816
|
-
bottom: (hl ? hl.bottom : 0),
|
|
817
|
-
right: (hl ? hl.right + vt-1 : vt-1),
|
|
818
|
-
height: ht
|
|
814
|
+
layout = {
|
|
815
|
+
left: (hl ? hl.left : 0),
|
|
816
|
+
bottom: (hl ? hl.bottom : 0),
|
|
817
|
+
right: (hl ? hl.right + vt-1 : vt-1),
|
|
818
|
+
height: ht
|
|
819
819
|
};
|
|
820
820
|
hscroll.set('layout', layout) ;
|
|
821
821
|
ho = this.get('horizontalOverlay');
|
|
@@ -824,15 +824,15 @@ SC.ScrollView = SC.View.extend({
|
|
|
824
824
|
clipLayout.bottom = 0 ;
|
|
825
825
|
}
|
|
826
826
|
if (hscroll) hscroll.set('isVisible', hasHorizontal) ;
|
|
827
|
-
|
|
827
|
+
|
|
828
828
|
if (hasVertical) {
|
|
829
829
|
ht = ht + this.get('verticalScrollerBottom') ;
|
|
830
830
|
vl = this.get('verticalScrollerLayout');
|
|
831
|
-
layout = {
|
|
832
|
-
top: (vl ? vl.top : 0),
|
|
833
|
-
bottom: (vl ? vl.bottom + ht : ht),
|
|
834
|
-
right: (vl ? vl.right : 0),
|
|
835
|
-
width: vt
|
|
831
|
+
layout = {
|
|
832
|
+
top: (vl ? vl.top : 0),
|
|
833
|
+
bottom: (vl ? vl.bottom + ht : ht),
|
|
834
|
+
right: (vl ? vl.right : 0),
|
|
835
|
+
width: vt
|
|
836
836
|
};
|
|
837
837
|
vscroll.set('layout', layout) ;
|
|
838
838
|
vo = this.get('verticalOverlay');
|
|
@@ -844,32 +844,31 @@ SC.ScrollView = SC.View.extend({
|
|
|
844
844
|
|
|
845
845
|
clip.adjust(clipLayout) ;
|
|
846
846
|
},
|
|
847
|
-
|
|
847
|
+
|
|
848
848
|
/** @private
|
|
849
849
|
Called whenever a scroller visibility changes. Calls the tile() method.
|
|
850
850
|
*/
|
|
851
851
|
scrollerVisibilityDidChange: function() {
|
|
852
852
|
this.tile();
|
|
853
853
|
}.observes('isVerticalScrollerVisible', 'isHorizontalScrollerVisible'),
|
|
854
|
-
|
|
854
|
+
|
|
855
855
|
// ..........................................................
|
|
856
856
|
// SCROLL WHEEL SUPPORT
|
|
857
|
-
//
|
|
858
|
-
|
|
857
|
+
//
|
|
858
|
+
|
|
859
859
|
/** @private */
|
|
860
860
|
_scroll_wheelDeltaX: 0,
|
|
861
|
-
|
|
861
|
+
|
|
862
862
|
/** @private */
|
|
863
863
|
_scroll_wheelDeltaY: 0,
|
|
864
|
-
|
|
864
|
+
|
|
865
865
|
/** @private */
|
|
866
866
|
mouseWheel: function(evt) {
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
this._scroll_wheelDeltaY += evt.wheelDeltaY / deltaAdjust;
|
|
867
|
+
this._scroll_wheelDeltaX += evt.wheelDeltaX;
|
|
868
|
+
this._scroll_wheelDeltaY += evt.wheelDeltaY;
|
|
869
|
+
|
|
871
870
|
this.invokeLater(this._scroll_mouseWheel, 10) ;
|
|
872
|
-
return this.get('canScrollHorizontal') || this.get('canScrollVertical') ;
|
|
871
|
+
return this.get('canScrollHorizontal') || this.get('canScrollVertical') ;
|
|
873
872
|
},
|
|
874
873
|
|
|
875
874
|
/** @private */
|
|
@@ -888,24 +887,24 @@ SC.ScrollView = SC.View.extend({
|
|
|
888
887
|
this._scroll_wheelDeltaX = 0;
|
|
889
888
|
}
|
|
890
889
|
},
|
|
891
|
-
|
|
890
|
+
|
|
892
891
|
/*..............................................
|
|
893
892
|
SCALING SUPPORT
|
|
894
893
|
*/
|
|
895
|
-
|
|
894
|
+
|
|
896
895
|
/**
|
|
897
896
|
Determines whether scaling is allowed.
|
|
898
|
-
|
|
897
|
+
|
|
899
898
|
@type Boolean
|
|
900
899
|
@default NO
|
|
901
900
|
*/
|
|
902
901
|
canScale: NO,
|
|
903
|
-
|
|
902
|
+
|
|
904
903
|
/** @private
|
|
905
904
|
The current scale.
|
|
906
905
|
*/
|
|
907
906
|
_scale: 1.0,
|
|
908
|
-
|
|
907
|
+
|
|
909
908
|
/**
|
|
910
909
|
@field
|
|
911
910
|
@type Number
|
|
@@ -917,39 +916,39 @@ SC.ScrollView = SC.View.extend({
|
|
|
917
916
|
}
|
|
918
917
|
return this._scale;
|
|
919
918
|
}.property().cacheable(),
|
|
920
|
-
|
|
919
|
+
|
|
921
920
|
/**
|
|
922
921
|
The minimum scale.
|
|
923
|
-
|
|
922
|
+
|
|
924
923
|
@type Number
|
|
925
924
|
@default 0.25
|
|
926
925
|
*/
|
|
927
926
|
minimumScale: 0.25,
|
|
928
|
-
|
|
927
|
+
|
|
929
928
|
/**
|
|
930
929
|
The maximum scale.
|
|
931
|
-
|
|
930
|
+
|
|
932
931
|
@type Number
|
|
933
932
|
@default 2.0
|
|
934
933
|
*/
|
|
935
934
|
maximumScale: 2.0,
|
|
936
|
-
|
|
935
|
+
|
|
937
936
|
/**
|
|
938
937
|
Whether to automatically determine the scale range based on the size of the content.
|
|
939
|
-
|
|
938
|
+
|
|
940
939
|
@type Boolean
|
|
941
940
|
@default NO
|
|
942
941
|
*/
|
|
943
942
|
autoScaleRange: NO,
|
|
944
|
-
|
|
943
|
+
|
|
945
944
|
/** @private */
|
|
946
945
|
_scale_css: "",
|
|
947
|
-
|
|
946
|
+
|
|
948
947
|
/** @private */
|
|
949
948
|
updateScale: function(scale) {
|
|
950
949
|
var contentView = this.get("contentView");
|
|
951
950
|
if (!contentView) return;
|
|
952
|
-
|
|
951
|
+
|
|
953
952
|
if (contentView.isScalable) {
|
|
954
953
|
this.get("contentView").applyScale(scale);
|
|
955
954
|
this._scale_css = "";
|
|
@@ -957,55 +956,55 @@ SC.ScrollView = SC.View.extend({
|
|
|
957
956
|
this._scale_css = "scale3d(" + scale + ", " + scale + ", 1)";
|
|
958
957
|
}
|
|
959
958
|
},
|
|
960
|
-
|
|
961
|
-
|
|
959
|
+
|
|
960
|
+
|
|
962
961
|
// ..........................................................
|
|
963
962
|
// Touch Support
|
|
964
|
-
//
|
|
965
|
-
|
|
963
|
+
//
|
|
964
|
+
|
|
966
965
|
/**
|
|
967
966
|
@type Boolean
|
|
968
967
|
@default YES
|
|
969
968
|
@readOnly
|
|
970
969
|
*/
|
|
971
970
|
acceptsMultitouch: YES,
|
|
972
|
-
|
|
971
|
+
|
|
973
972
|
/**
|
|
974
973
|
The scroll deceleration rate.
|
|
975
|
-
|
|
974
|
+
|
|
976
975
|
@type Number
|
|
977
976
|
@default SC.NORMAL_SCROLL_DECELERATION
|
|
978
977
|
*/
|
|
979
978
|
decelerationRate: SC.NORMAL_SCROLL_DECELERATION,
|
|
980
|
-
|
|
979
|
+
|
|
981
980
|
/**
|
|
982
981
|
If YES, bouncing will always be enabled in the horizontal direction, even if the content
|
|
983
982
|
is smaller or the same size as the view.
|
|
984
|
-
|
|
983
|
+
|
|
985
984
|
@type Boolean
|
|
986
985
|
@default NO
|
|
987
986
|
*/
|
|
988
987
|
alwaysBounceHorizontal: NO,
|
|
989
|
-
|
|
988
|
+
|
|
990
989
|
/**
|
|
991
990
|
If NO, bouncing will not be enabled in the vertical direction when the content is smaller
|
|
992
991
|
or the same size as the scroll view.
|
|
993
|
-
|
|
992
|
+
|
|
994
993
|
@type Boolean
|
|
995
994
|
@default YES
|
|
996
995
|
*/
|
|
997
996
|
alwaysBounceVertical: YES,
|
|
998
|
-
|
|
997
|
+
|
|
999
998
|
/**
|
|
1000
999
|
Whether to delay touches from passing through to the content.
|
|
1001
|
-
|
|
1000
|
+
|
|
1002
1001
|
@type Boolean
|
|
1003
1002
|
@default YES
|
|
1004
1003
|
*/
|
|
1005
1004
|
delaysContentTouches: YES,
|
|
1006
|
-
|
|
1005
|
+
|
|
1007
1006
|
/** @private
|
|
1008
|
-
If the view supports it, this
|
|
1007
|
+
If the view supports it, this
|
|
1009
1008
|
*/
|
|
1010
1009
|
_touchScrollDidChange: function() {
|
|
1011
1010
|
if (this.get("contentView").touchScrollDidChange) {
|
|
@@ -1014,23 +1013,23 @@ SC.ScrollView = SC.View.extend({
|
|
|
1014
1013
|
this._scroll_verticalScrollOffset
|
|
1015
1014
|
);
|
|
1016
1015
|
}
|
|
1017
|
-
|
|
1016
|
+
|
|
1018
1017
|
// tell scrollers
|
|
1019
1018
|
if (this.verticalScrollerView && this.verticalScrollerView.touchScrollDidChange) {
|
|
1020
1019
|
this.verticalScrollerView.touchScrollDidChange(this._scroll_verticalScrollOffset);
|
|
1021
1020
|
}
|
|
1022
|
-
|
|
1021
|
+
|
|
1023
1022
|
if (this.horizontalScrollerView && this.horizontalScrollerView.touchScrollDidChange) {
|
|
1024
1023
|
this.horizontalScrollerView.touchScrollDidChange(this._scroll_horizontalScrollOffset);
|
|
1025
1024
|
}
|
|
1026
1025
|
},
|
|
1027
|
-
|
|
1026
|
+
|
|
1028
1027
|
/** @private */
|
|
1029
1028
|
_touchScrollDidStart: function() {
|
|
1030
1029
|
if (this.get("contentView").touchScrollDidStart) {
|
|
1031
1030
|
this.get("contentView").touchScrollDidStart(this._scroll_horizontalScrollOffset, this._scroll_verticalScrollOffset);
|
|
1032
1031
|
}
|
|
1033
|
-
|
|
1032
|
+
|
|
1034
1033
|
// tell scrollers
|
|
1035
1034
|
if (this.verticalScrollerView && this.verticalScrollerView.touchScrollDidStart) {
|
|
1036
1035
|
this.verticalScrollerView.touchScrollDidStart(this._touch_verticalScrollOffset);
|
|
@@ -1039,23 +1038,23 @@ SC.ScrollView = SC.View.extend({
|
|
|
1039
1038
|
this.horizontalScrollerView.touchScrollDidStart(this._touch_horizontalScrollOffset);
|
|
1040
1039
|
}
|
|
1041
1040
|
},
|
|
1042
|
-
|
|
1041
|
+
|
|
1043
1042
|
/** @private */
|
|
1044
1043
|
_touchScrollDidEnd: function() {
|
|
1045
1044
|
if (this.get("contentView").touchScrollDidEnd) {
|
|
1046
1045
|
this.get("contentView").touchScrollDidEnd(this._scroll_horizontalScrollOffset, this._scroll_verticalScrollOffset);
|
|
1047
1046
|
}
|
|
1048
|
-
|
|
1047
|
+
|
|
1049
1048
|
// tell scrollers
|
|
1050
1049
|
if (this.verticalScrollerView && this.verticalScrollerView.touchScrollDidEnd) {
|
|
1051
1050
|
this.verticalScrollerView.touchScrollDidEnd(this._touch_verticalScrollOffset);
|
|
1052
1051
|
}
|
|
1053
|
-
|
|
1052
|
+
|
|
1054
1053
|
if (this.horizontalScrollerView && this.horizontalScrollerView.touchScrollDidEnd) {
|
|
1055
1054
|
this.horizontalScrollerView.touchScrollDidEnd(this._touch_horizontalScrollOffset);
|
|
1056
1055
|
}
|
|
1057
1056
|
},
|
|
1058
|
-
|
|
1057
|
+
|
|
1059
1058
|
/** @private */
|
|
1060
1059
|
_applyCSSTransforms: function(layer) {
|
|
1061
1060
|
var transform = "";
|
|
@@ -1063,19 +1062,20 @@ SC.ScrollView = SC.View.extend({
|
|
|
1063
1062
|
transform += 'translate3d('+ -this._scroll_horizontalScrollOffset +'px, '+ -Math.round(this._scroll_verticalScrollOffset)+'px,0) ';
|
|
1064
1063
|
transform += this._scale_css;
|
|
1065
1064
|
if (layer) {
|
|
1066
|
-
|
|
1067
|
-
|
|
1065
|
+
var style = layer.style;
|
|
1066
|
+
style.webkitTransform = transform;
|
|
1067
|
+
style.webkitTransformOrigin = "top left";
|
|
1068
1068
|
}
|
|
1069
1069
|
},
|
|
1070
|
-
|
|
1070
|
+
|
|
1071
1071
|
/** @private */
|
|
1072
1072
|
captureTouch: function(touch) {
|
|
1073
1073
|
return YES;
|
|
1074
1074
|
},
|
|
1075
|
-
|
|
1075
|
+
|
|
1076
1076
|
/** @private */
|
|
1077
1077
|
touchGeneration: 0,
|
|
1078
|
-
|
|
1078
|
+
|
|
1079
1079
|
/** @private */
|
|
1080
1080
|
touchStart: function(touch) {
|
|
1081
1081
|
var generation = ++this.touchGeneration;
|
|
@@ -1093,21 +1093,21 @@ SC.ScrollView = SC.View.extend({
|
|
|
1093
1093
|
/** @private */
|
|
1094
1094
|
beginTouchesInContent: function(gen) {
|
|
1095
1095
|
if (gen !== this.touchGeneration) return;
|
|
1096
|
-
|
|
1096
|
+
|
|
1097
1097
|
var touch = this.touch, itemView;
|
|
1098
|
-
|
|
1098
|
+
|
|
1099
1099
|
// NOTE! On iPad it is possible that the timer set in touchStart() will not have yet fired and that touchEnd() will
|
|
1100
|
-
// come in in the same Run Loop as the one that started with the call to touchStart(). The bad thing that happens is that
|
|
1100
|
+
// come in in the same Run Loop as the one that started with the call to touchStart(). The bad thing that happens is that
|
|
1101
1101
|
// even though we cleared this.touch, occasionally if touchEnd() comes in right at the end of the Run Loop and
|
|
1102
1102
|
// then the timer expires and starts a new Run Loop to call beginTouchesInContent(), that this.touch will STILL exist
|
|
1103
1103
|
// here. There's no explanation for it, and it's not 100% reproducible, but what happens is that if we try to capture
|
|
1104
1104
|
// the touch that has already ended, assignTouch() in RootResponder will check touch.hasEnded and throw an exception.
|
|
1105
|
-
|
|
1105
|
+
|
|
1106
1106
|
// Therefore, don't capture a touch if the touch still exists and hasEnded
|
|
1107
1107
|
if (touch && this.tracking && !this.dragging && !touch.touch.scrollHasEnded && !touch.touch.hasEnded) {
|
|
1108
1108
|
// try to capture the touch
|
|
1109
1109
|
touch.touch.captureTouch(this, YES);
|
|
1110
|
-
|
|
1110
|
+
|
|
1111
1111
|
if (!touch.touch.touchResponder) {
|
|
1112
1112
|
// if it DIDN'T WORK!!!!!
|
|
1113
1113
|
// then we need to take possession again.
|
|
@@ -1131,35 +1131,44 @@ SC.ScrollView = SC.View.extend({
|
|
|
1131
1131
|
*/
|
|
1132
1132
|
beginTouchTracking: function(touch, starting) {
|
|
1133
1133
|
var avg = touch.averagedTouchesForView(this, starting);
|
|
1134
|
-
|
|
1134
|
+
|
|
1135
1135
|
var verticalScrollOffset = this._scroll_verticalScrollOffset || 0,
|
|
1136
1136
|
horizontalScrollOffset = this._scroll_horizontalScrollOffset || 0,
|
|
1137
1137
|
startClipOffsetX = horizontalScrollOffset,
|
|
1138
1138
|
startClipOffsetY = verticalScrollOffset,
|
|
1139
|
-
needsScrollEnd = NO
|
|
1140
|
-
|
|
1139
|
+
needsScrollEnd = NO,
|
|
1140
|
+
contentWidth = 0,
|
|
1141
|
+
contentHeight = 0,
|
|
1142
|
+
viewFrame,
|
|
1143
|
+
view;
|
|
1144
|
+
|
|
1141
1145
|
if (this.touch && this.touch.timeout) {
|
|
1142
1146
|
// clear the timeout
|
|
1143
1147
|
clearTimeout(this.touch.timeout);
|
|
1144
1148
|
this.touch.timeout = null;
|
|
1145
|
-
|
|
1149
|
+
|
|
1146
1150
|
// get the scroll offsets
|
|
1147
1151
|
startClipOffsetX = this.touch.startClipOffset.x;
|
|
1148
1152
|
startClipOffsetY = this.touch.startClipOffset.y;
|
|
1149
1153
|
needsScrollEnd = YES;
|
|
1150
1154
|
}
|
|
1151
|
-
|
|
1155
|
+
|
|
1152
1156
|
// calculate container+content width/height
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
+
view = this.get('contentView') ;
|
|
1158
|
+
|
|
1159
|
+
if(view){
|
|
1160
|
+
viewFrame = view.get('frame');
|
|
1161
|
+
contentWidth = viewFrame.width;
|
|
1162
|
+
contentHeight = viewFrame.height;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1157
1165
|
if(view.calculatedWidth && view.calculatedWidth!==0) contentWidth = view.calculatedWidth;
|
|
1158
1166
|
if (view.calculatedHeight && view.calculatedHeight !==0) contentHeight = view.calculatedHeight;
|
|
1159
|
-
|
|
1160
|
-
var
|
|
1161
|
-
|
|
1162
|
-
|
|
1167
|
+
|
|
1168
|
+
var containerFrame = this.get('containerView').get('frame'),
|
|
1169
|
+
containerWidth = containerFrame.width,
|
|
1170
|
+
containerHeight = containerFrame.height;
|
|
1171
|
+
|
|
1163
1172
|
|
|
1164
1173
|
// calculate position in content
|
|
1165
1174
|
var globalFrame = this.convertFrameToView(this.get("frame"), null),
|
|
@@ -1169,62 +1178,62 @@ SC.ScrollView = SC.View.extend({
|
|
|
1169
1178
|
this.touch = {
|
|
1170
1179
|
startTime: touch.timeStamp,
|
|
1171
1180
|
notCalculated: YES,
|
|
1172
|
-
|
|
1173
|
-
enableScrolling: {
|
|
1174
|
-
x: contentWidth * this._scale > containerWidth || this.get("alwaysBounceHorizontal"),
|
|
1175
|
-
y: contentHeight * this._scale > containerHeight || this.get("alwaysBounceVertical")
|
|
1181
|
+
|
|
1182
|
+
enableScrolling: {
|
|
1183
|
+
x: contentWidth * this._scale > containerWidth || this.get("alwaysBounceHorizontal"),
|
|
1184
|
+
y: contentHeight * this._scale > containerHeight || this.get("alwaysBounceVertical")
|
|
1176
1185
|
},
|
|
1177
1186
|
scrolling: { x: NO, y: NO },
|
|
1178
|
-
|
|
1187
|
+
|
|
1179
1188
|
enableBouncing: SC.platform.bounceOnScroll,
|
|
1180
|
-
|
|
1189
|
+
|
|
1181
1190
|
// offsets and velocities
|
|
1182
1191
|
startClipOffset: { x: startClipOffsetX, y: startClipOffsetY },
|
|
1183
1192
|
lastScrollOffset: { x: horizontalScrollOffset, y: verticalScrollOffset },
|
|
1184
1193
|
startTouchOffset: { x: avg.x, y: avg.y },
|
|
1185
1194
|
scrollVelocity: { x: 0, y: 0 },
|
|
1186
|
-
|
|
1195
|
+
|
|
1187
1196
|
startTouchOffsetInContent: { x: positionInContentX, y: positionInContentY },
|
|
1188
|
-
|
|
1197
|
+
|
|
1189
1198
|
containerSize: { width: containerWidth, height: containerHeight },
|
|
1190
1199
|
contentSize: { width: contentWidth, height: contentHeight },
|
|
1191
|
-
|
|
1200
|
+
|
|
1192
1201
|
startScale: this._scale,
|
|
1193
1202
|
startDistance: avg.d,
|
|
1194
1203
|
canScale: this.get("canScale") && SC.platform.pinchToZoom,
|
|
1195
1204
|
minimumScale: this.get("minimumScale"),
|
|
1196
1205
|
maximumScale: this.get("maximumScale"),
|
|
1197
|
-
|
|
1206
|
+
|
|
1198
1207
|
globalFrame: globalFrame,
|
|
1199
|
-
|
|
1208
|
+
|
|
1200
1209
|
// cache some things
|
|
1201
|
-
layer:
|
|
1210
|
+
layer: view.get('layer'), //contentView
|
|
1202
1211
|
|
|
1203
1212
|
// some constants
|
|
1204
1213
|
resistanceCoefficient: 0.998,
|
|
1205
1214
|
resistanceAsymptote: 320,
|
|
1206
1215
|
decelerationFromEdge: 0.05,
|
|
1207
1216
|
accelerationToEdge: 0.1,
|
|
1208
|
-
|
|
1217
|
+
|
|
1209
1218
|
// how much percent of the other drag direction you must drag to start dragging that direction too.
|
|
1210
1219
|
scrollTolerance: { x: 15, y: 15 },
|
|
1211
1220
|
scaleTolerance: 5,
|
|
1212
1221
|
secondaryScrollTolerance: 30,
|
|
1213
1222
|
scrollLock: 500,
|
|
1214
|
-
|
|
1223
|
+
|
|
1215
1224
|
decelerationRate: this.get("decelerationRate"),
|
|
1216
1225
|
|
|
1217
1226
|
// general status
|
|
1218
|
-
lastEventTime: touch.timeStamp,
|
|
1219
|
-
|
|
1227
|
+
lastEventTime: touch.timeStamp,
|
|
1228
|
+
|
|
1220
1229
|
// the touch used
|
|
1221
1230
|
touch: (starting ? touch : (this.touch ? this.touch.touch : null)),
|
|
1222
|
-
|
|
1231
|
+
|
|
1223
1232
|
// needsScrollEnd will cause a scrollDidEnd even if this particular touch does not start a scroll.
|
|
1224
1233
|
// the reason for this is because we don't want to say we've stopped scrolling just because we got
|
|
1225
1234
|
// another touch, but simultaneously, we still need to send a touch end eventually.
|
|
1226
1235
|
// there are two cases in which this will be used:
|
|
1227
|
-
//
|
|
1236
|
+
//
|
|
1228
1237
|
// 1. If the touch was sent to content touches (in which case we will not be scrolling)
|
|
1229
1238
|
// 2. If the touch ends before scrolling starts (no scrolling then, either)
|
|
1230
1239
|
needsScrollEnd: needsScrollEnd
|
|
@@ -1235,33 +1244,33 @@ SC.ScrollView = SC.View.extend({
|
|
|
1235
1244
|
this.dragging = NO;
|
|
1236
1245
|
}
|
|
1237
1246
|
},
|
|
1238
|
-
|
|
1247
|
+
|
|
1239
1248
|
/** @private */
|
|
1240
1249
|
_adjustForEdgeResistance: function(offset, minOffset, maxOffset, resistanceCoefficient, asymptote) {
|
|
1241
1250
|
var distanceFromEdge;
|
|
1242
|
-
|
|
1251
|
+
|
|
1243
1252
|
// find distance from edge
|
|
1244
1253
|
if (offset < minOffset) distanceFromEdge = offset - minOffset;
|
|
1245
1254
|
else if (offset > maxOffset) distanceFromEdge = maxOffset - offset;
|
|
1246
1255
|
else return offset;
|
|
1247
|
-
|
|
1256
|
+
|
|
1248
1257
|
// manipulate logarithmically
|
|
1249
1258
|
distanceFromEdge = Math.pow(resistanceCoefficient, Math.abs(distanceFromEdge)) * asymptote;
|
|
1250
|
-
|
|
1259
|
+
|
|
1251
1260
|
// adjust mathematically
|
|
1252
1261
|
if (offset < minOffset) distanceFromEdge = distanceFromEdge - asymptote;
|
|
1253
1262
|
else distanceFromEdge = -distanceFromEdge + asymptote;
|
|
1254
|
-
|
|
1263
|
+
|
|
1255
1264
|
// generate final value
|
|
1256
1265
|
return Math.min(Math.max(minOffset, offset), maxOffset) + distanceFromEdge;
|
|
1257
1266
|
},
|
|
1258
|
-
|
|
1267
|
+
|
|
1259
1268
|
/** @private */
|
|
1260
1269
|
touchesDragged: function(evt, touches) {
|
|
1261
1270
|
var avg = evt.averagedTouchesForView(this);
|
|
1262
1271
|
this.updateTouchScroll(avg.x, avg.y, avg.d, evt.timeStamp);
|
|
1263
1272
|
},
|
|
1264
|
-
|
|
1273
|
+
|
|
1265
1274
|
/** @private */
|
|
1266
1275
|
updateTouchScroll: function(touchX, touchY, distance, timeStamp) {
|
|
1267
1276
|
// get some vars
|
|
@@ -1272,62 +1281,65 @@ SC.ScrollView = SC.View.extend({
|
|
|
1272
1281
|
maxOffsetY,
|
|
1273
1282
|
offsetX,
|
|
1274
1283
|
maxOffsetX,
|
|
1275
|
-
minOffsetX, minOffsetY
|
|
1276
|
-
|
|
1284
|
+
minOffsetX, minOffsetY,
|
|
1285
|
+
touchScroll = touch.scrolling,
|
|
1286
|
+
hAlign = this.get("horizontalAlign"),
|
|
1287
|
+
vAlign = this.get("verticalAlign");
|
|
1288
|
+
|
|
1277
1289
|
// calculate new position in content
|
|
1278
1290
|
var positionInContentX = ((this._scroll_horizontalScrollOffset||0) + touchXInFrame) / this._scale,
|
|
1279
1291
|
positionInContentY = ((this._scroll_verticalScrollOffset||0) + touchYInFrame) / this._scale;
|
|
1280
|
-
|
|
1292
|
+
|
|
1281
1293
|
// calculate deltas
|
|
1282
1294
|
var deltaX = positionInContentX - touch.startTouchOffsetInContent.x,
|
|
1283
1295
|
deltaY = positionInContentY - touch.startTouchOffsetInContent.y;
|
|
1284
|
-
|
|
1296
|
+
|
|
1285
1297
|
var isDragging = touch.dragging;
|
|
1286
|
-
if (!
|
|
1298
|
+
if (!touchScroll.x && Math.abs(deltaX) > touch.scrollTolerance.x && touch.enableScrolling.x) {
|
|
1287
1299
|
// say we are scrolling
|
|
1288
1300
|
isDragging = YES;
|
|
1289
|
-
|
|
1301
|
+
touchScroll.x = YES;
|
|
1290
1302
|
touch.scrollTolerance.y = touch.secondaryScrollTolerance;
|
|
1291
|
-
|
|
1303
|
+
|
|
1292
1304
|
// reset position
|
|
1293
1305
|
touch.startTouchOffset.x = touchX;
|
|
1294
1306
|
deltaX = 0;
|
|
1295
1307
|
}
|
|
1296
|
-
if (!
|
|
1308
|
+
if (!touchScroll.y && Math.abs(deltaY) > touch.scrollTolerance.y && touch.enableScrolling.y) {
|
|
1297
1309
|
// say we are scrolling
|
|
1298
1310
|
isDragging = YES;
|
|
1299
|
-
|
|
1311
|
+
touchScroll.y = YES;
|
|
1300
1312
|
touch.scrollTolerance.x = touch.secondaryScrollTolerance;
|
|
1301
|
-
|
|
1313
|
+
|
|
1302
1314
|
// reset position
|
|
1303
1315
|
touch.startTouchOffset.y = touchY;
|
|
1304
1316
|
deltaY = 0;
|
|
1305
1317
|
}
|
|
1306
|
-
|
|
1318
|
+
|
|
1307
1319
|
// handle scroll start
|
|
1308
1320
|
if (isDragging && !touch.dragging) {
|
|
1309
1321
|
touch.dragging = YES;
|
|
1310
1322
|
this.dragging = YES;
|
|
1311
1323
|
this._touchScrollDidStart();
|
|
1312
1324
|
}
|
|
1313
|
-
|
|
1325
|
+
|
|
1314
1326
|
// calculate new offset
|
|
1315
|
-
if (!
|
|
1316
|
-
if (
|
|
1317
|
-
if (deltaX > touch.scrollLock && !
|
|
1327
|
+
if (!touchScroll.x && !touchScroll.y && !touch.canScale) return;
|
|
1328
|
+
if (touchScroll.x && !touchScroll.y) {
|
|
1329
|
+
if (deltaX > touch.scrollLock && !touchScroll.y) touch.enableScrolling.y = NO;
|
|
1318
1330
|
}
|
|
1319
|
-
if (
|
|
1320
|
-
if (deltaY > touch.scrollLock && !
|
|
1331
|
+
if (touchScroll.y && !touchScroll.x) {
|
|
1332
|
+
if (deltaY > touch.scrollLock && !touchScroll.x) touch.enableScrolling.x = NO;
|
|
1321
1333
|
}
|
|
1322
|
-
|
|
1334
|
+
|
|
1323
1335
|
// handle scaling through pinch gesture
|
|
1324
1336
|
if (touch.canScale) {
|
|
1325
|
-
|
|
1337
|
+
|
|
1326
1338
|
var startDistance = touch.startDistance, dd = distance - startDistance;
|
|
1327
1339
|
if (Math.abs(dd) > touch.scaleTolerance) {
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1340
|
+
touchScroll.y = YES; // if you scale, you can scroll.
|
|
1341
|
+
touchScroll.x = YES;
|
|
1342
|
+
|
|
1331
1343
|
// we want to say something that was the startDistance away from each other should now be
|
|
1332
1344
|
// distance away. So, if we are twice as far away as we started...
|
|
1333
1345
|
var scale = touch.startScale * (distance / Math.max(startDistance, 50));
|
|
@@ -1339,28 +1351,28 @@ SC.ScrollView = SC.View.extend({
|
|
|
1339
1351
|
newPositionInContentY = positionInContentY * this._scale;
|
|
1340
1352
|
}
|
|
1341
1353
|
}
|
|
1342
|
-
|
|
1354
|
+
|
|
1343
1355
|
// these do exactly what they sound like. So, this comment is just to
|
|
1344
1356
|
// block off the code a bit
|
|
1345
1357
|
// In english, these calculate the minimum X/Y offsets
|
|
1346
|
-
minOffsetX = this.minimumScrollOffset(touch.contentSize.width * this._scale, touch.containerSize.width,
|
|
1347
|
-
minOffsetY = this.minimumScrollOffset(touch.contentSize.height * this._scale, touch.containerSize.height,
|
|
1348
|
-
|
|
1358
|
+
minOffsetX = this.minimumScrollOffset(touch.contentSize.width * this._scale, touch.containerSize.width, hAlign);
|
|
1359
|
+
minOffsetY = this.minimumScrollOffset(touch.contentSize.height * this._scale, touch.containerSize.height, vAlign);
|
|
1360
|
+
|
|
1349
1361
|
// and now, maximum...
|
|
1350
|
-
maxOffsetX = this.maximumScrollOffset(touch.contentSize.width * this._scale, touch.containerSize.width,
|
|
1351
|
-
maxOffsetY = this.maximumScrollOffset(touch.contentSize.height * this._scale, touch.containerSize.height,
|
|
1352
|
-
|
|
1353
|
-
|
|
1362
|
+
maxOffsetX = this.maximumScrollOffset(touch.contentSize.width * this._scale, touch.containerSize.width, hAlign);
|
|
1363
|
+
maxOffsetY = this.maximumScrollOffset(touch.contentSize.height * this._scale, touch.containerSize.height, vAlign);
|
|
1364
|
+
|
|
1365
|
+
|
|
1354
1366
|
// So, the following is the completely written out algebra:
|
|
1355
1367
|
// (offsetY + touchYInFrame) / this._scale = touch.startTouchOffsetInContent.y
|
|
1356
1368
|
// offsetY + touchYInFrame = touch.startTouchOffsetInContent.y * this._scale;
|
|
1357
1369
|
// offsetY = touch.startTouchOffset * this._scale - touchYInFrame
|
|
1358
|
-
|
|
1370
|
+
|
|
1359
1371
|
// and the result applied:
|
|
1360
1372
|
offsetX = touch.startTouchOffsetInContent.x * this._scale - touchXInFrame;
|
|
1361
1373
|
offsetY = touch.startTouchOffsetInContent.y * this._scale - touchYInFrame;
|
|
1362
|
-
|
|
1363
|
-
|
|
1374
|
+
|
|
1375
|
+
|
|
1364
1376
|
// we need to adjust for edge resistance, or, if bouncing is disabled, just stop flat.
|
|
1365
1377
|
if (touch.enableBouncing) {
|
|
1366
1378
|
offsetX = this._adjustForEdgeResistance(offsetX, minOffsetX, maxOffsetX, touch.resistanceCoefficient, touch.resistanceAsymptote);
|
|
@@ -1369,22 +1381,22 @@ SC.ScrollView = SC.View.extend({
|
|
|
1369
1381
|
offsetX = Math.max(minOffsetX, Math.min(maxOffsetX, offsetX));
|
|
1370
1382
|
offsetY = Math.max(minOffsetY, Math.min(maxOffsetY, offsetY));
|
|
1371
1383
|
}
|
|
1372
|
-
|
|
1384
|
+
|
|
1373
1385
|
// and now, _if_ scrolling is enabled, set the new coordinates
|
|
1374
|
-
if (
|
|
1375
|
-
if (
|
|
1376
|
-
|
|
1386
|
+
if (touchScroll.x) this._scroll_horizontalScrollOffset = offsetX;
|
|
1387
|
+
if (touchScroll.y) this._scroll_verticalScrollOffset = offsetY;
|
|
1388
|
+
|
|
1377
1389
|
// and apply the CSS transforms.
|
|
1378
1390
|
this._applyCSSTransforms(touch.layer);
|
|
1379
1391
|
this._touchScrollDidChange();
|
|
1380
|
-
|
|
1381
|
-
|
|
1392
|
+
|
|
1393
|
+
|
|
1382
1394
|
// now we must prepare for momentum scrolling by calculating the momentum.
|
|
1383
1395
|
if (timeStamp - touch.lastEventTime >= 1 || touch.notCalculated) {
|
|
1384
1396
|
touch.notCalculated = NO;
|
|
1385
1397
|
var horizontalOffset = this._scroll_horizontalScrollOffset;
|
|
1386
1398
|
var verticalOffset = this._scroll_verticalScrollOffset;
|
|
1387
|
-
|
|
1399
|
+
|
|
1388
1400
|
touch.scrollVelocity.x = ((horizontalOffset - touch.lastScrollOffset.x) / Math.max(1, timeStamp - touch.lastEventTime)); // in px per ms
|
|
1389
1401
|
touch.scrollVelocity.y = ((verticalOffset - touch.lastScrollOffset.y) / Math.max(1, timeStamp - touch.lastEventTime)); // in px per ms
|
|
1390
1402
|
touch.lastScrollOffset.x = horizontalOffset;
|
|
@@ -1397,7 +1409,7 @@ SC.ScrollView = SC.View.extend({
|
|
|
1397
1409
|
touchEnd: function(touch) {
|
|
1398
1410
|
var touchStatus = this.touch,
|
|
1399
1411
|
avg = touch.averagedTouchesForView(this);
|
|
1400
|
-
|
|
1412
|
+
|
|
1401
1413
|
touch.scrollHasEnded = YES;
|
|
1402
1414
|
if (avg.touchCount > 0) {
|
|
1403
1415
|
this.beginTouchTracking(touch, NO);
|
|
@@ -1412,12 +1424,12 @@ SC.ScrollView = SC.View.extend({
|
|
|
1412
1424
|
} else {
|
|
1413
1425
|
// well. The scrolling stopped. Let us tell everyone if there was a pending one that this non-drag op interrupted.
|
|
1414
1426
|
if (touchStatus.needsScrollEnd) this._touchScrollDidEnd();
|
|
1415
|
-
|
|
1427
|
+
|
|
1416
1428
|
// this part looks weird, but it is actually quite simple.
|
|
1417
1429
|
// First, we send the touch off for capture+starting again, but telling it to return to us
|
|
1418
1430
|
// if nothing is found or if it is released.
|
|
1419
1431
|
touch.captureTouch(this, YES);
|
|
1420
|
-
|
|
1432
|
+
|
|
1421
1433
|
// if we went anywhere, did anything, etc., call end()
|
|
1422
1434
|
if (touch.touchResponder && touch.touchResponder !== this) {
|
|
1423
1435
|
touch.end();
|
|
@@ -1425,26 +1437,26 @@ SC.ScrollView = SC.View.extend({
|
|
|
1425
1437
|
// if it was released to us or stayed with us the whole time, or is for some
|
|
1426
1438
|
// wacky reason empty (in which case it is ours still). If so, and there is a next responder,
|
|
1427
1439
|
// relay to that.
|
|
1428
|
-
|
|
1440
|
+
|
|
1429
1441
|
if (touch.nextTouchResponder) touch.makeTouchResponder(touch.nextTouchResponder);
|
|
1430
1442
|
} else {
|
|
1431
1443
|
// in this case, the view that captured it and changed responder should have handled
|
|
1432
1444
|
// everything for us.
|
|
1433
1445
|
}
|
|
1434
|
-
|
|
1446
|
+
|
|
1435
1447
|
this.touch = null;
|
|
1436
1448
|
}
|
|
1437
|
-
|
|
1449
|
+
|
|
1438
1450
|
this.tracking = NO;
|
|
1439
1451
|
this.dragging = NO;
|
|
1440
1452
|
}
|
|
1441
1453
|
},
|
|
1442
|
-
|
|
1454
|
+
|
|
1443
1455
|
/** @private */
|
|
1444
1456
|
touchCancelled: function(touch) {
|
|
1445
1457
|
var touchStatus = this.touch,
|
|
1446
1458
|
avg = touch.averagedTouchesForView(this);
|
|
1447
|
-
|
|
1459
|
+
|
|
1448
1460
|
// if we are decelerating, we don't want to stop that. That would be bad. Because there's no point.
|
|
1449
1461
|
if (!this.touch || !this.touch.timeout) {
|
|
1450
1462
|
this.beginPropertyChanges();
|
|
@@ -1453,11 +1465,11 @@ SC.ScrollView = SC.View.extend({
|
|
|
1453
1465
|
this.set("horizontalScrollOffset", this._scroll_horizontalScrollOffset);
|
|
1454
1466
|
this.endPropertyChanges();
|
|
1455
1467
|
this.tracking = NO;
|
|
1456
|
-
|
|
1468
|
+
|
|
1457
1469
|
if (this.dragging) {
|
|
1458
1470
|
this._touchScrollDidEnd();
|
|
1459
1471
|
}
|
|
1460
|
-
|
|
1472
|
+
|
|
1461
1473
|
this.dragging = NO;
|
|
1462
1474
|
this.touch = null;
|
|
1463
1475
|
}
|
|
@@ -1470,16 +1482,16 @@ SC.ScrollView = SC.View.extend({
|
|
|
1470
1482
|
x: touch.scrollVelocity.x * 10,
|
|
1471
1483
|
y: touch.scrollVelocity.y * 10
|
|
1472
1484
|
};
|
|
1473
|
-
|
|
1485
|
+
|
|
1474
1486
|
this.decelerateAnimation();
|
|
1475
1487
|
},
|
|
1476
|
-
|
|
1488
|
+
|
|
1477
1489
|
/** @private
|
|
1478
1490
|
Does bounce calculations, adjusting velocity.
|
|
1479
|
-
|
|
1491
|
+
|
|
1480
1492
|
Bouncing is fun. Functions that handle it should have fun names,
|
|
1481
1493
|
don'tcha think?
|
|
1482
|
-
|
|
1494
|
+
|
|
1483
1495
|
P.S.: should this be named "bouncityBounce" instead?
|
|
1484
1496
|
*/
|
|
1485
1497
|
bouncyBounce: function(velocity, value, minValue, maxValue, de, ac, additionalAcceleration) {
|
|
@@ -1520,24 +1532,28 @@ SC.ScrollView = SC.View.extend({
|
|
|
1520
1532
|
// be changed later in this function).
|
|
1521
1533
|
var touch = this.touch,
|
|
1522
1534
|
scale = this._scale,
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1535
|
+
touchDim = touch.contentSize,
|
|
1536
|
+
touchContainerDim = touch.containerSize,
|
|
1537
|
+
hAlign = this.get("horizontalAlign"),
|
|
1538
|
+
vAlign = this.get("verticalAlign"),
|
|
1539
|
+
minOffsetX = this.minimumScrollOffset(touchDim.width * this._scale, touchContainerDim.width, hAlign),
|
|
1540
|
+
minOffsetY = this.minimumScrollOffset(touchDim.height * this._scale, touchContainerDim.height, vAlign),
|
|
1541
|
+
maxOffsetX = this.maximumScrollOffset(touchDim.width * this._scale, touchContainerDim.width, hAlign),
|
|
1542
|
+
maxOffsetY = this.maximumScrollOffset(touchDim.height * this._scale, touchContainerDim.height, vAlign),
|
|
1543
|
+
|
|
1528
1544
|
now = Date.now(),
|
|
1529
1545
|
t = Math.max(now - touch.lastEventTime, 1),
|
|
1530
|
-
|
|
1546
|
+
|
|
1531
1547
|
newX = this._scroll_horizontalScrollOffset + touch.decelerationVelocity.x * (t/10),
|
|
1532
1548
|
newY = this._scroll_verticalScrollOffset + touch.decelerationVelocity.y * (t/10);
|
|
1533
|
-
|
|
1549
|
+
|
|
1534
1550
|
var de = touch.decelerationFromEdge, ac = touch.accelerationToEdge;
|
|
1535
|
-
|
|
1551
|
+
|
|
1536
1552
|
// under a few circumstances, we may want to force a valid X/Y position.
|
|
1537
1553
|
// For instance, if bouncing is disabled, or if position was okay before
|
|
1538
1554
|
// adjusting scale.
|
|
1539
1555
|
var forceValidXPosition = !touch.enableBouncing, forceValidYPosition = !touch.enableBouncing;
|
|
1540
|
-
|
|
1556
|
+
|
|
1541
1557
|
// determine if position was okay before adjusting scale (which we do, in
|
|
1542
1558
|
// a lovely, animated way, for the scaled out/in too far bounce-back).
|
|
1543
1559
|
// if the position was okay, then we are going to make sure that we keep the
|
|
@@ -1547,7 +1563,7 @@ SC.ScrollView = SC.View.extend({
|
|
|
1547
1563
|
// minimum and maximum scroll offsets)
|
|
1548
1564
|
if (newX >= minOffsetX && newX <= maxOffsetX) forceValidXPosition = YES;
|
|
1549
1565
|
if (newY >= minOffsetY && newY <= maxOffsetY) forceValidYPosition = YES;
|
|
1550
|
-
|
|
1566
|
+
|
|
1551
1567
|
// We are going to change scale in a moment, but the position should stay the
|
|
1552
1568
|
// same, if possible (unless it would be more jarring, as described above, in
|
|
1553
1569
|
// the case of starting with a valid position and ending with an invalid one).
|
|
@@ -1559,67 +1575,67 @@ SC.ScrollView = SC.View.extend({
|
|
|
1559
1575
|
// bounces back around the center of the screen?
|
|
1560
1576
|
newX /= this._scale;
|
|
1561
1577
|
newY /= this._scale;
|
|
1562
|
-
|
|
1563
|
-
// scale velocity (amount to change) starts out at 0 each time, because
|
|
1578
|
+
|
|
1579
|
+
// scale velocity (amount to change) starts out at 0 each time, because
|
|
1564
1580
|
// it is calculated by how far out of bounds it is, rather than by the
|
|
1565
1581
|
// previous such velocity.
|
|
1566
1582
|
var sv = 0;
|
|
1567
|
-
|
|
1583
|
+
|
|
1568
1584
|
// do said calculation; we'll use the same bouncyBounce method used for everything
|
|
1569
1585
|
// else, but our adjustor that gives a minimum amount to change by and (which, as we'll
|
|
1570
|
-
// discuss, is to make the stop feel slightly more like a stop), we'll leave at 0
|
|
1571
|
-
// (scale doesn't really need it as much; if you disagree, at least come up with
|
|
1586
|
+
// discuss, is to make the stop feel slightly more like a stop), we'll leave at 0
|
|
1587
|
+
// (scale doesn't really need it as much; if you disagree, at least come up with
|
|
1572
1588
|
// numbers more appropriate for scale than the ones for X/Y)
|
|
1573
1589
|
sv = this.bouncyBounce(sv, scale, touch.minimumScale, touch.maximumScale, de, ac, 0);
|
|
1574
|
-
|
|
1590
|
+
|
|
1575
1591
|
// add the amount to scale. This is linear, rather than multiplicative. If you think
|
|
1576
1592
|
// it should be multiplicative (or however you say that), come up with a new formula.
|
|
1577
1593
|
this._scale = scale = scale + sv;
|
|
1578
|
-
|
|
1594
|
+
|
|
1579
1595
|
// now we can convert newX/Y back to scale-specific coordinates...
|
|
1580
1596
|
newX *= this._scale;
|
|
1581
1597
|
newY *= this._scale;
|
|
1582
|
-
|
|
1598
|
+
|
|
1583
1599
|
// It looks very weird if the content started in-bounds, but the scale animation
|
|
1584
1600
|
// made it not be in bounds; it causes the position to animate snapping back, and,
|
|
1585
1601
|
// well, it looks very weird. It is more proper to just make sure it stays in a valid
|
|
1586
1602
|
// position. So, we'll determine the new maximum/minimum offsets, and then, if it was
|
|
1587
1603
|
// originally a valid position, we'll adjust the new position to a valid position as well.
|
|
1588
|
-
|
|
1589
|
-
|
|
1604
|
+
|
|
1605
|
+
|
|
1590
1606
|
// determine new max offset
|
|
1591
|
-
minOffsetX = this.minimumScrollOffset(
|
|
1592
|
-
minOffsetY = this.minimumScrollOffset(
|
|
1593
|
-
maxOffsetX = this.maximumScrollOffset(
|
|
1594
|
-
maxOffsetY = this.maximumScrollOffset(
|
|
1595
|
-
|
|
1607
|
+
minOffsetX = this.minimumScrollOffset(touchDim.width * this._scale, touchContainerDim.width, hAlign);
|
|
1608
|
+
minOffsetY = this.minimumScrollOffset(touchDim.height * this._scale, touchContainerDim.height, vAlign);
|
|
1609
|
+
maxOffsetX = this.maximumScrollOffset(touchDim.width * this._scale, touchContainerDim.width, hAlign);
|
|
1610
|
+
maxOffsetY = this.maximumScrollOffset(touchDim.height * this._scale, touchContainerDim.height, vAlign);
|
|
1611
|
+
|
|
1596
1612
|
// see if scaling messed up the X position (but ignore if 'tweren't right to begin with).
|
|
1597
1613
|
if (forceValidXPosition && (newX < minOffsetX || newX > maxOffsetX)) {
|
|
1598
1614
|
// Correct the position
|
|
1599
1615
|
newX = Math.max(minOffsetX, Math.min(newX, maxOffsetX));
|
|
1600
|
-
|
|
1616
|
+
|
|
1601
1617
|
// also, make the velocity be ZERO; it is obviously not needed...
|
|
1602
1618
|
touch.decelerationVelocity.x = 0;
|
|
1603
1619
|
}
|
|
1604
|
-
|
|
1620
|
+
|
|
1605
1621
|
// now the y
|
|
1606
1622
|
if (forceValidYPosition && (newY < minOffsetY || newY > maxOffsetY)) {
|
|
1607
1623
|
// again, correct it...
|
|
1608
1624
|
newY = Math.max(minOffsetY, Math.min(newY, maxOffsetY));
|
|
1609
|
-
|
|
1625
|
+
|
|
1610
1626
|
// also, make the velocity be ZERO; it is obviously not needed...
|
|
1611
1627
|
touch.decelerationVelocity.y = 0;
|
|
1612
1628
|
}
|
|
1613
|
-
|
|
1614
|
-
|
|
1629
|
+
|
|
1630
|
+
|
|
1615
1631
|
// now that we are done modifying the position, we may update the actual scroll
|
|
1616
1632
|
this._scroll_horizontalScrollOffset = newX;
|
|
1617
1633
|
this._scroll_verticalScrollOffset = newY;
|
|
1618
|
-
|
|
1634
|
+
|
|
1619
1635
|
this._applyCSSTransforms(touch.layer); // <- Does what it sounds like.
|
|
1620
1636
|
|
|
1621
1637
|
this._touchScrollDidChange();
|
|
1622
|
-
|
|
1638
|
+
|
|
1623
1639
|
// Now we have to adjust the velocities. The velocities are simple x and y numbers that
|
|
1624
1640
|
// get added to the scroll X/Y positions each frame.
|
|
1625
1641
|
// The default decay rate is .950 per frame. To achieve some semblance of accuracy, we
|
|
@@ -1628,34 +1644,35 @@ SC.ScrollView = SC.View.extend({
|
|
|
1628
1644
|
// modify the velocity for the next frame. My mind goes blank when I try to figure out
|
|
1629
1645
|
// a way to fix this (given that we don't want to change the velocity on the first frame),
|
|
1630
1646
|
// and as it seems to work great as-is, I'm just leaving it.
|
|
1631
|
-
var decay = touch.decelerationRate
|
|
1632
|
-
|
|
1633
|
-
touch.decelerationVelocity.
|
|
1634
|
-
|
|
1647
|
+
var decay = touch.decelerationRate,
|
|
1648
|
+
decayXtime = Math.pow(decay, (t / 10));
|
|
1649
|
+
touch.decelerationVelocity.y *= decayXtime;
|
|
1650
|
+
touch.decelerationVelocity.x *= decayXtime;
|
|
1651
|
+
|
|
1635
1652
|
// We have a bouncyBounce method that adjusts the velocity for bounce. That is, if it is
|
|
1636
1653
|
// out of range and still going, it will slow it down. This step is decelerationFromEdge.
|
|
1637
|
-
// If it is not moving (or has come to a stop from decelerating), but is still out of range,
|
|
1654
|
+
// If it is not moving (or has come to a stop from decelerating), but is still out of range,
|
|
1638
1655
|
// it will start it moving back into range (accelerationToEdge)
|
|
1639
1656
|
// we supply de and ac as these properties.
|
|
1640
1657
|
// The .3 artificially increases the acceleration by .3; this is actually to make the final
|
|
1641
1658
|
// stop a bit more abrupt.
|
|
1642
1659
|
touch.decelerationVelocity.x = this.bouncyBounce(touch.decelerationVelocity.x, newX, minOffsetX, maxOffsetX, de, ac, 0.3);
|
|
1643
1660
|
touch.decelerationVelocity.y = this.bouncyBounce(touch.decelerationVelocity.y, newY, minOffsetY, maxOffsetY, de, ac, 0.3);
|
|
1644
|
-
|
|
1661
|
+
|
|
1645
1662
|
// if we ain't got no velocity... then we must be finished, as there is no where else to go.
|
|
1646
1663
|
// to determine our velocity, we take the absolue value, and use that; if it is less than .01, we
|
|
1647
1664
|
// must be done. Note that we check scale's most recent velocity, calculated above using bouncyBounce,
|
|
1648
1665
|
// as well.
|
|
1649
|
-
var absXVelocity = Math.abs(touch.decelerationVelocity.x)
|
|
1650
|
-
|
|
1666
|
+
var absXVelocity = Math.abs(touch.decelerationVelocity.x),
|
|
1667
|
+
absYVelocity = Math.abs(touch.decelerationVelocity.y);
|
|
1651
1668
|
if (absYVelocity < 0.05 && absXVelocity < 0.05 && Math.abs(sv) < 0.05) {
|
|
1652
1669
|
// we can reset the timeout, as it will no longer be required, and we don't want to re-cancel it later.
|
|
1653
1670
|
touch.timeout = null;
|
|
1654
1671
|
this.touch = null;
|
|
1655
|
-
|
|
1672
|
+
|
|
1656
1673
|
// trigger scroll end
|
|
1657
1674
|
this._touchScrollDidEnd();
|
|
1658
|
-
|
|
1675
|
+
|
|
1659
1676
|
// set the scale, vertical, and horizontal offsets to what they technically already are,
|
|
1660
1677
|
// but don't know they are yet. This will finally update things like, say, the clipping frame.
|
|
1661
1678
|
this.beginPropertyChanges();
|
|
@@ -1663,10 +1680,10 @@ SC.ScrollView = SC.View.extend({
|
|
|
1663
1680
|
this.set("verticalScrollOffset", this._scroll_verticalScrollOffset);
|
|
1664
1681
|
this.set("horizontalScrollOffset", this._scroll_horizontalScrollOffset);
|
|
1665
1682
|
this.endPropertyChanges();
|
|
1666
|
-
|
|
1683
|
+
|
|
1667
1684
|
return;
|
|
1668
1685
|
}
|
|
1669
|
-
|
|
1686
|
+
|
|
1670
1687
|
// We now set up the next round. We are doing this as raw as we possibly can, not touching the
|
|
1671
1688
|
// run loop at all. This speeds up performance drastically--keep in mind, we're on comparatively
|
|
1672
1689
|
// slow devices, here. So, we'll just make a closure, saving "this" into "self" and calling
|
|
@@ -1676,32 +1693,32 @@ SC.ScrollView = SC.View.extend({
|
|
|
1676
1693
|
touch.lastEventTime = Date.now();
|
|
1677
1694
|
this.touch.timeout = setTimeout(function(){
|
|
1678
1695
|
SC.run(self.decelerateAnimation(), self);
|
|
1679
|
-
},
|
|
1696
|
+
}, 30);
|
|
1680
1697
|
},
|
|
1681
|
-
|
|
1698
|
+
|
|
1682
1699
|
// ..........................................................
|
|
1683
1700
|
// INTERNAL SUPPORT
|
|
1684
|
-
//
|
|
1685
|
-
|
|
1701
|
+
//
|
|
1702
|
+
|
|
1686
1703
|
/** @private
|
|
1687
1704
|
Instantiate scrollers & container views as needed. Replace their classes
|
|
1688
1705
|
in the regular properties.
|
|
1689
1706
|
*/
|
|
1690
1707
|
createChildViews: function() {
|
|
1691
|
-
var childViews = [] , view;
|
|
1692
|
-
|
|
1693
|
-
// create the containerView. We must always have a container view.
|
|
1708
|
+
var childViews = [] , view;
|
|
1709
|
+
|
|
1710
|
+
// create the containerView. We must always have a container view.
|
|
1694
1711
|
// also, setup the contentView as the child of the containerView...
|
|
1695
1712
|
if (SC.none(view = this.containerView)) view = SC.ContainerView;
|
|
1696
|
-
|
|
1713
|
+
|
|
1697
1714
|
childViews.push(this.containerView = this.createChildView(view, {
|
|
1698
1715
|
contentView: this.contentView,
|
|
1699
1716
|
isScrollContainer: YES
|
|
1700
1717
|
}));
|
|
1701
|
-
|
|
1718
|
+
|
|
1702
1719
|
// and replace our own contentView...
|
|
1703
1720
|
this.contentView = this.containerView.get('contentView');
|
|
1704
|
-
|
|
1721
|
+
|
|
1705
1722
|
// create a horizontal scroller view if needed...
|
|
1706
1723
|
view = SC.platform.touch ? this.get("horizontalTouchScrollerView") : this.get("horizontalScrollerView");
|
|
1707
1724
|
if (view) {
|
|
@@ -1713,7 +1730,7 @@ SC.ScrollView = SC.View.extend({
|
|
|
1713
1730
|
childViews.push(view);
|
|
1714
1731
|
} else this.horizontalScrollerView = null ;
|
|
1715
1732
|
}
|
|
1716
|
-
|
|
1733
|
+
|
|
1717
1734
|
// create a vertical scroller view if needed...
|
|
1718
1735
|
view = SC.platform.touch ? this.get("verticalTouchScrollerView") : this.get("verticalScrollerView");
|
|
1719
1736
|
if (view) {
|
|
@@ -1725,20 +1742,20 @@ SC.ScrollView = SC.View.extend({
|
|
|
1725
1742
|
childViews.push(view);
|
|
1726
1743
|
} else this.verticalScrollerView = null ;
|
|
1727
1744
|
}
|
|
1728
|
-
|
|
1745
|
+
|
|
1729
1746
|
// set childViews array.
|
|
1730
1747
|
this.childViews = childViews ;
|
|
1731
|
-
|
|
1748
|
+
|
|
1732
1749
|
this.contentViewDidChange() ; // setup initial display...
|
|
1733
1750
|
this.tile() ; // set up initial tiling
|
|
1734
1751
|
},
|
|
1735
|
-
|
|
1752
|
+
|
|
1736
1753
|
/** @private */
|
|
1737
1754
|
init: function() {
|
|
1738
1755
|
sc_super();
|
|
1739
|
-
|
|
1756
|
+
|
|
1740
1757
|
// start observing initial content view. The content view's frame has
|
|
1741
|
-
// already been setup in prepareDisplay so we don't need to call
|
|
1758
|
+
// already been setup in prepareDisplay so we don't need to call
|
|
1742
1759
|
// viewFrameDidChange...
|
|
1743
1760
|
this._scroll_contentView = this.get('contentView') ;
|
|
1744
1761
|
var contentView = this._scroll_contentView ;
|
|
@@ -1751,7 +1768,7 @@ SC.ScrollView = SC.View.extend({
|
|
|
1751
1768
|
|
|
1752
1769
|
if (this.get('isVisibleInWindow')) this._scsv_registerAutoscroll() ;
|
|
1753
1770
|
},
|
|
1754
|
-
|
|
1771
|
+
|
|
1755
1772
|
/** @private
|
|
1756
1773
|
Registers/deregisters view with SC.Drag for autoscrolling
|
|
1757
1774
|
*/
|
|
@@ -1759,7 +1776,7 @@ SC.ScrollView = SC.View.extend({
|
|
|
1759
1776
|
if (this.get('isVisibleInWindow')) SC.Drag.addScrollableView(this);
|
|
1760
1777
|
else SC.Drag.removeScrollableView(this);
|
|
1761
1778
|
}.observes('isVisibleInWindow'),
|
|
1762
|
-
|
|
1779
|
+
|
|
1763
1780
|
/** @private
|
|
1764
1781
|
Whenever the contentView is changed, we need to observe the content view's
|
|
1765
1782
|
frame to be notified whenever it's size changes.
|
|
@@ -1771,7 +1788,7 @@ SC.ScrollView = SC.View.extend({
|
|
|
1771
1788
|
layerObserver = this.contentViewLayerDidChange;
|
|
1772
1789
|
|
|
1773
1790
|
if (newView !== oldView) {
|
|
1774
|
-
|
|
1791
|
+
|
|
1775
1792
|
// stop observing old content view
|
|
1776
1793
|
if (oldView) {
|
|
1777
1794
|
oldView.removeObserver('calculatedWidth', this, this.contentViewFrameDidChange);
|
|
@@ -1779,7 +1796,7 @@ SC.ScrollView = SC.View.extend({
|
|
|
1779
1796
|
oldView.removeObserver('frame', this, frameObserver);
|
|
1780
1797
|
oldView.removeObserver('layer', this, layerObserver);
|
|
1781
1798
|
}
|
|
1782
|
-
|
|
1799
|
+
|
|
1783
1800
|
// update cache
|
|
1784
1801
|
this._scroll_contentView = newView;
|
|
1785
1802
|
if (newView) {
|
|
@@ -1788,10 +1805,10 @@ SC.ScrollView = SC.View.extend({
|
|
|
1788
1805
|
newView.addObserver('calculatedHeight', this, this.contentViewFrameDidChange);
|
|
1789
1806
|
newView.addObserver('layer', this, layerObserver);
|
|
1790
1807
|
}
|
|
1791
|
-
|
|
1808
|
+
|
|
1792
1809
|
// replace container
|
|
1793
1810
|
this.containerView.set('contentView', newView);
|
|
1794
|
-
|
|
1811
|
+
|
|
1795
1812
|
this.contentViewFrameDidChange();
|
|
1796
1813
|
}
|
|
1797
1814
|
}.observes('contentView'),
|
|
@@ -1813,20 +1830,20 @@ SC.ScrollView = SC.View.extend({
|
|
|
1813
1830
|
|
|
1814
1831
|
/** @private */
|
|
1815
1832
|
oldMaxHOffset: 0,
|
|
1816
|
-
|
|
1833
|
+
|
|
1817
1834
|
/** @private */
|
|
1818
1835
|
oldMaxVOffset: 0,
|
|
1819
1836
|
|
|
1820
1837
|
/** @private
|
|
1821
|
-
Invoked whenever the contentView's frame changes. This will update the
|
|
1822
|
-
scroller
|
|
1838
|
+
Invoked whenever the contentView's frame changes. This will update the
|
|
1839
|
+
scroller maximum and optionally update the scroller visibility if the
|
|
1823
1840
|
size of the contentView changes. We don't care about the origin since
|
|
1824
1841
|
that is tracked separately from the offset values.
|
|
1825
1842
|
|
|
1826
1843
|
@param {Boolean} force (optional) Re-calculate everything even if the contentView’s frame didn’t change size
|
|
1827
1844
|
*/
|
|
1828
1845
|
contentViewFrameDidChange: function(force) {
|
|
1829
|
-
var view = this.get('contentView'),
|
|
1846
|
+
var view = this.get('contentView'),
|
|
1830
1847
|
f = (view) ? view.get('frame') : null,
|
|
1831
1848
|
scale = this._scale,
|
|
1832
1849
|
width = 0,
|
|
@@ -1851,7 +1868,7 @@ SC.ScrollView = SC.View.extend({
|
|
|
1851
1868
|
dim = this.getPath('containerView.frame');
|
|
1852
1869
|
dimWidth = dim.width;
|
|
1853
1870
|
dimHeight = dim.height;
|
|
1854
|
-
|
|
1871
|
+
|
|
1855
1872
|
if (this.get('hasHorizontalScroller') && (view = this.get('horizontalScrollerView'))) {
|
|
1856
1873
|
// decide if it should be visible or not
|
|
1857
1874
|
if (this.get('autohidesHorizontalScroller')) {
|
|
@@ -1860,7 +1877,7 @@ SC.ScrollView = SC.View.extend({
|
|
|
1860
1877
|
view.setIfChanged('maximum', width-dimWidth) ;
|
|
1861
1878
|
view.setIfChanged('proportion', dimWidth/width);
|
|
1862
1879
|
}
|
|
1863
|
-
|
|
1880
|
+
|
|
1864
1881
|
if (this.get('hasVerticalScroller') && (view = this.get('verticalScrollerView'))) {
|
|
1865
1882
|
// decide if it should be visible or not
|
|
1866
1883
|
if (this.get('autohidesVerticalScroller')) {
|
|
@@ -1869,20 +1886,20 @@ SC.ScrollView = SC.View.extend({
|
|
|
1869
1886
|
view.setIfChanged('maximum', height-dimHeight) ;
|
|
1870
1887
|
view.setIfChanged('proportion', dimHeight/height);
|
|
1871
1888
|
}
|
|
1872
|
-
|
|
1889
|
+
|
|
1873
1890
|
// If there is no vertical scroller and auto hiding is on, make
|
|
1874
1891
|
// sure we are at the top if not already there
|
|
1875
|
-
if (!this.get('isVerticalScrollerVisible') && (this.get('verticalScrollOffset') !== 0) &&
|
|
1892
|
+
if (!this.get('isVerticalScrollerVisible') && (this.get('verticalScrollOffset') !== 0) &&
|
|
1876
1893
|
this.get('autohidesVerticalScroller')) {
|
|
1877
1894
|
this.set('verticalScrollOffset', 0);
|
|
1878
1895
|
}
|
|
1879
|
-
|
|
1896
|
+
|
|
1880
1897
|
// Same thing for horizontal scrolling.
|
|
1881
|
-
if (!this.get('isHorizontalScrollerVisible') && (this.get('horizontalScrollOffset') !== 0) &&
|
|
1898
|
+
if (!this.get('isHorizontalScrollerVisible') && (this.get('horizontalScrollOffset') !== 0) &&
|
|
1882
1899
|
this.get('autohidesHorizontalScroller')) {
|
|
1883
1900
|
this.set('horizontalScrollOffset', 0);
|
|
1884
1901
|
}
|
|
1885
|
-
|
|
1902
|
+
|
|
1886
1903
|
// This forces to recalculate the height of the frame when is at the bottom
|
|
1887
1904
|
// of the scroll and the content dimension are smaller that the previous one
|
|
1888
1905
|
var mxVOffSet = this.get('maximumVerticalScrollOffset'),
|
|
@@ -1894,10 +1911,14 @@ SC.ScrollView = SC.View.extend({
|
|
|
1894
1911
|
if (forceHeight || forceWidth) {
|
|
1895
1912
|
this.forceDimensionsRecalculation(forceWidth, forceHeight, vOffSet, hOffSet);
|
|
1896
1913
|
}
|
|
1914
|
+
|
|
1915
|
+
// send change notifications since they don't invalidate automatically
|
|
1916
|
+
this.notifyPropertyChange('maximumVerticalScrollOffset');
|
|
1917
|
+
this.notifyPropertyChange('maximumHorizontalScrollOffset');
|
|
1897
1918
|
},
|
|
1898
1919
|
|
|
1899
1920
|
/** @private
|
|
1900
|
-
If our frame changes, then we need to re-calculate the
|
|
1921
|
+
If our frame changes, then we need to re-calculate the visibility of our
|
|
1901
1922
|
scrollers, etc.
|
|
1902
1923
|
*/
|
|
1903
1924
|
frameDidChange: function() {
|
|
@@ -1916,15 +1937,15 @@ SC.ScrollView = SC.View.extend({
|
|
|
1916
1937
|
},
|
|
1917
1938
|
|
|
1918
1939
|
/** @private
|
|
1919
|
-
Whenever the horizontal scroll offset changes, update the scrollers and
|
|
1940
|
+
Whenever the horizontal scroll offset changes, update the scrollers and
|
|
1920
1941
|
edit the location of the contentView.
|
|
1921
1942
|
*/
|
|
1922
1943
|
_scroll_horizontalScrollOffsetDidChange: function() {
|
|
1923
1944
|
this.invokeLast(this.adjustElementScroll);
|
|
1924
1945
|
}.observes('horizontalScrollOffset'),
|
|
1925
|
-
|
|
1946
|
+
|
|
1926
1947
|
/** @private
|
|
1927
|
-
Whenever the vertical scroll offset changes, update the scrollers and
|
|
1948
|
+
Whenever the vertical scroll offset changes, update the scrollers and
|
|
1928
1949
|
edit the location of the contentView.
|
|
1929
1950
|
*/
|
|
1930
1951
|
_scroll_verticalScrollOffsetDidChange: function() {
|
|
@@ -1956,7 +1977,7 @@ SC.ScrollView = SC.View.extend({
|
|
|
1956
1977
|
|
|
1957
1978
|
if (container && !SC.platform.touch) {
|
|
1958
1979
|
container = container.$()[0];
|
|
1959
|
-
|
|
1980
|
+
|
|
1960
1981
|
if (container) {
|
|
1961
1982
|
if (verticalScrollOffset !== this._verticalScrollOffset) {
|
|
1962
1983
|
container.scrollTop = verticalScrollOffset;
|
|
@@ -1989,8 +2010,8 @@ SC.ScrollView = SC.View.extend({
|
|
|
1989
2010
|
|
|
1990
2011
|
/** @private */
|
|
1991
2012
|
_scroll_verticalScrollOffset: 0,
|
|
1992
|
-
|
|
2013
|
+
|
|
1993
2014
|
/** @private */
|
|
1994
2015
|
_scroll_horizontalScrollOffset: 0
|
|
1995
|
-
|
|
2016
|
+
|
|
1996
2017
|
});
|