scarpe 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (223) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/CHANGELOG.md +16 -2
  4. data/Gemfile.lock +7 -3
  5. data/README.md +24 -8
  6. data/Rakefile +1 -1
  7. data/examples/animate.rb +20 -0
  8. data/examples/arrow.rb +10 -0
  9. data/examples/btn_tooltip.rb +7 -0
  10. data/examples/button_style_changed.rb +7 -0
  11. data/examples/button_styles_default.rb +6 -0
  12. data/examples/gen.rb +8 -8
  13. data/examples/highlander.rb +3 -3
  14. data/examples/legacy/README.md +6 -0
  15. data/examples/legacy/not_checked/shoes-contrib/basic/shoes-notes.rb +1 -1
  16. data/examples/legacy/not_checked/simple/anim-shapes.rb +1 -1
  17. data/examples/legacy/not_checked/speedometer_app.rb +55 -0
  18. data/examples/legacy/working/simple/image-icon.rb +3 -0
  19. data/examples/legacy/{not_checked → working}/simple/image.rb +1 -1
  20. data/examples/list_box_choose.rb +17 -0
  21. data/examples/local_assets/local_file_server.rb +82 -0
  22. data/examples/local_assets/sample.gif +0 -0
  23. data/examples/local_assets/sample.mp4 +0 -0
  24. data/examples/local_fonts.rb +2 -2
  25. data/examples/local_images.rb +2 -3
  26. data/examples/para/para_text.rb +14 -0
  27. data/examples/progress.rb +31 -0
  28. data/examples/radio/radio_groups.rb +2 -2
  29. data/examples/rect.rb +4 -0
  30. data/examples/rotate_shapes.rb +17 -0
  31. data/examples/simpler-menu.rb +21 -0
  32. data/exe/scarpe +2 -1
  33. data/lacci/Gemfile +2 -0
  34. data/lacci/Gemfile.lock +8 -1
  35. data/lacci/lacci.gemspec +1 -1
  36. data/lacci/lib/lacci/scarpe_cli.rb +2 -1
  37. data/lacci/lib/lacci/scarpe_core.rb +2 -1
  38. data/lacci/lib/lacci/version.rb +1 -1
  39. data/lacci/lib/scarpe/niente/app.rb +23 -0
  40. data/lacci/lib/scarpe/niente/display_service.rb +62 -0
  41. data/lacci/lib/scarpe/niente/drawable.rb +57 -0
  42. data/lacci/lib/scarpe/niente/logger.rb +29 -0
  43. data/lacci/lib/scarpe/niente/shoes_spec.rb +87 -0
  44. data/lacci/lib/scarpe/niente.rb +20 -0
  45. data/lacci/lib/shoes/app.rb +88 -43
  46. data/lacci/lib/shoes/background.rb +2 -2
  47. data/lacci/lib/shoes/border.rb +2 -2
  48. data/lacci/lib/shoes/builtins.rb +63 -0
  49. data/lacci/lib/shoes/changelog.rb +52 -0
  50. data/lacci/lib/shoes/colors.rb +3 -1
  51. data/lacci/lib/shoes/constants.rb +19 -1
  52. data/lacci/lib/shoes/display_service.rb +39 -16
  53. data/lacci/lib/shoes/download.rb +2 -2
  54. data/lacci/lib/shoes/drawable.rb +380 -0
  55. data/lacci/lib/shoes/drawables/arc.rb +49 -0
  56. data/lacci/lib/shoes/drawables/arrow.rb +41 -0
  57. data/lacci/lib/shoes/drawables/button.rb +73 -0
  58. data/lacci/lib/shoes/{widgets → drawables}/check.rb +5 -4
  59. data/lacci/lib/shoes/{widgets → drawables}/document_root.rb +3 -3
  60. data/lacci/lib/shoes/{widgets → drawables}/edit_box.rb +6 -6
  61. data/lacci/lib/shoes/{widgets → drawables}/edit_line.rb +6 -6
  62. data/lacci/lib/shoes/{widgets → drawables}/flow.rb +6 -6
  63. data/lacci/lib/shoes/{widgets → drawables}/image.rb +6 -6
  64. data/lacci/lib/shoes/{widgets → drawables}/line.rb +7 -5
  65. data/lacci/lib/shoes/drawables/link.rb +34 -0
  66. data/lacci/lib/shoes/drawables/list_box.rb +56 -0
  67. data/lacci/lib/shoes/drawables/para.rb +118 -0
  68. data/lacci/lib/shoes/drawables/progress.rb +14 -0
  69. data/lacci/lib/shoes/drawables/radio.rb +33 -0
  70. data/lacci/lib/shoes/drawables/rect.rb +17 -0
  71. data/lacci/lib/shoes/{widgets → drawables}/shape.rb +6 -7
  72. data/lacci/lib/shoes/{widgets → drawables}/slot.rb +32 -20
  73. data/lacci/lib/shoes/{widgets → drawables}/span.rb +8 -7
  74. data/lacci/lib/shoes/{widgets → drawables}/stack.rb +6 -4
  75. data/lacci/lib/shoes/drawables/star.rb +50 -0
  76. data/lacci/lib/shoes/drawables/subscription_item.rb +93 -0
  77. data/lacci/lib/shoes/drawables/text_drawable.rb +63 -0
  78. data/lacci/lib/shoes/drawables/video.rb +16 -0
  79. data/lacci/lib/shoes/drawables/widget.rb +69 -0
  80. data/lacci/lib/shoes/drawables.rb +31 -0
  81. data/lacci/lib/shoes/errors.rb +28 -0
  82. data/lacci/lib/shoes/log.rb +2 -2
  83. data/lacci/lib/shoes/ruby_extensions.rb +15 -0
  84. data/lacci/lib/shoes/spacing.rb +2 -2
  85. data/lacci/lib/shoes-spec.rb +93 -0
  86. data/lacci/lib/shoes.rb +27 -7
  87. data/lacci/test/test_helper.rb +54 -0
  88. data/lacci/test/test_lacci.rb +12 -3
  89. data/lacci/test/test_shoes_errors.rb +49 -0
  90. data/lib/scarpe/cats_cradle.rb +81 -59
  91. data/lib/scarpe/errors.rb +77 -0
  92. data/lib/scarpe/evented_assertions.rb +50 -17
  93. data/lib/scarpe/shoes_spec.rb +181 -0
  94. data/lib/scarpe/version.rb +2 -2
  95. data/lib/scarpe/wv/app.rb +20 -20
  96. data/lib/scarpe/wv/arc.rb +4 -47
  97. data/lib/scarpe/wv/arrow.rb +9 -0
  98. data/lib/scarpe/wv/button.rb +7 -35
  99. data/lib/scarpe/wv/check.rb +3 -5
  100. data/lib/scarpe/wv/control_interface.rb +18 -20
  101. data/lib/scarpe/wv/document_root.rb +81 -4
  102. data/lib/scarpe/wv/{widget.rb → drawable.rb} +66 -43
  103. data/lib/scarpe/wv/edit_box.rb +4 -17
  104. data/lib/scarpe/wv/edit_line.rb +4 -18
  105. data/lib/scarpe/wv/flow.rb +2 -18
  106. data/lib/scarpe/wv/image.rb +8 -28
  107. data/lib/scarpe/wv/line.rb +3 -25
  108. data/lib/scarpe/wv/link.rb +3 -16
  109. data/lib/scarpe/wv/list_box.rb +6 -29
  110. data/lib/scarpe/wv/para.rb +11 -30
  111. data/lib/scarpe/wv/progress.rb +19 -0
  112. data/lib/scarpe/wv/radio.rb +9 -10
  113. data/lib/scarpe/wv/rect.rb +13 -0
  114. data/lib/scarpe/wv/shape.rb +3 -8
  115. data/lib/scarpe/wv/slot.rb +8 -25
  116. data/lib/scarpe/wv/span.rb +3 -27
  117. data/lib/scarpe/wv/stack.rb +2 -18
  118. data/lib/scarpe/wv/star.rb +3 -53
  119. data/lib/scarpe/wv/subscription_item.rb +38 -4
  120. data/lib/scarpe/wv/text_drawable.rb +32 -0
  121. data/lib/scarpe/wv/video.rb +15 -15
  122. data/lib/scarpe/wv/web_wrangler.rb +299 -329
  123. data/lib/scarpe/wv/webview_local_display.rb +48 -33
  124. data/lib/scarpe/wv/webview_relay_display.rb +12 -12
  125. data/lib/scarpe/wv/webview_relay_util.rb +7 -10
  126. data/lib/scarpe/wv/wv_display_worker.rb +2 -2
  127. data/lib/scarpe/wv.rb +45 -12
  128. data/lib/scarpe/wv_local.rb +1 -1
  129. data/lib/scarpe/wv_relay.rb +1 -1
  130. data/lib/scarpe.rb +1 -0
  131. data/logger/debug_web_wrangler.json +1 -1
  132. data/logger/scarpe_wv_test.json +1 -1
  133. data/scarpe-components/Gemfile.lock +86 -0
  134. data/scarpe-components/lib/scarpe/components/base64.rb +3 -7
  135. data/scarpe-components/lib/scarpe/components/calzini/alert.rb +49 -0
  136. data/scarpe-components/lib/scarpe/components/calzini/art_widgets.rb +203 -0
  137. data/scarpe-components/lib/scarpe/components/calzini/button.rb +39 -0
  138. data/scarpe-components/lib/scarpe/components/calzini/misc.rb +146 -0
  139. data/scarpe-components/lib/scarpe/components/calzini/para.rb +35 -0
  140. data/scarpe-components/lib/scarpe/components/calzini/slots.rb +155 -0
  141. data/scarpe-components/lib/scarpe/components/calzini/text_widgets.rb +65 -0
  142. data/scarpe-components/lib/scarpe/components/calzini.rb +149 -0
  143. data/scarpe-components/lib/scarpe/components/errors.rb +20 -0
  144. data/scarpe-components/lib/scarpe/components/file_helpers.rb +1 -0
  145. data/scarpe-components/lib/scarpe/components/html.rb +131 -0
  146. data/scarpe-components/lib/scarpe/components/minitest_export_reporter.rb +75 -0
  147. data/scarpe-components/lib/scarpe/components/minitest_import_runnable.rb +98 -0
  148. data/scarpe-components/lib/scarpe/components/minitest_result.rb +86 -0
  149. data/scarpe-components/lib/scarpe/components/modular_logger.rb +5 -5
  150. data/scarpe-components/lib/scarpe/components/print_logger.rb +9 -5
  151. data/scarpe-components/lib/scarpe/components/promises.rb +14 -14
  152. data/scarpe-components/lib/scarpe/components/segmented_file_loader.rb +36 -17
  153. data/scarpe-components/lib/scarpe/components/string_helpers.rb +10 -0
  154. data/scarpe-components/lib/scarpe/components/tiranti.rb +225 -0
  155. data/scarpe-components/lib/scarpe/components/unit_test_helpers.rb +45 -5
  156. data/scarpe-components/lib/scarpe/components/version.rb +2 -2
  157. data/scarpe-components/test/calzini/test_calzini_alert.rb +30 -0
  158. data/scarpe-components/test/calzini/test_calzini_art_drawables.rb +105 -0
  159. data/scarpe-components/test/calzini/test_calzini_button.rb +52 -0
  160. data/scarpe-components/test/calzini/test_calzini_misc.rb +115 -0
  161. data/scarpe-components/test/calzini/test_calzini_para.rb +37 -0
  162. data/scarpe-components/test/calzini/test_calzini_slots.rb +130 -0
  163. data/scarpe-components/test/calzini/test_calzini_text_drawables.rb +41 -0
  164. data/scarpe-components/test/mtr_data/exception.json +1 -0
  165. data/scarpe-components/test/mtr_data/fail_with_message.json +1 -0
  166. data/scarpe-components/test/mtr_data/skipped_no_message.json +1 -0
  167. data/scarpe-components/test/mtr_data/skipped_w_msg.json +1 -0
  168. data/scarpe-components/test/mtr_data/succeed_2_asserts.json +1 -0
  169. data/scarpe-components/test/test_dimensions.rb +26 -0
  170. data/scarpe-components/test/test_helper.rb +20 -0
  171. data/scarpe-components/test/test_html.rb +65 -0
  172. data/scarpe-components/test/test_minitest_result.rb +61 -0
  173. data/scarpe-components/test/test_promises.rb +5 -4
  174. data/scarpe-components/test/test_segmented_app_files.rb +8 -6
  175. data/scarpegen.rb +14 -14
  176. data/sig/scarpe.rbs +1 -1
  177. data/templates/basic_class_template.erb +13 -14
  178. data/templates/class_template_with_event_bind.erb +4 -4
  179. data/templates/class_template_with_shapes.erb +8 -17
  180. data/templates/example_template.erb +1 -1
  181. data/templates/module_template.erb +4 -4
  182. data/templates/webview_template.erb +3 -2
  183. metadata +113 -55
  184. data/examples/legacy/not_checked/shoes-contrib/elements/image-icon.rb +0 -3
  185. data/lacci/lib/shoes/widget.rb +0 -218
  186. data/lacci/lib/shoes/widgets/alert.rb +0 -19
  187. data/lacci/lib/shoes/widgets/arc.rb +0 -51
  188. data/lacci/lib/shoes/widgets/button.rb +0 -35
  189. data/lacci/lib/shoes/widgets/font.rb +0 -14
  190. data/lacci/lib/shoes/widgets/link.rb +0 -25
  191. data/lacci/lib/shoes/widgets/list_box.rb +0 -25
  192. data/lacci/lib/shoes/widgets/para.rb +0 -68
  193. data/lacci/lib/shoes/widgets/radio.rb +0 -35
  194. data/lacci/lib/shoes/widgets/star.rb +0 -44
  195. data/lacci/lib/shoes/widgets/subscription_item.rb +0 -60
  196. data/lacci/lib/shoes/widgets/text_widget.rb +0 -51
  197. data/lacci/lib/shoes/widgets/video.rb +0 -15
  198. data/lacci/lib/shoes/widgets.rb +0 -29
  199. data/lib/scarpe/wv/alert.rb +0 -66
  200. data/lib/scarpe/wv/background.rb +0 -27
  201. data/lib/scarpe/wv/border.rb +0 -24
  202. data/lib/scarpe/wv/control_interface_test.rb +0 -238
  203. data/lib/scarpe/wv/dimensions.rb +0 -22
  204. data/lib/scarpe/wv/font.rb +0 -36
  205. data/lib/scarpe/wv/html.rb +0 -108
  206. data/lib/scarpe/wv/spacing.rb +0 -41
  207. data/lib/scarpe/wv/text_widget.rb +0 -30
  208. /data/examples/legacy/not_checked/{expert → shoes-contrib/basic}/definr.rb +0 -0
  209. /data/examples/legacy/not_checked/{expert → shoes-contrib/basic}/funnies.rb +0 -0
  210. /data/examples/legacy/not_checked/shoes-contrib/{elements → basic}/list_box-select-class.rb +0 -0
  211. /data/examples/legacy/{not_checked/shoes-contrib/basic → working/simple}/basic-edit-box.rb +0 -0
  212. /data/examples/legacy/{not_checked/shoes-contrib/elements → working/simple}/basic-fps.rb +0 -0
  213. /data/examples/legacy/{not_checked/shoes-contrib/elements → working/simple}/border-cat.rb +0 -0
  214. /data/examples/legacy/{not_checked/shoes-contrib/elements → working/simple}/check-mate.rb +0 -0
  215. /data/examples/legacy/{not_checked/shoes-contrib/manipulation → working/simple}/clear-slot.rb +0 -0
  216. /data/examples/legacy/{not_checked/shoes-contrib/basic → working/simple}/clock.rb +0 -0
  217. /data/examples/legacy/{not_checked/shoes-contrib/basic → working/simple}/gradient-shoes.rb +0 -0
  218. /data/examples/legacy/{not_checked/shoes-contrib/basic → working/simple}/list_box-shape-report.rb +0 -0
  219. /data/examples/legacy/{not_checked/shoes-contrib/elements → working/simple}/list_box.rb +0 -0
  220. /data/examples/legacy/{not_checked/shoes-contrib/elements → working/simple}/phat-button.rb +0 -0
  221. /data/examples/legacy/{not_checked/shoes-contrib → working}/simple/simple-calc.rb +0 -0
  222. /data/examples/legacy/{not_checked/shoes-contrib/position → working/simple}/stack-width.rb +0 -0
  223. /data/examples/legacy/{not_checked/shoes-contrib/elements → working/simple}/width-introspec.rb +0 -0
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class Scarpe
4
- # This is the simplest type of Webview DisplayService. It creates Webview widgets
5
- # corresponding to Shoes widgets, manages the Webview and its DOM tree, and
3
+ module Scarpe
4
+ # This is the simplest type of Webview DisplayService. It creates Webview drawables
5
+ # corresponding to Shoes drawables, manages the Webview and its DOM tree, and
6
6
  # generally keeps the Shoes/Webview connection working.
