sproutcore 1.7.1.beta → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +44 -0
- data/README.rdoc +20 -20
- data/VERSION.yml +3 -3
- data/lib/Buildfile +1 -1
- data/lib/buildtasks/build.rake +5 -0
- data/lib/buildtasks/manifest.rake +19 -1
- data/lib/frameworks/sproutcore/Buildfile +19 -17
- data/lib/frameworks/sproutcore/CHANGELOG.md +163 -29
- data/lib/frameworks/sproutcore/README.md +29 -8
- data/lib/frameworks/sproutcore/apps/statechart_routing/Buildfile +12 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/controllers/login_controller.js +11 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/controllers/main_controller.js +7 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/controllers/statechart_controller.js +17 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/core.js +25 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/main.js +15 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/resources/_theme.css +18 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/resources/bar_page.js +14 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/resources/foo_page.js +14 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/resources/loading.rhtml +9 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/resources/login_page.js +61 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/resources/main_page.js +46 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/statechart.js +76 -0
- data/lib/frameworks/sproutcore/apps/statechart_routing/theme.js +27 -0
- data/lib/frameworks/sproutcore/apps/tests/controllers/targets.js +1 -1
- data/lib/frameworks/sproutcore/apps/tests/states/no_targets.js +1 -1
- data/lib/frameworks/sproutcore/apps/tests/states/ready_detail.js +1 -1
- data/lib/frameworks/sproutcore/apps/tests/states/ready_empty.js +1 -1
- data/lib/frameworks/sproutcore/apps/tests/states/ready_list.js +1 -1
- data/lib/frameworks/sproutcore/apps/tests/states/ready_no_tests.js +1 -1
- data/lib/frameworks/sproutcore/apps/welcome/controllers/targets.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/ajax/system/request.js +14 -1
- data/lib/frameworks/sproutcore/frameworks/ajax/system/response.js +15 -15
- data/lib/frameworks/sproutcore/frameworks/ajax/tests/system/request.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/animation/core.js +8 -5
- data/lib/frameworks/sproutcore/frameworks/bootstrap/system/browser.js +302 -70
- data/lib/frameworks/sproutcore/frameworks/bootstrap/system/loader.js +19 -14
- data/lib/frameworks/sproutcore/frameworks/bootstrap/tests/system/browser.js +471 -149
- data/lib/frameworks/sproutcore/frameworks/core_foundation/controllers/array.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/core_foundation/ext/object.js +42 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/ext/run_loop.js +3 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/ext/string.js +7 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/action_support.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/delegate_support.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/responder_context.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/selection_support.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/body_overflow.js +63 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/keyboard.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/layout.js +37 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/main.js +28 -6
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/pane.js +10 -3
- data/lib/frameworks/sproutcore/frameworks/core_foundation/protocols/sparse_array_delegate.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/browser.js +66 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/builder.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/cursor.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/event.js +58 -57
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/locale.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/locale.js.orig +445 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/platform.js +51 -31
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/ready.js +5 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/render_context.js +53 -69
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/responder.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +98 -72
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/string.js +37 -3
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/timer.js +7 -4
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/controllers/array/array_case.js +21 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/controllers/object/content_destroyed.js +7 -7
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/mixins/string.js +23 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/browser.js +66 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/event.js +22 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/locale.js +11 -11
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/render_context/end.js +4 -4
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/render_context/escape_html.js +41 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/render_context/helpers_className.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/render_context/helpers_style.js +8 -8
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/render_context/update.js +17 -16
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/selection_set/remove.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/build_children.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/class_name_bindings_test.js +15 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/createChildViews.js +5 -5
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view.js +50 -30
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/acceleration.js +46 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/animation.js +1 -43
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/keyboard.js +8 -34
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout.js +3 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout_style.js +10 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/manipulation.js +6 -5
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/theming.js +22 -2
- data/lib/frameworks/sproutcore/frameworks/datastore/data_sources/data_source.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/datastore/mixins/relationship_support.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/models/child_attribute.js +0 -2
- data/lib/frameworks/sproutcore/frameworks/datastore/models/children_attribute.js +35 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/models/record.js +46 -19
- data/lib/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +23 -9
- data/lib/frameworks/sproutcore/frameworks/datastore/models/single_attribute.js +2 -3
- data/lib/frameworks/sproutcore/frameworks/datastore/system/many_array.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/system/nested_store.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/datastore/system/query.js +294 -302
- data/lib/frameworks/sproutcore/frameworks/datastore/system/query.js.orig +1531 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/system/record_array.js +4 -2
- data/lib/frameworks/sproutcore/frameworks/datastore/system/store.js +14 -11
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/integration/many_array.js +63 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/many_attribute.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record.js +4 -4
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_array.js +50 -10
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_array_complex.js +4 -4
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_complex.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record/destroy.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record/refresh.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record_attribute.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/single_attribute.js +114 -67
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/commitChangesFromNestedStore.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/readDataHash.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/query/compare.js +54 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/query/evaluation.js +29 -9
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/query/parse.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/record_array/core_methods.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/record_array/flush.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/cancelRecord.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/commitChangesFromNestedStore.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/commitRecord.js +37 -45
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/find.js +127 -127
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/pushChanges.js +16 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/pushRelationships.js +42 -4
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/readDataHash.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/core/system/datetime.js +13 -7
- data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/core/tests/system/datetime.js +8 -0
- data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/localized/resources/strings.js +2 -1
- data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/localized/system/datetime.js +1 -0
- data/lib/frameworks/sproutcore/frameworks/debug/core.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/core.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/mixins/collection_row_delegate.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/mixins/collection_view_delegate.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/alert.js +1 -4
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/menu.js +19 -6
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/modal.js +30 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/palette.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/panel.js +24 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/picker.js +121 -28
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/sheet.js +15 -15
- data/lib/frameworks/sproutcore/frameworks/desktop/protocols/drag_data_source.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/protocols/drop_target.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/protocols/responder.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/button.js +39 -15
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/collection.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/disclosure.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/image_button.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/panel.js +14 -6
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/popup_button.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/progress.js +11 -11
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/segment.js +4 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/segmented.js +1 -51
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/slider.js +11 -16
- data/lib/frameworks/sproutcore/frameworks/desktop/resources/images/icons/sc-icon-error-48.png +0 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/resources/slider.css +0 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/system/drag.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/system/undo_manager.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/alert/ui.js +9 -9
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/button/content.js +11 -11
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/button/ui.js +2 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/collection/reload.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/date_field/ui.js +107 -81
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/list/rowDelegate.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/progress/ui.js +68 -60
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/radio/methods.js +57 -12
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/scroll/integration.js +21 -19
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/scroller.js +5 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/ui.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/select/ui.js +32 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/split/methods.js +12 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/stacked/ui_comments.js +12 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/tab/methods.js +0 -8
- data/lib/frameworks/sproutcore/frameworks/desktop/views/button.js +77 -132
- data/lib/frameworks/sproutcore/frameworks/desktop/views/checkbox.js +5 -6
- data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +16 -15
- data/lib/frameworks/sproutcore/frameworks/desktop/views/date_field.js +52 -52
- data/lib/frameworks/sproutcore/frameworks/desktop/views/disclosure.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/views/grid.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/views/list.js +147 -147
- data/lib/frameworks/sproutcore/frameworks/desktop/views/list_item.js +11 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_item.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_scroll.js +5 -5
- data/lib/frameworks/sproutcore/frameworks/desktop/views/popup_button.js +22 -12
- data/lib/frameworks/sproutcore/frameworks/desktop/views/radio.js +13 -7
- data/lib/frameworks/sproutcore/frameworks/desktop/views/scene.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll.js +462 -441
- data/lib/frameworks/sproutcore/frameworks/desktop/views/scroller.js +48 -62
- data/lib/frameworks/sproutcore/frameworks/desktop/views/segment.js +22 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/views/segmented.js +150 -32
- data/lib/frameworks/sproutcore/frameworks/desktop/views/select.js +104 -45
- data/lib/frameworks/sproutcore/frameworks/desktop/views/select_button.js +42 -20
- data/lib/frameworks/sproutcore/frameworks/desktop/views/slider.js +24 -24
- data/lib/frameworks/sproutcore/frameworks/desktop/views/split.js +148 -154
- data/lib/frameworks/sproutcore/frameworks/desktop/views/stacked.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/views/static_content.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/views/tab.js +8 -7
- data/lib/frameworks/sproutcore/frameworks/desktop/views/web.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/experimental/Buildfile +2 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/apps/greenhouse/controllers/files.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/apps/greenhouse/controllers/library.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/apps/greenhouse/controllers/targets.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/apps/greenhouse/controllers/view_configs.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/apps/greenhouse/mixins/drop_down.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/apps/greenhouse/states/ready.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/apps/greenhouse/views/plist_item.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/apps/greenhouse/views/web.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/designer/controllers/page_design.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/designer/css/css_style_sheet.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/designer/designers/object_designer.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/designer/designers/view_designer.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/designer/mixins/snap_lines.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/designer/views/designer_drop_target.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/designer/views/drawing.js +21 -21
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/designer/views/page_item_view.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/views/form.js +59 -53
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/menu/views/menu/scroll.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/polymorphism/tests/models/polymorphism/simple.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/core_scroll.js +6 -6
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/desktop/scroll.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/touch/scroll.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/ext/menu.js +14 -10
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/ext/menu_item.js +17 -6
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/views/popup_button.js +38 -14
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/views/select.js +5 -13
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/mixins/split_child.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/mixins/split_thumb.js +5 -3
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/tests/children.js +19 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/tests/methods.js +20 -2
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/tests/split_thumb.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/views/split.js +35 -12
- data/lib/frameworks/sproutcore/frameworks/formatters/README +6 -0
- data/lib/frameworks/sproutcore/frameworks/formatters/english.lproj/strings.js +174 -0
- data/lib/frameworks/sproutcore/frameworks/formatters/formatters/date_formatter.js +351 -0
- data/lib/frameworks/sproutcore/frameworks/formatters/tests/date_formatter.js +517 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/core.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/auto_resize.js +345 -138
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/button.js +5 -3
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/content_value_support.js +176 -42
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/editable.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/flowed_layout.js +137 -105
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/gestureable.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inline_editable.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inline_editor.js +16 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/static_layout.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/validatable.js +47 -47
- data/lib/frameworks/sproutcore/frameworks/foundation/private/tree_item_observer.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/helpers/sizing.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/label.js +28 -6
- data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/render_delegate.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/resources/benchmark.css +0 -5
- data/lib/frameworks/sproutcore/frameworks/foundation/resources/bootstrap.rhtml +34 -19
- data/lib/frameworks/sproutcore/frameworks/foundation/resources/button_view.css +0 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/resources/label.css +1 -5
- data/lib/frameworks/sproutcore/frameworks/foundation/resources/text_field.css +8 -9
- data/lib/frameworks/sproutcore/frameworks/foundation/system/benchmark.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/system/module.js +179 -47
- data/lib/frameworks/sproutcore/frameworks/foundation/system/task_queue.js +34 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/system/text_selection.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/system/user_defaults.js +26 -12
- data/lib/frameworks/sproutcore/frameworks/foundation/system/utils/misc.js +7 -7
- data/lib/frameworks/sproutcore/frameworks/foundation/system/utils/string_measurement.js +12 -4
- data/lib/frameworks/sproutcore/frameworks/foundation/system/utils/string_metric_optimization.js +202 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/content_value_support/content.js +77 -8
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/flowed_layout/tests.js +1 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_editable/beginEditing.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_editable/commitEditing.js +4 -3
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_editable/discardEditing.js +4 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_editor/beginEditing.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_editor/commitEditing.js +4 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_editor/discardEditing.js +4 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/system/utils/pointInElement.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/label/ui.js +0 -8
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/ui.js +163 -149
- data/lib/frameworks/sproutcore/frameworks/foundation/validators/credit_card.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/validators/date.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/validators/date_time.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/validators/password.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/validators/validator.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/foundation/views/field.js +16 -43
- data/lib/frameworks/sproutcore/frameworks/foundation/views/image.js +4 -3
- data/lib/frameworks/sproutcore/frameworks/foundation/views/inline_text_field.js +67 -54
- data/lib/frameworks/sproutcore/frameworks/foundation/views/label.js +49 -38
- data/lib/frameworks/sproutcore/frameworks/foundation/views/text_field.js +285 -242
- data/lib/frameworks/sproutcore/frameworks/jquery/jquery-buffer.js +13 -13
- data/lib/frameworks/sproutcore/frameworks/jquery/jquery-buffered.js +19 -22
- data/lib/frameworks/sproutcore/frameworks/jquery/jquery-sc.js +9 -3
- data/lib/frameworks/sproutcore/frameworks/jquery/jquery.js +231 -186
- data/lib/frameworks/sproutcore/frameworks/media/views/audio.js +145 -143
- data/lib/frameworks/sproutcore/frameworks/media/views/video.js +156 -154
- data/lib/frameworks/sproutcore/frameworks/qunit/qunit/qunit.js +5 -5
- data/lib/frameworks/sproutcore/frameworks/routing/system/routes.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/routing/system/routes.js.orig +540 -0
- data/lib/frameworks/sproutcore/frameworks/routing/tests/system/routes.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/core.js +15 -8
- data/lib/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/base.js +5 -5
- data/lib/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/replace.js +12 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/ext/function.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/array.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/copyable.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/enumerable.js +7 -7
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +98 -32
- data/lib/frameworks/sproutcore/frameworks/runtime/private/chain_observer.js +7 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/private/observer_queue.js +14 -3
- data/lib/frameworks/sproutcore/frameworks/runtime/private/observer_set.js +98 -13
- data/lib/frameworks/sproutcore/frameworks/runtime/system/binding.js +8 -14
- data/lib/frameworks/sproutcore/frameworks/runtime/system/enumerator.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/system/error.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/system/index_set.js +23 -6
- data/lib/frameworks/sproutcore/frameworks/runtime/system/logger.js +69 -18
- data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +57 -31
- data/lib/frameworks/sproutcore/frameworks/runtime/system/run_loop.js +189 -14
- data/lib/frameworks/sproutcore/frameworks/runtime/system/string.js +82 -22
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/chained.js +20 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/observable.js +125 -4
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/private/observer_queue.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/binding.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/index_set/rangeStartForIndex.js +37 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/index_set/remove.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/logger.js +16 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/run_loop.js +75 -4
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/string.js +41 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/mixins/statechart_delegate.js +113 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/private/state_path_matcher.js +312 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/system/async.js +18 -22
- data/lib/frameworks/sproutcore/frameworks/statechart/system/state.js +508 -131
- data/lib/frameworks/sproutcore/frameworks/statechart/system/state_route_handler_context.js +78 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/system/statechart.js +265 -44
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/event_handling/basic/with_concurrent_states.js +16 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/event_handling/responder/responder_chain.js +11 -3
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/private/state_path_matcher.js +116 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/state/methods/add_substate.js +108 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/state/methods/find_first_relative_current_state/with_concurrent.js +179 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/state/methods/find_first_relative_current_state/without_concurrent.js +74 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/state/methods/get_state.js +141 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/state/methods/get_substate.js +340 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/state/methods/route_triggered.js +161 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/state/methods/try_to_handle_event.js +288 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/state_transitioning/history_state/standard/without_concurrent_states/context.js +5 -33
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/state_transitioning/routing/with_concurrent_states/basic.js +213 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/state_transitioning/routing/without_concurrent_states/basic.js +212 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/state_transitioning/standard/without_concurrent_states/core.js +8 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/{state/namespacing.js → statechart/methods/get_state.js} +3 -41
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/statechart/{invoke_state_method.js → methods/invoke_state_method.js} +1 -1
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/{event_handling/advanced → statechart}/respond_to_event.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/system/state_route_handler_context/methods/retry.js +64 -0
- data/lib/frameworks/sproutcore/frameworks/table/core.js +2 -0
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/controls/button.js +0 -1
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/ext/handlebars.js +29 -5
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/ext/handlebars/bind.js +4 -3
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/ext/handlebars/collection.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/ext/handlebars/localization.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/ext/handlebars/view.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{handlebars → template_view}/handlebars.js +493 -357
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/mixins/template_helpers/checkbox_support.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/mixins/template_helpers/text_field_support.js +13 -2
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/panes/template.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/tests/controls/button.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/tests/mixins/template_helpers/checkbox_support.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/tests/mixins/template_helpers/text_field_support.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/tests/panes/template.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/tests/views/template/collection.js +39 -14
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/tests/views/template/core.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/tests/views/template/handlebars.js +57 -6
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/views/bindable_span.js +21 -6
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/views/template.js +9 -3
- data/lib/frameworks/sproutcore/frameworks/{core_foundation → template_view}/views/template_collection.js +55 -26
- data/lib/frameworks/sproutcore/frameworks/testing/system/equiv.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/testing/system/plan.js +122 -122
- data/lib/frameworks/sproutcore/frameworks/testing/system/runner.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/testing/system/suite.js +4 -4
- data/lib/frameworks/sproutcore/frameworks/yuireset/resources/base.css +1 -1
- data/lib/frameworks/sproutcore/frameworks/yuireset/resources/reset.css +0 -1
- data/lib/frameworks/sproutcore/frameworks/yuireset/resources/view.css +4 -4
- data/lib/frameworks/sproutcore/lib/index.rhtml +55 -32
- data/lib/frameworks/sproutcore/license.js +2 -4
- data/lib/frameworks/sproutcore/themes/ace/resources/body.css +5 -1
- data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/18px/button.css +2 -2
- data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/24px/button.css +21 -13
- data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/30px/button.css +17 -10
- data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/44px/button.css +4 -3
- data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/24px/button.css +20 -12
- data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/30px/button.css +16 -8
- data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/jumbo/button.css +17 -0
- data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/small/button.css +17 -0
- data/lib/frameworks/sproutcore/themes/ace/resources/disclosure/ace/disclosure.css +2 -2
- data/lib/frameworks/sproutcore/themes/ace/resources/master-detail/master-detail.css +2 -2
- data/lib/frameworks/sproutcore/themes/ace/resources/picker/popover/popover.css +5 -3
- data/lib/frameworks/sproutcore/themes/iphone_theme/english.lproj/core.css +1 -1
- data/lib/frameworks/sproutcore/themes/legacy_theme/english.lproj/toolbar.css +1 -1
- data/lib/gen/app/USAGE +17 -4
- data/lib/gen/language/Buildfile +4 -4
- data/lib/gen/language/USAGE +4 -4
- data/lib/gen/page/templates/pages/@target_name@/Buildfile +7 -7
- data/lib/gen/{html_app → statechart_app}/Buildfile +0 -0
- data/lib/gen/{html_app → statechart_app}/README +0 -0
- data/lib/gen/statechart_app/USAGE +21 -0
- data/lib/gen/statechart_app/templates/apps/@target_name@/Buildfile +9 -0
- data/lib/gen/statechart_app/templates/apps/@target_name@/core.js +24 -0
- data/lib/gen/statechart_app/templates/apps/@target_name@/main.js +26 -0
- data/lib/gen/statechart_app/templates/apps/@target_name@/resources/_theme.css +18 -0
- data/lib/gen/statechart_app/templates/apps/@target_name@/resources/loading.rhtml +9 -0
- data/lib/gen/statechart_app/templates/apps/@target_name@/resources/main_page.js +21 -0
- data/lib/gen/statechart_app/templates/apps/@target_name@/statechart.js +8 -0
- data/lib/gen/statechart_app/templates/apps/@target_name@/states/ready_state.js +12 -0
- data/lib/gen/statechart_app/templates/apps/@target_name@/theme.js +24 -0
- data/lib/sproutcore/builders.rb +1 -0
- data/lib/sproutcore/builders/base.rb +19 -1
- data/lib/sproutcore/builders/chance_file.rb +6 -1
- data/lib/sproutcore/builders/handlebars.rb +1 -9
- data/lib/sproutcore/builders/javascript.rb +1 -10
- data/lib/sproutcore/builders/json.rb +25 -0
- data/lib/sproutcore/builders/less.rb +1 -1
- data/lib/sproutcore/builders/sass.rb +1 -1
- data/lib/sproutcore/builders/stylesheet.rb +1 -9
- data/lib/sproutcore/helpers/html5_manifest.rb +1 -1
- data/lib/sproutcore/helpers/static_helper.rb +42 -0
- data/lib/sproutcore/rack/proxy.rb +21 -3
- data/lib/sproutcore/rack/service.rb +3 -2
- data/lib/sproutcore/tools.rb +18 -25
- data/lib/sproutcore/tools/gen.rb +10 -3
- data/lib/sproutcore/tools/init.rb +11 -10
- data/spec/buildtasks/manifest/prepare_build_tasks/json_spec.rb +62 -0
- data/spec/fixtures/builder_tests/apps/handlebars_test/Buildfile +1 -1
- data/spec/fixtures/builder_tests/apps/json_test/sc_static.json +2 -0
- data/spec/lib/builders/json_spec.rb +53 -0
- data/sproutcore.gemspec +2 -2
- data/vendor/chance/lib/chance/parser.rb +1 -1
- metadata +222 -177
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/datetime.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/debug/invoke_once_last_debugging.js +0 -259
- data/lib/frameworks/sproutcore/frameworks/documentation/core.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/system/chance.js +0 -69
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/editable/ui.js +0 -44
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_text_field/ui.js +0 -64
- data/lib/frameworks/sproutcore/frameworks/mini/license.js +0 -30
- data/lib/gen/html_app/USAGE +0 -15
- data/lib/gen/html_app/templates/apps/@target_name@/@target_name@.js +0 -11
- data/lib/gen/html_app/templates/apps/@target_name@/resources/images/.gitkeep +0 -0
- data/lib/gen/html_app/templates/apps/@target_name@/resources/stylesheets/@target_name@.css +0 -6
- data/lib/gen/html_app/templates/apps/@target_name@/resources/templates/@target_name@.handlebars +0 -1
- data/lib/gen/html_project/Buildfile +0 -45
- data/lib/gen/html_project/INIT +0 -3
- data/lib/gen/html_project/README +0 -1
- data/lib/gen/html_project/USAGE +0 -2
- data/lib/gen/html_project/templates/@filename@/Buildfile +0 -5
- data/lib/gen/html_project/templates/@filename@/README +0 -4
|
@@ -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
|