sproutcore 1.5.0.pre.3 → 1.5.0.pre.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.rspec +1 -0
- data/CHANGELOG +42 -0
- data/README.txt +25 -0
- data/VERSION.yml +1 -1
- data/bin/sc-build +1 -1
- data/bin/sc-build-number +1 -1
- data/bin/sc-docs +1 -1
- data/bin/sc-gen +1 -1
- data/bin/sc-init +1 -1
- data/bin/sc-manifest +1 -1
- data/bin/sc-server +1 -1
- data/bin/sproutcore +1 -1
- data/lib/buildtasks/build.rake +5 -0
- data/lib/buildtasks/manifest.rake +20 -1
- data/lib/frameworks/sproutcore/Buildfile +12 -9
- data/lib/frameworks/sproutcore/CHANGELOG.md +48 -0
- data/lib/frameworks/sproutcore/apps/greenhouse/README +2 -9
- data/lib/frameworks/sproutcore/apps/greenhouse/TODO +11 -27
- data/lib/frameworks/sproutcore/apps/greenhouse/controllers/library.js +3 -10
- data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/css/main-page.css +4 -31
- data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/dialogs.js +5 -4
- data/lib/frameworks/sproutcore/apps/greenhouse/models/dir.js +3 -3
- data/lib/frameworks/sproutcore/apps/greenhouse/models/file.js +2 -2
- data/lib/frameworks/sproutcore/apps/greenhouse/states/main.js +31 -14
- data/lib/frameworks/sproutcore/apps/greenhouse/states/modals.js +2 -1
- data/lib/frameworks/sproutcore/apps/greenhouse/states/ready.js +27 -1
- data/lib/frameworks/sproutcore/apps/greenhouse/tests/views/list_item.js +1 -0
- data/lib/frameworks/sproutcore/apps/greenhouse/tests/views/plist_item.js +20 -0
- data/lib/frameworks/sproutcore/apps/greenhouse/theme.js +25 -0
- data/lib/frameworks/sproutcore/apps/greenhouse/views/plist_item.js +161 -24
- data/lib/frameworks/sproutcore/apps/greenhouse/views/tear_off_picker.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/bootstrap/system/browser.js +37 -25
- data/lib/frameworks/sproutcore/frameworks/bootstrap/tests/system/browser.js +135 -26
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/controllers/array.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/controllers/controller.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/controllers/object.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/core.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/ext/object.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/ext/run_loop.js +1 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/mixins/delegate_support.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/mixins/responder_context.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/mixins/selection_support.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/mixins/string.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/keyboard.js +68 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/layout.js +108 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/panes/main.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/manipulation.js +27 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/panes/pane.js +215 -505
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/template.js +24 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/visibility.js +11 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/protocols/observable_protocol.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/protocols/sparse_array_delegate.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/resources/core.css +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/resources/view.css +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/application.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/browser.js +1 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/builder.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/core_query.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/cursor.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/device.js +210 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/event.js +5 -5
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/json.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/locale.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/page.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/platform.js +31 -5
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/ready.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/render_context.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/responder.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/root_responder.js +83 -110
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/selection_set.js +7 -4
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/sparse_array.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/theme.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/timer.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/utils/rect.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/utils.js +151 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/array/array_case.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/array/enum_case.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/array/null_case.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/array/selection_support.js +26 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/array/single_case.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/object/empty_case.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/object/multiple_case.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/object/single_case.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/object/single_enumerable_case.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/mixins/responder_context.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/mixins/string.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/panes/template.js +14 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/builder.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/core_query/within.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/json.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/locale.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/begin.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/element.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/end.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/get.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/helpers_attr.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/helpers_basic.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/helpers_className.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/helpers_style.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/init.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/join.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/push_text.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/tag.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/update.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/root_responder/makeKeyPane.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/root_responder/makeMainPane.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/root_responder/makeMenuPane.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/root_responder/root_responder.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/root_responder/targetForAction.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/selection_set/add.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/selection_set/copy.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/selection_set/indexSetForSource.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/selection_set/isEqual.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/selection_set/remove.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/sparse_array.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/theme.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/timer/invalidate.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/timer/invokeLater.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/timer/isPaused.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/timer/performAction.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/timer/schedule.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/utils/normalizeURL.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/utils/offset.js +268 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/utils/rect.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/main_pane.js +43 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/pane/append_remove.js +107 -18
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/pane/child_view.js +20 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/pane/firstResponder.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/pane/keyPane.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/pane/layout.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/pane/sendEvent.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template/checkbox_support.js +32 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template/text_field_support.js +73 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template_view/collection.js +65 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template_view/core.js +67 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template_view/handlebars.js +295 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/animation.js +19 -18
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/build.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/build_children.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/clippingFrame.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/convertFrames.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/convertLayouts.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/createChildViews.js +18 -15
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/createLayer.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/destroyLayer.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/didAppendToDocument.js +11 -8
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/findLayerInParentLayer.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/init.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/insertBefore.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/isVisible.js +28 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/isVisibleInWindow.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/keyboard.js +22 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/layer.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/layoutChildViews.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutDidChange.js +180 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutStyle.js +640 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/parentViewDidChange.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/prepareContext.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/removeChild.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/render.js +125 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/render_delegate_support.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/replaceChild.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/static_layout.js +21 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/theme.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/updateLayer.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/updateLayerLocation.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/view.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/viewDidResize.js +0 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/template/checkbox_support.js +20 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/template/collection.js +99 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/template/text_field_support.js +35 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/template.js +77 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/animation.js +187 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/base.js +1 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/cursor.js +41 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/enabled.js +57 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/keyboard.js +223 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout.js +1150 -0
- data/lib/frameworks/sproutcore/frameworks/{amber/views → core_foundation/views/view}/layout_style.js +93 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/manipulation.js +489 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/theming.js +362 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/touch.js +67 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/visibility.js +113 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view.js +1280 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/models/child_attribute.js +27 -53
- data/lib/frameworks/sproutcore/frameworks/datastore/models/children_attribute.js +13 -19
- data/lib/frameworks/sproutcore/frameworks/datastore/models/many_attribute.js +1 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/models/record.js +183 -71
- data/lib/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +1 -2
- data/lib/frameworks/sproutcore/frameworks/datastore/system/child_array.js +26 -46
- data/lib/frameworks/sproutcore/frameworks/datastore/system/nested_store.js +25 -4
- data/lib/frameworks/sproutcore/frameworks/datastore/system/store.js +139 -21
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/data_sources/fixtures.js +6 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/integration/cyclical_relationship.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/{parentless.js → data_store.js} +62 -16
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record.js +51 -17
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_array.js +36 -10
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_array_complex.js +11 -11
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_complex.js +8 -8
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record/normalize.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/{foundation/english.lproj → datetime/resources}/strings.js +1 -0
- data/lib/frameworks/sproutcore/frameworks/{foundation → datetime}/system/datetime.js +5 -37
- data/lib/frameworks/sproutcore/frameworks/{foundation → datetime}/tests/system/datetime.js +1 -0
- data/lib/frameworks/sproutcore/frameworks/debug/core.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/designer/controllers/designs.js +1 -2
- data/lib/frameworks/sproutcore/frameworks/designer/designers/object_designer.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/designer/designers/view_designer.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/designer/views/designer_drop_target.js +9 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/english.lproj/segmented.css +71 -70
- data/lib/frameworks/sproutcore/frameworks/desktop/mixins/collection_row_delegate.js +10 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/segment.js +4 -19
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/segmented.js +33 -14
- data/lib/frameworks/sproutcore/frameworks/desktop/system/drag.js +25 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/date_field/ui.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/methods.js +25 -103
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/ui.js +102 -92
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/tab/ui.js +22 -25
- data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +38 -25
- data/lib/frameworks/sproutcore/frameworks/desktop/views/date_field.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/views/segment.js +42 -22
- data/lib/frameworks/sproutcore/frameworks/desktop/views/segmented.js +513 -230
- data/lib/frameworks/sproutcore/frameworks/desktop/views/select_field.js +0 -2
- data/lib/frameworks/sproutcore/frameworks/experimental/README.md +23 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/device_motion/README.md +11 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/device_motion/device.js +215 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/device_motion/platform.js +67 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/polymorphism/README.md +34 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/polymorphism/models/polymorphic_single_attribute.js +183 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/polymorphism/models/record.js +23 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/polymorphism/tests/models/polymorphic/single.js +124 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/auto_resize.js +0 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inner_frame.js +151 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/canvas_image.js +27 -17
- data/lib/frameworks/sproutcore/frameworks/foundation/system/image_queue.js +6 -3
- data/lib/frameworks/sproutcore/frameworks/foundation/system/logger.js +163 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/system/user_defaults.js +6 -3
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_text_field/beginEditing.js +1 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/system/logger.js +44 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/image/ui.js +200 -167
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/ui.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/views/image.js +52 -137
- data/lib/frameworks/sproutcore/frameworks/foundation/views/text_field.js +7 -11
- data/lib/frameworks/sproutcore/frameworks/handlebars/extensions.js +138 -0
- data/lib/frameworks/sproutcore/frameworks/handlebars/handlebars.js +1338 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/core.js +32 -26
- data/lib/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/base.js +162 -3
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/array.js +10 -5
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/enumerable.js +123 -3
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +12 -5
- data/lib/frameworks/sproutcore/frameworks/runtime/private/chain_observer.js +50 -13
- data/lib/frameworks/sproutcore/frameworks/runtime/system/logger.js +163 -333
- data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +58 -8
- data/lib/frameworks/sproutcore/frameworks/runtime/system/run_loop.js +2 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/core/itemType.js +9 -6
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/core/makeArray.js +15 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/array.js +2 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/chained.js +31 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/observable.js +18 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/logger.js +31 -143
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/object/concatenated_properties.js +71 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/object/enhance.js +177 -0
- data/lib/frameworks/sproutcore/frameworks/table/views/table.js +5 -4
- data/lib/frameworks/sproutcore/frameworks/table/views/table_header.js +5 -3
- data/lib/frameworks/sproutcore/themes/ace/resources/button/button.js +8 -2
- data/lib/frameworks/sproutcore/themes/ace/resources/menu/menu.css +2 -3
- data/lib/frameworks/sproutcore/themes/ace/resources/segmented/18px/segmented.css +1 -1
- data/lib/frameworks/sproutcore/themes/ace/resources/segmented/24px/segmented.css +1 -1
- data/lib/frameworks/sproutcore/themes/ace/resources/segmented/30px/segmented.css +1 -1
- data/lib/frameworks/sproutcore/themes/ace/resources/segmented/44px/segmented.css +1 -1
- data/lib/frameworks/sproutcore/themes/ace/resources/segmented/segmented.css +2 -2
- data/lib/frameworks/sproutcore/themes/standard_theme/english.lproj/segmented.css +62 -62
- data/lib/gen/html_app/Buildfile +36 -0
- data/lib/gen/html_app/README +1 -0
- data/lib/gen/html_app/USAGE +15 -0
- data/lib/gen/html_app/templates/apps/@target_name@/@target_name@.js +14 -0
- data/lib/gen/html_app/templates/apps/@target_name@/resources/images/.gitkeep +0 -0
- data/lib/gen/html_app/templates/apps/@target_name@/resources/stylesheets/@target_name@.css +0 -0
- data/lib/gen/html_app/templates/apps/@target_name@/resources/templates/@target_name@.handlebars +1 -0
- data/lib/gen/html_project/Buildfile +45 -0
- data/lib/gen/html_project/INIT +3 -0
- data/lib/gen/html_project/README +1 -0
- data/lib/gen/html_project/USAGE +2 -0
- data/lib/gen/html_project/templates/@filename@/Buildfile +8 -0
- data/lib/gen/html_project/templates/@filename@/README +7 -0
- data/lib/sproutcore/builders/handlebars.rb +30 -0
- data/lib/sproutcore/builders.rb +1 -1
- data/lib/sproutcore/helpers/static_helper.rb +3 -3
- data/lib/sproutcore/tools/init.rb +25 -9
- data/spec/buildtasks/manifest/prepare_build_tasks/handlebars_spec.rb +39 -0
- data/spec/fixtures/builder_tests/apps/handlebars_test/template.handlebars +5 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/templates/demo.handlebars +4 -0
- data/spec/lib/builders/handlebars_spec.rb +29 -0
- data/vendor/chance/lib/chance/imagers/data_url.rb +20 -7
- data/vendor/chance/lib/chance/instance.rb +4 -1
- data/vendor/chance/lib/chance/parser.rb +31 -31
- data/vendor/chance/lib/chance/slicing.rb +38 -8
- metadata +195 -225
- data/lib/frameworks/sproutcore/frameworks/amber/system/device.js +0 -143
- data/lib/frameworks/sproutcore/frameworks/amber/system/utils.js +0 -174
- data/lib/frameworks/sproutcore/frameworks/amber/tests/views/main_pane.js +0 -31
- data/lib/frameworks/sproutcore/frameworks/amber/tests/views/pane/sendTouchEvent.js +0 -267
- data/lib/frameworks/sproutcore/frameworks/amber/tests/views/view/layoutDidChange.js +0 -149
- data/lib/frameworks/sproutcore/frameworks/amber/tests/views/view/layoutStyle.js +0 -602
- data/lib/frameworks/sproutcore/frameworks/amber/tests/views/view/render.js +0 -115
- data/lib/frameworks/sproutcore/frameworks/amber/views/base.js +0 -1
- data/lib/frameworks/sproutcore/frameworks/amber/views/view.js +0 -4003
- data/lib/frameworks/sproutcore/frameworks/datastore/models/child_record.js +0 -105
|
@@ -0,0 +1,1280 @@
|
|
|
1
|
+
// ==========================================================================
|
|
2
|
+
// Project: SproutCore - JavaScript Application Framework
|
|
3
|
+
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
|
4
|
+
// Portions ©2008-2010 Apple Inc. All rights reserved.
|
|
5
|
+
// License: Licensed under MIT license (see license.js)
|
|
6
|
+
// ==========================================================================
|
|
7
|
+
|
|
8
|
+
sc_require('system/browser');
|
|
9
|
+
sc_require('system/event');
|
|
10
|
+
sc_require('system/cursor');
|
|
11
|
+
sc_require('system/responder') ;
|
|
12
|
+
sc_require('system/theme');
|
|
13
|
+
|
|
14
|
+
sc_require('mixins/string') ;
|
|
15
|
+
sc_require('views/view/base') ;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
Default property to disable or enable by default the contextMenu
|
|
19
|
+
*/
|
|
20
|
+
SC.CONTEXT_MENU_ENABLED = YES;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
Default property to disable or enable if the focus can jump to the address
|
|
24
|
+
bar or not.
|
|
25
|
+
*/
|
|
26
|
+
SC.TABBING_ONLY_INSIDE_DOCUMENT = YES;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
Tells the property (when fetched with themed()) to get its value from the renderer (if any).
|
|
30
|
+
*/
|
|
31
|
+
SC.FROM_THEME = "__FROM_THEME__"; // doesn't really matter what it is, so long as it is unique. Readability is a plus.
|
|
32
|
+
|
|
33
|
+
/** @private - custom array used for child views */
|
|
34
|
+
SC.EMPTY_CHILD_VIEWS_ARRAY = [];
|
|
35
|
+
SC.EMPTY_CHILD_VIEWS_ARRAY.needsClone = YES;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
@class
|
|
39
|
+
|
|
40
|
+
Base class for managing a view. Views provide two functions:
|
|
41
|
+
|
|
42
|
+
1. They translate state and events into drawing instructions for the
|
|
43
|
+
web browser and
|
|
44
|
+
|
|
45
|
+
2. They act as first responders for incoming keyboard, mouse, and
|
|
46
|
+
touch events.
|
|
47
|
+
|
|
48
|
+
h2. View Initialization
|
|
49
|
+
|
|
50
|
+
When a view is setup, there are several methods you can override that
|
|
51
|
+
will be called at different times depending on how your view is created.
|
|
52
|
+
Here is a guide to which method you want to override and when:
|
|
53
|
+
|
|
54
|
+
- *init:* override this method for any general object setup (such as
|
|
55
|
+
observers, starting timers and animations, etc) that you need to happen
|
|
56
|
+
everytime the view is created, regardless of whether or not its layer
|
|
57
|
+
exists yet.
|
|
58
|
+
|
|
59
|
+
- *render:* override this method to generate or update your HTML to reflect
|
|
60
|
+
the current state of your view. This method is called both when your view
|
|
61
|
+
is first created and later anytime it needs to be updated.
|
|
62
|
+
|
|
63
|
+
- *didCreateLayer:* the render() method is used to generate new HTML.
|
|
64
|
+
Override this method to perform any additional setup on the DOM you might
|
|
65
|
+
need to do after creating the view. For example, if you need to listen
|
|
66
|
+
for events.
|
|
67
|
+
|
|
68
|
+
- *willDestroyLayer:* if you implement didCreateLayer() to setup event
|
|
69
|
+
listeners, you should implement this method as well to remove the same
|
|
70
|
+
just before the DOM for your view is destroyed.
|
|
71
|
+
|
|
72
|
+
- *updateLayer:* Normally, when a view needs to update its content, it will
|
|
73
|
+
re-render the view using the render() method. If you would like to
|
|
74
|
+
override this behavior with your own custom updating code, you can
|
|
75
|
+
replace updateLayer() with your own implementation instead.
|
|
76
|
+
|
|
77
|
+
- *didAppendToDocument:* in theory all DOM setup could be done
|
|
78
|
+
in didCreateLayer() as you already have a DOM element instantiated.
|
|
79
|
+
However there is cases where the element has to be first appended to the
|
|
80
|
+
Document because there is either a bug on the browser or you are using
|
|
81
|
+
plugins which objects are not instantiated until you actually append the
|
|
82
|
+
element to the DOM. This will allow you to do things like registering
|
|
83
|
+
DOM events on flash or quicktime objects.
|
|
84
|
+
|
|
85
|
+
@extends SC.Responder
|
|
86
|
+
@extends SC.DelegateSupport
|
|
87
|
+
@since SproutCore 1.0
|
|
88
|
+
*/
|
|
89
|
+
SC.CoreView.reopen(
|
|
90
|
+
/** @scope SC.View.prototype */ {
|
|
91
|
+
|
|
92
|
+
concatenatedProperties: 'outlets displayProperties classNames renderMixin didCreateLayerMixin willDestroyLayerMixin'.w(),
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
The current pane.
|
|
96
|
+
@property {SC.Pane}
|
|
97
|
+
*/
|
|
98
|
+
pane: function() {
|
|
99
|
+
var view = this ;
|
|
100
|
+
while (view && !view.isPane) { view = view.get('parentView') ; }
|
|
101
|
+
return view ;
|
|
102
|
+
}.property('parentView').cacheable(),
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
The page this view was instantiated from. This is set by the page object
|
|
106
|
+
during instantiation.
|
|
107
|
+
|
|
108
|
+
@property {SC.Page}
|
|
109
|
+
*/
|
|
110
|
+
page: null,
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
If the view is currently inserted into the DOM of a parent view, this
|
|
114
|
+
property will point to the parent of the view.
|
|
115
|
+
*/
|
|
116
|
+
parentView: null,
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
The isVisible property determines if the view is shown in the view
|
|
120
|
+
hierarchy it is a part of. A view can have isVisible == YES and still have
|
|
121
|
+
isVisibleInWindow == NO. This occurs, for instance, when a parent view has
|
|
122
|
+
isVisible == NO. Default is YES.
|
|
123
|
+
|
|
124
|
+
The isVisible property is considered part of the layout and so changing it
|
|
125
|
+
will trigger a layout update.
|
|
126
|
+
|
|
127
|
+
@property {Boolean}
|
|
128
|
+
*/
|
|
129
|
+
isVisible: YES,
|
|
130
|
+
isVisibleBindingDefault: SC.Binding.bool(),
|
|
131
|
+
|
|
132
|
+
// ..........................................................
|
|
133
|
+
// CHILD VIEW SUPPORT
|
|
134
|
+
//
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
Array of child views. You should never edit this array directly unless
|
|
138
|
+
you are implementing createChildViews(). Most of the time, you should
|
|
139
|
+
use the accessor methods such as appendChild(), insertBefore() and
|
|
140
|
+
removeChild().
|
|
141
|
+
|
|
142
|
+
@property {Array}
|
|
143
|
+
*/
|
|
144
|
+
childViews: SC.EMPTY_CHILD_VIEWS_ARRAY,
|
|
145
|
+
|
|
146
|
+
// ..........................................................
|
|
147
|
+
// LAYER SUPPORT
|
|
148
|
+
//
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
Returns the current layer for the view. The layer for a view is only
|
|
152
|
+
generated when the view first becomes visible in the window and even
|
|
153
|
+
then it will not be computed until you request this layer property.
|
|
154
|
+
|
|
155
|
+
If the layer is not actually set on the view itself, then the layer will
|
|
156
|
+
be found by calling this.findLayerInParentLayer().
|
|
157
|
+
|
|
158
|
+
You can also set the layer by calling set on this property.
|
|
159
|
+
|
|
160
|
+
@property {DOMElement} the layer
|
|
161
|
+
*/
|
|
162
|
+
layer: function(key, value) {
|
|
163
|
+
if (value !== undefined) {
|
|
164
|
+
this._view_layer = value ;
|
|
165
|
+
|
|
166
|
+
// no layer...attempt to discover it...
|
|
167
|
+
} else {
|
|
168
|
+
value = this._view_layer;
|
|
169
|
+
if (!value) {
|
|
170
|
+
var parent = this.get('parentView');
|
|
171
|
+
if (parent) { parent = parent.get('layer'); }
|
|
172
|
+
if (parent) { this._view_layer = value = this.findLayerInParentLayer(parent); }
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return value ;
|
|
176
|
+
}.property('isVisibleInWindow').cacheable(),
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
Get a CoreQuery object for this view's layer, or pass in a selector string
|
|
180
|
+
to get a CoreQuery object for a DOM node nested within this layer.
|
|
181
|
+
|
|
182
|
+
@param {String} sel a CoreQuery-compatible selector string
|
|
183
|
+
@returns {SC.CoreQuery} the CoreQuery object for the DOM node
|
|
184
|
+
*/
|
|
185
|
+
$: function(sel) {
|
|
186
|
+
var layer = this.get('layer') ;
|
|
187
|
+
|
|
188
|
+
if(!layer) { return SC.$(); }
|
|
189
|
+
else if(sel === undefined) { return SC.$(layer); }
|
|
190
|
+
else { return SC.$(sel, layer); }
|
|
191
|
+
},
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
Returns the DOM element that should be used to hold child views when they
|
|
195
|
+
are added/remove via DOM manipulation. The default implementation simply
|
|
196
|
+
returns the layer itself. You can override this to return a DOM element
|
|
197
|
+
within the layer.
|
|
198
|
+
|
|
199
|
+
@property {DOMElement} the container layer
|
|
200
|
+
*/
|
|
201
|
+
containerLayer: function() {
|
|
202
|
+
return this.get('layer') ;
|
|
203
|
+
}.property('layer').cacheable(),
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
The ID to use when trying to locate the layer in the DOM. If you do not
|
|
207
|
+
set the layerId explicitly, then the view's GUID will be used instead.
|
|
208
|
+
This ID must be set at the time the view is created.
|
|
209
|
+
|
|
210
|
+
@property {String}
|
|
211
|
+
@readOnly
|
|
212
|
+
*/
|
|
213
|
+
layerId: function(key, value) {
|
|
214
|
+
if (value) { this._layerId = value; }
|
|
215
|
+
if (this._layerId) { return this._layerId; }
|
|
216
|
+
return SC.guidFor(this) ;
|
|
217
|
+
}.property().cacheable(),
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
Attempts to discover the layer in the parent layer. The default
|
|
221
|
+
implementation looks for an element with an ID of layerId (or the view's
|
|
222
|
+
guid if layerId is null). You can override this method to provide your
|
|
223
|
+
own form of lookup. For example, if you want to discover your layer using
|
|
224
|
+
a CSS class name instead of an ID.
|
|
225
|
+
|
|
226
|
+
@param {DOMElement} parentLayer the parent's DOM layer
|
|
227
|
+
@returns {DOMElement} the discovered layer
|
|
228
|
+
*/
|
|
229
|
+
findLayerInParentLayer: function(parentLayer) {
|
|
230
|
+
var id = "#" + this.get('layerId');
|
|
231
|
+
return jQuery(id)[0] || jQuery(id, parentLayer)[0] ;
|
|
232
|
+
},
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
Returns YES if the receiver is a subview of a given view or if it's
|
|
236
|
+
identical to that view. Otherwise, it returns NO.
|
|
237
|
+
|
|
238
|
+
@property {SC.View} view
|
|
239
|
+
*/
|
|
240
|
+
isDescendantOf: function(view) {
|
|
241
|
+
var parentView = this.get('parentView');
|
|
242
|
+
|
|
243
|
+
if(this === view) { return YES; }
|
|
244
|
+
else if(parentView) { return parentView.isDescendantOf(view); }
|
|
245
|
+
else { return NO; }
|
|
246
|
+
},
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
This method is invoked whenever a display property changes. It will set
|
|
250
|
+
the layerNeedsUpdate method to YES. If you need to perform additional
|
|
251
|
+
setup whenever the display changes, you can override this method as well.
|
|
252
|
+
|
|
253
|
+
@returns {SC.View} receiver
|
|
254
|
+
*/
|
|
255
|
+
displayDidChange: function() {
|
|
256
|
+
this.set('layerNeedsUpdate', YES) ;
|
|
257
|
+
return this;
|
|
258
|
+
},
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
Setting this property to YES will cause the updateLayerIfNeeded method to
|
|
262
|
+
be invoked at the end of the runloop. You can also force a view to update
|
|
263
|
+
sooner by calling updateLayerIfNeeded() directly. The method will update
|
|
264
|
+
the layer only if this property is YES.
|
|
265
|
+
|
|
266
|
+
@property {Boolean}
|
|
267
|
+
@test in updateLayer
|
|
268
|
+
*/
|
|
269
|
+
layerNeedsUpdate: NO,
|
|
270
|
+
|
|
271
|
+
/** @private
|
|
272
|
+
Schedules the updateLayerIfNeeded method to run at the end of the runloop
|
|
273
|
+
if layerNeedsUpdate is set to YES.
|
|
274
|
+
*/
|
|
275
|
+
_view_layerNeedsUpdateDidChange: function() {
|
|
276
|
+
if (this.get('layerNeedsUpdate')) {
|
|
277
|
+
this.invokeOnce(this.updateLayerIfNeeded) ;
|
|
278
|
+
}
|
|
279
|
+
}.observes('layerNeedsUpdate'),
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
Updates the layer only if the view is visible onscreen and if
|
|
283
|
+
layerNeedsUpdate is set to YES. Normally you will not invoke this method
|
|
284
|
+
directly. Instead you set the layerNeedsUpdate property to YES and this
|
|
285
|
+
method will be called once at the end of the runloop.
|
|
286
|
+
|
|
287
|
+
If you need to update view's layer sooner than the end of the runloop, you
|
|
288
|
+
can call this method directly. If your view is not visible in the window
|
|
289
|
+
but you want it to update anyway, then call this method, passing YES for
|
|
290
|
+
the 'skipIsVisibleInWindowCheck' parameter.
|
|
291
|
+
|
|
292
|
+
You should not override this method. Instead override updateLayer() or
|
|
293
|
+
render().
|
|
294
|
+
|
|
295
|
+
@returns {SC.View} receiver
|
|
296
|
+
@test in updateLayer
|
|
297
|
+
*/
|
|
298
|
+
updateLayerIfNeeded: function(skipIsVisibleInWindowCheck) {
|
|
299
|
+
var needsUpdate = this.get('layerNeedsUpdate'),
|
|
300
|
+
shouldUpdate = needsUpdate && (skipIsVisibleInWindowCheck || this.get('isVisibleInWindow'));
|
|
301
|
+
if (shouldUpdate) {
|
|
302
|
+
// only update a layer if it already exists
|
|
303
|
+
if (this.get('layer')) {
|
|
304
|
+
this.beginPropertyChanges() ;
|
|
305
|
+
this.set('layerNeedsUpdate', NO) ;
|
|
306
|
+
this.updateLayer() ;
|
|
307
|
+
this.endPropertyChanges() ;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return this ;
|
|
312
|
+
},
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
This is the core method invoked to update a view layer whenever it has
|
|
316
|
+
changed. This method simply creates a render context focused on the
|
|
317
|
+
layer element and then calls your render() method.
|
|
318
|
+
|
|
319
|
+
You will not usually call or override this method directly. Instead you
|
|
320
|
+
should set the layerNeedsUpdate property to YES to cause this method to
|
|
321
|
+
run at the end of the run loop, or you can call updateLayerIfNeeded()
|
|
322
|
+
to force the layer to update immediately.
|
|
323
|
+
|
|
324
|
+
Instead of overriding this method, consider overidding the render() method
|
|
325
|
+
instead, which is called both when creating and updating a layer. If you
|
|
326
|
+
do not want your render() method called when updating a layer, then you
|
|
327
|
+
should override this method instead.
|
|
328
|
+
|
|
329
|
+
@param optionalContext provided only for backwards-compatibility.
|
|
330
|
+
|
|
331
|
+
@returns {SC.View} receiver
|
|
332
|
+
*/
|
|
333
|
+
updateLayer: function(optionalContext) {
|
|
334
|
+
var mixins, idx, len, hasLegacyRenderMethod;
|
|
335
|
+
|
|
336
|
+
var context = optionalContext || this.renderContext(this.get('layer')) ;
|
|
337
|
+
this._renderLayerSettings(context, NO);
|
|
338
|
+
|
|
339
|
+
// If the render method takes two parameters, we assume that it is a
|
|
340
|
+
// legacy implementation that takes context and firstTime. If it has only
|
|
341
|
+
// one parameter, we assume it is the render delegates style that requires
|
|
342
|
+
// only context. Note that, for backwards compatibility, the default
|
|
343
|
+
// SC.View implementation of render uses the old style.
|
|
344
|
+
hasLegacyRenderMethod = !this.update;
|
|
345
|
+
// Call render with firstTime set to NO to indicate an update, rather than
|
|
346
|
+
// full re-render, should be performed.
|
|
347
|
+
if (hasLegacyRenderMethod) {
|
|
348
|
+
this.render(context, NO);
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
this.update(context.$());
|
|
352
|
+
}
|
|
353
|
+
if (mixins = this.renderMixin) {
|
|
354
|
+
len = mixins.length;
|
|
355
|
+
for(idx=0; idx<len; ++idx) { mixins[idx].call(this, context, NO) ; }
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
context.update() ;
|
|
359
|
+
if (context._innerHTMLReplaced) {
|
|
360
|
+
var pane = this.get('pane');
|
|
361
|
+
if(pane && pane.get('isPaneAttached')) {
|
|
362
|
+
this._notifyDidAppendToDocument();
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// If this view uses static layout, then notify that the frame (likely)
|
|
367
|
+
// changed.
|
|
368
|
+
if (this.useStaticLayout) { this.viewDidResize(); }
|
|
369
|
+
|
|
370
|
+
if (this.didUpdateLayer) { this.didUpdateLayer(); } // call to update DOM
|
|
371
|
+
if(this.designer && this.designer.viewDidUpdateLayer) {
|
|
372
|
+
this.designer.viewDidUpdateLayer(); //let the designer know
|
|
373
|
+
}
|
|
374
|
+
return this ;
|
|
375
|
+
},
|
|
376
|
+
|
|
377
|
+
parentViewDidResize: function() {
|
|
378
|
+
this.viewDidResize();
|
|
379
|
+
},
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
Override this in a child class to define behavior that should be invoked
|
|
383
|
+
when a parent's view was resized.
|
|
384
|
+
*/
|
|
385
|
+
viewDidResize: function() {},
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
Creates a new renderContext with the passed tagName or element. You
|
|
389
|
+
can override this method to provide further customization to the context
|
|
390
|
+
if needed. Normally you will not need to call or override this method.
|
|
391
|
+
|
|
392
|
+
@returns {SC.RenderContext}
|
|
393
|
+
*/
|
|
394
|
+
renderContext: function(tagNameOrElement) {
|
|
395
|
+
return SC.RenderContext(tagNameOrElement) ;
|
|
396
|
+
},
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
Creates the layer by creating a renderContext and invoking the view's
|
|
400
|
+
render() method. This will only create the layer if the layer does not
|
|
401
|
+
already exist.
|
|
402
|
+
|
|
403
|
+
When you create a layer, it is expected that your render() method will
|
|
404
|
+
also render the HTML for all child views as well. This method will
|
|
405
|
+
notify the view along with any of its childViews that its layer has been
|
|
406
|
+
created.
|
|
407
|
+
|
|
408
|
+
@returns {SC.View} receiver
|
|
409
|
+
*/
|
|
410
|
+
createLayer: function() {
|
|
411
|
+
if (this.get('layer')) { return this ; } // nothing to do
|
|
412
|
+
|
|
413
|
+
var context = this.renderContext(this.get('tagName')) ;
|
|
414
|
+
|
|
415
|
+
// now prepare the content like normal.
|
|
416
|
+
this.renderToContext(context) ;
|
|
417
|
+
this.set('layer', context.element()) ;
|
|
418
|
+
|
|
419
|
+
// now notify the view and its child views..
|
|
420
|
+
this._notifyDidCreateLayer() ;
|
|
421
|
+
|
|
422
|
+
return this ;
|
|
423
|
+
},
|
|
424
|
+
|
|
425
|
+
/** @private -
|
|
426
|
+
Invokes the receivers didCreateLayer() method if it exists and then
|
|
427
|
+
invokes the same on all child views.
|
|
428
|
+
*/
|
|
429
|
+
_notifyDidCreateLayer: function() {
|
|
430
|
+
this.notifyPropertyChange("layer");
|
|
431
|
+
if (this.didCreateLayer) { this.didCreateLayer() ; }
|
|
432
|
+
|
|
433
|
+
// and notify others
|
|
434
|
+
var mixins = this.didCreateLayerMixin, len, idx,
|
|
435
|
+
childViews = this.get('childViews'),
|
|
436
|
+
childView;
|
|
437
|
+
if (mixins) {
|
|
438
|
+
len = mixins.length ;
|
|
439
|
+
for (idx=0; idx<len; ++idx) { mixins[idx].call(this) ; }
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
len = childViews.length ;
|
|
443
|
+
for (idx=0; idx<len; ++idx) {
|
|
444
|
+
childView = childViews[idx];
|
|
445
|
+
if (!childView) { continue; }
|
|
446
|
+
|
|
447
|
+
// A parent view creating a layer might result in the creation of a
|
|
448
|
+
// child view's DOM node being created via a render context without
|
|
449
|
+
// createLayer() being invoked on the child. In such cases, if anyone
|
|
450
|
+
// had requested 'layer' and it was cached as null, we need to
|
|
451
|
+
// invalidate it.
|
|
452
|
+
childView.notifyPropertyChange('layer');
|
|
453
|
+
|
|
454
|
+
childView._notifyDidCreateLayer() ;
|
|
455
|
+
}
|
|
456
|
+
},
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
Destroys any existing layer along with the layer for any child views as
|
|
460
|
+
well. If the view does not currently have a layer, then this method will
|
|
461
|
+
do nothing.
|
|
462
|
+
|
|
463
|
+
If you implement willDestroyLayer() on your view or if any mixins
|
|
464
|
+
implement willDestroLayerMixin(), then this method will be invoked on your
|
|
465
|
+
view before your layer is destroyed to give you a chance to clean up any
|
|
466
|
+
event handlers, etc.
|
|
467
|
+
|
|
468
|
+
If you write a willDestroyLayer() handler, you can assume that your
|
|
469
|
+
didCreateLayer() handler was called earlier for the same layer.
|
|
470
|
+
|
|
471
|
+
Normally you will not call or override this method yourself, but you may
|
|
472
|
+
want to implement the above callbacks when it is run.
|
|
473
|
+
|
|
474
|
+
@returns {SC.View} receiver
|
|
475
|
+
*/
|
|
476
|
+
destroyLayer: function() {
|
|
477
|
+
var layer = this.get('layer') ;
|
|
478
|
+
if (layer) {
|
|
479
|
+
|
|
480
|
+
// Now notify the view and its child views. It will also set the
|
|
481
|
+
// layer property to null.
|
|
482
|
+
this._notifyWillDestroyLayer() ;
|
|
483
|
+
|
|
484
|
+
// do final cleanup
|
|
485
|
+
if (layer.parentNode) { layer.parentNode.removeChild(layer) ; }
|
|
486
|
+
layer = null ;
|
|
487
|
+
}
|
|
488
|
+
return this ;
|
|
489
|
+
},
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
Destroys and recreates the current layer. This can be more efficient than
|
|
493
|
+
modifying individual child views.
|
|
494
|
+
|
|
495
|
+
@returns {SC.View} receiver
|
|
496
|
+
*/
|
|
497
|
+
replaceLayer: function() {
|
|
498
|
+
this.destroyLayer();
|
|
499
|
+
//this.set('layerLocationNeedsUpdate', YES) ;
|
|
500
|
+
this.invokeOnce(this.updateLayerLocation) ;
|
|
501
|
+
},
|
|
502
|
+
|
|
503
|
+
/** @private -
|
|
504
|
+
Invokes willDestroyLayer() on view and child views. Then sets layer to
|
|
505
|
+
null for receiver.
|
|
506
|
+
*/
|
|
507
|
+
_notifyWillDestroyLayer: function() {
|
|
508
|
+
if (this.willDestroyLayer) { this.willDestroyLayer() ; }
|
|
509
|
+
var mixins = this.willDestroyLayerMixin, len, idx,
|
|
510
|
+
childViews = this.get('childViews') ;
|
|
511
|
+
if (mixins) {
|
|
512
|
+
len = mixins.length ;
|
|
513
|
+
for (idx=0; idx<len; ++idx) { mixins[idx].call(this) ; }
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
len = childViews.length ;
|
|
517
|
+
for (idx=0; idx<len; ++idx) { childViews[idx]._notifyWillDestroyLayer() ; }
|
|
518
|
+
|
|
519
|
+
this.set('layer', null) ;
|
|
520
|
+
},
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
@private
|
|
526
|
+
|
|
527
|
+
Renders to a context.
|
|
528
|
+
Rendering only happens for the initial rendering. Further updates happen in updateLayer,
|
|
529
|
+
and are not done to contexts, but to layers.
|
|
530
|
+
Note: You should not generally override nor directly call this method. This method is only
|
|
531
|
+
called by createLayer to set up the layer initially, and by renderChildViews, to write to
|
|
532
|
+
a context.
|
|
533
|
+
|
|
534
|
+
@param {SC.RenderContext} context the render context.
|
|
535
|
+
@param {Boolean} firstTime Provided for compatibility when rendering legacy views only.
|
|
536
|
+
*/
|
|
537
|
+
renderToContext: function(context, firstTime) {
|
|
538
|
+
var hasLegacyRenderMethod, mixins, idx, len;
|
|
539
|
+
|
|
540
|
+
this.beginPropertyChanges() ;
|
|
541
|
+
this.set('layerNeedsUpdate', NO) ;
|
|
542
|
+
|
|
543
|
+
if (SC.none(firstTime)) { firstTime = YES; }
|
|
544
|
+
|
|
545
|
+
this._renderLayerSettings(context, firstTime);
|
|
546
|
+
|
|
547
|
+
// If the render method takes two parameters, we assume that it is a
|
|
548
|
+
// legacy implementation that takes context and firstTime. If it has only
|
|
549
|
+
// one parameter, we assume it is the render delegates style that requires
|
|
550
|
+
// only context. Note that, for backwards compatibility, the default
|
|
551
|
+
// SC.View implementation of render uses the old style.
|
|
552
|
+
hasLegacyRenderMethod = !this.update;
|
|
553
|
+
|
|
554
|
+
// Let the render method handle rendering. If we have a render delegate
|
|
555
|
+
// object set, it will be used there.
|
|
556
|
+
if (hasLegacyRenderMethod) {
|
|
557
|
+
this.render(context, firstTime);
|
|
558
|
+
}
|
|
559
|
+
// This view implements the render delegate protocol.
|
|
560
|
+
else {
|
|
561
|
+
if (firstTime) {
|
|
562
|
+
this.render(context);
|
|
563
|
+
} else {
|
|
564
|
+
this.update(context.$());
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
if (firstTime && !this._didRenderChildViews) { this.renderChildViews(context, firstTime); }
|
|
569
|
+
|
|
570
|
+
if (mixins = this.renderMixin) {
|
|
571
|
+
len = mixins.length;
|
|
572
|
+
for(idx=0; idx<len; ++idx) { mixins[idx].call(this, context, firstTime) ; }
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
this.endPropertyChanges() ;
|
|
576
|
+
},
|
|
577
|
+
|
|
578
|
+
_renderLayerSettings: function(context, firstTime) {
|
|
579
|
+
context.resetClassNames();
|
|
580
|
+
context.resetStyles();
|
|
581
|
+
|
|
582
|
+
this.applyAttributesToContext(context);
|
|
583
|
+
},
|
|
584
|
+
|
|
585
|
+
applyAttributesToContext: function(context) {
|
|
586
|
+
context.addClass(this.get('classNames'));
|
|
587
|
+
|
|
588
|
+
var cursor = this.get('cursor');
|
|
589
|
+
if (cursor) { context.addClass(cursor.get('className')); }
|
|
590
|
+
|
|
591
|
+
if (this.get('isTextSelectable')) { context.addClass('allow-select'); }
|
|
592
|
+
if (!this.get('isVisible')) { context.addClass('hidden'); }
|
|
593
|
+
if (this.get('isFirstResponder')) { context.addClass('focus'); }
|
|
594
|
+
|
|
595
|
+
context.id(this.get('layerId'));
|
|
596
|
+
context.attr('role', this.get('ariaRole'));
|
|
597
|
+
},
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
@private
|
|
601
|
+
|
|
602
|
+
Invoked by createLayer() and updateLayer() to actually render a context.
|
|
603
|
+
This method calls the render() method on your view along with any
|
|
604
|
+
renderMixin() methods supplied by mixins you might have added.
|
|
605
|
+
|
|
606
|
+
You should not override this method directly. Nor should you call it. It is OLD.
|
|
607
|
+
|
|
608
|
+
@param {SC.RenderContext} context the render context
|
|
609
|
+
@param {Boolean} firstTime YES if this is creating a layer
|
|
610
|
+
@returns {void}
|
|
611
|
+
*/
|
|
612
|
+
prepareContext: function(context, firstTime) {
|
|
613
|
+
// eventually, firstTime will be removed because it is ugly.
|
|
614
|
+
// for now, we will sense whether we are doing things the ugly way or not.
|
|
615
|
+
// if ugly, we will allow updates through.
|
|
616
|
+
if (firstTime !== false) { firstTime = YES; } // the GOOD code path :)
|
|
617
|
+
|
|
618
|
+
if (firstTime) {
|
|
619
|
+
this.renderToContext(context);
|
|
620
|
+
} else {
|
|
621
|
+
this.updateLayer(context);
|
|
622
|
+
}
|
|
623
|
+
},
|
|
624
|
+
|
|
625
|
+
/**
|
|
626
|
+
Your render method should invoke this method to render any child views,
|
|
627
|
+
especially if this is the first time the view will be rendered. This will
|
|
628
|
+
walk down the childView chain, rendering all of the children in a nested
|
|
629
|
+
way.
|
|
630
|
+
|
|
631
|
+
@param {SC.RenderContext} context the context
|
|
632
|
+
@param {Boolean} firstName true if the layer is being created
|
|
633
|
+
@returns {SC.RenderContext} the render context
|
|
634
|
+
@test in render
|
|
635
|
+
*/
|
|
636
|
+
renderChildViews: function(context, firstTime) {
|
|
637
|
+
var cv = this.get('childViews'), len = cv.length, idx, view ;
|
|
638
|
+
for (idx=0; idx<len; ++idx) {
|
|
639
|
+
view = cv[idx] ;
|
|
640
|
+
if (!view) { continue; }
|
|
641
|
+
context = context.begin(view.get('tagName')) ;
|
|
642
|
+
view.renderToContext(context, firstTime);
|
|
643
|
+
context = context.end() ;
|
|
644
|
+
}
|
|
645
|
+
return context;
|
|
646
|
+
},
|
|
647
|
+
|
|
648
|
+
/** @private -
|
|
649
|
+
override to add support for theming or in your view
|
|
650
|
+
*/
|
|
651
|
+
render: function() { },
|
|
652
|
+
|
|
653
|
+
/** @private -
|
|
654
|
+
Invokes the receivers didAppendLayerToDocument() method if it exists and
|
|
655
|
+
then invokes the same on all child views.
|
|
656
|
+
*/
|
|
657
|
+
|
|
658
|
+
_notifyDidAppendToDocument: function() {
|
|
659
|
+
if (this.didAppendToDocument) { this.didAppendToDocument(); }
|
|
660
|
+
|
|
661
|
+
var i=0, child, childLen, children = this.get('childViews');
|
|
662
|
+
for(i=0, childLen=children.length; i<childLen; i++) {
|
|
663
|
+
child = children[i];
|
|
664
|
+
if(child._notifyDidAppendToDocument){
|
|
665
|
+
child._notifyDidAppendToDocument();
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
},
|
|
669
|
+
|
|
670
|
+
childViewsObserver: function(){
|
|
671
|
+
var childViews = this.get('childViews'), i, iLen, child;
|
|
672
|
+
for(i=0, iLen = childViews.length; i<iLen; i++){
|
|
673
|
+
child = childViews[i];
|
|
674
|
+
if(child._notifyDidAppendToDocument){
|
|
675
|
+
child._notifyDidAppendToDocument();
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
}.observes('childViews'),
|
|
679
|
+
|
|
680
|
+
// ..........................................................
|
|
681
|
+
// STANDARD RENDER PROPERTIES
|
|
682
|
+
//
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
Tag name for the view's outer element. The tag name is only used when
|
|
686
|
+
a layer is first created. If you change the tagName for an element, you
|
|
687
|
+
must destroy and recreate the view layer.
|
|
688
|
+
|
|
689
|
+
@property {String}
|
|
690
|
+
*/
|
|
691
|
+
tagName: 'div',
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
The WAI-ARIA role of the control represented by this view. For example, a
|
|
695
|
+
button may have a role of type 'button', or a pane may have a role of
|
|
696
|
+
type 'alertdialog'. This property is used by assistive software to help
|
|
697
|
+
visually challenged users navigate rich web applications.
|
|
698
|
+
|
|
699
|
+
The full list of valid WAI-ARIA roles is available at:
|
|
700
|
+
http://www.w3.org/TR/wai-aria/roles#roles_categorization
|
|
701
|
+
|
|
702
|
+
@property {String}
|
|
703
|
+
*/
|
|
704
|
+
ariaRole: null,
|
|
705
|
+
|
|
706
|
+
/**
|
|
707
|
+
Standard CSS class names to apply to the view's outer element. This
|
|
708
|
+
property automatically inherits any class names defined by the view's
|
|
709
|
+
superclasses as well.
|
|
710
|
+
|
|
711
|
+
@property {Array}
|
|
712
|
+
*/
|
|
713
|
+
classNames: ['sc-view'],
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
Tool tip property that will be set to the title attribute on the HTML
|
|
717
|
+
rendered element.
|
|
718
|
+
|
|
719
|
+
@property {String}
|
|
720
|
+
*/
|
|
721
|
+
toolTip: null,
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
The computed tooltip. This is generated by localizing the toolTip
|
|
725
|
+
property if necessary.
|
|
726
|
+
|
|
727
|
+
@property {String}
|
|
728
|
+
*/
|
|
729
|
+
displayToolTip: function() {
|
|
730
|
+
var ret = this.get('toolTip');
|
|
731
|
+
return (ret && this.get('localize')) ? ret.loc() : (ret || '');
|
|
732
|
+
}.property('toolTip','localize').cacheable(),
|
|
733
|
+
|
|
734
|
+
/**
|
|
735
|
+
Determines if the user can select text within the view. Normally this is
|
|
736
|
+
set to NO to disable text selection. You should set this to YES if you
|
|
737
|
+
are creating a view that includes editable text. Otherwise, settings this
|
|
738
|
+
to YES will probably make your controls harder to use and it is not
|
|
739
|
+
recommended.
|
|
740
|
+
|
|
741
|
+
@property {Boolean}
|
|
742
|
+
@readOnly
|
|
743
|
+
*/
|
|
744
|
+
isTextSelectable: NO,
|
|
745
|
+
|
|
746
|
+
/**
|
|
747
|
+
You can set this array to include any properties that should immediately
|
|
748
|
+
invalidate the display. The display will be automatically invalidated
|
|
749
|
+
when one of these properties change.
|
|
750
|
+
|
|
751
|
+
These are the properties that will be visible to any Render Delegate.
|
|
752
|
+
When the RenderDelegate asks for a property it needs, the view checks the
|
|
753
|
+
displayProperties array. It first looks for the property name prefixed
|
|
754
|
+
by 'display'; for instance, if the render delegate needs a 'title',
|
|
755
|
+
the view will attempt to find 'displayTitle'. If there is no 'displayTitle'
|
|
756
|
+
in displayProperties, the view will then try 'title'. If 'title' is not
|
|
757
|
+
in displayProperties either, an error will be thrown.
|
|
758
|
+
|
|
759
|
+
This allows you to avoid collisions between your view's API and the Render
|
|
760
|
+
Delegate's API.
|
|
761
|
+
|
|
762
|
+
Implementation note: 'isVisible' is also effectively a display property,
|
|
763
|
+
but it is not declared as such because the same effect is implemented
|
|
764
|
+
inside _sc_isVisibleDidChange(). This avoids having two observers on
|
|
765
|
+
'isVisible', which is:
|
|
766
|
+
a. More efficient
|
|
767
|
+
b. More correct, because we can guarantee the order of operations
|
|
768
|
+
|
|
769
|
+
@property {Array}
|
|
770
|
+
@readOnly
|
|
771
|
+
*/
|
|
772
|
+
displayProperties: ['isFirstResponder'],
|
|
773
|
+
|
|
774
|
+
// .......................................................
|
|
775
|
+
// SC.RESPONDER SUPPORT
|
|
776
|
+
//
|
|
777
|
+
|
|
778
|
+
/** @property
|
|
779
|
+
The nextResponder is usually the parentView.
|
|
780
|
+
*/
|
|
781
|
+
nextResponder: function() {
|
|
782
|
+
return this.get('parentView') ;
|
|
783
|
+
}.property('parentView').cacheable(),
|
|
784
|
+
|
|
785
|
+
|
|
786
|
+
/** @property
|
|
787
|
+
Set to YES if your view is willing to accept first responder status. This
|
|
788
|
+
is used when calculcating key responder loop.
|
|
789
|
+
*/
|
|
790
|
+
acceptsFirstResponder: NO,
|
|
791
|
+
|
|
792
|
+
// .......................................................
|
|
793
|
+
// CORE DISPLAY METHODS
|
|
794
|
+
//
|
|
795
|
+
|
|
796
|
+
/** @private
|
|
797
|
+
Setup a view, but do not finish waking it up.
|
|
798
|
+
- configure childViews
|
|
799
|
+
- Determine the view's theme
|
|
800
|
+
- Fetch a render delegate from the theme, if necessary
|
|
801
|
+
- register the view with the global views hash, which is used for event
|
|
802
|
+
dispatch
|
|
803
|
+
*/
|
|
804
|
+
init: function() {
|
|
805
|
+
var parentView = this.get('parentView'),
|
|
806
|
+
path, root, lp, displayProperties ;
|
|
807
|
+
|
|
808
|
+
sc_super();
|
|
809
|
+
|
|
810
|
+
// Register the view for event handling. This hash is used by
|
|
811
|
+
// SC.RootResponder to dispatch incoming events.
|
|
812
|
+
SC.View.views[this.get('layerId')] = this;
|
|
813
|
+
|
|
814
|
+
// setup child views. be sure to clone the child views array first
|
|
815
|
+
this.childViews = this.get('childViews').slice() ;
|
|
816
|
+
this.createChildViews() ; // setup child Views
|
|
817
|
+
|
|
818
|
+
// register display property observers ..
|
|
819
|
+
// TODO: Optimize into class setup
|
|
820
|
+
displayProperties = this.get('displayProperties') ;
|
|
821
|
+
for(var i=0, l=displayProperties.length; i<l; i++) {
|
|
822
|
+
this.addObserver(displayProperties[i], this, this.displayDidChange);
|
|
823
|
+
}
|
|
824
|
+
},
|
|
825
|
+
|
|
826
|
+
/**
|
|
827
|
+
Wakes up the view. The default implementation immediately syncs any
|
|
828
|
+
bindings, which may cause the view to need its display updated. You
|
|
829
|
+
can override this method to perform any additional setup. Be sure to
|
|
830
|
+
call sc_super to setup bindings and to call awake on childViews.
|
|
831
|
+
|
|
832
|
+
It is best to awake a view before you add it to the DOM. This way when
|
|
833
|
+
the DOM is generated, it will have the correct initial values and will
|
|
834
|
+
not require any additional setup.
|
|
835
|
+
|
|
836
|
+
@returns {void}
|
|
837
|
+
*/
|
|
838
|
+
awake: function() {
|
|
839
|
+
sc_super();
|
|
840
|
+
var childViews = this.get('childViews'), len = childViews.length, idx ;
|
|
841
|
+
for (idx=0; idx<len; ++idx) {
|
|
842
|
+
if (!childViews[idx]) { continue ; }
|
|
843
|
+
childViews[idx].awake() ;
|
|
844
|
+
}
|
|
845
|
+
},
|
|
846
|
+
|
|
847
|
+
/**
|
|
848
|
+
Removes the child view from the parent view.
|
|
849
|
+
|
|
850
|
+
@param {SC.View} view
|
|
851
|
+
@returns {SC.View} receiver
|
|
852
|
+
*/
|
|
853
|
+
removeChild: function(view) {
|
|
854
|
+
// update parent node
|
|
855
|
+
view.set('parentView', null) ;
|
|
856
|
+
|
|
857
|
+
// remove view from childViews array.
|
|
858
|
+
var childViews = this.get('childViews'),
|
|
859
|
+
idx = childViews.indexOf(view) ;
|
|
860
|
+
if (idx>=0) { childViews.removeAt(idx); }
|
|
861
|
+
|
|
862
|
+
return this ;
|
|
863
|
+
},
|
|
864
|
+
|
|
865
|
+
/**
|
|
866
|
+
Removes all children from the parentView.
|
|
867
|
+
|
|
868
|
+
@returns {SC.View} receiver
|
|
869
|
+
*/
|
|
870
|
+
removeAllChildren: function() {
|
|
871
|
+
var childViews = this.get('childViews'), view ;
|
|
872
|
+
while (view = childViews.objectAt(childViews.get('length')-1)) {
|
|
873
|
+
this.removeChild(view) ;
|
|
874
|
+
}
|
|
875
|
+
return this ;
|
|
876
|
+
},
|
|
877
|
+
|
|
878
|
+
/**
|
|
879
|
+
Removes the view from its parentView, if one is found. Otherwise
|
|
880
|
+
does nothing.
|
|
881
|
+
|
|
882
|
+
@returns {SC.View} receiver
|
|
883
|
+
*/
|
|
884
|
+
removeFromParent: function() {
|
|
885
|
+
var parent = this.get('parentView') ;
|
|
886
|
+
if (parent) { parent.removeChild(this) ; }
|
|
887
|
+
return this ;
|
|
888
|
+
},
|
|
889
|
+
|
|
890
|
+
/**
|
|
891
|
+
You must call this method on a view to destroy the view (and all of its
|
|
892
|
+
child views). This will remove the view from any parent node, then make
|
|
893
|
+
sure that the DOM element managed by the view can be released by the
|
|
894
|
+
memory manager.
|
|
895
|
+
*/
|
|
896
|
+
destroy: function() {
|
|
897
|
+
if (this.get('isDestroyed')) { return this; } // nothing to do
|
|
898
|
+
|
|
899
|
+
this._destroy(); // core destroy method
|
|
900
|
+
|
|
901
|
+
// remove from parent if found
|
|
902
|
+
if (this.get('parentView')) { this.removeFromParent(); }
|
|
903
|
+
|
|
904
|
+
//Do generic destroy. It takes care of mixins and sets isDestroyed to YES.
|
|
905
|
+
sc_super();
|
|
906
|
+
return this; // done with cleanup
|
|
907
|
+
},
|
|
908
|
+
|
|
909
|
+
_destroy: function() {
|
|
910
|
+
if (this.get('isDestroyed')) { return this ; } // nothing to do
|
|
911
|
+
|
|
912
|
+
// destroy the layer -- this will avoid each child view destroying
|
|
913
|
+
// the layer over and over again...
|
|
914
|
+
this.destroyLayer() ;
|
|
915
|
+
|
|
916
|
+
// first destroy any children.
|
|
917
|
+
var childViews = this.get('childViews'), len = childViews.length, idx ;
|
|
918
|
+
if (len) {
|
|
919
|
+
childViews = childViews.slice() ;
|
|
920
|
+
for (idx=0; idx<len; ++idx) { childViews[idx].destroy() ; }
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
// next remove view from global hash
|
|
924
|
+
delete SC.View.views[this.get('layerId')] ;
|
|
925
|
+
delete this._CQ ;
|
|
926
|
+
delete this.page ;
|
|
927
|
+
|
|
928
|
+
return this ;
|
|
929
|
+
},
|
|
930
|
+
|
|
931
|
+
/**
|
|
932
|
+
This method is called when your view is first created to setup any child
|
|
933
|
+
views that are already defined on your class. If any are found, it will
|
|
934
|
+
instantiate them for you.
|
|
935
|
+
|
|
936
|
+
The default implementation of this method simply steps through your
|
|
937
|
+
childViews array, which is expects to either be empty or to contain View
|
|
938
|
+
designs that can be instantiated
|
|
939
|
+
|
|
940
|
+
Alternatively, you can implement this method yourself in your own
|
|
941
|
+
subclasses to look for views defined on specific properties and then build
|
|
942
|
+
a childViews array yourself.
|
|
943
|
+
|
|
944
|
+
Note that when you implement this method yourself, you should never
|
|
945
|
+
instantiate views directly. Instead, you should use
|
|
946
|
+
this.createChildView() method instead. This method can be much faster in
|
|
947
|
+
a production environment than creating views yourself.
|
|
948
|
+
|
|
949
|
+
@returns {SC.View} receiver
|
|
950
|
+
*/
|
|
951
|
+
createChildViews: function() {
|
|
952
|
+
var childViews = this.get('childViews'),
|
|
953
|
+
len = childViews.length,
|
|
954
|
+
idx, key, views, view ;
|
|
955
|
+
|
|
956
|
+
this.beginPropertyChanges() ;
|
|
957
|
+
|
|
958
|
+
// swap the array
|
|
959
|
+
for (idx=0; idx<len; ++idx) {
|
|
960
|
+
if (key = (view = childViews[idx])) {
|
|
961
|
+
|
|
962
|
+
// is this is a key name, lookup view class
|
|
963
|
+
if (typeof key === SC.T_STRING) {
|
|
964
|
+
view = this[key];
|
|
965
|
+
} else {
|
|
966
|
+
key = null ;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
if (!view) {
|
|
970
|
+
console.error ("No view with name "+key+" has been found in "+this.toString());
|
|
971
|
+
// skip this one.
|
|
972
|
+
continue;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
// createChildView creates the view if necessary, but also sets
|
|
976
|
+
// important properties, such as parentView
|
|
977
|
+
view = this.createChildView(view) ;
|
|
978
|
+
if (key) { this[key] = view ; } // save on key name if passed
|
|
979
|
+
}
|
|
980
|
+
childViews[idx] = view;
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
this.endPropertyChanges() ;
|
|
984
|
+
return this ;
|
|
985
|
+
},
|
|
986
|
+
|
|
987
|
+
/**
|
|
988
|
+
Instantiates a view to be added to the childViews array during view
|
|
989
|
+
initialization. You generally will not call this method directly unless
|
|
990
|
+
you are overriding createChildViews(). Note that this method will
|
|
991
|
+
automatically configure the correct settings on the new view instance to
|
|
992
|
+
act as a child of the parent.
|
|
993
|
+
|
|
994
|
+
@param {Class} viewClass
|
|
995
|
+
@param {Hash} attrs optional attributes to add
|
|
996
|
+
@returns {SC.View} new instance
|
|
997
|
+
@test in createChildViews
|
|
998
|
+
*/
|
|
999
|
+
createChildView: function(view, attrs) {
|
|
1000
|
+
if (!view.isClass) {
|
|
1001
|
+
attrs = view;
|
|
1002
|
+
} else {
|
|
1003
|
+
// attrs should always exist...
|
|
1004
|
+
if (!attrs) { attrs = {} ; }
|
|
1005
|
+
// clone the hash that was given so we dont pollute it if it's being reused
|
|
1006
|
+
else { attrs = SC.clone(attrs); }
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
attrs.owner = attrs.parentView = this ;
|
|
1010
|
+
attrs.isVisibleInWindow = this.get('isVisibleInWindow');
|
|
1011
|
+
if (!attrs.page) { attrs.page = this.page ; }
|
|
1012
|
+
|
|
1013
|
+
// Now add this to the attributes and create.
|
|
1014
|
+
if (view.isClass) { view = view.create(attrs); }
|
|
1015
|
+
return view ;
|
|
1016
|
+
},
|
|
1017
|
+
|
|
1018
|
+
/** walk like a duck */
|
|
1019
|
+
isView: YES,
|
|
1020
|
+
|
|
1021
|
+
/**
|
|
1022
|
+
Default method called when a selectstart event is triggered. This event is
|
|
1023
|
+
only supported by IE. Used in sproutcore to disable text selection and
|
|
1024
|
+
IE8 accelerators. The accelerators will be enabled only in
|
|
1025
|
+
text selectable views. In FF and Safari we use the css style 'allow-select'.
|
|
1026
|
+
|
|
1027
|
+
If you want to enable text selection in certain controls is recommended
|
|
1028
|
+
to override this function to always return YES , instead of setting
|
|
1029
|
+
isTextSelectable to true.
|
|
1030
|
+
|
|
1031
|
+
For example in textfield you dont want to enable textSelection on the text
|
|
1032
|
+
hint only on the actual text you are entering. You can achieve that by
|
|
1033
|
+
only overriding this method.
|
|
1034
|
+
|
|
1035
|
+
@param evt {SC.Event} the selectstart event
|
|
1036
|
+
@returns YES if selectable
|
|
1037
|
+
*/
|
|
1038
|
+
selectStart: function(evt) {
|
|
1039
|
+
return this.get('isTextSelectable');
|
|
1040
|
+
},
|
|
1041
|
+
|
|
1042
|
+
/**
|
|
1043
|
+
Used to block the contextMenu per view.
|
|
1044
|
+
|
|
1045
|
+
@param evt {SC.Event} the contextmenu event
|
|
1046
|
+
@returns YES if the contextmenu can show up
|
|
1047
|
+
*/
|
|
1048
|
+
contextMenu: function(evt) {
|
|
1049
|
+
if(!this.get('isContextMenuEnabled')) evt.stop();
|
|
1050
|
+
return true;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
});
|
|
1054
|
+
|
|
1055
|
+
SC.CoreView.mixin(/** @scope SC.CoreView */ {
|
|
1056
|
+
|
|
1057
|
+
/** @private walk like a duck -- used by SC.Page */
|
|
1058
|
+
isViewClass: YES,
|
|
1059
|
+
|
|
1060
|
+
/**
|
|
1061
|
+
This method works just like extend() except that it will also preserve
|
|
1062
|
+
the passed attributes in case you want to use a view builder later, if
|
|
1063
|
+
needed.
|
|
1064
|
+
|
|
1065
|
+
@param {Hash} attrs Attributes to add to view
|
|
1066
|
+
@returns {Class} SC.View subclass to create
|
|
1067
|
+
@function
|
|
1068
|
+
*/
|
|
1069
|
+
design: function() {
|
|
1070
|
+
if (this.isDesign) { return this; } // only run design one time
|
|
1071
|
+
var ret = this.extend.apply(this, arguments);
|
|
1072
|
+
ret.isDesign = YES ;
|
|
1073
|
+
if (SC.ViewDesigner) {
|
|
1074
|
+
SC.ViewDesigner.didLoadDesign(ret, this, SC.A(arguments));
|
|
1075
|
+
}
|
|
1076
|
+
return ret ;
|
|
1077
|
+
},
|
|
1078
|
+
|
|
1079
|
+
extend: function() {
|
|
1080
|
+
var last = arguments[arguments.length - 1];
|
|
1081
|
+
|
|
1082
|
+
if (last && !SC.none(last.theme)) {
|
|
1083
|
+
last.themeName = last.theme;
|
|
1084
|
+
delete last.theme;
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
return SC.Object.extend.apply(this, arguments);
|
|
1088
|
+
},
|
|
1089
|
+
|
|
1090
|
+
/**
|
|
1091
|
+
Helper applies the layout to the prototype.
|
|
1092
|
+
*/
|
|
1093
|
+
layout: function(layout) {
|
|
1094
|
+
this.prototype.layout = layout ;
|
|
1095
|
+
return this ;
|
|
1096
|
+
},
|
|
1097
|
+
|
|
1098
|
+
/**
|
|
1099
|
+
Helper applies the classNames to the prototype
|
|
1100
|
+
*/
|
|
1101
|
+
classNames: function(sc) {
|
|
1102
|
+
sc = (this.prototype.classNames || []).concat(sc);
|
|
1103
|
+
this.prototype.classNames = sc;
|
|
1104
|
+
return this ;
|
|
1105
|
+
},
|
|
1106
|
+
|
|
1107
|
+
/**
|
|
1108
|
+
Help applies the tagName
|
|
1109
|
+
*/
|
|
1110
|
+
tagName: function(tg) {
|
|
1111
|
+
this.prototype.tagName = tg;
|
|
1112
|
+
return this ;
|
|
1113
|
+
},
|
|
1114
|
+
|
|
1115
|
+
/**
|
|
1116
|
+
Helper adds the childView
|
|
1117
|
+
*/
|
|
1118
|
+
childView: function(cv) {
|
|
1119
|
+
var childViews = this.prototype.childViews || [];
|
|
1120
|
+
if (childViews === this.superclass.prototype.childViews) {
|
|
1121
|
+
childViews = childViews.slice();
|
|
1122
|
+
}
|
|
1123
|
+
childViews.push(cv) ;
|
|
1124
|
+
this.prototype.childViews = childViews;
|
|
1125
|
+
return this ;
|
|
1126
|
+
},
|
|
1127
|
+
|
|
1128
|
+
/**
|
|
1129
|
+
Helper adds a binding to a design
|
|
1130
|
+
*/
|
|
1131
|
+
bind: function(keyName, path) {
|
|
1132
|
+
var p = this.prototype, s = this.superclass.prototype;
|
|
1133
|
+
var bindings = p._bindings ;
|
|
1134
|
+
if (!bindings || bindings === s._bindings) {
|
|
1135
|
+
bindings = p._bindings = (bindings || []).slice() ;
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
keyName = keyName + "Binding";
|
|
1139
|
+
p[keyName] = path ;
|
|
1140
|
+
bindings.push(keyName);
|
|
1141
|
+
|
|
1142
|
+
return this ;
|
|
1143
|
+
},
|
|
1144
|
+
|
|
1145
|
+
/**
|
|
1146
|
+
Helper sets a generic property on a design.
|
|
1147
|
+
*/
|
|
1148
|
+
prop: function(keyName, value) {
|
|
1149
|
+
this.prototype[keyName] = value;
|
|
1150
|
+
return this ;
|
|
1151
|
+
},
|
|
1152
|
+
|
|
1153
|
+
/**
|
|
1154
|
+
Used to construct a localization for a view. The default implementation
|
|
1155
|
+
will simply return the passed attributes.
|
|
1156
|
+
*/
|
|
1157
|
+
localization: function(attrs, rootElement) {
|
|
1158
|
+
// add rootElement
|
|
1159
|
+
if (rootElement) attrs.rootElement = SC.$(rootElement)[0];
|
|
1160
|
+
return attrs;
|
|
1161
|
+
},
|
|
1162
|
+
|
|
1163
|
+
/**
|
|
1164
|
+
Creates a view instance, first finding the DOM element you name and then
|
|
1165
|
+
using that as the root element. You should not use this method very
|
|
1166
|
+
often, but it is sometimes useful if you want to attach to already
|
|
1167
|
+
existing HTML.
|
|
1168
|
+
|
|
1169
|
+
@param {String|Element} element
|
|
1170
|
+
@param {Hash} attrs
|
|
1171
|
+
@returns {SC.View} instance
|
|
1172
|
+
*/
|
|
1173
|
+
viewFor: function(element, attrs) {
|
|
1174
|
+
var args = SC.$A(arguments); // prepare to edit
|
|
1175
|
+
if (SC.none(element)) {
|
|
1176
|
+
args.shift(); // remove if no element passed
|
|
1177
|
+
} else args[0] = { rootElement: SC.$(element)[0] } ;
|
|
1178
|
+
var ret = this.create.apply(this, arguments) ;
|
|
1179
|
+
args = args[0] = null;
|
|
1180
|
+
return ret ;
|
|
1181
|
+
},
|
|
1182
|
+
|
|
1183
|
+
/**
|
|
1184
|
+
Create a new view with the passed attributes hash. If you have the
|
|
1185
|
+
Designer module loaded, this will also create a peer designer if needed.
|
|
1186
|
+
*/
|
|
1187
|
+
create: function() {
|
|
1188
|
+
var last = arguments[arguments.length - 1];
|
|
1189
|
+
|
|
1190
|
+
if (last && last.theme) {
|
|
1191
|
+
last.themeName = last.theme;
|
|
1192
|
+
delete last.theme;
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
var C=this, ret = new C(arguments);
|
|
1196
|
+
if (SC.ViewDesigner) {
|
|
1197
|
+
SC.ViewDesigner.didCreateView(ret, SC.$A(arguments));
|
|
1198
|
+
}
|
|
1199
|
+
return ret ;
|
|
1200
|
+
},
|
|
1201
|
+
|
|
1202
|
+
/**
|
|
1203
|
+
Applies the passed localization hash to the component views. Call this
|
|
1204
|
+
method before you call create(). Returns the receiver. Typically you
|
|
1205
|
+
will do something like this:
|
|
1206
|
+
|
|
1207
|
+
view = SC.View.design({...}).loc(localizationHash).create();
|
|
1208
|
+
|
|
1209
|
+
@param {Hash} loc
|
|
1210
|
+
@param rootElement {String} optional rootElement with prepped HTML
|
|
1211
|
+
@returns {SC.View} receiver
|
|
1212
|
+
*/
|
|
1213
|
+
loc: function(loc) {
|
|
1214
|
+
var childLocs = loc.childViews;
|
|
1215
|
+
delete loc.childViews; // clear out child views before applying to attrs
|
|
1216
|
+
|
|
1217
|
+
this.applyLocalizedAttributes(loc) ;
|
|
1218
|
+
if (SC.ViewDesigner) {
|
|
1219
|
+
SC.ViewDesigner.didLoadLocalization(this, SC.$A(arguments));
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
// apply localization recursively to childViews
|
|
1223
|
+
var childViews = this.prototype.childViews, idx = childViews.length,
|
|
1224
|
+
viewClass;
|
|
1225
|
+
while(--idx>=0) {
|
|
1226
|
+
viewClass = childViews[idx];
|
|
1227
|
+
loc = childLocs[idx];
|
|
1228
|
+
if (loc && viewClass && viewClass.loc) viewClass.loc(loc) ;
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
return this; // done!
|
|
1232
|
+
},
|
|
1233
|
+
|
|
1234
|
+
/**
|
|
1235
|
+
Internal method actually updates the localizated attributes on the view
|
|
1236
|
+
class. This is overloaded in design mode to also save the attributes.
|
|
1237
|
+
*/
|
|
1238
|
+
applyLocalizedAttributes: function(loc) {
|
|
1239
|
+
SC.mixin(this.prototype, loc) ;
|
|
1240
|
+
},
|
|
1241
|
+
|
|
1242
|
+
views: {}
|
|
1243
|
+
|
|
1244
|
+
}) ;
|
|
1245
|
+
|
|
1246
|
+
// .......................................................
|
|
1247
|
+
// OUTLET BUILDER
|
|
1248
|
+
//
|
|
1249
|
+
|
|
1250
|
+
/**
|
|
1251
|
+
Generates a computed property that will look up the passed property path
|
|
1252
|
+
the first time you try to get the value. Use this whenever you want to
|
|
1253
|
+
define an outlet that points to another view or object. The root object
|
|
1254
|
+
used for the path will be the receiver.
|
|
1255
|
+
*/
|
|
1256
|
+
SC.outlet = function(path, root) {
|
|
1257
|
+
return function(key) {
|
|
1258
|
+
return (this[key] = SC.objectForPropertyPath(path, (root !== undefined) ? root : this)) ;
|
|
1259
|
+
}.property();
|
|
1260
|
+
};
|
|
1261
|
+
|
|
1262
|
+
/** @private on unload clear cached divs. */
|
|
1263
|
+
SC.CoreView.unload = function() {
|
|
1264
|
+
// delete view items this way to ensure the views are cleared. The hash
|
|
1265
|
+
// itself may be owned by multiple view subclasses.
|
|
1266
|
+
var views = SC.View.views;
|
|
1267
|
+
if (views) {
|
|
1268
|
+
for(var key in views) {
|
|
1269
|
+
if (!views.hasOwnProperty(key)) continue ;
|
|
1270
|
+
delete views[key];
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
} ;
|
|
1274
|
+
|
|
1275
|
+
SC.View = SC.CoreView.extend({});
|
|
1276
|
+
|
|
1277
|
+
//unload views for IE, trying to collect memory.
|
|
1278
|
+
if(SC.browser.msie) SC.Event.add(window, 'unload', SC.View, SC.View.unload) ;
|
|
1279
|
+
|
|
1280
|
+
|