7
7
  #
8
8
  # This is an in-process Webview-based display service, with all the limitations that
@@ -10,7 +10,7 @@ class Scarpe
10
10
  # process, too many or too large evals can crash the process, etc.
11
11
  # Frequently it's better to use a RelayDisplayService to a second
12
12
  # process containing one of these.
13
- class WebviewDisplayService < Shoes::DisplayService
13
+ class Webview::DisplayService < Shoes::DisplayService
14
14
  include Shoes::Log
15
15
 
16
16
  class << self
@@ -20,67 +20,82 @@ class Scarpe
20
20
  # The ControlInterface is used to handle internal events in Webview Scarpe
21
21
  attr_reader :control_interface
22
22
 
23
- # The DocumentRoot is the top widget of the Webview-side widget tree
23
+ # The DocumentRoot is the top drawable of the Webview-side drawable tree
24
24
  attr_reader :doc_root
25
25
 
26
- # app is the Scarpe::WebviewApp
26
+ # app is the Scarpe::Webview::App
27
27
  attr_reader :app
28
28
 
29
29
  # wrangler is the Scarpe::WebWrangler
30
30
  attr_reader :wrangler
31
31
 
32
- # This is called before any of the various WebviewWidgets are created, to be
32
+ # This is called before any of the various Webview::Drawables are created, to be
33
33
  # able to create them and look them up.
