glimmer-dsl-opal 0.0.7 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +56 -0
  3. data/README.md +815 -76
  4. data/VERSION +1 -1
  5. data/lib/glimmer-dsl-opal.rb +45 -8
  6. data/lib/glimmer-dsl-opal/ext/date.rb +13 -0
  7. data/lib/glimmer-dsl-opal/ext/exception.rb +5 -0
  8. data/lib/glimmer-dsl-opal/missing/net/http.rb +17 -0
  9. data/lib/glimmer-dsl-opal/missing/uri.rb +64 -0
  10. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/contact_manager.rb +2 -3
  11. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/contact_manager/contact.rb +0 -0
  12. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/contact_manager/contact_manager_presenter.rb +0 -0
  13. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/contact_manager/contact_repository.rb +24 -99
  14. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/login.rb +0 -0
  15. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/tic_tac_toe.rb +0 -0
  16. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/tic_tac_toe/board.rb +0 -0
  17. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/tic_tac_toe/cell.rb +0 -0
  18. data/lib/{samples → glimmer-dsl-opal/samples}/hello/hello_browser.rb +0 -0
  19. data/lib/glimmer-dsl-opal/samples/hello/hello_combo.rb +63 -0
  20. data/lib/{samples → glimmer-dsl-opal/samples}/hello/hello_computed.rb +19 -19
  21. data/lib/{samples → glimmer-dsl-opal/samples}/hello/hello_computed/contact.rb +0 -0
  22. data/lib/glimmer-dsl-opal/samples/hello/hello_custom_shell.rb +155 -0
  23. data/lib/glimmer-dsl-opal/samples/hello/hello_custom_widget.rb +86 -0
  24. data/lib/{samples → glimmer-dsl-opal/samples}/hello/hello_list_multi_selection.rb +0 -0
  25. data/lib/{samples → glimmer-dsl-opal/samples}/hello/hello_list_single_selection.rb +0 -0
  26. data/lib/glimmer-dsl-opal/samples/hello/hello_tab.rb +50 -0
  27. data/lib/glimmer-dsl-opal/samples/hello/hello_world.rb +29 -0
  28. data/lib/glimmer-dsl-opal/vendor/jquery.js +2 -0
  29. data/lib/glimmer/data_binding/element_binding.rb +1 -1
  30. data/lib/glimmer/data_binding/ext/observable_model.rb +6 -6
  31. data/lib/glimmer/data_binding/list_selection_binding.rb +1 -1
  32. data/lib/glimmer/data_binding/table_items_binding.rb +70 -0
  33. data/lib/glimmer/dsl/opal/async_exec_expression.rb +2 -2
  34. data/lib/glimmer/dsl/opal/color_expression.rb +38 -0
  35. data/lib/glimmer/dsl/opal/column_properties_expression.rb +22 -0
  36. data/lib/glimmer/dsl/opal/combo_selection_data_binding_expression.rb +2 -2
  37. data/lib/glimmer/dsl/opal/custom_widget_expression.rb +77 -0
  38. data/lib/glimmer/dsl/opal/dsl.rb +15 -14
  39. data/lib/glimmer/dsl/opal/font_expression.rb +47 -0
  40. data/lib/glimmer/dsl/opal/layout_data_expression.rb +2 -2
  41. data/lib/glimmer/dsl/opal/layout_expression.rb +22 -0
  42. data/lib/glimmer/dsl/opal/list_selection_data_binding_expression.rb +2 -3
  43. data/lib/glimmer/dsl/opal/message_box_expression.rb +2 -2
  44. data/lib/glimmer/dsl/opal/property_expression.rb +5 -2
  45. data/lib/glimmer/dsl/opal/rgb_expression.rb +32 -0
  46. data/lib/glimmer/dsl/opal/rgba_expression.rb +32 -0
  47. data/lib/glimmer/dsl/opal/shell_expression.rb +18 -2
  48. data/lib/glimmer/dsl/opal/swt_expression.rb +46 -0
  49. data/lib/glimmer/dsl/opal/{composite_expression.rb → table_column_expression.rb} +3 -3
  50. data/lib/glimmer/dsl/opal/{list_expression.rb → table_expression.rb} +3 -3
  51. data/lib/glimmer/dsl/opal/table_items_data_binding_expression.rb +29 -0
  52. data/lib/glimmer/dsl/opal/widget_expression.rb +24 -0
  53. data/lib/glimmer/dsl/opal/widget_listener_expression.rb +16 -3
  54. data/lib/glimmer/swt.rb +499 -0
  55. data/lib/glimmer/swt/browser_proxy.rb +27 -0
  56. data/lib/glimmer/swt/button_proxy.rb +40 -0
  57. data/lib/glimmer/swt/color_proxy.rb +119 -0
  58. data/lib/glimmer/{opal/select_proxy.rb → swt/combo_proxy.rb} +24 -19
  59. data/lib/glimmer/swt/composite_proxy.rb +31 -0
  60. data/lib/glimmer/{opal → swt}/display_proxy.rb +6 -4
  61. data/lib/glimmer/{opal → swt}/event_listener_proxy.rb +1 -1
  62. data/lib/glimmer/swt/fill_layout_proxy.rb +84 -0
  63. data/lib/glimmer/swt/font_proxy.rb +79 -0
  64. data/lib/glimmer/swt/grid_layout_proxy.rb +71 -0
  65. data/lib/glimmer/swt/label_proxy.rb +34 -0
  66. data/lib/glimmer/swt/layout_data_proxy.rb +87 -0
  67. data/lib/glimmer/swt/layout_proxy.rb +63 -0
  68. data/lib/glimmer/{opal → swt}/list_proxy.rb +31 -23
  69. data/lib/glimmer/swt/message_box_proxy.rb +143 -0
  70. data/lib/glimmer/{opal → swt}/point.rb +1 -1
  71. data/lib/glimmer/{opal → swt}/property_owner.rb +1 -1
  72. data/lib/glimmer/swt/row_layout_proxy.rb +105 -0
  73. data/lib/glimmer/swt/shell_proxy.rb +246 -0
  74. data/lib/glimmer/swt/style_constantizable.rb +154 -0
  75. data/lib/glimmer/swt/swt_proxy.rb +53 -0
  76. data/lib/glimmer/{opal/tab_folder.rb → swt/tab_folder_proxy.rb} +21 -15
  77. data/lib/glimmer/swt/tab_item_proxy.rb +84 -0
  78. data/lib/glimmer/swt/table_column_proxy.rb +56 -0
  79. data/lib/glimmer/swt/table_item_proxy.rb +147 -0
  80. data/lib/glimmer/swt/table_proxy.rb +159 -0
  81. data/lib/glimmer/swt/text_proxy.rb +46 -0
  82. data/lib/glimmer/swt/widget_proxy.rb +490 -0
  83. data/lib/glimmer/ui/custom_shell.rb +91 -0
  84. data/lib/glimmer/ui/custom_widget.rb +291 -0
  85. data/lib/glimmer/util/proc_tracker.rb +39 -0
  86. metadata +131 -76
  87. data/lib/glimmer/config.rb +0 -22
  88. data/lib/glimmer/dsl/engine.rb +0 -193
  89. data/lib/glimmer/dsl/expression.rb +0 -42
  90. data/lib/glimmer/dsl/expression_handler.rb +0 -48
  91. data/lib/glimmer/dsl/opal/browser_expression.rb +0 -17
  92. data/lib/glimmer/dsl/opal/button_expression.rb +0 -18
  93. data/lib/glimmer/dsl/opal/combo_expression.rb +0 -17
  94. data/lib/glimmer/dsl/opal/grid_layout_expression.rb +0 -17
  95. data/lib/glimmer/dsl/opal/label_expression.rb +0 -17
  96. data/lib/glimmer/dsl/opal/tab_folder_expression.rb +0 -17
  97. data/lib/glimmer/dsl/opal/tab_item_expression.rb +0 -17
  98. data/lib/glimmer/dsl/opal/text_expression.rb +0 -22
  99. data/lib/glimmer/dsl/parent_expression.rb +0 -12
  100. data/lib/glimmer/dsl/static_expression.rb +0 -36
  101. data/lib/glimmer/dsl/top_level_expression.rb +0 -7
  102. data/lib/glimmer/error.rb +0 -6
  103. data/lib/glimmer/invalid_keyword_error.rb +0 -6
  104. data/lib/glimmer/opal/div_proxy.rb +0 -22
  105. data/lib/glimmer/opal/document_proxy.rb +0 -178
  106. data/lib/glimmer/opal/element_proxy.rb +0 -287
  107. data/lib/glimmer/opal/grid_layout_proxy.rb +0 -54
  108. data/lib/glimmer/opal/iframe_proxy.rb +0 -23
  109. data/lib/glimmer/opal/input_proxy.rb +0 -45
  110. data/lib/glimmer/opal/label_proxy.rb +0 -25
  111. data/lib/glimmer/opal/layout_data_proxy.rb +0 -31
  112. data/lib/glimmer/opal/modal.rb +0 -94
  113. data/lib/glimmer/opal/tab_item.rb +0 -98
  114. data/lib/samples/elaborate/launch +0 -6
  115. data/lib/samples/hello/hello_combo.rb +0 -34
  116. data/lib/samples/hello/hello_tab.rb +0 -24
  117. data/lib/samples/hello/hello_world.rb +0 -8
  118. data/lib/samples/hello/launch +0 -10
  119. data/lib/samples/launch +0 -4
