glimmer-dsl-opal 0.0.5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +41 -0
  3. data/README.md +1003 -58
  4. data/VERSION +1 -1
  5. data/lib/glimmer-dsl-opal.rb +26 -8
  6. data/lib/glimmer/data_binding/element_binding.rb +1 -1
  7. data/lib/glimmer/data_binding/ext/observable_model.rb +40 -0
  8. data/lib/glimmer/data_binding/list_selection_binding.rb +1 -1
  9. data/lib/glimmer/data_binding/table_items_binding.rb +70 -0
  10. data/lib/glimmer/dsl/opal/async_exec_expression.rb +17 -0
  11. data/lib/glimmer/dsl/opal/column_properties_expression.rb +22 -0
  12. data/lib/glimmer/dsl/opal/combo_selection_data_binding_expression.rb +2 -2
  13. data/lib/glimmer/dsl/opal/dsl.rb +10 -12
  14. data/lib/glimmer/dsl/opal/layout_data_expression.rb +2 -2
  15. data/lib/glimmer/dsl/opal/{text_expression.rb → layout_expression.rb} +5 -5
  16. data/lib/glimmer/dsl/opal/list_selection_data_binding_expression.rb +2 -3
  17. data/lib/glimmer/dsl/opal/message_box_expression.rb +20 -0
  18. data/lib/glimmer/dsl/opal/observe_expression.rb +32 -0
  19. data/lib/glimmer/dsl/opal/shell_expression.rb +2 -2
  20. data/lib/glimmer/dsl/opal/{composite_expression.rb → table_column_expression.rb} +3 -3
  21. data/lib/glimmer/dsl/opal/{list_expression.rb → table_expression.rb} +3 -3
  22. data/lib/glimmer/dsl/opal/table_items_data_binding_expression.rb +29 -0
  23. data/lib/glimmer/dsl/opal/widget_expression.rb +23 -0
  24. data/lib/glimmer/opal/display_proxy.rb +23 -0
  25. data/lib/glimmer/opal/element_proxy.rb +48 -13
  26. data/lib/glimmer/swt/browser_proxy.rb +27 -0
  27. data/lib/glimmer/swt/button_proxy.rb +40 -0
  28. data/lib/glimmer/{opal/select_proxy.rb → swt/combo_proxy.rb} +15 -11
  29. data/lib/glimmer/swt/composite_proxy.rb +31 -0
  30. data/lib/glimmer/{opal → swt}/event_listener_proxy.rb +1 -1
  31. data/lib/glimmer/{opal → swt}/grid_layout_proxy.rb +7 -18
  32. data/lib/glimmer/swt/label_proxy.rb +30 -0
  33. data/lib/glimmer/swt/layout_data_proxy.rb +52 -0
  34. data/lib/glimmer/swt/layout_proxy.rb +60 -0
  35. data/lib/glimmer/{opal → swt}/list_proxy.rb +18 -15
  36. data/lib/glimmer/swt/message_box_proxy.rb +146 -0
  37. data/lib/glimmer/{opal → swt}/point.rb +1 -1
  38. data/lib/glimmer/{opal → swt}/property_owner.rb +1 -1
  39. data/lib/glimmer/swt/shell_proxy.rb +235 -0
  40. data/lib/glimmer/swt/tab_folder_proxy.rb +52 -0
  41. data/lib/glimmer/swt/tab_item_proxy.rb +101 -0
  42. data/lib/glimmer/swt/table_column_proxy.rb +56 -0
  43. data/lib/glimmer/swt/table_item_proxy.rb +147 -0
  44. data/lib/glimmer/swt/table_proxy.rb +177 -0
  45. data/lib/glimmer/swt/text_proxy.rb +46 -0
  46. data/lib/glimmer/swt/widget_proxy.rb +389 -0
  47. data/lib/jquery.js +2 -0
  48. data/lib/samples/elaborate/contact_manager.rb +2 -3
  49. data/lib/samples/elaborate/login.rb +0 -1
  50. data/lib/samples/elaborate/tic_tac_toe.rb +5 -5
  51. data/lib/samples/hello/hello_computed.rb +19 -19
  52. data/lib/samples/hello/hello_tab.rb +2 -2
  53. metadata +92 -59
  54. data/lib/glimmer/config.rb +0 -22
  55. data/lib/glimmer/dsl/engine.rb +0 -193
  56. data/lib/glimmer/dsl/expression.rb +0 -42
  57. data/lib/glimmer/dsl/expression_handler.rb +0 -48
  58. data/lib/glimmer/dsl/opal/browser_expression.rb +0 -17
  59. data/lib/glimmer/dsl/opal/button_expression.rb +0 -18
  60. data/lib/glimmer/dsl/opal/combo_expression.rb +0 -17
  61. data/lib/glimmer/dsl/opal/grid_layout_expression.rb +0 -17
  62. data/lib/glimmer/dsl/opal/label_expression.rb +0 -17
  63. data/lib/glimmer/dsl/parent_expression.rb +0 -12
  64. data/lib/glimmer/dsl/static_expression.rb +0 -36
  65. data/lib/glimmer/dsl/top_level_expression.rb +0 -7
  66. data/lib/glimmer/error.rb +0 -6
  67. data/lib/glimmer/invalid_keyword_error.rb +0 -6
  68. data/lib/glimmer/opal/div_proxy.rb +0 -20
  69. data/lib/glimmer/opal/document_proxy.rb +0 -90
  70. data/lib/glimmer/opal/iframe_proxy.rb +0 -23
  71. data/lib/glimmer/opal/input_proxy.rb +0 -41
  72. data/lib/glimmer/opal/label_proxy.rb +0 -25
  73. data/lib/glimmer/opal/layout_data_proxy.rb +0 -31