34
34
  def initialize
35
- if WebviewDisplayService.instance
36
- raise "ERROR! This is meant to be a singleton!"
35
+ if Webview::DisplayService.instance
36
+ raise Shoes::Errors::SingletonError, "ERROR! This is meant to be a singleton!"
37
37
  end
38
38
 
39
- WebviewDisplayService.instance = self
39
+ Webview::DisplayService.instance = self
40
40
 
41
41
  super()
42
- log_init("WV::WebviewDisplayService")
42
+ log_init("Webview::DisplayService")
43
43
 
44
- @display_widget_for = {}
44
+ @display_drawable_for = {}
45
45
  end
46
46
 
47
- # Create a Webview display widget for a specific Shoes widget, and pair it with
48
- # the linkable ID for this Shoes widget.
47
+ # Create a Webview display drawable for a specific Shoes drawable, and pair it with
48
+ # the linkable ID for this Shoes drawable.
49
49
  #
50
- # @param widget_class_name [String] The class name of the Shoes widget, e.g. Shoes::Button
51
- # @param widget_id [String] the linkable ID for widget events
52
- # @param properties [Hash] a JSON-serialisable Hash with the widget's display properties
53
- # @return [WebviewWidget] the newly-created Webview widget
54
- def create_display_widget_for(widget_class_name, widget_id, properties)
55
- if widget_class_name == "App"
50
+ # @param drawable_class_name [String] The class name of the Shoes drawable, e.g. Shoes::Button
51
+ # @param drawable_id [String] the linkable ID for drawable events
52
+ # @param properties [Hash] a JSON-serialisable Hash with the drawable's Shoes styles
53
+ # @param is_widget [Boolean] whether the class is a user-defined Shoes::Widget subclass
54
+ # @return [Webview::Drawable] the newly-created Webview drawable
55
+ def create_display_drawable_for(drawable_class_name, drawable_id, properties, is_widget:)
56
+ existing = query_display_drawable_for(drawable_id, nil_ok: true)
57
+ if existing
58
+ @log.warn("There is already a display drawable for #{drawable_id.inspect}! Returning #{existing.class.name}.")
59
+ return existing
60
+ end
61
+
62
+ if drawable_class_name == "App"
56
63
  unless @doc_root