@@ -0,0 +1,53 @@
1
+ # Copyright (c) 2020 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'glimmer/swt'
23
+ require 'glimmer/swt/style_constantizable'
24
+
25
+ module Glimmer
26
+ module SWT
27
+ # Proxy for org.eclipse.swt.SWT
28
+ #
29
+ # Follows the Proxy Design Pattern
30
+ class SWTProxy
31
+ include StyleConstantizable
32
+
33
+ class << self
34
+ def constant_source_class
35
+ SWT
36
+ end
37
+
38
+ def constant_value_none
39
+ SWT::NONE
40
+ end
41
+
42
+ def extra_styles
43
+ EXTRA_STYLES
44
+ end
45
+ end
46
+
47
+ EXTRA_STYLES = {
48
+ NO_RESIZE: self[:shell_trim, :resize!, :max!],
49
+ NO_SORT: -7,
50
+ }
51
+ end
52
+ end
53
+ end
@@ -1,8 +1,8 @@
1
- require 'glimmer/opal/div_proxy'
1
+ require 'glimmer/swt/widget_proxy'
2
2
 
3
3
  module Glimmer
4
- module Opal
5
- class TabFolder < ElementProxy
4
+ module SWT
5
+ class TabFolderProxy < WidgetProxy
6
6
  attr_reader :tabs
