opal 0.0.1 → 0.1.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/.gitignore +10 -1
- data/.gitmodules +0 -0
- data/Opalfile +371 -0
- data/README.md +45 -0
- data/Rakefile +237 -34
- data/VERSION +1 -1
- data/bin/opal +13 -0
- data/demos/apps/browser_demo/index.html +11 -0
- data/demos/apps/browser_demo/lib/browser_demo.rb +31 -0
- data/demos/apps/simple_opal/Opalfile +13 -0
- data/demos/apps/simple_opal/index.html +11 -0
- data/demos/apps/simple_opal/lib/app_controller.rb +62 -0
- data/demos/apps/simple_opal/lib/main_window.rb +146 -0
- data/demos/browser/request/index.html +52 -0
- data/demos/browser/request/request.rb +48 -0
- data/gen/browser/__PROJECT_NAME__/index.html +10 -0
- data/gen/browser/__PROJECT_NAME__/lib/__PROJECT_NAME__.rb +1 -0
- data/lib/opal.rb +48 -3
- data/lib/opal/builders/base.rb +50 -0
- data/lib/opal/builders/css.rb +46 -0
- data/lib/opal/builders/javascript.rb +44 -0
- data/lib/opal/builders/opal.rb +79 -0
- data/lib/opal/builders/ruby.rb +50 -0
- data/lib/opal/builders/ruby/generate.rb +1851 -0
- data/lib/opal/builders/ruby/nodes.rb +210 -0
- data/lib/opal/builders/ruby/ruby.rb +916 -0
- data/lib/opal/builders/ruby/ruby_parser.rb +6008 -0
- data/lib/opal/builders/ruby/ruby_parser.rb.y +1451 -0
- data/lib/opal/models/build_item.rb +104 -0
- data/lib/opal/models/hash_struct.rb +40 -0
- data/lib/opal/models/project.rb +215 -0
- data/lib/opal/models/struct_accessors.rb +58 -0
- data/lib/opal/models/target.rb +176 -0
- data/lib/opal/opal/env/console.rb +66 -0
- data/lib/opal/opal/env/fs.rb +98 -0
- data/lib/opal/opal/env/object.rb +48 -0
- data/lib/opal/opal/environment.rb +139 -0
- data/lib/opal/opal/gen.rb +62 -0
- data/lib/opal/opal/opal.rb +68 -0
- data/lib/opal/opal/repl.rb +38 -0
- data/lib/opal/opalfile/dsl.rb +62 -0
- data/lib/opal/opalfile/opalfile.rb +133 -0
- data/lib/opal/opalfile/task.rb +96 -0
- data/lib/opal/opalfile/task_manager.rb +63 -0
- data/lib/opal/opalfile/task_scope.rb +52 -0
- data/lib/opal/rack/app_server.rb +119 -0
- data/opals/aristo/README.md +16 -0
- data/opals/browser/Opalfile +11 -0
- data/opals/browser/README.md +146 -0
- data/opals/browser/SIZZLE_LICESNSE.txt +148 -0
- data/opals/browser/lib/browser.rb +118 -0
- data/opals/browser/lib/browser/builder.rb +41 -0
- data/opals/browser/lib/browser/canvas_context.rb +115 -0
- data/opals/browser/lib/browser/dimensions.rb +50 -0
- data/opals/browser/lib/browser/document.rb +146 -0
- data/opals/browser/lib/browser/element.rb +487 -0
- data/opals/browser/lib/browser/element/attributes.rb +88 -0
- data/opals/browser/lib/browser/element/css.rb +290 -0
- data/opals/browser/lib/browser/element/form.rb +146 -0
- data/opals/browser/lib/browser/event/dom_events.rb +81 -0
- data/opals/browser/lib/browser/event/event.rb +177 -0
- data/opals/browser/lib/browser/event/trigger_events.rb +53 -0
- data/opals/browser/lib/browser/geometry.rb +97 -0
- data/opals/browser/lib/browser/json.rb +32 -0
- data/opals/browser/lib/browser/json_parse.js +321 -0
- data/opals/browser/lib/browser/request/request.rb +201 -0
- data/opals/browser/lib/browser/sizzle.js +1068 -0
- data/opals/browser/lib/browser/string.rb +42 -0
- data/opals/browser/lib/browser/touch.rb +37 -0
- data/{runtime/yaml.js → opals/browser/lib/browser/vml_context.js} +8 -8
- data/opals/browser/lib/browser/window.rb +36 -0
- data/opals/browser/spec/browser/browser_detection_spec.rb +7 -0
- data/opals/browser/spec/document/aref_spec.rb +110 -0
- data/opals/browser/spec/document/ready_spec.rb +16 -0
- data/opals/browser/spec/element/body_spec.rb +11 -0
- data/opals/browser/spec/element/clear_spec.rb +26 -0
- data/opals/browser/spec/element/empty_spec.rb +29 -0
- data/opals/browser/spec/element/has_class_spec.rb +40 -0
- data/opals/browser/spec/element/hidden_spec.rb +23 -0
- data/opals/browser/spec/element/hide_spec.rb +31 -0
- data/opals/browser/spec/element/remove_spec.rb +25 -0
- data/opals/browser/spec/element/show_spec.rb +31 -0
- data/opals/browser/spec/element/style_spec.rb +69 -0
- data/opals/browser/spec/element/toggle_spec.rb +31 -0
- data/opals/browser/spec/element/visible_spec.rb +23 -0
- data/opals/browser/spec/spec_helper.rb +1 -0
- data/opals/cherry_kit/Opalfile +6 -0
- data/opals/cherry_kit/bin/cherry_kit.rb +11 -0
- data/opals/cherry_kit/lib/cherry_kit.rb +29 -0
- data/opals/foundation/Opalfile +11 -0
- data/opals/foundation/bin/foundation.rb +12 -0
- data/opals/foundation/lib/foundation.rb +32 -0
- data/opals/foundation/lib/foundation/__table_view_desktop/outline_view.rb +57 -0
- data/opals/foundation/lib/foundation/__table_view_desktop/table_column.rb +59 -0
- data/opals/foundation/lib/foundation/__table_view_desktop/table_header_view.rb +34 -0
- data/opals/foundation/lib/foundation/__table_view_desktop/table_view.rb +304 -0
- data/opals/foundation/lib/foundation/controllers/array_controller.rb +54 -0
- data/opals/foundation/lib/foundation/controllers/controller.rb +74 -0
- data/opals/foundation/lib/foundation/controllers/controller_selection_proxy.rb +67 -0
- data/opals/foundation/lib/foundation/controllers/object_controller.rb +145 -0
- data/opals/foundation/lib/foundation/controllers/view.rb +40 -0
- data/opals/foundation/lib/foundation/core/application.rb +476 -0
- data/opals/foundation/lib/foundation/core/attributes.rb +146 -0
- data/opals/foundation/lib/foundation/core/bindings.rb +125 -0
- data/opals/foundation/lib/foundation/core/builder.rb +101 -0
- data/opals/foundation/lib/foundation/core/event.rb +112 -0
- data/opals/foundation/lib/foundation/core/index_path.rb +49 -0
- data/opals/foundation/lib/foundation/core/index_set.rb +97 -0
- data/opals/foundation/lib/foundation/core/notification.rb +113 -0
- data/opals/foundation/lib/foundation/core/observable.rb +275 -0
- data/opals/foundation/lib/foundation/core/observable_array.rb +30 -0
- data/opals/foundation/lib/foundation/core/responder.rb +85 -0
- data/opals/foundation/lib/foundation/core/run_loop.rb +89 -0
- data/opals/foundation/lib/foundation/core/touch.rb +95 -0
- data/opals/foundation/lib/foundation/gestures/gesture_recognizer.rb +35 -0
- data/opals/foundation/lib/foundation/rendering/render_context.rb +100 -0
- data/opals/foundation/lib/foundation/rendering/renderer.rb +137 -0
- data/opals/foundation/lib/foundation/rendering/root_theme.rb +77 -0
- data/opals/foundation/lib/foundation/rendering/root_theme/button.rb +62 -0
- data/opals/foundation/lib/foundation/rendering/root_theme/control.rb +72 -0
- data/opals/foundation/lib/foundation/rendering/root_theme/label.rb +54 -0
- data/opals/foundation/lib/foundation/rendering/root_theme/scroller.rb +58 -0
- data/opals/foundation/lib/foundation/rendering/root_theme/slider.rb +72 -0
- data/opals/foundation/lib/foundation/rendering/root_theme/table_view.rb +97 -0
- data/opals/foundation/lib/foundation/rendering/root_theme/text_field.rb +55 -0
- data/opals/foundation/lib/foundation/rendering/root_theme/view.rb +81 -0
- data/opals/foundation/lib/foundation/rendering/theme.rb +38 -0
- data/opals/foundation/lib/foundation/table_view/cell.rb +39 -0
- data/opals/foundation/lib/foundation/table_view/table.rb +171 -0
- data/opals/foundation/lib/foundation/views/button.rb +63 -0
- data/opals/foundation/lib/foundation/views/checkbox.rb +28 -0
- data/opals/foundation/lib/foundation/views/clip.rb +47 -0
- data/opals/foundation/lib/foundation/views/control.rb +199 -0
- data/opals/foundation/lib/foundation/views/label.rb +54 -0
- data/opals/foundation/lib/foundation/views/scroll.rb +294 -0
- data/opals/foundation/lib/foundation/views/scroll_view_desktop.rb +152 -0
- data/opals/foundation/lib/foundation/views/scroller.rb +54 -0
- data/opals/foundation/lib/foundation/views/slider.rb +93 -0
- data/opals/foundation/lib/foundation/views/text_field.rb +83 -0
- data/opals/foundation/lib/foundation/views/view.rb +426 -0
- data/opals/foundation/lib/foundation/windows/window.rb +191 -0
- data/opals/foundation/resources/button/button.css +23 -0
- data/{runtime/init.js → opals/foundation/resources/foundation.css} +27 -33
- data/opals/foundation/resources/scroll/scroll.css +22 -0
- data/opals/foundation/resources/scroll_view/scroll_view.css +3 -0
- data/opals/foundation/resources/scroll_view/scroller.css +3 -0
- data/opals/foundation/resources/slider/regular/slider.css +3 -0
- data/opals/foundation/resources/slider/slider.css +27 -0
- data/opals/foundation/resources/table_view/outline_view.css +3 -0
- data/opals/foundation/resources/table_view/table_view.css +15 -0
- data/opals/foundation/resources/text_field/text_field.css +71 -0
- data/opals/foundation/spec/spec_helper.rb +1 -0
- data/opals/foundation/spec/system/attributes/get_attribute_spec.rb +69 -0
- data/opals/foundation/spec/system/attributes/get_path_spec.rb +44 -0
- data/opals/foundation/spec/system/attributes/set_path_spec.rb +24 -0
- data/opals/foundation/spec/system/attributes/set_spec.rb +58 -0
- data/opals/foundation/spec/system/bindings/bindings.rb +85 -0
- data/opals/foundation/spec/system/key_value_binding/bind_spec.rb +43 -0
- data/opals/foundation/spec/system/observable/dependant_keys_spec.rb +74 -0
- data/opals/foundation/spec/system/observable/observe_spec.rb +292 -0
- data/opals/foundation/spec/system/observable/remove_observer_spec.rb +60 -0
- data/opals/opal/Opalfile +14 -0
- data/opals/opal/spec/core/array/append_spec.rb +30 -0
- data/opals/opal/spec/core/array/assoc_spec.rb +29 -0
- data/opals/opal/spec/core/array/at_spec.rb +37 -0
- data/opals/opal/spec/core/array/clear_spec.rb +22 -0
- data/opals/opal/spec/core/array/collect_bang_spec.rb +27 -0
- data/opals/opal/spec/core/array/collect_spec.rb +27 -0
- data/opals/opal/spec/core/array/compact_spec.rb +15 -0
- data/opals/opal/spec/core/array/concat_spec.rb +15 -0
- data/opals/opal/spec/core/array/constructor_spec.rb +14 -0
- data/opals/opal/spec/core/array/each_spec.rb +9 -0
- data/opals/opal/spec/core/array/element_reference_spec.rb +4 -0
- data/opals/opal/spec/core/array/first_spec.rb +35 -0
- data/opals/opal/spec/core/array/include_spec.rb +9 -0
- data/opals/opal/spec/core/array/map_spec.rb +31 -0
- data/opals/opal/spec/core/builtin_constants/builtin_constants_spec.rb +7 -0
- data/opals/opal/spec/core/false/and_spec.rb +10 -0
- data/opals/opal/spec/core/false/inspect_spec.rb +6 -0
- data/opals/opal/spec/core/false/or_spec.rb +10 -0
- data/opals/opal/spec/core/false/to_s_spec.rb +6 -0
- data/opals/opal/spec/core/false/xor_spec.rb +10 -0
- data/opals/opal/spec/core/file/join_spec.rb +19 -0
- data/opals/opal/spec/core/kernel/instance_eval_spec.rb +0 -0
- data/opals/opal/spec/core/kernel/loop_spec.rb +24 -0
- data/opals/opal/spec/core/kernel/raise_spec.rb +0 -0
- data/opals/opal/spec/core/module/attr_accessor_spec.rb +28 -0
- data/opals/opal/spec/core/number/lt_spec.rb +12 -0
- data/opals/opal/spec/core/true/and_spec.rb +10 -0
- data/opals/opal/spec/core/true/inspect_spec.rb +6 -0
- data/opals/opal/spec/core/true/or_spec.rb +10 -0
- data/opals/opal/spec/core/true/to_s_spec.rb +6 -0
- data/opals/opal/spec/core/true/xor_spec.rb +10 -0
- data/opals/opal/spec/fixtures/super.rb +70 -0
- data/opals/opal/spec/language/____temp_remove_this.rb +12 -0
- data/opals/opal/spec/language/and_spec.rb +62 -0
- data/opals/opal/spec/language/array_spec.rb +52 -0
- data/opals/opal/spec/language/block_spec.rb +18 -0
- data/opals/opal/spec/language/break_spec.rb +36 -0
- data/opals/opal/spec/language/case_spec.rb +103 -0
- data/opals/opal/spec/language/def_spec.rb +11 -0
- data/opals/opal/spec/language/eigenclass_spec.rb +60 -0
- data/opals/opal/spec/language/hash_spec.rb +29 -0
- data/opals/opal/spec/language/if_spec.rb +54 -0
- data/opals/opal/spec/language/loop_spec.rb +11 -0
- data/opals/opal/spec/language/metaclass_spec.rb +21 -0
- data/opals/opal/spec/language/method_spec.rb +64 -0
- data/opals/opal/spec/language/next_spec.rb +25 -0
- data/opals/opal/spec/language/or_spec.rb +34 -0
- data/opals/opal/spec/language/redo_spec.rb +24 -0
- data/opals/opal/spec/language/rescue_spec.rb +20 -0
- data/opals/opal/spec/language/return_spec.rb +47 -0
- data/opals/opal/spec/language/string_spec.rb +25 -0
- data/opals/opal/spec/language/super_spec.rb +26 -0
- data/opals/opal/spec/language/until_spec.rb +157 -0
- data/opals/opal/spec/language/while_spec.rb +163 -0
- data/opals/opal/spec/spec_helper.rb +5 -0
- data/opals/runtime/Opalfile +68 -0
- data/opals/runtime/README.md +12 -0
- data/opals/runtime/docs/debugging.md +51 -0
- data/opals/runtime/lib/array.rb +1516 -0
- data/opals/runtime/lib/basic_object.rb +49 -0
- data/opals/runtime/lib/class.rb +54 -0
- data/opals/runtime/lib/dir.rb +36 -0
- data/opals/runtime/lib/error.rb +49 -0
- data/opals/runtime/lib/false_class.rb +52 -0
- data/opals/runtime/lib/file.rb +79 -0
- data/opals/runtime/lib/hash.rb +791 -0
- data/opals/runtime/lib/io.rb +39 -0
- data/opals/runtime/lib/kernel.rb +288 -0
- data/opals/runtime/lib/match_data.rb +36 -0
- data/opals/runtime/lib/module.rb +109 -0
- data/opals/runtime/lib/nil_class.rb +69 -0
- data/opals/runtime/lib/number.rb +398 -0
- data/opals/runtime/lib/proc.rb +77 -0
- data/opals/runtime/lib/range.rb +63 -0
- data/opals/runtime/lib/regexp.rb +111 -0
- data/opals/runtime/lib/ruby.rb +30 -0
- data/opals/runtime/lib/string.rb +328 -0
- data/opals/runtime/lib/symbol.rb +40 -0
- data/opals/runtime/lib/top_self.rb +33 -0
- data/opals/runtime/lib/true_class.rb +45 -0
- data/opals/runtime/runtime/browser.js +287 -0
- data/opals/runtime/runtime/debug.js +182 -0
- data/opals/runtime/runtime/opal.js +1010 -0
- data/opals/runtime/runtime/post_opal.js +1 -0
- data/opals/runtime/runtime/pre_opal.js +2 -0
- data/opals/runtime/runtime/server_side.js +50 -0
- data/opals/spec/LICENSE.txt +26 -0
- data/opals/spec/Opalfile +5 -0
- data/opals/spec/bin/spec.rb +43 -0
- data/opals/spec/lib/spec.rb +33 -0
- data/opals/spec/lib/spec/dsl.rb +41 -0
- data/opals/spec/lib/spec/example.rb +35 -0
- data/opals/spec/lib/spec/example/before_and_after_hooks.rb +81 -0
- data/opals/spec/lib/spec/example/errors.rb +42 -0
- data/opals/spec/lib/spec/example/example_group.rb +37 -0
- data/opals/spec/lib/spec/example/example_group_factory.rb +43 -0
- data/opals/spec/lib/spec/example/example_group_hierarchy.rb +45 -0
- data/opals/spec/lib/spec/example/example_group_methods.rb +142 -0
- data/opals/spec/lib/spec/example/example_group_proxy.rb +41 -0
- data/opals/spec/lib/spec/example/example_methods.rb +73 -0
- data/opals/spec/lib/spec/example/example_proxy.rb +48 -0
- data/opals/spec/lib/spec/expectations.rb +46 -0
- data/opals/spec/lib/spec/expectations/errors.rb +35 -0
- data/opals/spec/lib/spec/expectations/fail_with.rb +37 -0
- data/opals/spec/lib/spec/expectations/handler.rb +48 -0
- data/opals/spec/lib/spec/matchers.rb +50 -0
- data/opals/spec/lib/spec/matchers/be.rb +26 -0
- data/opals/spec/lib/spec/matchers/generated_descriptions.rb +47 -0
- data/opals/spec/lib/spec/matchers/operator_matcher.rb +66 -0
- data/opals/spec/lib/spec/runner.rb +48 -0
- data/opals/spec/lib/spec/runner/example_group_runner.rb +71 -0
- data/opals/spec/lib/spec/runner/formatter/html_formatter.rb +100 -0
- data/opals/spec/lib/spec/runner/formatter/terminal_formatter.rb +82 -0
- data/opals/spec/lib/spec/runner/options.rb +63 -0
- data/opals/spec/lib/spec/runner/reporter.rb +123 -0
- data/opals/spec/resources/index.html +25 -0
- data/opals/spec/resources/spec.css +132 -0
- data/spec/cherry_kit/iseq_spec.rb +38 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/vienna_spec.rb +7 -0
- data/yard/index.html +43 -0
- data/yard/style.css +765 -0
- metadata +312 -49
- data/docs/jarv.rdoc +0 -27
- data/runtime/array.js +0 -153
- data/runtime/class.js +0 -469
- data/runtime/compar.js +0 -73
- data/runtime/dir.js +0 -115
- data/runtime/enum.js +0 -74
- data/runtime/file.js +0 -165
- data/runtime/gem.js +0 -241
- data/runtime/hash.js +0 -181
- data/runtime/load.js +0 -251
- data/runtime/module.js +0 -98
- data/runtime/number.js +0 -148
- data/runtime/object.js +0 -522
- data/runtime/opal.js +0 -200
- data/runtime/parse.js +0 -2218
- data/runtime/range.js +0 -56
- data/runtime/re.js +0 -91
- data/runtime/string.js +0 -199
- data/runtime/variable.js +0 -184
- data/runtime/vm.js +0 -1150
- data/tasks/build.rb +0 -16
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#
|
|
2
|
+
# index_path.rb
|
|
3
|
+
# vienna
|
|
4
|
+
#
|
|
5
|
+
# Created by Adam Beynon.
|
|
6
|
+
# Copyright 2010 Adam Beynon.
|
|
7
|
+
#
|
|
8
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
9
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
10
|
+
# in the Software without restriction, including without limitation the rights
|
|
11
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
12
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
13
|
+
# furnished to do so, subject to the following conditions:
|
|
14
|
+
#
|
|
15
|
+
# The above copyright notice and this permission notice shall be included in
|
|
16
|
+
# all copies or substantial portions of the Software.
|
|
17
|
+
#
|
|
18
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
24
|
+
# THE SOFTWARE.
|
|
25
|
+
#
|
|
26
|
+
|
|
27
|
+
module CherryKit
|
|
28
|
+
|
|
29
|
+
class IndexPath
|
|
30
|
+
|
|
31
|
+
def initialize(path)
|
|
32
|
+
if path.is_a? Number
|
|
33
|
+
@path = [path]
|
|
34
|
+
elsif path.is_a? Array
|
|
35
|
+
@path = path
|
|
36
|
+
else
|
|
37
|
+
@path = []
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def length
|
|
42
|
+
@path.length
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def [](index)
|
|
46
|
+
@path[index]
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#
|
|
2
|
+
# index_set.rb
|
|
3
|
+
# vienna
|
|
4
|
+
#
|
|
5
|
+
# Created by Adam Beynon.
|
|
6
|
+
# Copyright 2010 Adam Beynon.
|
|
7
|
+
#
|
|
8
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
9
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
10
|
+
# in the Software without restriction, including without limitation the rights
|
|
11
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
12
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
13
|
+
# furnished to do so, subject to the following conditions:
|
|
14
|
+
#
|
|
15
|
+
# The above copyright notice and this permission notice shall be included in
|
|
16
|
+
# all copies or substantial portions of the Software.
|
|
17
|
+
#
|
|
18
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
24
|
+
# THE SOFTWARE.
|
|
25
|
+
#
|
|
26
|
+
|
|
27
|
+
module CherryKit
|
|
28
|
+
|
|
29
|
+
# Set of ranges (ruby ranges) to express multiple index values (1..3 and 7..8)
|
|
30
|
+
#
|
|
31
|
+
class IndexSet
|
|
32
|
+
|
|
33
|
+
attr_reader :length
|
|
34
|
+
|
|
35
|
+
def initialize(index)
|
|
36
|
+
`if (#{index} == undefined) {
|
|
37
|
+
#{index} = #{nil};
|
|
38
|
+
}`
|
|
39
|
+
|
|
40
|
+
@length = 0
|
|
41
|
+
@ranges = []
|
|
42
|
+
|
|
43
|
+
if index.is_a? Number
|
|
44
|
+
add_index index
|
|
45
|
+
elsif index.is_a? Range
|
|
46
|
+
add_range index
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def add_index(index)
|
|
51
|
+
puts "adding index #{index}"
|
|
52
|
+
add_range Range.new index, index + 1, true
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def add_range(range)
|
|
56
|
+
# puts "adding range with length #{range.length}"
|
|
57
|
+
if @length == 0
|
|
58
|
+
@length = range.length
|
|
59
|
+
@ranges = [range]
|
|
60
|
+
else
|
|
61
|
+
@length = @length + range.length
|
|
62
|
+
@ranges << range
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Returns true or false whether the index set includes the given index,
|
|
67
|
+
# range or index set
|
|
68
|
+
#
|
|
69
|
+
# @param {Number|Range|IndexSet} index
|
|
70
|
+
# @returns {true|false}
|
|
71
|
+
#
|
|
72
|
+
def include?(index)
|
|
73
|
+
if index.is_a? Number
|
|
74
|
+
include_index? index
|
|
75
|
+
elsif index.is_a? Range
|
|
76
|
+
include_range? index
|
|
77
|
+
else
|
|
78
|
+
raise "Bad index given to Range#include? #{index}"
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def include_index?(index)
|
|
83
|
+
found_index = false
|
|
84
|
+
@ranges.each do |range|
|
|
85
|
+
if range.include? index
|
|
86
|
+
found_index = true
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
found_index
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def dup
|
|
94
|
+
self
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
#
|
|
2
|
+
# notification.rb
|
|
3
|
+
# vienna
|
|
4
|
+
#
|
|
5
|
+
# Created by Adam Beynon.
|
|
6
|
+
# Copyright 2010 Adam Beynon.
|
|
7
|
+
#
|
|
8
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
9
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
10
|
+
# in the Software without restriction, including without limitation the rights
|
|
11
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
12
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
13
|
+
# furnished to do so, subject to the following conditions:
|
|
14
|
+
#
|
|
15
|
+
# The above copyright notice and this permission notice shall be included in
|
|
16
|
+
# all copies or substantial portions of the Software.
|
|
17
|
+
#
|
|
18
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
24
|
+
# THE SOFTWARE.
|
|
25
|
+
#
|
|
26
|
+
|
|
27
|
+
module Kernel
|
|
28
|
+
|
|
29
|
+
def notify(notification_name)
|
|
30
|
+
CherryKit::NotificationCenter.default_center.post_notification :name => notification_name, :sender => self
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
module CherryKit
|
|
35
|
+
|
|
36
|
+
class NotificationCenter
|
|
37
|
+
|
|
38
|
+
def initialize
|
|
39
|
+
# Dispatch table is a hash of all observed objects. Each key in the hash
|
|
40
|
+
# is the observed object, and each value is an array of hashes with keys
|
|
41
|
+
# for all relevant properties
|
|
42
|
+
@dispatch_table = {}
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Add an observer with the given action for the notification name sent by
|
|
46
|
+
# the object.
|
|
47
|
+
#
|
|
48
|
+
# add_observer some_object, :object_got_update, :object_updated, self
|
|
49
|
+
#
|
|
50
|
+
# def object_got_update(notification)
|
|
51
|
+
# puts "some object got an update from #{notification[:sender]}"
|
|
52
|
+
# end
|
|
53
|
+
#
|
|
54
|
+
# @param {Object} observer that wants to know about notifications
|
|
55
|
+
# @param {Symbol} action to send on response to the notification
|
|
56
|
+
# @param {Symbol} notification name to listen for
|
|
57
|
+
# @param {Object} object to watch for notifications
|
|
58
|
+
#
|
|
59
|
+
# @returns self
|
|
60
|
+
#
|
|
61
|
+
def add_observer(observer, action, name, object)
|
|
62
|
+
# puts "in add observers"
|
|
63
|
+
observers = (@dispatch_table[object] || @dispatch_table[object] = [])
|
|
64
|
+
|
|
65
|
+
# puts 'observers is #{observers}'
|
|
66
|
+
# `console.log(#{observers});`
|
|
67
|
+
|
|
68
|
+
observers << {
|
|
69
|
+
:observer => observer,
|
|
70
|
+
:action => action,
|
|
71
|
+
:name => name,
|
|
72
|
+
:sender => object
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
self
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Returns the default notification center for the application.
|
|
79
|
+
#
|
|
80
|
+
# @returns [NotificationCenter]
|
|
81
|
+
#
|
|
82
|
+
def self.default_center
|
|
83
|
+
@default_center ||= self.new
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Post a notification. Expected options are:
|
|
87
|
+
#
|
|
88
|
+
# :name - Symbol name of the notification
|
|
89
|
+
# :sender - Object reference
|
|
90
|
+
# :user_info - hash of any additional options that may be required
|
|
91
|
+
#
|
|
92
|
+
# @param [Hash] options
|
|
93
|
+
# @returns
|
|
94
|
+
#
|
|
95
|
+
def post_notification(options)
|
|
96
|
+
observers = @dispatch_table[options[:sender]]
|
|
97
|
+
|
|
98
|
+
# puts "all observers: #{observers}"
|
|
99
|
+
# `console.log(#{@dispatch_table});`
|
|
100
|
+
|
|
101
|
+
if observers
|
|
102
|
+
observers.each do |observer|
|
|
103
|
+
if observer[:name] == options[:name]
|
|
104
|
+
observer[:observer].__send__(observer[:action], observer)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
self
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
end
|
|
113
|
+
end
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
#
|
|
2
|
+
# key_value_observing.rb
|
|
3
|
+
# vienna
|
|
4
|
+
#
|
|
5
|
+
# Created by Adam Beynon.
|
|
6
|
+
# Copyright 2010 Adam Beynon.
|
|
7
|
+
#
|
|
8
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
9
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
10
|
+
# in the Software without restriction, including without limitation the rights
|
|
11
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
12
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
13
|
+
# furnished to do so, subject to the following conditions:
|
|
14
|
+
#
|
|
15
|
+
# The above copyright notice and this permission notice shall be included in
|
|
16
|
+
# all copies or substantial portions of the Software.
|
|
17
|
+
#
|
|
18
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
24
|
+
# THE SOFTWARE.
|
|
25
|
+
#
|
|
26
|
+
|
|
27
|
+
module CherryKit
|
|
28
|
+
|
|
29
|
+
# Observer pattern
|
|
30
|
+
#
|
|
31
|
+
# Observers via callback, all keys:
|
|
32
|
+
#
|
|
33
|
+
# :old => old value
|
|
34
|
+
# :new => new value
|
|
35
|
+
# :path => attribute path
|
|
36
|
+
#
|
|
37
|
+
module Observable
|
|
38
|
+
|
|
39
|
+
def will_change_attribute(attribute)
|
|
40
|
+
if @__observer_info
|
|
41
|
+
__send_change_notifications attribute.to_s, true, :kind => :setting
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def did_change_attribute(attribute)
|
|
46
|
+
if @__observer_info
|
|
47
|
+
__send_change_notifications attribute.to_s, false, nil
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# New
|
|
53
|
+
#
|
|
54
|
+
# @returns {Proc} action the observer
|
|
55
|
+
#
|
|
56
|
+
def observe(path, &action)
|
|
57
|
+
# always deal with strings for path names (not symbols)
|
|
58
|
+
path = path.to_s
|
|
59
|
+
# ensure we have our observer dictionary
|
|
60
|
+
@__observer_info ||= {}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
if path.index '.'
|
|
64
|
+
# puts "looking up observer info"
|
|
65
|
+
# puts self
|
|
66
|
+
ForwardingObserver.new(self, path, &action)
|
|
67
|
+
# else
|
|
68
|
+
end
|
|
69
|
+
__replace_setter_for_key path
|
|
70
|
+
# end
|
|
71
|
+
|
|
72
|
+
observer_info = @__observer_info[path]
|
|
73
|
+
|
|
74
|
+
# add the observer
|
|
75
|
+
observer_info[:observers] << action
|
|
76
|
+
|
|
77
|
+
action
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
# Private method to replace the setter methods for the given key.
|
|
83
|
+
#
|
|
84
|
+
# @param [String] key
|
|
85
|
+
# @returns nil
|
|
86
|
+
#
|
|
87
|
+
def __replace_setter_for_key(key)
|
|
88
|
+
key = key.to_s
|
|
89
|
+
|
|
90
|
+
# puts "replacing setter for #{key}"
|
|
91
|
+
|
|
92
|
+
# if we have already done this key, skip
|
|
93
|
+
return if @__observer_info[key]
|
|
94
|
+
|
|
95
|
+
# mark key as being replaced
|
|
96
|
+
@__observer_info[key] = observer_info = {
|
|
97
|
+
# an array of procs. These are what we notify when we change
|
|
98
|
+
:observers => [],
|
|
99
|
+
# change. This is usually the old value, which we store (will_change)
|
|
100
|
+
:change => nil,
|
|
101
|
+
# dependants - the keys which depend on this key
|
|
102
|
+
:dependants => []
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
methods_to_replace = {
|
|
106
|
+
"#{key}=" => proc do |key, original_method|
|
|
107
|
+
# we simply return a closure which takes a single param, the value. We
|
|
108
|
+
# gather the key for sending will_change_value_for_key(), and keep our
|
|
109
|
+
# original method so we can call it between notifications
|
|
110
|
+
proc do |value|
|
|
111
|
+
will_change_attribute(key)
|
|
112
|
+
`#{original_method}.apply(#{self}, [#{value}]);`
|
|
113
|
+
did_change_attribute(key)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
methods_to_replace.each do |method_id, implementation|
|
|
119
|
+
`var js_id = #{self}.mid2jsid(#{method_id.to_s}.toString());`
|
|
120
|
+
# only replace method if we have implemented it
|
|
121
|
+
if respond_to? method_id
|
|
122
|
+
original = `#{self}[js_id];`
|
|
123
|
+
# define new method as result of calling the closure
|
|
124
|
+
`#{self}[js_id] = #{implementation}.apply(#{implementation}.__self__, [#{key}, #{original}]);`
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# puts "looking up dependencies for #{key}"
|
|
129
|
+
# puts self.class.lookup_affecting_keys_for(key)
|
|
130
|
+
# go through all dependencies (keys affecting)
|
|
131
|
+
self.class.lookup_affecting_keys_for(key).each do |affecting_key|
|
|
132
|
+
__replace_setter_for_key affecting_key
|
|
133
|
+
@__observer_info[affecting_key.to_s][:dependants] << key
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Notifications that we are about to change the key, did change etc
|
|
139
|
+
def __send_change_notifications(key, before, options)
|
|
140
|
+
key = key.to_s
|
|
141
|
+
# puts "sending notification for key #{key}"
|
|
142
|
+
options = options || {}
|
|
143
|
+
|
|
144
|
+
# if we are sending a notification before we change the value
|
|
145
|
+
# (will_change_value_for_key)
|
|
146
|
+
if before
|
|
147
|
+
# puts "will_change: #{key}"
|
|
148
|
+
# notify dependants
|
|
149
|
+
@__observer_info[key][:dependants].each do |dependee|
|
|
150
|
+
__send_change_notifications(dependee, true, {})
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
old_value = get_attribute key
|
|
154
|
+
@__observer_info[key][:change] = old_value
|
|
155
|
+
else
|
|
156
|
+
# after..
|
|
157
|
+
old_value = @__observer_info[key][:change]
|
|
158
|
+
new_value = get_attribute key
|
|
159
|
+
|
|
160
|
+
changes = {}
|
|
161
|
+
changes[:old] = old_value
|
|
162
|
+
changes[:new] = new_value
|
|
163
|
+
changes[:path] = key
|
|
164
|
+
changes[:object] = self
|
|
165
|
+
|
|
166
|
+
# notify every observer that we have changed
|
|
167
|
+
# puts "did_change: #{key}"
|
|
168
|
+
@__observer_info[key][:observers].each do |block_callback|
|
|
169
|
+
`#{block_callback}.apply(#{block_callback}.__self__, [#{changes}]);`
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# puts "dependee keys for #{key} are:"
|
|
173
|
+
# `console.log(#{@__observer_info[key][:dependants]});`
|
|
174
|
+
@__observer_info[key][:dependants].each do |dependee|
|
|
175
|
+
__send_change_notifications(dependee, false, {})
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Remove an observing object for the given key path
|
|
181
|
+
def remove_observer(observer, path)
|
|
182
|
+
observers = @__observer_info[path.to_s][:observers]
|
|
183
|
+
|
|
184
|
+
observers.delete(observer)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# Forward observer calls for multipart observer paths
|
|
195
|
+
class ForwardingObserver
|
|
196
|
+
|
|
197
|
+
def initialize(object, path, action)
|
|
198
|
+
|
|
199
|
+
@object = object
|
|
200
|
+
@path = path
|
|
201
|
+
@action = action
|
|
202
|
+
|
|
203
|
+
index = path.index '.'
|
|
204
|
+
|
|
205
|
+
unless index
|
|
206
|
+
raise "ForwardingObserver must be given a multipart attr string"
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
@first_part = path.slice 0, index
|
|
210
|
+
@second_part = path.slice index + 1, path.length - index
|
|
211
|
+
|
|
212
|
+
# Observe the first part of the key. When it changes we must notify the
|
|
213
|
+
# observer of the change. Also, as it has changed we must remove our
|
|
214
|
+
# observer for the second part, and readd ourself as an observer of the
|
|
215
|
+
# second part.
|
|
216
|
+
#
|
|
217
|
+
@observer = object.observe(@first_part) do |changes|
|
|
218
|
+
# puts "notifying for #{@first_part} from #{changes[:path]}"
|
|
219
|
+
`#{action}.__fun__(#{changes});`
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# current value of getting the first part
|
|
223
|
+
@value = object.get_attribute @first_part
|
|
224
|
+
|
|
225
|
+
# Observe the second part
|
|
226
|
+
@value.observe(@second_part) do |changes|
|
|
227
|
+
dict = {
|
|
228
|
+
:new => changes[:new],
|
|
229
|
+
:old => changes[:old],
|
|
230
|
+
:path => "#{@first_part}.#{changes[:path]}",
|
|
231
|
+
:object => object
|
|
232
|
+
}
|
|
233
|
+
`#{@observer}.__fun__(#{dict});`
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
class Object
|
|
239
|
+
|
|
240
|
+
# Define that the given affectors will affect the result of the key_name.
|
|
241
|
+
# When key_name is observed, then all the affectors must also be observed so
|
|
242
|
+
# that if they change, we know that key_name might also change
|
|
243
|
+
#
|
|
244
|
+
# @param {Hash} affectors
|
|
245
|
+
#
|
|
246
|
+
def self.keys_affecting(affectors)
|
|
247
|
+
# make sure this exists
|
|
248
|
+
@__kvo_affecting_keys ||= {}
|
|
249
|
+
|
|
250
|
+
affectors.each do |key_name, affecting_keys|
|
|
251
|
+
# puts "setting affectors for #{key_name}"
|
|
252
|
+
@__kvo_affecting_keys[key_name.to_s] = affecting_keys
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# Lookup the keys affecting the given key.
|
|
257
|
+
#
|
|
258
|
+
# @param {Symbol} key_name
|
|
259
|
+
# @returns {Array} affecting keys
|
|
260
|
+
#
|
|
261
|
+
def self.lookup_affecting_keys_for(key_name)
|
|
262
|
+
key_name = key_name.to_s
|
|
263
|
+
@__kvo_affecting_keys ||= {}
|
|
264
|
+
# puts "in looking up for #{key_name.to_s}"
|
|
265
|
+
if @__kvo_affecting_keys[key_name]
|
|
266
|
+
return @__kvo_affecting_keys[key_name]
|
|
267
|
+
else
|
|
268
|
+
return @__kvo_affecting_keys[key_name] = []
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
Object.include CherryKit::Observable
|
|
274
|
+
|
|
275
|
+
require 'foundation/core/observable_array'
|