57
- raise "WebviewDocumentRoot is supposed to be created before WebviewApp!"
64
+ raise Scarpe::MissingDocRootError, "Webview::DocumentRoot is supposed to be created before Webview::App!"
58
65
  end
59
66
 
60
- display_app = Scarpe::WebviewApp.new(properties)
67
+ display_app = Scarpe::Webview::App.new(properties)
61
68
  display_app.document_root = @doc_root
62
69
  @control_interface = display_app.control_interface
63
70
  @control_interface.doc_root = @doc_root
64
71
  @app = @control_interface.app
65
72
  @wrangler = @control_interface.wrangler
66
73
 
67
- set_widget_pairing(widget_id, display_app)
74
+ set_drawable_pairing(drawable_id, display_app)
68
75
 
69
76
  return display_app
70
77
  end
71
78
 
72
- # Create a corresponding display widget
73
- display_class = Scarpe::WebviewWidget.display_class_for(widget_class_name)
74
- display_widget = display_class.new(properties)
75
- set_widget_pairing(widget_id, display_widget)
79
+ # Create a corresponding display drawable
80
+
81
+ if is_widget
82
+ display_class = Scarpe::Webview::Flow
83
+ else
84
+ display_class = Scarpe::Webview::Drawable.display_class_for(drawable_class_name)
85
+ unless display_class < Scarpe::Webview::Drawable
86
+ raise Scarpe::BadDisplayClassType, "Wrong display class type #{display_class.inspect} for class name #{drawable_class_name.inspect}!"
87
+ end
88
+ end
89
+ display_drawable = display_class.new(properties)
90
+ set_drawable_pairing(drawable_id, display_drawable)
76
91
 
