sproutcore 1.7.1.beta → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -60,6 +60,13 @@ SC.RecordAttribute = SC.Object.extend(
|
|
60
60
|
value will be substituted instead. Note that `defaultValue`s are not
|
61
61
|
converted, so the value should be in the output type expected by the
|
62
62
|
attribute.
|
63
|
+
|
64
|
+
value will be substituted instead. Note that `defaultValue`s are not
|
65
|
+
converted, so the value should be in the output type expected by the
|
66
|
+
attribute.
|
67
|
+
value will be substituted instead. Note that default values are placed
|
68
|
+
directly in the data hash, so when you call get they will be put through
|
69
|
+
the toType transform before being read.
|
63
70
|
|
64
71
|
If you use a `defaultValue` function, the arguments given to it are the
|
65
72
|
record instance and the key.
|
@@ -302,23 +309,30 @@ SC.RecordAttribute = SC.Object.extend(
|
|
302
309
|
// careful: don't overwrite value here. we want the return value to
|
303
310
|
// cache.
|
304
311
|
nvalue = this.fromType(record, key, value) ; // convert to attribute.
|
305
|
-
record.writeAttribute(attrKey, nvalue);
|
312
|
+
record.writeAttribute(attrKey, nvalue);
|
306
313
|
}
|
307
314
|
|
308
|
-
|
315
|
+
value = record.readAttribute(attrKey);
|
309
316
|
if (SC.none(value) && (value = this.get('defaultValue'))) {
|
310
317
|
if (typeof value === SC.T_FUNCTION) {
|
311
|
-
value =
|
312
|
-
// write default value so it doesn't have to be executed again
|
313
|
-
if ((nvalue !== value) && record.get('store').readDataHash(record.get('storeKey'))) {
|
314
|
-
record.writeAttribute(attrKey, value, true);
|
315
|
-
}
|
318
|
+
value = value(record, key, this);
|
316
319
|
}
|
317
|
-
}
|
320
|
+
}
|
321
|
+
|
322
|
+
value = this.toType(record, key, value);
|
318
323
|
|
319
324
|
return value ;
|
320
325
|
},
|
321
326
|
|
327
|
+
/**
|
328
|
+
Apply needs to implemented for sc_super to work.
|
329
|
+
|
330
|
+
@see SC.RecordAttribute#call
|
331
|
+
*/
|
332
|
+
apply: function(target, args) {
|
333
|
+
return this.call.apply(target, args);
|
334
|
+
},
|
335
|
+
|
322
336
|
// ..........................................................
|
323
337
|
// INTERNAL SUPPORT
|
324
338
|
//
|
@@ -377,7 +391,7 @@ SC.RecordAttribute.mixin(
|
|
377
391
|
- `to(value, attr, klass, record, key)` converts the passed value
|
378
392
|
(which will be of the class expected by the attribute) into the
|
379
393
|
underlying attribute value
|
380
|
-
- `from(value, attr, klass, record, key)` converts the
|
394
|
+
- `from(value, attr, klass, record, key)` converts the underlying
|
381
395
|
attribute value into a value of the class
|
382
396
|
|
383
397
|
You can also provide an array of keys to observer on the return value.
|
@@ -113,7 +113,7 @@ SC.SingleAttribute = SC.RecordAttribute.extend(
|
|
113
113
|
isMaster = this.get('isMaster'), attr;
|
114
114
|
|
115
115
|
// ok, you removed me, I'll remove you... if isMaster, notify change.
|
116
|
-
record.writeAttribute(key, null, !isMaster);
|
116
|
+
record.writeAttribute(this.get('key') || key, null, !isMaster);
|
117
117
|
record.notifyPropertyChange(key);
|
118
118
|
|
119
119
|
// if we have another value, notify them as well...
|
@@ -135,7 +135,6 @@ SC.SingleAttribute = SC.RecordAttribute.extend(
|
|
135
135
|
@param {String} inverseKey key on inverse that was modified
|
136
136
|
*/
|
137
137
|
inverseDidAddRecord: function(record, key, inverseRecord, inverseKey) {
|
138
|
-
|
139
138
|
var myInverseKey = this.get('inverse'),
|
140
139
|
curRec = this._scsa_call(record, key),
|
141
140
|
isMaster = this.get('isMaster'),
|
@@ -143,7 +142,7 @@ SC.SingleAttribute = SC.RecordAttribute.extend(
|
|
143
142
|
|
144
143
|
// ok, replace myself with the new value...
|
145
144
|
nvalue = this.fromType(record, key, inverseRecord); // convert to attr.
|
146
|
-
record.writeAttribute(key, nvalue, !isMaster);
|
145
|
+
record.writeAttribute(this.get('key') || key, nvalue, !isMaster);
|
147
146
|
record.notifyPropertyChange(key);
|
148
147
|
|
149
148
|
// if we have another value, notify them as well...
|
@@ -255,7 +255,7 @@ SC.ManyArray = SC.Object.extend(SC.Enumerable, SC.Array,
|
|
255
255
|
// objects are added and removed
|
256
256
|
if (inverse) {
|
257
257
|
|
258
|
-
//
|
258
|
+
// notify removals
|
259
259
|
for(i=0;i<amt;i++) {
|
260
260
|
inverseRecord = toRemove[i];
|
261
261
|
attr = inverseRecord ? inverseRecord[inverse] : null;
|
@@ -77,7 +77,7 @@ SC.NestedStore = SC.Store.extend(
|
|
77
77
|
/** @private
|
78
78
|
Array contains the base revision for an attribute hash when it was first
|
79
79
|
cloned from the parent store. If the attribute hash is edited and
|
80
|
-
|
80
|
+
committed, the commit will fail if the parent attributes hash has been
|
81
81
|
edited since.
|
82
82
|
|
83
83
|
This is a form of optimistic locking, hence the name.
|
@@ -402,7 +402,7 @@ SC.NestedStore = SC.Store.extend(
|
|
402
402
|
/** @private - bookkeeping for a single data hash. */
|
403
403
|
dataHashDidChange: function(storeKeys, rev, statusOnly, key) {
|
404
404
|
// update the revision for storeKey. Use generateStoreKey() because that
|
405
|
-
//
|
405
|
+
// guarantees a universally (to this store hierarchy anyway) unique
|
406
406
|
// key value.
|
407
407
|
if (!rev) rev = SC.Store.generateStoreKey();
|
408
408
|
var isArray, len, idx, storeKey;
|
@@ -13,52 +13,52 @@ sc_require('models/record');
|
|
13
13
|
|
14
14
|
This permits you to perform queries on your data store,
|
15
15
|
written in a SQL-like language. Here is a simple example:
|
16
|
-
|
16
|
+
|
17
17
|
q = SC.Query.create({
|
18
18
|
conditions: "firstName = 'Jonny' AND lastName = 'Cash'"
|
19
19
|
})
|
20
|
-
|
20
|
+
|
21
21
|
You can check if a certain record matches the query by calling
|
22
22
|
|
23
23
|
q.contains(record)
|
24
|
-
|
24
|
+
|
25
25
|
To find all records of your store, that match query q, use findAll with
|
26
26
|
query q as argument:
|
27
|
-
|
27
|
+
|
28
28
|
r = MyApp.store.findAll(q)
|
29
|
-
|
29
|
+
|
30
30
|
`r` will be a record array containing all matching records.
|
31
31
|
To limit the query to a record type of `MyApp.MyModel`,
|
32
32
|
you can specify the type as a property of the query like this:
|
33
|
-
|
34
|
-
q = SC.Query.create({
|
33
|
+
|
34
|
+
q = SC.Query.create({
|
35
35
|
conditions: "firstName = 'Jonny' AND lastName = 'Cash'",
|
36
|
-
recordType: MyApp.MyModel
|
36
|
+
recordType: MyApp.MyModel
|
37
37
|
})
|
38
|
-
|
38
|
+
|
39
39
|
Calling `find()` like above will now return only records of type t.
|
40
40
|
It is recommended to limit your query to a record type, since the query will
|
41
41
|
have to look for matching records in the whole store, if no record type
|
42
42
|
is given.
|
43
|
-
|
43
|
+
|
44
44
|
You can give an order, which the resulting records should follow, like this:
|
45
|
-
|
46
|
-
q = SC.Query.create({
|
45
|
+
|
46
|
+
q = SC.Query.create({
|
47
47
|
conditions: "firstName = 'Jonny' AND lastName = 'Cash'",
|
48
48
|
recordType: MyApp.MyModel,
|
49
|
-
orderBy: "lastName, year DESC"
|
49
|
+
orderBy: "lastName, year DESC"
|
50
50
|
});
|
51
|
-
|
51
|
+
|
52
52
|
The default order direction is ascending. You can change it to descending
|
53
53
|
by writing `'DESC'` behind the property name like in the example above.
|
54
54
|
If no order is given, or records are equal in respect to a given order,
|
55
|
-
records will be ordered by
|
55
|
+
records will be ordered by their storeKey.
|
56
56
|
|
57
57
|
SproutCore Query Language
|
58
58
|
=====
|
59
|
-
|
59
|
+
|
60
60
|
Features of the query language:
|
61
|
-
|
61
|
+
|
62
62
|
Primitives:
|
63
63
|
|
64
64
|
- record properties
|
@@ -66,28 +66,28 @@ sc_require('models/record');
|
|
66
66
|
- `true`, `false`
|
67
67
|
- numbers (integers and floats)
|
68
68
|
- strings (double or single quoted)
|
69
|
-
|
69
|
+
|
70
70
|
Parameters:
|
71
71
|
|
72
72
|
- `%@` (wild card)
|
73
73
|
- `{parameterName}` (named parameter)
|
74
74
|
|
75
|
-
Wild cards are used to identify parameters by the order in which they appear
|
76
|
-
in the query string. Named parameters can be used when tracking the order
|
77
|
-
becomes difficult. Both types of parameters can be used by giving the
|
75
|
+
Wild cards are used to identify parameters by the order in which they appear
|
76
|
+
in the query string. Named parameters can be used when tracking the order
|
77
|
+
becomes difficult. Both types of parameters can be used by giving the
|
78
78
|
parameters as a property to your query object:
|
79
|
-
|
79
|
+
|
80
80
|
yourQuery.parameters = yourParameters
|
81
|
-
|
81
|
+
|
82
82
|
where yourParameters should have one of the following formats:
|
83
83
|
|
84
84
|
* for wild cards: `[firstParam, secondParam, thirdParam]`
|
85
85
|
* for named params: `{name1: param1, mane2: parma2}`
|
86
86
|
|
87
87
|
You cannot use both types of parameters in a single query!
|
88
|
-
|
88
|
+
|
89
89
|
Operators:
|
90
|
-
|
90
|
+
|
91
91
|
- `=`
|
92
92
|
- `!=`
|
93
93
|
- `<`
|
@@ -103,18 +103,18 @@ sc_require('models/record');
|
|
103
103
|
- `ANY` -- (checks if the thing on its left is contained in the array
|
104
104
|
on its right, you will have to use a parameter
|
105
105
|
to insert the array)
|
106
|
-
- `TYPE_IS` -- (unary operator expecting a string containing the name
|
106
|
+
- `TYPE_IS` -- (unary operator expecting a string containing the name
|
107
107
|
of a Model class on its right side, only records of this
|
108
108
|
type will match)
|
109
|
-
|
109
|
+
|
110
110
|
Boolean Operators:
|
111
|
-
|
111
|
+
|
112
112
|
- `AND`
|
113
113
|
- `OR`
|
114
114
|
- `NOT`
|
115
|
-
|
115
|
+
|
116
116
|
Parenthesis for grouping:
|
117
|
-
|
117
|
+
|
118
118
|
- `(` and `)`
|
119
119
|
|
120
120
|
|
@@ -129,11 +129,11 @@ sc_require('models/record');
|
|
129
129
|
to control ordering of specific record properties like this:
|
130
130
|
|
131
131
|
SC.Query.registerComparison(property_name, comparison_for_this_property);
|
132
|
-
|
132
|
+
|
133
133
|
Examples
|
134
|
-
|
134
|
+
|
135
135
|
Some example queries:
|
136
|
-
|
136
|
+
|
137
137
|
TODO add examples
|
138
138
|
|
139
139
|
@extends SC.Object
|
@@ -142,69 +142,69 @@ sc_require('models/record');
|
|
142
142
|
@since SproutCore 1.0
|
143
143
|
*/
|
144
144
|
|
145
|
-
SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
145
|
+
SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
146
146
|
/** @scope SC.Query.prototype */ {
|
147
147
|
|
148
148
|
// ..........................................................
|
149
149
|
// PROPERTIES
|
150
|
-
//
|
151
|
-
|
152
|
-
/**
|
150
|
+
//
|
151
|
+
|
152
|
+
/**
|
153
153
|
Walk like a duck.
|
154
|
-
|
154
|
+
|
155
155
|
@type Boolean
|
156
156
|
*/
|
157
157
|
isQuery: YES,
|
158
|
-
|
158
|
+
|
159
159
|
/**
|
160
|
-
Unparsed query conditions. If you are handling a query yourself, then
|
160
|
+
Unparsed query conditions. If you are handling a query yourself, then
|
161
161
|
you will find the base query string here.
|
162
|
-
|
162
|
+
|
163
163
|
@type String
|
164
164
|
*/
|
165
165
|
conditions: null,
|
166
|
-
|
166
|
+
|
167
167
|
/**
|
168
168
|
Optional orderBy parameters. This can be a string of keys, optionally
|
169
|
-
beginning with the strings `"DESC "` or `"ASC "` to select descending or
|
169
|
+
beginning with the strings `"DESC "` or `"ASC "` to select descending or
|
170
170
|
ascending order.
|
171
|
-
|
171
|
+
|
172
172
|
Alternatively, you can specify a comparison function, in which case the
|
173
173
|
two records will be sent to it. Your comparison function, as with any
|
174
174
|
other, is expected to return -1, 0, or 1.
|
175
|
-
|
175
|
+
|
176
176
|
@type String | Function
|
177
177
|
*/
|
178
178
|
orderBy: null,
|
179
|
-
|
179
|
+
|
180
180
|
/**
|
181
181
|
The base record type or types for the query. This must be specified to
|
182
|
-
filter the kinds of records this query will work on. You may either
|
182
|
+
filter the kinds of records this query will work on. You may either
|
183
183
|
set this to a single record type or to an array or set of record types.
|
184
|
-
|
184
|
+
|
185
185
|
@type SC.Record
|
186
186
|
*/
|
187
187
|
recordType: null,
|
188
|
-
|
188
|
+
|
189
189
|
/**
|
190
|
-
Optional array of multiple record types. If the query accepts multiple
|
190
|
+
Optional array of multiple record types. If the query accepts multiple
|
191
191
|
record types, this is how you can check for it.
|
192
|
-
|
192
|
+
|
193
193
|
@type SC.Enumerable
|
194
194
|
*/
|
195
195
|
recordTypes: null,
|
196
|
-
|
196
|
+
|
197
197
|
/**
|
198
198
|
Returns the complete set of `recordType`s matched by this query. Includes
|
199
199
|
any named `recordType`s plus their subclasses.
|
200
|
-
|
200
|
+
|
201
201
|
@property
|
202
202
|
@type SC.Enumerable
|
203
203
|
*/
|
204
204
|
expandedRecordTypes: function() {
|
205
205
|
var ret = SC.CoreSet.create(), rt, q ;
|
206
|
-
|
207
|
-
if (rt = this.get('recordType')) this._scq_expandRecordType(rt, ret);
|
206
|
+
|
207
|
+
if (rt = this.get('recordType')) this._scq_expandRecordType(rt, ret);
|
208
208
|
else if (rt = this.get('recordTypes')) {
|
209
209
|
rt.forEach(function(t) { this._scq_expandRecordType(t, ret); }, this);
|
210
210
|
} else this._scq_expandRecordType(SC.Record, ret);
|
@@ -215,74 +215,74 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
215
215
|
q = SC.Query._scq_queriesWithExpandedRecordTypes = SC.CoreSet.create();
|
216
216
|
}
|
217
217
|
q.add(this);
|
218
|
-
|
218
|
+
|
219
219
|
return ret.freeze() ;
|
220
220
|
}.property('recordType', 'recordTypes').cacheable(),
|
221
221
|
|
222
|
-
/** @private
|
222
|
+
/** @private
|
223
223
|
expands a single record type into the set. called recursively
|
224
224
|
*/
|
225
225
|
_scq_expandRecordType: function(recordType, set) {
|
226
226
|
if (set.contains(recordType)) return; // nothing to do
|
227
227
|
set.add(recordType);
|
228
|
-
|
228
|
+
|
229
229
|
if (SC.typeOf(recordType)===SC.T_STRING) {
|
230
230
|
recordType = SC.objectForPropertyPath(recordType);
|
231
231
|
}
|
232
|
-
|
233
|
-
recordType.subclasses.forEach(function(t) {
|
232
|
+
|
233
|
+
recordType.subclasses.forEach(function(t) {
|
234
234
|
this._scq_expandRecordType(t, set);
|
235
|
-
}, this);
|
235
|
+
}, this);
|
236
236
|
},
|
237
|
-
|
237
|
+
|
238
238
|
/**
|
239
|
-
Optional hash of parameters. These parameters may be interpolated into
|
240
|
-
the query conditions. If you are handling the query manually, these
|
239
|
+
Optional hash of parameters. These parameters may be interpolated into
|
240
|
+
the query conditions. If you are handling the query manually, these
|
241
241
|
parameters will not be used.
|
242
|
-
|
242
|
+
|
243
243
|
@type Hash
|
244
244
|
*/
|
245
245
|
parameters: null,
|
246
|
-
|
246
|
+
|
247
247
|
/**
|
248
|
-
Indicates the location where the result set for this query is stored.
|
248
|
+
Indicates the location where the result set for this query is stored.
|
249
249
|
Currently the available options are:
|
250
|
-
|
250
|
+
|
251
251
|
- `SC.Query.LOCAL` -- indicates that the query results will be
|
252
252
|
automatically computed from the in-memory store.
|
253
253
|
- `SC.Query.REMOTE` -- indicates that the query results are kept on a
|
254
254
|
remote server and hence must be loaded from the `DataSource`.
|
255
|
-
|
256
|
-
The default setting for this property is `SC.Query.LOCAL`.
|
257
|
-
|
255
|
+
|
256
|
+
The default setting for this property is `SC.Query.LOCAL`.
|
257
|
+
|
258
258
|
Note that even if a query location is `LOCAL`, your `DataSource` will
|
259
259
|
still have its `fetch()` method called for the query. For `LOCAL`
|
260
260
|
queries, you won't need to explicitly provide the query result set; you
|
261
261
|
can just load records into the in-memory store as needed and let the query
|
262
262
|
recompute automatically.
|
263
|
-
|
264
|
-
If your query location is `REMOTE`, then your `DataSource` will need to
|
265
|
-
provide the actual set of query results manually. Usually you will only
|
263
|
+
|
264
|
+
If your query location is `REMOTE`, then your `DataSource` will need to
|
265
|
+
provide the actual set of query results manually. Usually you will only
|
266
266
|
need to use a `REMOTE` query if you are retrieving a large data set and you
|
267
267
|
don't want to pay the cost of computing the result set client side.
|
268
|
-
|
268
|
+
|
269
269
|
@type String
|
270
270
|
*/
|
271
271
|
location: 'local', // SC.Query.LOCAL
|
272
|
-
|
272
|
+
|
273
273
|
/**
|
274
|
-
Another query that will optionally limit the search of records. This is
|
274
|
+
Another query that will optionally limit the search of records. This is
|
275
275
|
usually configured for you when you do `find()` from another record array.
|
276
|
-
|
276
|
+
|
277
277
|
@type SC.Query
|
278
278
|
*/
|
279
279
|
scope: null,
|
280
|
-
|
281
|
-
|
280
|
+
|
281
|
+
|
282
282
|
/**
|
283
|
-
Returns `YES` if query location is Remote. This is sometimes more
|
283
|
+
Returns `YES` if query location is Remote. This is sometimes more
|
284
284
|
convenient than checking the location.
|
285
|
-
|
285
|
+
|
286
286
|
@property
|
287
287
|
@type Boolean
|
288
288
|
*/
|
@@ -291,65 +291,65 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
291
291
|
}.property('location').cacheable(),
|
292
292
|
|
293
293
|
/**
|
294
|
-
Returns `YES` if query location is Local. This is sometimes more
|
294
|
+
Returns `YES` if query location is Local. This is sometimes more
|
295
295
|
convenient than checking the location.
|
296
|
-
|
296
|
+
|
297
297
|
@property
|
298
298
|
@type Boolean
|
299
299
|
*/
|
300
300
|
isLocal: function() {
|
301
301
|
return this.get('location') === SC.Query.LOCAL;
|
302
302
|
}.property('location').cacheable(),
|
303
|
-
|
303
|
+
|
304
304
|
/**
|
305
305
|
Indicates whether a record is editable or not. Defaults to `NO`. Local
|
306
306
|
queries should never be made editable. Remote queries may be editable or
|
307
307
|
not depending on the data source.
|
308
308
|
*/
|
309
309
|
isEditable: NO,
|
310
|
-
|
310
|
+
|
311
311
|
// ..........................................................
|
312
312
|
// PRIMITIVE METHODS
|
313
|
-
//
|
314
|
-
|
315
|
-
/**
|
316
|
-
Returns `YES` if record is matched by the query, `NO` otherwise. This is
|
317
|
-
used when computing a query locally.
|
318
|
-
|
313
|
+
//
|
314
|
+
|
315
|
+
/**
|
316
|
+
Returns `YES` if record is matched by the query, `NO` otherwise. This is
|
317
|
+
used when computing a query locally.
|
318
|
+
|
319
319
|
@param {SC.Record} record the record to check
|
320
320
|
@param {Hash} parameters optional override parameters
|
321
321
|
@returns {Boolean} YES if record belongs, NO otherwise
|
322
|
-
*/
|
322
|
+
*/
|
323
323
|
contains: function(record, parameters) {
|
324
324
|
|
325
325
|
// check the recordType if specified
|
326
|
-
var rtype, ret = YES ;
|
326
|
+
var rtype, ret = YES ;
|
327
327
|
if (rtype = this.get('recordTypes')) { // plural form
|
328
328
|
ret = rtype.find(function(t) { return SC.kindOf(record, t); });
|
329
329
|
} else if (rtype = this.get('recordType')) { // singular
|
330
330
|
ret = SC.kindOf(record, rtype);
|
331
331
|
}
|
332
|
-
|
332
|
+
|
333
333
|
if (!ret) return NO ; // if either did not pass, does not contain
|
334
334
|
|
335
335
|
// if we have a scope - check for that as well
|
336
336
|
var scope = this.get('scope');
|
337
337
|
if (scope && !scope.contains(record)) return NO ;
|
338
|
-
|
338
|
+
|
339
339
|
// now try parsing
|
340
340
|
if (!this._isReady) this.parse(); // prepare the query if needed
|
341
341
|
if (!this._isReady) return NO ;
|
342
342
|
if (parameters === undefined) parameters = this.parameters || this;
|
343
|
-
|
343
|
+
|
344
344
|
// if parsing worked we check if record is contained
|
345
345
|
// if parsing failed no record will be contained
|
346
346
|
return this._tokenTree.evaluate(record, parameters);
|
347
347
|
},
|
348
|
-
|
348
|
+
|
349
349
|
/**
|
350
350
|
Returns `YES` if the query matches one or more of the record types in the
|
351
351
|
passed set.
|
352
|
-
|
352
|
+
|
353
353
|
@param {SC.Set} types set of record types
|
354
354
|
@returns {Boolean} YES if record types match
|
355
355
|
*/
|
@@ -357,48 +357,40 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
357
357
|
var rtype = this.get('recordType');
|
358
358
|
if (rtype) {
|
359
359
|
return !!types.find(function(t) { return SC.kindOf(t, rtype); });
|
360
|
-
|
360
|
+
|
361
361
|
} else if (rtype = this.get('recordTypes')) {
|
362
|
-
return !!rtype.find(function(t) {
|
362
|
+
return !!rtype.find(function(t) {
|
363
363
|
return !!types.find(function(t2) { return SC.kindOf(t2,t); });
|
364
364
|
});
|
365
|
-
|
365
|
+
|
366
366
|
} else return YES; // allow anything through
|
367
367
|
},
|
368
|
-
|
368
|
+
|
369
369
|
/**
|
370
370
|
Returns the sort order of the two passed records, taking into account the
|
371
371
|
orderBy property set on this query. This method does not verify that the
|
372
372
|
two records actually belong in the query set or not; this is checked using
|
373
373
|
`contains()`.
|
374
|
-
|
374
|
+
|
375
375
|
@param {SC.Record} record1 the first record
|
376
376
|
@param {SC.Record} record2 the second record
|
377
|
-
@returns {Number} -1 if record1 < record2,
|
377
|
+
@returns {Number} -1 if record1 < record2,
|
378
378
|
+1 if record1 > record2,
|
379
379
|
0 if equal
|
380
380
|
*/
|
381
381
|
compare: function(record1, record2) {
|
382
|
-
|
383
|
-
// CLASS METHOD. IF YOU CHANGE THIS IMPLEMENTATION, BE SURE
|
384
|
-
// TO UPDATE IT THERE, TOO.
|
385
|
-
//
|
386
|
-
// (Any clients overriding this method will have their version called,
|
387
|
-
// however. That's why we'll keep this here; clients might want to
|
388
|
-
// override it and call sc_super()).
|
389
|
-
|
390
|
-
var result = 0,
|
382
|
+
var result = 0,
|
391
383
|
propertyName, order, len, i;
|
392
384
|
|
393
385
|
// fast cases go here
|
394
386
|
if (record1 === record2) return 0;
|
395
|
-
|
387
|
+
|
396
388
|
// if called for the first time we have to build the order array
|
397
389
|
if (!this._isReady) this.parse();
|
398
|
-
if (!this._isReady) { // can't parse
|
399
|
-
return SC.compare(record1.get('
|
390
|
+
if (!this._isReady) { // can't parse, so use storeKey. Not proper, but consistent.
|
391
|
+
return SC.compare(record1.get('storeKey'),record2.get('storeKey'));
|
400
392
|
}
|
401
|
-
|
393
|
+
|
402
394
|
// For every property specified in orderBy until non-eql result is found.
|
403
395
|
// Or, if orderBy is a comparison function, simply invoke it with the
|
404
396
|
// records.
|
@@ -414,54 +406,54 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
414
406
|
if (SC.Query.comparisons[propertyName]) {
|
415
407
|
result = SC.Query.comparisons[propertyName](
|
416
408
|
record1.get(propertyName),record2.get(propertyName));
|
417
|
-
|
409
|
+
|
418
410
|
// if not use default SC.compare()
|
419
411
|
} else {
|
420
412
|
result = SC.compare(
|
421
413
|
record1.get(propertyName), record2.get(propertyName) );
|
422
414
|
}
|
423
|
-
|
415
|
+
|
424
416
|
if ((result!==0) && order[i].descending) result = (-1) * result;
|
425
417
|
}
|
426
418
|
}
|
427
419
|
|
428
|
-
// return result or compare by
|
420
|
+
// return result or compare by storeKey
|
429
421
|
if (result !== 0) return result ;
|
430
|
-
else return SC.compare(record1.get('
|
422
|
+
else return SC.compare(record1.get('storeKey'),record2.get('storeKey'));
|
431
423
|
},
|
432
424
|
|
433
|
-
/** @private
|
434
|
-
Becomes YES once the query has been successfully parsed
|
425
|
+
/** @private
|
426
|
+
Becomes YES once the query has been successfully parsed
|
435
427
|
*/
|
436
428
|
_isReady: NO,
|
437
|
-
|
429
|
+
|
438
430
|
/**
|
439
431
|
This method has to be called before the query object can be used.
|
440
|
-
You will
|
432
|
+
You will normally not have to do this; it will be called automatically
|
441
433
|
if you try to evaluate a query.
|
442
434
|
You can, however, use this function for testing your queries.
|
443
|
-
|
435
|
+
|
444
436
|
@returns {Boolean} true if parsing succeeded, false otherwise
|
445
437
|
*/
|
446
438
|
parse: function() {
|
447
439
|
var conditions = this.get('conditions'),
|
448
440
|
lang = this.get('queryLanguage'),
|
449
441
|
tokens, tree;
|
450
|
-
|
442
|
+
|
451
443
|
tokens = this._tokenList = this.tokenizeString(conditions, lang);
|
452
444
|
tree = this._tokenTree = this.buildTokenTree(tokens, lang);
|
453
445
|
this._order = this.buildOrder(this.get('orderBy'));
|
454
|
-
|
446
|
+
|
455
447
|
this._isReady = !!tree && !tree.error;
|
456
448
|
if (tree && tree.error) throw tree.error;
|
457
449
|
return this._isReady;
|
458
450
|
},
|
459
|
-
|
451
|
+
|
460
452
|
/**
|
461
453
|
Returns the same query but with the scope set to the passed record array.
|
462
454
|
This will copy the receiver. It also stores these queries in a cache to
|
463
455
|
reuse them if possible.
|
464
|
-
|
456
|
+
|
465
457
|
@param {SC.RecordArray} recordArray the scope
|
466
458
|
@returns {SC.Query} new query
|
467
459
|
*/
|
@@ -469,44 +461,44 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
469
461
|
// look for a cached query on record array.
|
470
462
|
var key = SC.keyFor('__query__', SC.guidFor(this)),
|
471
463
|
ret = recordArray[key];
|
472
|
-
|
464
|
+
|
473
465
|
if (!ret) {
|
474
466
|
recordArray[key] = ret = this.copy();
|
475
467
|
ret.set('scope', recordArray);
|
476
468
|
ret.freeze();
|
477
469
|
}
|
478
|
-
|
470
|
+
|
479
471
|
return ret ;
|
480
472
|
},
|
481
|
-
|
473
|
+
|
482
474
|
// ..........................................................
|
483
475
|
// PRIVATE SUPPORT
|
484
|
-
//
|
476
|
+
//
|
485
477
|
|
486
478
|
/** @private
|
487
479
|
Properties that need to be copied when cloning the query.
|
488
480
|
*/
|
489
481
|
copyKeys: ['conditions', 'orderBy', 'recordType', 'recordTypes', 'parameters', 'location', 'scope'],
|
490
|
-
|
482
|
+
|
491
483
|
/** @private */
|
492
484
|
concatenatedProperties: ['copyKeys'],
|
493
485
|
|
494
|
-
/** @private
|
495
|
-
Implement the Copyable API to clone a query object once it has been
|
486
|
+
/** @private
|
487
|
+
Implement the Copyable API to clone a query object once it has been
|
496
488
|
created.
|
497
489
|
*/
|
498
490
|
copy: function() {
|
499
|
-
var opts = {},
|
491
|
+
var opts = {},
|
500
492
|
keys = this.get('copyKeys'),
|
501
493
|
loc = keys ? keys.length : 0,
|
502
494
|
key, value, ret;
|
503
|
-
|
495
|
+
|
504
496
|
while(--loc >= 0) {
|
505
497
|
key = keys[loc];
|
506
498
|
value = this.get(key);
|
507
499
|
if (value !== undefined) opts[key] = value ;
|
508
500
|
}
|
509
|
-
|
501
|
+
|
510
502
|
ret = this.constructor.create(opts);
|
511
503
|
opts = null;
|
512
504
|
return ret ;
|
@@ -515,14 +507,14 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
515
507
|
// ..........................................................
|
516
508
|
// QUERY LANGUAGE DEFINITION
|
517
509
|
//
|
518
|
-
|
519
|
-
|
510
|
+
|
511
|
+
|
520
512
|
/**
|
521
513
|
This is the definition of the query language. You can extend it
|
522
514
|
by using `SC.Query.registerQueryExtension()`.
|
523
515
|
*/
|
524
516
|
queryLanguage: {
|
525
|
-
|
517
|
+
|
526
518
|
'UNKNOWN': {
|
527
519
|
firstCharacter: /[^\s'"\w\d\(\)\{\}]/,
|
528
520
|
notAllowed: /[\-\s'"\w\d\(\)\{\}]/
|
@@ -532,7 +524,7 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
532
524
|
firstCharacter: /[a-zA-Z_]/,
|
533
525
|
notAllowed: /[^a-zA-Z_0-9\.]/,
|
534
526
|
evalType: 'PRIMITIVE',
|
535
|
-
|
527
|
+
|
536
528
|
/** @ignore */
|
537
529
|
evaluate: function (r,w) {
|
538
530
|
var tokens = this.tokenValue.split('.');
|
@@ -558,14 +550,14 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
558
550
|
notAllowed: /[^\d\-\.]/,
|
559
551
|
format: /^-?\d+$|^-?\d+\.\d+$/,
|
560
552
|
evalType: 'PRIMITIVE',
|
561
|
-
|
553
|
+
|
562
554
|
/** @ignore */
|
563
555
|
evaluate: function (r,w) { return parseFloat(this.tokenValue); }
|
564
556
|
},
|
565
557
|
|
566
558
|
'STRING': {
|
567
559
|
firstCharacter: /['"]/,
|
568
|
-
|
560
|
+
delimited: true,
|
569
561
|
evalType: 'PRIMITIVE',
|
570
562
|
|
571
563
|
/** @ignore */
|
@@ -575,7 +567,7 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
575
567
|
'PARAMETER': {
|
576
568
|
firstCharacter: /\{/,
|
577
569
|
lastCharacter: '}',
|
578
|
-
|
570
|
+
delimited: true,
|
579
571
|
evalType: 'PRIMITIVE',
|
580
572
|
|
581
573
|
/** @ignore */
|
@@ -651,7 +643,7 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
651
643
|
evaluate: function (r,w) {
|
652
644
|
var left = this.leftSide.evaluate(r,w);
|
653
645
|
var right = this.rightSide.evaluate(r,w);
|
654
|
-
return SC.isEqual(left, right);
|
646
|
+
return SC.isEqual(left, right);
|
655
647
|
}
|
656
648
|
},
|
657
649
|
|
@@ -665,7 +657,7 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
665
657
|
evaluate: function (r,w) {
|
666
658
|
var left = this.leftSide.evaluate(r,w);
|
667
659
|
var right = this.rightSide.evaluate(r,w);
|
668
|
-
return !SC.isEqual(left, right);
|
660
|
+
return !SC.isEqual(left, right);
|
669
661
|
}
|
670
662
|
},
|
671
663
|
|
@@ -749,7 +741,7 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
749
741
|
evaluate: function (r,w) {
|
750
742
|
var all = this.leftSide.evaluate(r,w);
|
751
743
|
var end = this.rightSide.evaluate(r,w);
|
752
|
-
return ( all && all.
|
744
|
+
return ( all && all.length >= end.length && all.lastIndexOf(end) === (all.length - end.length));
|
753
745
|
}
|
754
746
|
},
|
755
747
|
|
@@ -859,7 +851,7 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
859
851
|
/** @ignore */
|
860
852
|
evaluate: function (r,w) { return true; }
|
861
853
|
},
|
862
|
-
|
854
|
+
|
863
855
|
'YES': {
|
864
856
|
reservedWord: true,
|
865
857
|
evalType: 'PRIMITIVE',
|
@@ -867,7 +859,7 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
867
859
|
/** @ignore */
|
868
860
|
evaluate: function (r,w) { return true; }
|
869
861
|
},
|
870
|
-
|
862
|
+
|
871
863
|
'NO': {
|
872
864
|
reservedWord: true,
|
873
865
|
evalType: 'PRIMITIVE',
|
@@ -875,26 +867,26 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
875
867
|
/** @ignore */
|
876
868
|
evaluate: function (r,w) { return false; }
|
877
869
|
}
|
878
|
-
|
870
|
+
|
879
871
|
},
|
880
|
-
|
872
|
+
|
881
873
|
|
882
874
|
// ..........................................................
|
883
875
|
// TOKENIZER
|
884
876
|
//
|
885
|
-
|
886
|
-
|
877
|
+
|
878
|
+
|
887
879
|
/**
|
888
880
|
Takes a string and tokenizes it based on the grammar definition
|
889
881
|
provided. Called by `parse()`.
|
890
|
-
|
882
|
+
|
891
883
|
@param {String} inputString the string to tokenize
|
892
884
|
@param {Object} grammar the grammar definition (normally queryLanguage)
|
893
885
|
@returns {Array} list of tokens
|
894
886
|
*/
|
895
887
|
tokenizeString: function (inputString, grammar) {
|
896
|
-
|
897
|
-
|
888
|
+
|
889
|
+
|
898
890
|
var tokenList = [],
|
899
891
|
c = null,
|
900
892
|
t = null,
|
@@ -903,28 +895,28 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
903
895
|
currentToken = null,
|
904
896
|
currentTokenType = null,
|
905
897
|
currentTokenValue = null,
|
906
|
-
|
898
|
+
currentDelimiter = null,
|
907
899
|
endOfString = false,
|
908
900
|
endOfToken = false,
|
909
901
|
belongsToToken = false,
|
910
902
|
skipThisCharacter = false,
|
911
903
|
rememberCount = {};
|
912
|
-
|
913
|
-
|
904
|
+
|
905
|
+
|
914
906
|
// helper function that adds tokens to the tokenList
|
915
|
-
|
907
|
+
|
916
908
|
function addToken (tokenType, tokenValue) {
|
917
909
|
t = grammar[tokenType];
|
918
910
|
//tokenType = t.tokenType;
|
919
|
-
|
911
|
+
|
920
912
|
// handling of special cases
|
921
913
|
// check format
|
922
914
|
if (t.format && !t.format.test(tokenValue)) tokenType = "UNKNOWN";
|
923
|
-
//
|
924
|
-
if (t.
|
925
|
-
|
915
|
+
// delimited token (e.g. by ")
|
916
|
+
if (t.delimited) skipThisCharacter = true;
|
917
|
+
|
926
918
|
// reserved words
|
927
|
-
if ( !t.
|
919
|
+
if ( !t.delimited ) {
|
928
920
|
for ( var anotherToken in grammar ) {
|
929
921
|
if ( grammar[anotherToken].reservedWord
|
930
922
|
&& anotherToken == tokenValue ) {
|
@@ -932,7 +924,7 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
932
924
|
}
|
933
925
|
}
|
934
926
|
}
|
935
|
-
|
927
|
+
|
936
928
|
// reset t
|
937
929
|
t = grammar[tokenType];
|
938
930
|
// remembering count type
|
@@ -950,49 +942,49 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
950
942
|
currentTokenType = null;
|
951
943
|
currentTokenValue = null;
|
952
944
|
}
|
953
|
-
|
954
|
-
|
945
|
+
|
946
|
+
|
955
947
|
// stepping through the string:
|
956
|
-
|
948
|
+
|
957
949
|
if (!inputString) return [];
|
958
|
-
|
950
|
+
|
959
951
|
var iStLength = inputString.length;
|
960
|
-
|
952
|
+
|
961
953
|
for (var i=0; i < iStLength; i++) {
|
962
|
-
|
954
|
+
|
963
955
|
// end reached?
|
964
956
|
endOfString = (i===iStLength-1);
|
965
|
-
|
957
|
+
|
966
958
|
// current character
|
967
959
|
c = inputString.charAt(i);
|
968
|
-
|
969
|
-
// set true after end of
|
970
|
-
// final
|
960
|
+
|
961
|
+
// set true after end of delimited token so that
|
962
|
+
// final delimiter is not caught again
|
971
963
|
skipThisCharacter = false;
|
972
|
-
|
973
|
-
|
964
|
+
|
965
|
+
|
974
966
|
// if currently inside a token
|
975
|
-
|
967
|
+
|
976
968
|
if ( currentToken ) {
|
977
|
-
|
969
|
+
|
978
970
|
// some helpers
|
979
971
|
t = grammar[currentToken];
|
980
|
-
endOfToken = t.
|
981
|
-
|
972
|
+
endOfToken = t.delimited ? c===currentDelimiter : t.notAllowed.test(c);
|
973
|
+
|
982
974
|
// if still in token
|
983
975
|
if ( !endOfToken ) currentTokenValue += c;
|
984
|
-
|
976
|
+
|
985
977
|
// if end of token reached
|
986
978
|
if (endOfToken || endOfString) {
|
987
979
|
addToken(currentToken, currentTokenValue);
|
988
980
|
}
|
989
|
-
|
981
|
+
|
990
982
|
// if end of string don't check again
|
991
983
|
if ( endOfString && !endOfToken ) skipThisCharacter = true;
|
992
984
|
}
|
993
|
-
|
985
|
+
|
994
986
|
// if not inside a token, look for next one
|
995
|
-
|
987
|
+
|
996
988
|
if ( !currentToken && !skipThisCharacter ) {
|
997
989
|
// look for matching tokenType
|
998
990
|
for ( token in grammar ) {
|
@@ -1007,10 +999,10 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
1007
999
|
t = grammar[currentToken];
|
1008
1000
|
currentTokenValue = c;
|
1009
1001
|
// handling of special cases
|
1010
|
-
if ( t.
|
1002
|
+
if ( t.delimited ) {
|
1011
1003
|
currentTokenValue = "";
|
1012
|
-
if ( t.lastCharacter )
|
1013
|
-
else
|
1004
|
+
if ( t.lastCharacter ) currentDelimiter = t.lastCharacter;
|
1005
|
+
else currentDelimiter = c;
|
1014
1006
|
}
|
1015
1007
|
|
1016
1008
|
if ( t.singleCharacter || endOfString ) {
|
@@ -1019,55 +1011,55 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
1019
1011
|
}
|
1020
1012
|
}
|
1021
1013
|
}
|
1022
|
-
|
1014
|
+
|
1023
1015
|
return tokenList;
|
1024
1016
|
},
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1017
|
+
|
1018
|
+
|
1019
|
+
|
1028
1020
|
// ..........................................................
|
1029
1021
|
// BUILD TOKEN TREE
|
1030
1022
|
//
|
1031
|
-
|
1023
|
+
|
1032
1024
|
/**
|
1033
1025
|
Takes an array of tokens and returns a tree, depending on the
|
1034
1026
|
specified tree logic. The returned object will have an error property
|
1035
1027
|
if building of the tree failed. Check it to get some information
|
1036
1028
|
about what happend.
|
1037
1029
|
If everything worked, the tree can be evaluated by calling
|
1038
|
-
|
1030
|
+
|
1039
1031
|
tree.evaluate(record, parameters)
|
1040
|
-
|
1032
|
+
|
1041
1033
|
If `tokenList` is empty, a single token will be returned which will
|
1042
1034
|
evaluate to true for all records.
|
1043
|
-
|
1035
|
+
|
1044
1036
|
@param {Array} tokenList the list of tokens
|
1045
1037
|
@param {Object} treeLogic the logic definition (normally queryLanguage)
|
1046
1038
|
@returns {Object} token tree
|
1047
1039
|
*/
|
1048
1040
|
buildTokenTree: function (tokenList, treeLogic) {
|
1049
|
-
|
1041
|
+
|
1050
1042
|
var l = tokenList.slice();
|
1051
1043
|
var i = 0;
|
1052
1044
|
var openParenthesisStack = [];
|
1053
1045
|
var shouldCheckAgain = false;
|
1054
1046
|
var error = [];
|
1055
|
-
|
1056
|
-
|
1047
|
+
|
1048
|
+
|
1057
1049
|
// empty tokenList is a special case
|
1058
1050
|
if (!tokenList || tokenList.length === 0) {
|
1059
1051
|
return { evaluate: function(){ return true; } };
|
1060
1052
|
}
|
1061
|
-
|
1062
|
-
|
1053
|
+
|
1054
|
+
|
1063
1055
|
// some helper functions
|
1064
|
-
|
1056
|
+
|
1065
1057
|
function tokenLogic (position) {
|
1066
1058
|
var p = position;
|
1067
1059
|
if ( p < 0 ) return false;
|
1068
|
-
|
1060
|
+
|
1069
1061
|
var tl = treeLogic[l[p].tokenType];
|
1070
|
-
|
1062
|
+
|
1071
1063
|
if ( ! tl ) {
|
1072
1064
|
error.push("logic for token '"+l[p].tokenType+"' is not defined");
|
1073
1065
|
return false;
|
@@ -1078,7 +1070,7 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
1078
1070
|
l[p].evaluate = tl.evaluate;
|
1079
1071
|
return tl;
|
1080
1072
|
}
|
1081
|
-
|
1073
|
+
|
1082
1074
|
function expectedType (side, position) {
|
1083
1075
|
var p = position;
|
1084
1076
|
var tl = tokenLogic(p);
|
@@ -1086,32 +1078,32 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
1086
1078
|
if (side == 'left') return tl.leftType;
|
1087
1079
|
if (side == 'right') return tl.rightType;
|
1088
1080
|
}
|
1089
|
-
|
1081
|
+
|
1090
1082
|
function evalType (position) {
|
1091
1083
|
var p = position;
|
1092
1084
|
var tl = tokenLogic(p);
|
1093
1085
|
if ( !tl ) return false;
|
1094
1086
|
else return tl.evalType;
|
1095
1087
|
}
|
1096
|
-
|
1088
|
+
|
1097
1089
|
function removeToken (position) {
|
1098
1090
|
l.splice(position, 1);
|
1099
1091
|
if ( position <= i ) i--;
|
1100
1092
|
}
|
1101
|
-
|
1093
|
+
|
1102
1094
|
function preceedingTokenExists (position) {
|
1103
1095
|
var p = position || i;
|
1104
1096
|
if ( p > 0 ) return true;
|
1105
1097
|
else return false;
|
1106
1098
|
}
|
1107
|
-
|
1099
|
+
|
1108
1100
|
function tokenIsMissingChilds (position) {
|
1109
1101
|
var p = position;
|
1110
1102
|
if ( p < 0 ) return true;
|
1111
1103
|
return (expectedType('left',p) && !l[p].leftSide)
|
1112
1104
|
|| (expectedType('right',p) && !l[p].rightSide);
|
1113
1105
|
}
|
1114
|
-
|
1106
|
+
|
1115
1107
|
function typesAreMatching (parent, child) {
|
1116
1108
|
var side = (child < parent) ? 'left' : 'right';
|
1117
1109
|
if ( parent < 0 || child < 0 ) return false;
|
@@ -1120,7 +1112,7 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
1120
1112
|
if ( expectedType(side,parent) == evalType(child) ) return true;
|
1121
1113
|
else return false;
|
1122
1114
|
}
|
1123
|
-
|
1115
|
+
|
1124
1116
|
function preceedingTokenCanBeMadeChild (position) {
|
1125
1117
|
var p = position;
|
1126
1118
|
if ( !tokenIsMissingChilds(p) ) return false;
|
@@ -1128,7 +1120,7 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
1128
1120
|
if ( typesAreMatching(p,p-1) ) return true;
|
1129
1121
|
else return false;
|
1130
1122
|
}
|
1131
|
-
|
1123
|
+
|
1132
1124
|
function preceedingTokenCanBeMadeParent (position) {
|
1133
1125
|
var p = position;
|
1134
1126
|
if ( tokenIsMissingChilds(p) ) return false;
|
@@ -1137,70 +1129,70 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
1137
1129
|
if ( typesAreMatching(p-1,p) ) return true;
|
1138
1130
|
else return false;
|
1139
1131
|
}
|
1140
|
-
|
1132
|
+
|
1141
1133
|
function makeChild (position) {
|
1142
1134
|
var p = position;
|
1143
1135
|
if (p<1) return false;
|
1144
1136
|
l[p].leftSide = l[p-1];
|
1145
1137
|
removeToken(p-1);
|
1146
1138
|
}
|
1147
|
-
|
1139
|
+
|
1148
1140
|
function makeParent (position) {
|
1149
1141
|
var p = position;
|
1150
1142
|
if (p<1) return false;
|
1151
1143
|
l[p-1].rightSide = l[p];
|
1152
1144
|
removeToken(p);
|
1153
1145
|
}
|
1154
|
-
|
1146
|
+
|
1155
1147
|
function removeParenthesesPair (position) {
|
1156
1148
|
removeToken(position);
|
1157
1149
|
removeToken(openParenthesisStack.pop());
|
1158
1150
|
}
|
1159
|
-
|
1151
|
+
|
1160
1152
|
// step through the tokenList
|
1161
|
-
|
1153
|
+
|
1162
1154
|
for (i=0; i < l.length; i++) {
|
1163
1155
|
shouldCheckAgain = false;
|
1164
|
-
|
1156
|
+
|
1165
1157
|
if ( l[i].tokenType == 'UNKNOWN' ) {
|
1166
1158
|
error.push('found unknown token: '+l[i].tokenValue);
|
1167
1159
|
}
|
1168
|
-
|
1160
|
+
|
1169
1161
|
if ( l[i].tokenType == 'OPEN_PAREN' ) openParenthesisStack.push(i);
|
1170
1162
|
if ( l[i].tokenType == 'CLOSE_PAREN' ) removeParenthesesPair(i);
|
1171
|
-
|
1163
|
+
|
1172
1164
|
if ( preceedingTokenCanBeMadeChild(i) ) makeChild(i);
|
1173
|
-
|
1165
|
+
|
1174
1166
|
if ( preceedingTokenCanBeMadeParent(i) ){
|
1175
1167
|
makeParent(i);
|
1176
1168
|
shouldCheckAgain = true;
|
1177
|
-
}
|
1178
|
-
|
1169
|
+
}
|
1170
|
+
|
1179
1171
|
if ( shouldCheckAgain ) i--;
|
1180
|
-
|
1172
|
+
|
1181
1173
|
}
|
1182
|
-
|
1174
|
+
|
1183
1175
|
// error if tokenList l is not a single token now
|
1184
1176
|
if (l.length == 1) l = l[0];
|
1185
1177
|
else error.push('string did not resolve to a single tree');
|
1186
|
-
|
1178
|
+
|
1187
1179
|
// error?
|
1188
1180
|
if (error.length > 0) return {error: error.join(',\n'), tree: l};
|
1189
1181
|
// everything fine - token list is now a tree and can be returned
|
1190
1182
|
else return l;
|
1191
|
-
|
1183
|
+
|
1192
1184
|
},
|
1193
|
-
|
1194
|
-
|
1185
|
+
|
1186
|
+
|
1195
1187
|
// ..........................................................
|
1196
1188
|
// ORDERING
|
1197
1189
|
//
|
1198
|
-
|
1190
|
+
|
1199
1191
|
/**
|
1200
1192
|
Takes a string containing an order statement and returns an array
|
1201
1193
|
describing this order for easier processing.
|
1202
1194
|
Called by `parse()`.
|
1203
|
-
|
1195
|
+
|
1204
1196
|
@param {String | Function} orderOp the string containing the order statement, or a comparison function
|
1205
1197
|
@returns {Array | Function} array of order statement, or a function if a function was specified
|
1206
1198
|
*/
|
@@ -1221,10 +1213,10 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
1221
1213
|
o[i] = {propertyName: p[0]};
|
1222
1214
|
if (p[1] && p[1] == 'DESC') o[i].descending = true;
|
1223
1215
|
}
|
1224
|
-
|
1216
|
+
|
1225
1217
|
return o;
|
1226
1218
|
}
|
1227
|
-
|
1219
|
+
|
1228
1220
|
}
|
1229
1221
|
|
1230
1222
|
});
|
@@ -1233,35 +1225,35 @@ SC.Query = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
1233
1225
|
// Class Methods
|
1234
1226
|
SC.Query.mixin( /** @scope SC.Query */ {
|
1235
1227
|
|
1236
|
-
/**
|
1228
|
+
/**
|
1237
1229
|
Constant used for `SC.Query#location`
|
1238
|
-
|
1230
|
+
|
1239
1231
|
@type String
|
1240
1232
|
*/
|
1241
1233
|
LOCAL: 'local',
|
1242
|
-
|
1243
|
-
/**
|
1234
|
+
|
1235
|
+
/**
|
1244
1236
|
Constant used for `SC.Query#location`
|
1245
|
-
|
1237
|
+
|
1246
1238
|
@type String
|
1247
1239
|
*/
|
1248
1240
|
REMOTE: 'remote',
|
1249
|
-
|
1241
|
+
|
1250
1242
|
/**
|
1251
|
-
Given a query, returns the associated `storeKey`. For the inverse of this
|
1243
|
+
Given a query, returns the associated `storeKey`. For the inverse of this
|
1252
1244
|
method see `SC.Store.queryFor()`.
|
1253
|
-
|
1245
|
+
|
1254
1246
|
@param {SC.Query} query the query
|
1255
1247
|
@returns {Number} a storeKey.
|
1256
1248
|
*/
|
1257
1249
|
storeKeyFor: function(query) {
|
1258
1250
|
return query ? query.get('storeKey') : null;
|
1259
1251
|
},
|
1260
|
-
|
1252
|
+
|
1261
1253
|
/**
|
1262
|
-
Will find which records match a give `SC.Query` and return an array of
|
1254
|
+
Will find which records match a give `SC.Query` and return an array of
|
1263
1255
|
store keys. This will also apply the sorting for the query.
|
1264
|
-
|
1256
|
+
|
1265
1257
|
@param {SC.Query} query to apply
|
1266
1258
|
@param {SC.RecordArray} records to search within
|
1267
1259
|
@param {SC.Store} store to materialize record from
|
@@ -1275,16 +1267,16 @@ SC.Query.mixin( /** @scope SC.Query */ {
|
|
1275
1267
|
ret.push(record.get('storeKey'));
|
1276
1268
|
}
|
1277
1269
|
}
|
1278
|
-
|
1270
|
+
|
1279
1271
|
ret = SC.Query.orderStoreKeys(ret, query, store);
|
1280
|
-
|
1272
|
+
|
1281
1273
|
return ret;
|
1282
1274
|
},
|
1283
|
-
|
1284
|
-
/**
|
1275
|
+
|
1276
|
+
/**
|
1285
1277
|
Sorts a set of store keys according to the orderBy property
|
1286
1278
|
of the `SC.Query`.
|
1287
|
-
|
1279
|
+
|
1288
1280
|
@param {Array} storeKeys to sort
|
1289
1281
|
@param {SC.Query} query to use for sorting
|
1290
1282
|
@param {SC.Store} store to materialize records from
|
@@ -1301,11 +1293,11 @@ SC.Query.mixin( /** @scope SC.Query */ {
|
|
1301
1293
|
return storeKeys;
|
1302
1294
|
},
|
1303
1295
|
|
1304
|
-
/**
|
1296
|
+
/**
|
1305
1297
|
Default sort method that is used when calling `containsStoreKeys()`
|
1306
1298
|
or `containsRecords()` on this query. Simply materializes two records
|
1307
1299
|
based on `storekey`s before passing on to `compare()`.
|
1308
|
-
|
1300
|
+
|
1309
1301
|
@param {Number} storeKey1 a store key
|
1310
1302
|
@param {Number} storeKey2 a store key
|
1311
1303
|
@returns {Number} -1 if record1 < record2, +1 if record1 > record2, 0 if equal
|
@@ -1316,45 +1308,45 @@ SC.Query.mixin( /** @scope SC.Query */ {
|
|
1316
1308
|
|
1317
1309
|
return query.compare(record1, record2);
|
1318
1310
|
},
|
1319
|
-
|
1311
|
+
|
1320
1312
|
/**
|
1321
|
-
Returns a `SC.Query` instance reflecting the passed properties. Where
|
1322
|
-
possible this method will return cached query instances so that multiple
|
1323
|
-
calls to this method will return the same instance. This is not possible
|
1324
|
-
however, when you pass custom parameters or set ordering. All returned
|
1313
|
+
Returns a `SC.Query` instance reflecting the passed properties. Where
|
1314
|
+
possible this method will return cached query instances so that multiple
|
1315
|
+
calls to this method will return the same instance. This is not possible
|
1316
|
+
however, when you pass custom parameters or set ordering. All returned
|
1325
1317
|
queries are frozen.
|
1326
|
-
|
1318
|
+
|
1327
1319
|
Usually you will not call this method directly. Instead use the more
|
1328
1320
|
convenient `SC.Query.local()` and `SC.Query.remote()`.
|
1329
|
-
|
1321
|
+
|
1330
1322
|
Examples
|
1331
|
-
|
1332
|
-
There are a number of different ways you can call this method.
|
1333
|
-
|
1334
|
-
The following return local queries selecting all records of a particular
|
1323
|
+
|
1324
|
+
There are a number of different ways you can call this method.
|
1325
|
+
|
1326
|
+
The following return local queries selecting all records of a particular
|
1335
1327
|
type or types, including any subclasses:
|
1336
|
-
|
1328
|
+
|
1337
1329
|
var people = SC.Query.local(Ab.Person);
|
1338
1330
|
var peopleAndCompanies = SC.Query.local([Ab.Person, Ab.Company]);
|
1339
|
-
|
1331
|
+
|
1340
1332
|
var people = SC.Query.local('Ab.Person');
|
1341
1333
|
var peopleAndCompanies = SC.Query.local('Ab.Person Ab.Company'.w());
|
1342
|
-
|
1334
|
+
|
1343
1335
|
var allRecords = SC.Query.local(SC.Record);
|
1344
|
-
|
1336
|
+
|
1345
1337
|
The following will match a particular type of condition:
|
1346
|
-
|
1338
|
+
|
1347
1339
|
var married = SC.Query.local(Ab.Person, "isMarried=YES");
|
1348
1340
|
var married = SC.Query.local(Ab.Person, "isMarried=%@", [YES]);
|
1349
1341
|
var married = SC.Query.local(Ab.Person, "isMarried={married}", {
|
1350
1342
|
married: YES
|
1351
1343
|
});
|
1352
|
-
|
1353
|
-
You can also pass a hash of options as the second parameter. This is
|
1344
|
+
|
1345
|
+
You can also pass a hash of options as the second parameter. This is
|
1354
1346
|
how you specify an order, for example:
|
1355
|
-
|
1347
|
+
|
1356
1348
|
var orderedPeople = SC.Query.local(Ab.Person, { orderBy: "firstName" });
|
1357
|
-
|
1349
|
+
|
1358
1350
|
@param {String} location the query location.
|
1359
1351
|
@param {SC.Record|Array} recordType the record type or types.
|
1360
1352
|
@param {String} conditions optional conditions
|
@@ -1362,16 +1354,16 @@ SC.Query.mixin( /** @scope SC.Query */ {
|
|
1362
1354
|
@returns {SC.Query}
|
1363
1355
|
*/
|
1364
1356
|
build: function(location, recordType, conditions, params) {
|
1365
|
-
|
1357
|
+
|
1366
1358
|
var opts = null,
|
1367
1359
|
ret, cache, key, tmp;
|
1368
|
-
|
1360
|
+
|
1369
1361
|
// fast case for query objects.
|
1370
|
-
if (recordType && recordType.isQuery) {
|
1362
|
+
if (recordType && recordType.isQuery) {
|
1371
1363
|
if (recordType.get('location') === location) return recordType;
|
1372
1364
|
else return recordType.copy().set('location', location).freeze();
|
1373
1365
|
}
|
1374
|
-
|
1366
|
+
|
1375
1367
|
// normalize recordType
|
1376
1368
|
if (typeof recordType === SC.T_STRING) {
|
1377
1369
|
ret = SC.objectForPropertyPath(recordType);
|
@@ -1386,7 +1378,7 @@ SC.Query.mixin( /** @scope SC.Query */ {
|
|
1386
1378
|
}, this);
|
1387
1379
|
recordType = ret ;
|
1388
1380
|
} else if (!recordType) recordType = SC.Record; // find all records
|
1389
|
-
|
1381
|
+
|
1390
1382
|
if (params === undefined) params = null;
|
1391
1383
|
if (conditions === undefined) conditions = null;
|
1392
1384
|
|
@@ -1395,28 +1387,28 @@ SC.Query.mixin( /** @scope SC.Query */ {
|
|
1395
1387
|
opts = conditions;
|
1396
1388
|
conditions = null ;
|
1397
1389
|
}
|
1398
|
-
|
1390
|
+
|
1399
1391
|
// special case - easy to cache.
|
1400
1392
|
if (!params && !opts) {
|
1401
1393
|
|
1402
1394
|
tmp = SC.Query._scq_recordTypeCache;
|
1403
1395
|
if (!tmp) tmp = SC.Query._scq_recordTypeCache = {};
|
1404
1396
|
cache = tmp[location];
|
1405
|
-
if (!cache) cache = tmp[location] = {};
|
1406
|
-
|
1397
|
+
if (!cache) cache = tmp[location] = {};
|
1398
|
+
|
1407
1399
|
if (recordType.isEnumerable) {
|
1408
1400
|
key = recordType.map(function(k) { return SC.guidFor(k); });
|
1409
1401
|
key = key.sort().join(':');
|
1410
1402
|
} else key = SC.guidFor(recordType);
|
1411
|
-
|
1403
|
+
|
1412
1404
|
if (conditions) key = [key, conditions].join('::');
|
1413
|
-
|
1405
|
+
|
1414
1406
|
ret = cache[key];
|
1415
1407
|
if (!ret) {
|
1416
1408
|
if (recordType.isEnumerable) {
|
1417
1409
|
opts = { recordTypes: recordType.copy() };
|
1418
1410
|
} else opts = { recordType: recordType };
|
1419
|
-
|
1411
|
+
|
1420
1412
|
opts.location = location ;
|
1421
1413
|
opts.conditions = conditions ;
|
1422
1414
|
ret = cache[key] = SC.Query.create(opts).freeze();
|
@@ -1438,14 +1430,14 @@ SC.Query.mixin( /** @scope SC.Query */ {
|
|
1438
1430
|
|
1439
1431
|
ret = SC.Query.create(opts).freeze();
|
1440
1432
|
}
|
1441
|
-
|
1433
|
+
|
1442
1434
|
return ret ;
|
1443
1435
|
},
|
1444
|
-
|
1436
|
+
|
1445
1437
|
/**
|
1446
1438
|
Returns a `LOCAL` query with the passed options. For a full description of
|
1447
1439
|
the parameters you can pass to this method, see `SC.Query.build()`.
|
1448
|
-
|
1440
|
+
|
1449
1441
|
@param {SC.Record|Array} recordType the record type or types.
|
1450
1442
|
@param {String} conditions optional conditions
|
1451
1443
|
@param {Hash} params optional params. or pass multiple args.
|
@@ -1454,11 +1446,11 @@ SC.Query.mixin( /** @scope SC.Query */ {
|
|
1454
1446
|
local: function(recordType, conditions, params) {
|
1455
1447
|
return this.build(SC.Query.LOCAL, recordType, conditions, params);
|
1456
1448
|
},
|
1457
|
-
|
1449
|
+
|
1458
1450
|
/**
|
1459
1451
|
Returns a `REMOTE` query with the passed options. For a full description of
|
1460
1452
|
the parameters you can pass to this method, see `SC.Query.build()`.
|
1461
|
-
|
1453
|
+
|
1462
1454
|
@param {SC.Record|Array} recordType the record type or types.
|
1463
1455
|
@param {String} conditions optional conditions
|
1464
1456
|
@param {Hash} params optional params. or pass multiple args.
|
@@ -1467,25 +1459,25 @@ SC.Query.mixin( /** @scope SC.Query */ {
|
|
1467
1459
|
remote: function(recordType, conditions, params) {
|
1468
1460
|
return this.build(SC.Query.REMOTE, recordType, conditions, params);
|
1469
1461
|
},
|
1470
|
-
|
1471
|
-
/** @private
|
1462
|
+
|
1463
|
+
/** @private
|
1472
1464
|
called by `SC.Record.extend()`. invalidates `expandedRecordTypes`
|
1473
1465
|
*/
|
1474
1466
|
_scq_didDefineRecordType: function() {
|
1475
1467
|
var q = SC.Query._scq_queriesWithExpandedRecordTypes;
|
1476
1468
|
if (q) {
|
1477
|
-
q.forEach(function(query) {
|
1469
|
+
q.forEach(function(query) {
|
1478
1470
|
query.notifyPropertyChange('expandedRecordTypes');
|
1479
1471
|
}, this);
|
1480
1472
|
q.clear();
|
1481
1473
|
}
|
1482
1474
|
}
|
1483
|
-
|
1475
|
+
|
1484
1476
|
});
|
1485
1477
|
|
1486
1478
|
|
1487
1479
|
/** @private
|
1488
|
-
Hash of registered comparisons by
|
1480
|
+
Hash of registered comparisons by property name.
|
1489
1481
|
*/
|
1490
1482
|
SC.Query.comparisons = {};
|
1491
1483
|
|
@@ -1494,7 +1486,7 @@ SC.Query.comparisons = {};
|
|
1494
1486
|
The function you pass should accept two values of this property
|
1495
1487
|
and return -1 if the first is smaller than the second,
|
1496
1488
|
0 if they are equal and 1 if the first is greater than the second.
|
1497
|
-
|
1489
|
+
|
1498
1490
|
@param {String} name of the record property
|
1499
1491
|
@param {Function} custom comparison function
|
1500
1492
|
@returns {SC.Query} receiver
|
@@ -1506,13 +1498,13 @@ SC.Query.registerComparison = function(propertyName, comparison) {
|
|
1506
1498
|
|
1507
1499
|
/**
|
1508
1500
|
Call to register an extension for the query language.
|
1509
|
-
You
|
1501
|
+
You should provide a name for your extension and a definition
|
1510
1502
|
specifying how it should be parsed and evaluated.
|
1511
|
-
|
1503
|
+
|
1512
1504
|
Have a look at `queryLanguage` for examples of definitions.
|
1513
|
-
|
1505
|
+
|
1514
1506
|
TODO add better documentation here
|
1515
|
-
|
1507
|
+
|
1516
1508
|
@param {String} tokenName name of the operator
|
1517
1509
|
@param {Object} token extension definition
|
1518
1510
|
@returns {SC.Query} receiver
|