7
7
 
8
8
  def initialize(parent, args)
@@ -11,35 +11,41 @@ module Glimmer
11
11
  end
12
12
 
13
13
  def add_child(child)
14
- super(child)
14
+ unless @children.include?(child)
15
+ @children << child
16
+ tabs_dom_element.append(child.tab_dom)
17
+ child.render
18
+ end
19
+
15
20
  if @children.size == 1
16
21
  child.show
17
22
  end
18
- end
23
+ end
19
24
 
20
25
  def hide_all_tab_content
21
26
  @children.each(&:hide)
22
27
  end
23
28
 
24
- def name
25
- 'div'
29
+ def tabs_path
30
+ path + " > ##{tabs_id}"
31
+ end
32
+
33
+ def tabs_id
34
+ id + '-tabs'
26
35
  end
27
36
 
28
- def tabs_dom
29
- tabs_id = id + '-tabs'
30
- @tabs_dom ||= DOM {
31
- div(id: tabs_id, class: 'tabs')
32
- }
37
+ def tabs_dom_element
38
+ Document.find(tabs_path)
33
39
  end
34
40
 
35
41
  def dom
36
42
  tab_folder_id = id
37
43
  tab_folder_id_style = css
38
- @dom ||= DOM {
44
+ @dom ||= html {
39
45
  div(id: tab_folder_id, style: tab_folder_id_style, class: 'tab-folder') {
40
-
46
+ div(id: tabs_id, class: 'tabs')
41
47
  }
42
- }.tap {|the_dom| the_dom << tabs_dom }
48
+ }.to_s
43
49
  end