77
- if widget_class_name == "DocumentRoot"
78
- # WebviewDocumentRoot is created before WebviewApp. Mostly doc_root is just like any other widget,
79
- # but we'll want a reference to it when we create WebviewApp.
80
- @doc_root = display_widget
92
+ if drawable_class_name == "DocumentRoot"
93
+ # DocumentRoot is created before App. Mostly doc_root is just like any other drawable,
94
+ # but we'll want a reference to it when we create App.
95
+ @doc_root = display_drawable
81
96
  end
82
97
 
83
- display_widget
98
+ display_drawable
84
99
  end
85
100
 
86
101
  # Destroy the display service and the app. Quit the process (eventually.)
@@ -88,7 +103,7 @@ class Scarpe
88
103
  # @return [void]
89
104
  def destroy
90
105
  @app.destroy
91
- WebviewDisplayService.instance = nil
106
+ Webview::DisplayService.instance = nil
92
107
  end
93
108
  end
94
109
  end
@@ -5,16 +5,16 @@ require "rbconfig"
5
5
 
6
6
  require_relative "webview_relay_util"
7
7
 
8
- class Scarpe
8
+ module Scarpe
9
9
  # This display service creates a child process and sends events
10
- # back and forth, but creates no widgets of its own. The child
11
- # process will spawn a worker with its own WebviewDisplayService
10
+ # back and forth, but creates no drawables of its own. The child
11
+ # process will spawn a worker with its own Webview::DisplayService
12
12
  # where the real Webview exists. By splitting the Webview
13
- # process from the Shoes widgets, it can be easier to return
13
+ # process from the Shoes drawables, it can be easier to return
14
14
  # control to Webview's event handler promptly. Also, the Ruby
15
15
  # process could run background threads if it wanted, and
16
16
  # otherwise behave like a process ***not*** containing Webview.
17
- class WVRelayDisplayService < Shoes::DisplayService
17
+ class Webview::RelayDisplayService < Shoes::DisplayService
18
18
  include Shoes::Log
19
19
  include WVRelayUtil # Needs Shoes::Log
20
20
 
@@ -23,7 +23,7 @@ class Scarpe
23
23
  # Create a Webview Relay Display Service
24
24
  def initialize
25
25
  super()
26
- log_init("WV::RelayDisplayService")
26
+ log_init("Webview::RelayDisplayService")
27
27
 
28
28
  @event_subs = []
29
29
  @shutdown = false
@@ -46,7 +46,7 @@ class Scarpe
46
46
  if event_name == "run"
47
47
  run_event_loop
48
48
  end
49
- rescue AppShutdownError
49
+ rescue Scarpe::AppShutdownError
50
50
  @shutdown = true
51
51
  @log.info("Attempting to shut down...")
52
52
  self.destroy
@@ -59,16 +59,16 @@ class Scarpe
59
59
  respond_to_datagram while ready_to_read?
60
60
  sleep 0.1
61
61
  end