@@ -0,0 +1,52 @@
1
+ require 'glimmer/swt/widget_proxy'
2
+
3
+ module Glimmer
4
+ module SWT
5
+ class TabFolderProxy < WidgetProxy
6
+ attr_reader :tabs
7
+
8
+ def initialize(parent, args)
9
+ super(parent, args)
10
+ @tabs = []
11
+ end
12
+
13
+ def add_child(child)
14
+ unless @children.include?(child)
15
+ @children << child
16
+ end
17
+ if @children.size == 1
18
+ child.show
19
+ end
20
+ end
21
+
22
+ def redraw
23
+ super()
24
+ @children.each do |child|
25
+ add_child(child) # TODO think of impact of this on performance
26
+ end
27
+ end
28
+
29
+ def hide_all_tab_content
30
+ @children.each(&:hide)
31
+ end
32
+
33
+ def tabs_path
34
+ path + " > ##{tabs_id}"
35
+ end
36
+
37
+ def tabs_id
38
+ id + '-tabs'
39
+ end
40
+
41
+ def dom
42
+ tab_folder_id = id
43
+ tab_folder_id_style = css
44
+ @dom ||= html {
45
+ div(id: tab_folder_id, style: tab_folder_id_style, class: 'tab-folder') {
46
+ div(id: tabs_id, class: 'tabs')
47
+ }
48
+ }.to_s
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,101 @@
1
+ require 'glimmer/swt/composite_proxy'
2
+
3
+ module Glimmer
4
+ module SWT
5
+ class TabItemProxy < CompositeProxy
6
+ include Glimmer
7
+ attr_reader :text, :content_visible
8
+
9
+ def initialize(parent, args)
10
+ super(parent, args)
11
+ css_classes << 'tab-item'
12
+ content {
13
+ on_widget_selected {
14
+ @parent.hide_all_tab_content
15
+ show
16
+ }
17
+ }
18
+ end
19
+
20
+ def show
21
+ # TODO refactor/rewrite via simply class application in jquery
22
+ # Document.find(path).remove_class('hide')
23
+ @content_visible = true
24
+ redraw
25
+ end
26
+
27
+ def hide
28
+ # TODO refactor/rewrite via simply class application in jquery
29
+ # Document.find(path).add_class('hide')
30
+ @content_visible = false
31
+ redraw
32
+ end
33
+
34
+ def text=(value)
35
+ @text = value
36
+ redraw
37
+ end
38
+
39
+ def selector
40
+ super + '-tab'
41
+ end
42
+
43
+ def observation_request_to_event_mapping
44
+ {
45
+ 'on_widget_selected' => {
46
+ event: 'click'
47
+ },
48
+ }
49
+ end
50
+
51
+ def listener_path
52
+ tab_path
53
+ end
54
+
55
+ def redraw
56
+ if @tab_dom
57
+ old_tab_dom = @tab_dom
58
+ @tab_dom = nil
59
+ Document.find(tab_path).replace_with(tab_dom)
60
+ else
61
+ Document.find(parent.tabs_path).append(tab_dom)
62
+ end
63
+ super()
64
+ end
65
+
66
+ def tab_path
67
+ "#{parent.tabs_path} > ##{tab_id}"
68
+ end
69
+
70
+ def tab_id
71
+ id + '-tab'
72
+ end
73
+
74
+ def tab_dom
75
+ tab_selected = @content_visible ? 'selected' : ''
76
+ @tab_dom ||= html {
77
+ button(id: tab_id, class: "tab #{tab_selected}") {
78
+ @text
79
+ }
80
+ }.to_s
81
+ end
82
+
83
+ def dom
84
+ tab_item_id = id
85
+ tab_item_id_style = css
86
+ tab_item_css_classes = css_classes
87
+ css_classes << name
88
+ if @content_visible
89
+ tab_item_css_classes.delete('hide')
90
+ else
91
+ tab_item_css_classes << 'hide'
92
+ end
93
+ tab_item_class_string = tab_item_css_classes.to_a.join(' ')
94
+ @dom ||= html {
95
+ div(id: tab_item_id, style: tab_item_id_style, class: tab_item_class_string) {
96
+ }
97
+ }.to_s
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,56 @@
1
+ require 'glimmer/swt/widget_proxy'
2
+
3
+ module Glimmer
4
+ module SWT
5
+ class TableColumnProxy < WidgetProxy
6
+ include Glimmer
7
+
8
+ attr_reader :text, :width
9
+
10
+ def text=(value)
11
+ @text = value
12
+ redraw
13
+ end
14
+
15
+ def width=(value)
16
+ @width = value
17
+ redraw
18
+ end
19
+
20
+ def parent_path
21
+ parent.columns_path
22
+ end
23
+
24
+ def css
25
+ <<~CSS
26
+ width: #{width}px;
27
+ CSS
28
+ end
29
+
30
+ def element
31
+ 'th'
32
+ end
33
+
34
+ def observation_request_to_event_mapping
35
+ {
36
+ 'on_widget_selected' => {
37
+ event: 'click'
38
+ },
39
+ }
40
+ end
41
+
42
+ def dom
43
+ table_column_text = text
44
+ table_column_id = id
45
+ table_column_id_style = css
46
+ table_column_css_classes = css_classes
47
+ table_column_css_classes << name
48
+ @dom ||= html {
49
+ th(id: table_column_id, style: table_column_id_style, class: table_column_css_classes.to_a.join(' ')) {
50
+ table_column_text
51
+ }
52
+ }.to_s
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,147 @@
1
+ require 'glimmer/swt/widget_proxy'
2
+
3
+ module Glimmer
4
+ module SWT
5
+ class TableItemProxy < WidgetProxy
6
+ attr_reader :data
7
+
8
+ def initialize(parent, args)
9
+ super(parent, args)
10
+ on_widget_selected { |event|
11
+ parent.select(parent.index_of(self), event.meta?)
12
+ }
13
+ end
14
+
15
+ def get_text(index)
16
+ text_array[index]
17
+ end
18
+
19
+ def set_text(index, text_value)
20
+ text_array[index] = text_value
21
+ redraw
22
+ end
23
+
24
+ def text_array
25
+ @text_array ||= []
26
+ end
27
+
28
+ def get_data(key = nil)
29
+ if key.nil?
30
+ @data
31
+ else
32
+ data_hash[key]
33
+ end
34
+ end
35
+
36
+ def set_data(key = nil, data_value)
37
+ if key.nil?
38
+ @data = data_value
39
+ else
40
+ data_hash[key] = data_value
41
+ end
42
+ end
43
+
44
+ def data_hash
45
+ @data_hash ||= {}
46
+ end
47
+
48
+ def parent_path
49
+ parent.items_path
50
+ end
51
+
52
+ def element
53
+ 'tr'
54
+ end
55
+
56
+ def redraw
57
+ super() #TODO re-enalbe and remove below lines
58
+
59
+ # TODO perhaps turn the following lambdas into methods
60
+ table_item_edit_handler = lambda do |event, cancel = false|
61
+ Async::Task.new do
62
+ text_value = event.target.value
63
+ edit_property = parent.column_properties[@edit_column_index]
64
+ edit_model = get_data
65
+ if !cancel && edit_model.send(edit_property) != text_value
66
+ edit_model.send("#{edit_property}=", text_value)
67
+ set_text(@edit_column_index, text_value)
68
+ end
69
+ @edit_column_index = nil
70
+ redraw
71
+ end
72
+ end
73
+ table_item_edit_cancel_handler = lambda do |event|
74
+ Async::Task.new do
75
+ table_item_edit_handler.call(event, true)
76
+ end
77
+ end
78
+ table_item_edit_key_handler = lambda do |event|
79
+ Async::Task.new do
80
+ if event.key_code == 13
81
+ table_item_edit_handler.call(event)
82
+ elsif event.key_code == 27
83
+ table_item_edit_cancel_handler.call(event)
84
+ end
85
+ end
86
+ end
87
+
88
+ if @edit_column_index
89
+ table_item_input = dom_element.find("td:nth-child(#{@edit_column_index + 1}) input")
90
+ if !table_item_input.empty?
91
+ Async::Task.new do
92
+ table_item_input.focus
93
+ table_item_input.on('keyup', &table_item_edit_key_handler)
94
+ table_item_input.on('focusout', &table_item_edit_cancel_handler)
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ def edit(column_index)
101
+ return if @edit_column_index == column_index.to_i
102
+ parent.select(parent.index_of(self), false)
103
+ @edit_column_index = column_index.to_i
104
+ redraw
105
+ end
106
+
107
+ def on_widget_selected(&block)
108
+ event = 'click'
109
+ delegate = $document.on(event, selector, &block)
110
+ EventListenerProxy.new(element_proxy: self, event: event, selector: selector, delegate: delegate)
111
+ end
112
+
113
+ def max_column_width(column_index)
114
+ parent_dom_element.find("tr td:nth-child(#{column_index + 1})").first.width
115
+ end
116
+
117
+ def dom
118
+ table_item_id = id
119
+ table_item_id_style = css
120
+ table_item_css_classes = css_classes
121
+ table_item_css_classes << name
122
+ table_item_selection = parent.selection.include?(self)
123
+ if table_item_selection
124
+ table_item_css_classes << 'selected'
125
+ else
126
+ table_item_css_classes.delete('selected')
127
+ end
128
+ table_item_text_array = text_array
129
+ table_item_max_width = max_column_width(@edit_column_index) if @edit_column_index
130
+
131
+ @dom ||= html {
132
+ tr(id: table_item_id, style: table_item_id_style, class: table_item_css_classes.to_a.join(' ')) {
133
+ table_item_text_array.each_with_index do |table_item_text, column_index|
134
+ td('data-column-index' => column_index) {
135
+ if @edit_column_index == column_index
136
+ input(type: 'text', value: table_item_text, style: "max-width: #{table_item_max_width - 11}px;")
137
+ else
138
+ table_item_text
139
+ end
140
+ }
141
+ end
142
+ }
143
+ }.to_s
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,177 @@
1
+ require 'glimmer/swt/widget_proxy'
2
+ require 'glimmer/swt/table_column_proxy'
3
+
4
+ module Glimmer
5
+ module SWT
6
+ class TableProxy < WidgetProxy
7
+ attr_reader :columns, :selection
8
+ attr_accessor :column_properties
9
+ alias items children
10
+
11
+ def initialize(parent, args)
12
+ super(parent, args)
13
+ @columns = []
14
+ @children = []
15
+ @selection = []
16
+ end
17
+
18
+ # Only table_columns may be added as children
19
+ def add_child(child)
20
+ if child.is_a?(TableColumnProxy)
21
+ @columns << child
22
+ else
23
+ @children << child
24
+ end
25
+ child.redraw
26
+ end
27
+
28
+ def remove_all
29
+ items.clear
30
+ redraw
31
+ end
32
+
33
+ def selection=(new_selection)
34
+ changed = (@selection + new_selection) - (@selection & new_selection)
35
+ @selection = new_selection
36
+ changed.each(&:redraw)
37
+ end
38
+
39
+ def items=(new_items)
40
+ @children = new_items
41
+ redraw
42
+ end
43
+
44
+ def search(&condition)
45
+ items.select {|item| condition.nil? || condition.call(item)}
46
+ end
47
+
48
+ def index_of(item)
49
+ items.index(item)
50
+ end
51
+
52
+ def select(index, meta = false)
53
+ new_selection = @selection.clone
54
+ selected_item = items[index]
55
+ if @selection.include?(selected_item)
56
+ new_selection.delete(selected_item) if meta
57
+ else
58
+ new_selection = [] if !meta || (!has_style?(:multi) && @selection.to_a.size >= 1)
59
+ new_selection << selected_item
60
+ end
61
+ self.selection = new_selection
62
+ end
63
+
64
+ def edit_table_item(table_item, column_index)
65
+ table_item.edit(column_index)
66
+ end
67
+
68
+ def selector
69
+ super + ' tbody'
70
+ end
71
+
72
+ def observation_request_to_event_mapping
73
+ mouse_handler = -> (event_listener) {
74
+ -> (event) {
75
+ event.singleton_class.send(:define_method, :table_item=) do |item|
76
+ @table_item = item
77
+ end
78
+ event.singleton_class.send(:define_method, :table_item) do
79
+ @table_item
80
+ end
81
+ table_row = event.target.parents('tr').first
82
+ table_data = event.target.parents('td').first
83
+ event.table_item = items.detect {|item| item.id == table_row.attr('id')}
84
+ event.singleton_class.send(:define_method, :column_index) do
85
+ (table_data || event.target).attr('data-column-index')
86
+ end
87
+ event_listener.call(event)
88
+ }
89
+ }
90
+
91
+ {
92
+ 'on_mouse_down' => {
93
+ event: 'mousedown',
94
+ event_handler: mouse_handler,
95
+ },
96
+ 'on_mouse_up' => {
97
+ event: 'mouseup',
98
+ event_handler: mouse_handler,
99
+ }
100
+ }
101
+ end
102
+
103
+ def redraw
104
+ super()
105
+ @columns.to_a.each(&:redraw)
106
+ end
107
+
108
+ # def redraw
109
+ # if @dom
110
+ # old_dom = @dom
111
+ # @dom = nil
112
+ # old_dom.replace dom
113
+ # else
114
+ # dom
115
+ # end
116
+ # if @last_redrawn_children != @children
117
+ # items_dom_element.empty
118
+ # @last_redrawn_children = @children
119
+ # @children = []
120
+ # @last_redrawn_children.each do |child|
121
+ # add_child(child)
122
+ # end
123
+ # end
124
+ # end
125
+
126
+ def element
127
+ 'table'
128
+ end
129
+
130
+ def columns_path
131
+ path + ' thead tr'
132
+ end
133
+
134
+ def columns_dom_element
135
+ Document.find(columns_path)
136
+ end
137
+
138
+ def items_path
139
+ path + ' tbody'
140
+ end
141
+
142
+ def items_dom_element
143
+ Document.find(items_path)
144
+ end
145
+
146
+ def columns_dom
147
+ tr {
148
+ }
149
+ end
150
+
151
+ def thead_dom
152
+ thead {
153
+ columns_dom
154
+ }
155
+ end
156
+
157
+ def items_dom
158
+ tbody {
159
+ }
160
+ end
161
+
162
+ def dom
163
+ table_id = id
164
+ table_id_style = css
165
+ table_id_css_classes = css_classes
166
+ table_id_css_classes << 'table'
167
+ table_id_css_classes_string = table_id_css_classes.to_a.join(' ')
168
+ @dom ||= html {
169
+ table(id: table_id, style: table_id_style, class: table_id_css_classes_string) {
170
+ thead_dom
171
+ items_dom
172
+ }
173
+ }.to_s
174
+ end
175
+ end
176
+ end
177
+ end