44
50
  end
45
51
  end
@@ -0,0 +1,84 @@
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
+ content {
12
+ on_widget_selected {
13
+ @parent.hide_all_tab_content
14
+ show
15
+ }
16
+ }
17
+ end
18
+
19
+ def show
20
+ @content_visible = true
21
+ dom_element.remove_class('hide')
22
+ tab_dom_element.add_class('selected')
23
+ end
24
+
25
+ def hide
26
+ @content_visible = false
27
+ dom_element.add_class('hide')
28
+ tab_dom_element.remove_class('selected')
29
+ end
30
+
31
+ def text=(value)
32
+ @text = value
33
+ tab_dom_element.html(@text)
34
+ end
35
+
36
+ def selector
37
+ super + '-tab'
38
+ end
39
+
40
+ def observation_request_to_event_mapping
41
+ {
42
+ 'on_widget_selected' => {
43
+ event: 'click'
44
+ },
45
+ }
46
+ end
47
+
48
+ def listener_path
49
+ tab_path
50
+ end
51
+
52
+ def tab_path
53
+ "#{parent.tabs_path} > ##{tab_id}"
54
+ end
55
+
56
+ def tab_dom_element
57
+ Document.find(tab_path)
58
+ end
59
+
60
+ def tab_id
61
+ id + '-tab'
62
+ end
63
+
64
+ # This contains the clickable tab area with tab names
65
+ def tab_dom
66
+ @tab_dom ||= html {
67
+ button(id: tab_id, class: "tab") {
68
+ @text
69
+ }
70
+ }.to_s
71
+ end
72
+
73
+ # This contains the tab content
74
+ def dom
75
+ tab_item_id = id
76
+ tab_item_class_string = [name, 'hide'].join(' ')
77
+ @dom ||= html {
78
+ div(id: tab_item_id, class: tab_item_class_string) {
79
+ }
80
+ }.to_s
81
+ end
82
+ end
83
+ end
84
+ 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,159 @@
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 element
109
+ 'table'
110
+ end
111
+
112
+ def columns_path
113
+ path + ' thead tr'
114
+ end
115
+
116
+ def columns_dom_element
117
+ Document.find(columns_path)
118
+ end
119
+
120
+ def items_path
121
+ path + ' tbody'
122
+ end
123
+
124
+ def items_dom_element
125
+ Document.find(items_path)
126
+ end
127
+
128
+ def columns_dom
129
+ tr {
130
+ }
131
+ end
132
+
133
+ def thead_dom
134
+ thead {
135
+ columns_dom
136
+ }
137
+ end
138
+
139
+ def items_dom
140
+ tbody {
141
+ }
142
+ end
143
+
144
+ def dom
145
+ table_id = id
146
+ table_id_style = css
147
+ table_id_css_classes = css_classes
148
+ table_id_css_classes << 'table'
149
+ table_id_css_classes_string = table_id_css_classes.to_a.join(' ')
150
+ @dom ||= html {
151
+ table(id: table_id, style: table_id_style, class: table_id_css_classes_string) {
152
+ thead_dom
153
+ items_dom
154
+ }
155
+ }.to_s
156
+ end
157
+ end
158
+ end
159
+ end