62
- rescue AppShutdownError
62
+ rescue Scarpe::AppShutdownError
63
63
  @shutdown = true
64
64
  @log.info("Attempting to shut down...")
65
65
  self.destroy
66
66
  end
67
67
 
68
- # This method sends a message to the worker process to create a widget. No actual
69
- # widget is created or registered with the display service.
70
- def create_display_widget_for(widget_class_name, widget_id, properties)
71
- send_datagram({ type: :create, class_name: widget_class_name, id: widget_id, properties: })
68
+ # This method sends a message to the worker process to create a drawable. No actual
69
+ # drawable is created or registered with the display service.
70
+ def create_display_drawable_for(drawable_class_name, drawable_id, properties)
71
+ send_datagram({ type: :create, class_name: drawable_class_name, id: drawable_id, properties: })
72
72
  # Don't need to return anything. It wouldn't be used anyway.
73
73
  end
74
74
 
@@ -2,10 +2,7 @@
2
2
 
3
3
  require "socket"
4
4
 
5
- class Scarpe
6
- # An error occurred which would normally be handled by shutting down the app
7
- class AppShutdownError < Scarpe::Error; end
8
-
5
+ module Scarpe
9
6
  # WVRelayUtil defines the datagram format for the sockets that connect a parent
10
7
  # Shoes application with a child display server.
11
8
  #
@@ -24,7 +21,7 @@ class Scarpe
24
21
  return if r.nil?
25
22
 
26
23
  unless e.empty?
27
- raise "#{@i_am}: Got error on connection(s) from IO.select! Dying!"
24
+ raise Scarpe::ConnectionError, "#{@i_am}: Got error on connection(s) from IO.select! Dying!"
28
25
  end
29
26
 
30
27
  !r.empty?
@@ -43,7 +40,7 @@ class Scarpe
43
40
  until written == to_write
44
41
  count = @to.write(dgram_str.byteslice(written..-1))
45
42
  if count.nil? || count == 0
46
- raise "Something was wrong in send_datagram! Write returned #{count.inspect}!"
43
+ raise Scarpe::DatagramSendError, "Something was wrong in send_datagram! Write returned #{count.inspect}!"
47
44
  end
48
45
 
49
46
  written += count
@@ -73,7 +70,7 @@ class Scarpe
73
70
  new_bytes = @from.read(10)
74
71
  if new_bytes.nil?
75
72
  # This is perfectly normal, if the connection closed
76
- raise AppShutdownError, "Got an unexpected EOF reading datagram! " +
73
+ raise Scarpe::AppShutdownError, "Got an unexpected EOF reading datagram! " +
77
74
  "Did the #{@i_am == :child ? "parent" : "child"} process die?"
78
75
  end
79
76
  @readbuf << new_bytes
@@ -90,7 +87,7 @@ class Scarpe
90
87
  @readbuf << new_bytes
91
88
  end
92
89
  rescue
93
- raise AppShutdownError, "Got exception #{$!.class} when receiving datagram... #{$!.inspect}"
90
+ raise Scarpe::AppShutdownError, "Got exception #{$!.class} when receiving datagram... #{$!.inspect}"
94
91
  end
95
92
 
96
93
  # Read a datagram from the internal buffer and then dispatch it to the
@@ -109,9 +106,9 @@ class Scarpe
109
106
  **kwargs_hash,
110
107
  )
111
108
  elsif m_data["type"] == "create"
112
- raise "Parent process should never receive :create datagram!" if @i_am == :parent
109
+ raise Scarpe::InvalidOperationError, "Parent process should never receive :create datagram!" if @i_am == :parent
113
110
 
114
- @wv_display.create_display_widget_for(m_data["class_name"], m_data["id"], m_data["properties"])
111
+ @wv_display.create_display_drawable_for(m_data["class_name"], m_data["id"], m_data["properties"])
115
112
  elsif m_data["type"] == "destroy"
116
113
  if @i_am == :parent
117
114
  @shutdown = true
@@ -38,11 +38,11 @@ class Scarpe::Webview::ContainedService < Shoes::Linkable
38
38
  # @param to [Socket] a writable socket on which to send output to the Shoes process
39
39
  def initialize(from, to)
40
40
  super()
41
- log_init("WV::DisplayWorker")
41
+ log_init("Webview::DisplayWorker")
42
42
 
43
43
  @i_am = :child
44
44
  @event_subs = []
45
- @wv_display = Scarpe::WebviewDisplayService.new
45
+ @wv_display = Scarpe::Webview::DisplayService.new
46
46
 
47
47
  @from = from
48
48
  @to = to
data/lib/scarpe/wv.rb CHANGED
@@ -8,11 +8,26 @@ require "securerandom"
8
8
  require "json"
9
9
 
10
10
  require "bloops"
11
+ require "scarpe/components/html" # HTML renderer
11
12
  require "scarpe/components/modular_logger"
12
13
  require "scarpe/components/promises"
14
+ require "scarpe/components/string_helpers"
13
15
 
14
16
  # Module to contain the various Scarpe Webview classes
15
- module Scarpe::Webview; end
17
+ module Scarpe::Webview
18
+ HTML = Scarpe::Components::HTML
19
+ end
20
+
21
+ # Set up Scarpe-Webview's HTML renderer
22
+ ren = ENV["SCARPE_HTML_RENDERER"] || "calzini"
23
+ # This should *not* be require_relative so that other gems can implement HTML renderers.
24
+ require "scarpe/components/#{ren}"
25
+ class Scarpe::Webview::Drawable < Shoes::Linkable
26
+ # By default it's Scarpe::Components::Calzini
27
+ comp = Scarpe::Components::StringHelpers.camelize(ENV["SCARPE_HTML_RENDERER"] || "calzini")
28
+ mod = Scarpe::Components.const_get(comp)
29
+ include mod
30
+ end
16
31
 
17
32
  # Set up hierarchical logging using the SCARPE_LOG_CONFIG var for configuration
18
33
  log_config = if ENV["SCARPE_LOG_CONFIG"]
@@ -28,22 +43,38 @@ require "scarpe/components/segmented_file_loader"
28
43
  loader = Scarpe::Components::SegmentedFileLoader.new
29
44
  Shoes.add_file_loader loader
30
45
 
46
+ # Fun trivia: listing the full set of available fonts is a fingerprinting attack, so it's not
47
+ # available from JS. These are all commonly available web fonts, though.
48
+ Shoes::FONTS.push(
49
+ "Helvetica",
50
+ "Arial",
51
+ "Arial Black",
52
+ "Verdana",
53
+ "Tahoma",
54
+ "Trebuchet MS",
55
+ "Impact",
56
+ "Gill Sans",
57
+ "Times New Roman",
58
+ "Georgia",
59
+ "Palatino",
60
+ "Baskerville",
61
+ "Courier",
62
+ "Lucida",
63
+ "Monaco",
64
+ )
65
+
66
+ require_relative "shoes_spec"
67
+ Shoes::Spec.instance = Scarpe::Test
68
+
31
69
  require_relative "wv/web_wrangler"
32
70
  require_relative "wv/control_interface"
33
71
 
34
- require_relative "wv/widget"
35
-
36
- require_relative "wv/dimensions"
37
- require_relative "wv/html"
72
+ require_relative "wv/drawable"
38
73
 
39
- require_relative "wv/spacing"
40
74
  require_relative "wv/star"
41
75
  require_relative "wv/radio"
42
- require_relative "wv/background"
43
- require_relative "wv/border"
44
76
 
45
77
  require_relative "wv/arc"
46
- require_relative "wv/font"
47
78
 
48
79
  require_relative "wv/app"
49
80
  require_relative "wv/para"
@@ -57,12 +88,14 @@ require_relative "wv/image"
57
88
  require_relative "wv/edit_box"
58
89
  require_relative "wv/edit_line"
59
90
  require_relative "wv/list_box"
60
- require_relative "wv/alert"
61
- require_relative "wv/span"
62
91
  require_relative "wv/shape"
63
92
 
64
- require_relative "wv/text_widget"
93
+ require_relative "wv/text_drawable"
94
+ require_relative "wv/span"
65
95
  require_relative "wv/link"
66
96
  require_relative "wv/line"
97
+ require_relative "wv/rect"
67
98
  require_relative "wv/video"
68
99
  require_relative "wv/check"
100
+ require_relative "wv/progress"
101
+ require_relative "wv/arrow"
@@ -3,4 +3,4 @@
3
3
  require_relative "wv"
4
4
  require_relative "wv/webview_local_display"
5
5
 
6
- Shoes::DisplayService.set_display_service_class(Scarpe::WebviewDisplayService)
6
+ Shoes::DisplayService.set_display_service_class(Scarpe::Webview::DisplayService)
@@ -3,4 +3,4 @@
3
3
  require_relative "wv"
4
4
  require_relative "wv/webview_relay_display"
5
5
 
6
- Shoes::DisplayService.set_display_service_class(Scarpe::WVRelayDisplayService)
6
+ Shoes::DisplayService.set_display_service_class(Scarpe::Webview::RelayDisplayService)
data/lib/scarpe.rb CHANGED
@@ -10,4 +10,5 @@ require "lacci/scarpe_core"
10
10
 
11
11
  d_s = ENV["SCARPE_DISPLAY_SERVICE"] || "wv_local"
12
12
  # This is require, not require_relative, to allow gems to supply a new display service
13
+ require "scarpe/errors"
13
14
  require "scarpe/#{d_s}"
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "default": "warn",
3
- "WV::WebWrangler": ["debug", "logger/web_wrangler.log"]
3
+ "Webview::WebWrangler": ["debug", "logger/web_wrangler.log"]
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "default": ["debug", "logger/test_failure.log"],
3
- "WebviewAPI": ["debug", "logger/test_failure_wv_api.log"]
3
+ "Webview::API": ["debug", "logger/test_failure_wv_api.log"]
4
4
  }
@@ -0,0 +1,86 @@
1
+ PATH
2
+ remote: ../lacci
3
+ specs:
4
+ lacci (0.3.0)
5
+ scarpe-components
6
+
7
+ PATH
8
+ remote: .
9
+ specs:
10
+ scarpe-components (0.3.0)
11
+
12
+ GEM
13
+ remote: https://rubygems.org/
14
+ specs:
15
+ ansi (1.5.0)
16
+ ast (2.4.2)
17
+ base64 (0.1.1)
18
+ builder (3.2.4)
19
+ debug (1.8.0)
20
+ irb (>= 1.5.0)
21
+ reline (>= 0.3.1)
22
+ io-console (0.6.0)
23
+ irb (1.8.0)
24
+ rdoc (~> 6.5)
25
+ reline (>= 0.3.6)
26
+ json (2.6.3)
27
+ language_server-protocol (3.17.0.3)
28
+ minitest (5.19.0)
29
+ minitest-reporters (1.6.1)
30
+ ansi
31
+ builder
32
+ minitest (>= 5.0)
33
+ ruby-progressbar
34
+ nokogiri (1.15.4-x86_64-darwin)
35
+ racc (~> 1.4)
36
+ parallel (1.23.0)
37
+ parser (3.2.2.3)
38
+ ast (~> 2.4.1)
39
+ racc
40
+ psych (5.1.0)
41
+ stringio
42
+ racc (1.7.1)
43
+ rainbow (3.1.1)
44
+ rake (13.0.6)
45
+ rdoc (6.5.0)
46
+ psych (>= 4.0.0)
47
+ regexp_parser (2.8.1)
48
+ reline (0.3.8)
49
+ io-console (~> 0.5)
50
+ rexml (3.2.6)
51
+ rubocop (1.56.2)
52
+ base64 (~> 0.1.1)
53
+ json (~> 2.3)
54
+ language_server-protocol (>= 3.17.0)
55
+ parallel (~> 1.10)
56
+ parser (>= 3.2.2.3)
57
+ rainbow (>= 2.2.2, < 4.0)
58
+ regexp_parser (>= 1.8, < 3.0)
59
+ rexml (>= 3.2.5, < 4.0)
60
+ rubocop-ast (>= 1.28.1, < 2.0)
61
+ ruby-progressbar (~> 1.7)
62
+ unicode-display_width (>= 2.4.0, < 3.0)
63
+ rubocop-ast (1.29.0)
64
+ parser (>= 3.2.1.0)
65
+ rubocop-shopify (2.14.0)
66
+ rubocop (~> 1.51)
67
+ ruby-progressbar (1.13.0)
68
+ stringio (3.0.8)
69
+ unicode-display_width (2.4.2)
70
+
71
+ PLATFORMS
72
+ x86_64-darwin-22
73
+
74
+ DEPENDENCIES
75
+ debug
76
+ lacci!
77
+ minitest (~> 5.0)
78
+ minitest-reporters
79
+ nokogiri
80
+ rake (~> 13.0)
81
+ rubocop (~> 1.21)
82
+ rubocop-shopify
83
+ scarpe-components!
84
+
85
+ BUNDLED WITH
86
+ 2.4.14
@@ -3,9 +3,9 @@
3
3
  require "base64"
4
4
  require "uri"
5
5
 
6
- class Scarpe; end
6
+ module Scarpe; end
7
7
  module Scarpe::Components; end
8
- class Scarpe
8
+ module Scarpe
9
9
  module Components::Base64
10
10
  def valid_url?(string)
11
11
  uri = URI.parse(string)
@@ -14,11 +14,7 @@ class Scarpe
14
14
  false
15
15
  end
16
16
 
17
- def encode_file_to_base64(image_filename)
18
- directory_path = File.dirname(__FILE__, 5)
19
-
20
- image_path = File.join(directory_path, image_filename)
21
-
17
+ def encode_file_to_base64(image_path)
22
18
  image_data = File.binread(image_path)
23
19
 
24
20
  encoded_data = ::Base64.strict_encode64(image_data)
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Scarpe::Components::Calzini
4
+ def alert_element(props)
5
+ event = props["event_name"] || "click"
6
+ onclick = handler_js_code(event)
7
+
8
+ HTML.render do |h|
9
+ h.div(id: html_id, style: alert_overlay_style(props)) do
10
+ h.div(style: alert_modal_style) do
11
+ h.div(style: {}) { props["text"] }
12
+ h.button(style: {}, onclick: onclick) { "OK" }
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ # If the whole drawable is hidden, the parent style adds display:none
21
+ def alert_overlay_style(props)
22
+ {
23
+ position: "fixed",
24
+ top: "0",
25
+ left: "0",
26
+ width: "100%",
27
+ height: "100%",
28
+ overflow: "auto",
29
+ "z-index": "1",
30
+ background: "rgba(0,0,0,0.4)",
31
+ display: "flex",
32
+ "align-items": "center",
33
+ "justify-content": "center",
34
+ }.merge(drawable_style(props))
35
+ end
36
+
37
+ def alert_modal_style
38
+ {
39
+ "min-width": "200px",
40
+ "min-height": "50px",
41
+ padding: "10px",
42
+ display: "flex",
43
+ background: "#fefefe",
44
+ "flex-direction": "column",
45
+ "justify-content": "space-between",
46
+ "border-radius": "9px",
47
+ }
48
+ end
49
+ end