glimmer-dsl-opal 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 67893f26592de179a00e15688b7814762edd60ff1c036b1389d177437ffaae5d
4
+ data.tar.gz: 2a6362729a7ecbe86231f2bcab62e25a46caadee1dc82c7f8abd84180d437ea2
5
+ SHA512:
6
+ metadata.gz: f8ac369bb79fcd6b8b5c46ba357f807d393e99e49303f4d983efb9a1b54551a51a2b80536b2da1111097ce9ed912ae7f7ae6d7968778ade6cd0ec13f1b45e3f3
7
+ data.tar.gz: 517dbe5aa02c3c6027e9aca9be18c88a60c99c19c362dab098aa0ddb18c42faed884d0e6815a5cb7889fbec1f55c0e19543c843773f1e8720489baad07a7af73
@@ -0,0 +1,6 @@
1
+ # Change Log
2
+
3
+ ## 0.0.1
4
+
5
+ - Initial support for webifying Glimmer SWT apps
6
+ - Support for Shell and Label widgets (text property only).
@@ -0,0 +1,20 @@
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.
@@ -0,0 +1,133 @@
1
+ # Glimmer DSL for Opal 0.0.1 Beta (Web GUI for Desktop Apps)
2
+ [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-opal.svg)](http://badge.fury.io/rb/glimmer-dsl-opal)
3
+
4
+ [Glimmer](https://github.com/AndyObtiva/glimmer) DSL for Opal is a web GUI adaptor for desktop apps built with [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt).
5
+
6
+ It enables running [Glimmer](https://github.com/AndyObtiva/glimmer) desktop apps on the web via [Rails](https://rubyonrails.org/) 5 and [Opal](https://opalrb.com/) 1.
7
+
8
+ NOTE: Version 0.0.1 only supports Hello, World! capabilities.
9
+
10
+ ## Examples
11
+
12
+ ### Hello, World!
13
+
14
+ Glimmer code (from `samples/hello/hello_world.rb`):
15
+ ```ruby
16
+ require 'glimmer-dsl-opal'
17
+
18
+ include Glimmer
19
+
20
+ shell {
21
+ text 'Glimmer'
22
+ label {
23
+ text 'Hello, World!'
24
+ }
25
+ }.open
26
+ ```
27
+
28
+ Run:
29
+ ```
30
+ glimmer samples/hello/hello_world.rb
31
+ ```
32
+
33
+ Glimmer app:
34
+
35
+ ![Glimmer DSL for Opal Hello World](images/glimmer-dsl-opal-hello-world.png)
36
+
37
+ ## Background
38
+
39
+ Ruby is a dynamically-typed object-oriented language, which provides great productivity gains due to its powerful expressive syntax and dynamic nature. While it is proven by the Ruby on Rails framework for web development, it currently lacks a robust platform-independent framework for building desktop applications. Given that Java libraries can now be utilized in Ruby code through JRuby, Eclipse technologies, such as SWT, JFace, and RCP can help fill the gap of desktop application development with Ruby.
40
+
41
+ ## Pre-requisites
42
+
43
+ - Rails 5: [https://github.com/rails/rails/tree/5-2-stable](https://github.com/rails/rails/tree/5-2-stable)
44
+ - Opal 1: [https://github.com/opal/opal-rails](https://github.com/opal/opal-rails)
45
+
46
+ ## Setup
47
+
48
+ Please follow these instructions to make Glimmer desktop apps work in Opal inside Rails 5
49
+
50
+ Start a new Rails 5 app:
51
+
52
+ ```
53
+ rails new hello_world
54
+ ```
55
+
56
+ Follow instructions to setup opal with a rails application: config/initializers/assets.rb
57
+
58
+ Add the following to `Gemfile`:
59
+ ```
60
+ gem 'opal-rails'
61
+ gem 'opal-browser'
62
+ gem 'glimmer-dsl-opal', '~> 0.0.1', require: false
63
+ ```
64
+
65
+ Edit `config/initializers/assets.rb` and add:
66
+ ```
67
+ Opal.use_gem 'glimmer-dsl-opal'
68
+ ```
69
+
70
+ Add the following Glimmer code to `app/assets/javascripts/application.js.rb`
71
+
72
+ ```ruby
73
+ require 'glimmer-dsl-opal' # brings opal and opal browser too
74
+
75
+ include Glimmer
76
+
77
+ shell {
78
+ text 'Glimmer'
79
+ label {
80
+ text 'Hello, World!'
81
+ }
82
+ }
83
+ ```
84
+
85
+ Start the Rails server:
86
+ ```
87
+ rails s
88
+ ```
89
+
90
+ Visit `http://localhost:3000`
91
+
92
+ You should see "Hello, World!"
93
+
94
+ ![Glimmer DSL for Opal Hello World](images/glimmer-dsl-opal-hello-world.png)
95
+
96
+ ## Help
97
+
98
+ ### Issues
99
+
100
+ You may submit [issues](https://github.com/AndyObtiva/glimmer/issues) on [GitHub](https://github.com/AndyObtiva/glimmer/issues).
101
+
102
+ [Click here to submit an issue.](https://github.com/AndyObtiva/glimmer/issues)
103
+
104
+ ### IRC Channel
105
+
106
+ If you need live help, try the [#glimmer](http://widget.mibbit.com/?settings=7514b8a196f8f1de939a351245db7aa8&server=irc.mibbit.net&channel=%23glimmer) IRC channel on [irc.mibbit.net](http://widget.mibbit.com/?settings=7514b8a196f8f1de939a351245db7aa8&server=irc.mibbit.net&channel=%23glimmer). If no one was available, you may [leave a GitHub issue](https://github.com/AndyObtiva/glimmer/issues) to schedule a meetup on IRC.
107
+
108
+ [Click here to connect to #glimmer IRC channel immediately via a web interface.](http://widget.mibbit.com/?settings=7514b8a196f8f1de939a351245db7aa8&server=irc.mibbit.net&channel=%23glimmer)
109
+
110
+ ## Feature Suggestions
111
+
112
+ These features have been suggested. You might see them in a future version of Glimmer. You are welcome to contribute more feature suggestions.
113
+
114
+ [TODO.md](TODO.md)
115
+
116
+ ## Change Log
117
+
118
+ [CHANGELOG.md](CHANGELOG.md)
119
+
120
+ ## Contributing
121
+
122
+ [CONTRIBUTING.md](CONTRIBUTING.md)
123
+
124
+ ## Contributors
125
+
126
+ * [Andy Maleh](https://github.com/AndyObtiva) (Founder)
127
+
128
+ [Click here to view contributor commits.](https://github.com/AndyObtiva/glimmer-dsl-opal/graphs/contributors)
129
+
130
+ ## License
131
+
132
+ Copyright (c) 2020 Andy Maleh.
133
+ See LICENSE.txt for further details.
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,8 @@
1
+ # if RUBY_ENGINE == 'opal' # or test if env is test
2
+ $LOAD_PATH.unshift(File.expand_path('..', __FILE__))
3
+
4
+ require 'opal'
5
+ require 'glimmer'
6
+
7
+ require 'glimmer/dsl/opal/dsl'
8
+ # end
@@ -0,0 +1,22 @@
1
+ module Glimmer
2
+ module Config
3
+ class << self
4
+ # Returns Glimmer logger (standard Ruby logger)
5
+ def logger
6
+ # unless defined? @@logger
7
+ # @@logger = Logger.new(STDOUT).tap {|logger| logger.level = Logger::WARN}
8
+ # end
9
+ @@logger if defined? @@logger
10
+ end
11
+
12
+ def enable_logging
13
+ @@logger = Logger.new(STDOUT).tap {|logger| logger.level = Logger::WARN}
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ if ENV['GLIMMER_LOGGER_LEVEL']
20
+ Glimmer::Config.enable_logging
21
+ Glimmer::Config.logger.level = ENV['GLIMMER_LOGGER_LEVEL'].downcase
22
+ end
@@ -0,0 +1,193 @@
1
+ require 'glimmer'
2
+ require 'glimmer/dsl/expression_handler'
3
+
4
+ module Glimmer
5
+ module DSL
6
+ # Glimmer DSL Engine
7
+ #
8
+ # Follows Interpreter and Chain of Responsibility Design Patterns
9
+ #
10
+ # When DSL engine interprets an expression, it attempts to handle
11
+ # with ordered expression array specified via `.expressions=` method.
12
+ class Engine
13
+ class << self
14
+ def dsl=(dsl_name)
15
+ dsl_name = dsl_name&.to_sym
16
+ if dsl_name
17
+ dsl_stack.push(dsl_name)
18
+ else
19
+ dsl_stack.clear
20
+ end
21
+ end
22
+
23
+ def dsl
24
+ dsl_stack.last
25
+ end
26
+
27
+ def dsls
28
+ static_expressions.values.map(&:keys).flatten.uniq
29
+ end
30
+
31
+ def disable_dsl(dsl_name)
32
+ dsl_name = dsl_name.to_sym
33
+ disabled_dsls << dsl_name
34
+ end
35
+
36
+ def enable_dsl(dsl_name)
37
+ dsl_name = dsl_name.to_sym
38
+ disabled_dsls.delete(dsl_name)
39
+ end
40
+
41
+ def disabled_dsls
42
+ @disabled_dsls ||= []
43
+ end
44
+
45
+ def enabled_dsls=(dsl_names)
46
+ dsls.each {|dsl_name| disable_dsl(dsl_name)}
47
+ dsl_names.each {|dsl_name| enable_dsl(dsl_name)}
48
+ end
49
+
50
+ # Resets Glimmer's engine activity and configuration. Useful in rspec before or after blocks in tests.
51
+ def reset
52
+ parent_stacks.values.each do |a_parent_stack|
53
+ a_parent_stack.clear
54
+ end
55
+ dsl_stack.clear
56
+ disabled_dsls.clear
57
+ end
58
+
59
+ # Dynamic expression chains of responsibility indexed by dsl
60
+ def dynamic_expression_chains_of_responsibility
61
+ @dynamic_expression_chains_of_responsibility ||= {}
62
+ end
63
+
64
+ # Static expressions indexed by keyword and dsl
65
+ def static_expressions
66
+ @static_expressions ||= {}
67
+ end
68
+
69
+ # Sets an ordered array of DSL expressions to support
70
+ #
71
+ # Every expression has an underscored name corresponding to an upper
72
+ # camelcase AbstractExpression subclass name in glimmer/dsl
73
+ #
74
+ # They are used in order following the Chain of Responsibility Design
75
+ # Pattern when interpretting a DSL expression
76
+ def add_dynamic_expressions(dsl_namespace, expression_names)
77
+ dsl = dsl_namespace.name.split("::").last.downcase.to_sym
78
+ dynamic_expression_chains_of_responsibility[dsl] = expression_names.reverse.map do |expression_name|
79
+ expression_class(dsl_namespace, expression_name).new
80
+ end.reduce(nil) do |last_expresion_handler, expression|
81
+ Glimmer::Config.logger&.debug "Adding dynamic expression: #{expression.class.name}"
82
+ expression_handler = ExpressionHandler.new(expression)
83
+ expression_handler.next = last_expresion_handler if last_expresion_handler
84
+ expression_handler
85
+ end
86
+ end
87
+
88
+ def add_static_expression(static_expression)
89
+ Glimmer::Config.logger&.debug "Adding static expression: #{static_expression.class.name}"
90
+ keyword = static_expression.class.keyword
91
+ static_expression_dsl = static_expression.class.dsl
92
+ static_expressions[keyword] ||= {}
93
+ static_expressions[keyword][static_expression_dsl] = static_expression
94
+ Glimmer.send(:define_method, keyword) do |*args, &block|
95
+ begin
96
+ retrieved_static_expression = Glimmer::DSL::Engine.static_expressions[keyword][Glimmer::DSL::Engine.dsl]
97
+ static_expression_dsl = (Glimmer::DSL::Engine.static_expressions[keyword].keys - Glimmer::DSL::Engine.disabled_dsls).last if retrieved_static_expression.nil?
98
+ interpretation = nil
99
+ if retrieved_static_expression.nil? && Glimmer::DSL::Engine.dsl && (static_expression_dsl.nil? || !Glimmer::DSL::Engine.static_expressions[keyword][static_expression_dsl].is_a?(TopLevelExpression))
100
+ begin
101
+ interpretation = Glimmer::DSL::Engine.interpret(keyword, *args, &block)
102
+ rescue => e
103
+ Glimmer::DSL::Engine.reset
104
+ raise e if static_expression_dsl.nil? || !Glimmer::DSL::Engine.static_expressions[keyword][static_expression_dsl].is_a?(TopLevelExpression)
105
+ end
106
+ end
107
+ if interpretation
108
+ interpretation
109
+ else
110
+ raise Glimmer::Error, "Unsupported keyword: #{keyword}" unless static_expression_dsl || retrieved_static_expression
111
+ Glimmer::DSL::Engine.dsl_stack.push(static_expression_dsl || Glimmer::DSL::Engine.dsl)
112
+ static_expression = Glimmer::DSL::Engine.static_expressions[keyword][Glimmer::DSL::Engine.dsl]
113
+ if !static_expression.can_interpret?(Glimmer::DSL::Engine.parent, keyword, *args, &block)
114
+ raise Error, "Invalid use of Glimmer keyword #{keyword} with args #{args} under parent #{Glimmer::DSL::Engine.parent}"
115
+ else
116
+ Glimmer::Config.logger&.debug "#{static_expression.class.name} will handle expression keyword #{keyword}"
117
+ static_expression.interpret(Glimmer::DSL::Engine.parent, keyword, *args, &block).tap do |ui_object|
118
+ Glimmer::DSL::Engine.add_content(ui_object, static_expression, &block) unless block.nil?
119
+ Glimmer::DSL::Engine.dsl_stack.pop
120
+ end
121
+ end
122
+ end
123
+ rescue StandardError => e
124
+ # Glimmer::DSL::Engine.dsl_stack.pop
125
+ Glimmer::DSL::Engine.reset
126
+ raise e
127
+ end
128
+ end
129
+ end
130
+
131
+ def expression_class(dsl_namespace, expression_name)
132
+ dsl_namespace.const_get(expression_class_name(expression_name).to_sym)
133
+ end
134
+
135
+ def expression_class_name(expression_name)
136
+ "#{expression_name}_expression".camelcase(:upper)
137
+ end
138
+
139
+ # Interprets Glimmer dynamic DSL expression consisting of keyword, args, and block (e.g. shell(:no_resize) { ... })
140
+ def interpret(keyword, *args, &block)
141
+ keyword = keyword.to_s
142
+ dynamic_expression_dsl = (dynamic_expression_chains_of_responsibility.keys - disabled_dsls).last if dsl.nil?
143
+ dsl_stack.push(dynamic_expression_dsl || dsl)
144
+ expression = dynamic_expression_chains_of_responsibility[dsl].handle(parent, keyword, *args, &block)
145
+ expression.interpret(parent, keyword, *args, &block).tap do |ui_object|
146
+ add_content(ui_object, expression, &block)
147
+ dsl_stack.pop
148
+ end
149
+ rescue StandardError => e
150
+ # dsl_stack.pop
151
+ reset
152
+ raise e
153
+ end
154
+
155
+ # Adds content block to parent UI object
156
+ #
157
+ # This allows evaluating parent UI object properties and children
158
+ #
159
+ # For example, a shell widget would get properties set and children added
160
+ def add_content(parent, expression, &block)
161
+ if block_given? && expression.is_a?(ParentExpression)
162
+ dsl_stack.push(expression.class.dsl)
163
+ parent_stack.push(parent)
164
+ expression.add_content(parent, &block)
165
+ parent_stack.pop
166
+ dsl_stack.pop
167
+ end
168
+ end
169
+
170
+ # Current parent while evaluating Glimmer DSL (nil if just started or done evaluatiing)
171
+ #
172
+ # Parents are maintained in a stack while evaluating Glimmer DSL
173
+ # to ensure properly ordered interpretation of DSL syntax
174
+ def parent
175
+ parent_stack.last
176
+ end
177
+
178
+ def parent_stack
179
+ parent_stacks[dsl] ||= []
180
+ end
181
+
182
+ def parent_stacks
183
+ @parent_stacks ||= {}
184
+ end
185
+
186
+ # Enables multiple DSLs to play well with each other when mixing together
187
+ def dsl_stack
188
+ @dsl_stack ||= []
189
+ end
190
+ end
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,42 @@
1
+ require 'glimmer/error'
2
+
3
+ module Glimmer
4
+ module DSL
5
+ # Represents a Glimmer DSL expression (e.g. label(:center) { ... })
6
+ #
7
+ # An expression object can interpret a keyword, args, and a block into a UI object
8
+ #
9
+ # Expressions subclasses follow the convention of using `and` and `or`
10
+ # english versino of Ruby's boolean operations. This allows easy DSL-like
11
+ # readability of the rules, and easy tagging with pd when troubleshooting.
12
+ class Expression
13
+ class << self
14
+ def dsl
15
+ @dsl ||= name.split(/::/)[-2].downcase.to_sym
16
+ end
17
+ end
18
+
19
+ # Checks if it can interpret parameters (subclass must override)
20
+ def can_interpret?(parent, keyword, *args, &block)
21
+ raise Error, "#can_interpret? must be implemented by an Expression subclass"
22
+ end
23
+
24
+ # Interprets parameters (subclass must override)
25
+ def interpret(parent, keyword, *args, &block)
26
+ raise Error, "#interpret must be implemented by an Expression subclass"
27
+ end
28
+
29
+ # Adds block content to specified parent UI object (Optional)
30
+ #
31
+ # Only expressions that receive a content block should implement
32
+ def add_content(parent, &block)
33
+ # No Op by default
34
+ end
35
+
36
+ # Checks if object is a Symbol or a String
37
+ def textual?(object)
38
+ object.is_a?(Symbol) or object.is_a?(String)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,48 @@
1
+ require 'glimmer/invalid_keyword_error'
2
+
3
+ module Glimmer
4
+ module DSL
5
+ # Expression handler for a Glimmer DSL specific expression
6
+ #
7
+ # Follows the Chain of Responsibility Design Pattern
8
+ #
9
+ # Handlers are configured in Glimmer::DSL in the right order
10
+ # to attempt handling Glimmer DSL interpretation calls
11
+ #
12
+ # Each handler knows the next handler in the chain of responsibility.
13
+ #
14
+ # If it handles successfully, it returns. Otherwise, it forwards to the next
15
+ # handler in the chain of responsibility
16
+ class ExpressionHandler
17
+ def initialize(expression)
18
+ @expression = expression
19
+ end
20
+
21
+ # Handles interpretation of Glimmer DSL expression if expression supports it
22
+ # If it succeeds, it returns the correct Glimmer DSL expression object
23
+ # Otherwise, it forwards to the next handler configured via `#next=` method
24
+ # If there is no handler next, then it raises an error
25
+ def handle(parent, keyword, *args, &block)
26
+ Glimmer::Config.logger&.debug "Attempting to handle #{keyword} with #{@expression.class.name.split(":").last}"
27
+ if @expression.can_interpret?(parent, keyword, *args, &block)
28
+ Glimmer::Config.logger&.debug "#{@expression.class.name} will handle expression keyword #{keyword}"
29
+ return @expression
30
+ elsif @next_expression_handler
31
+ return @next_expression_handler.handle(parent, keyword, *args, &block)
32
+ else
33
+ # TODO see if we need a better response here (e.g. dev mode error raising vs production mode silent failure)
34
+ message = "Glimmer keyword #{keyword} with args #{args} cannot be handled"
35
+ message += " inside parent #{parent}" if parent
36
+ message += "! Check the validity of the code."
37
+ # Glimmer::Config.logger&.error message
38
+ raise InvalidKeywordError, message
39
+ end
40
+ end
41
+
42
+ # Sets the next handler in the expression handler chain of responsibility
43
+ def next=(next_expression_handler)
44
+ @next_expression_handler = next_expression_handler
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,21 @@
1
+ require 'opal'
2
+ require 'browser'
3
+
4
+ require 'glimmer/dsl/engine'
5
+ # Dir[File.expand_path('../*_expression.rb', __FILE__)].each {|f| require f}
6
+ require 'glimmer/dsl/opal/shell_expression'
7
+ require 'glimmer/dsl/opal/label_expression'
8
+ require 'glimmer/dsl/opal/property_expression'
9
+
10
+ module Glimmer
11
+ module DSL
12
+ module Opal
13
+ Engine.add_dynamic_expressions(
14
+ Opal,
15
+ %w[
16
+ property
17
+ ]
18
+ )
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ require 'glimmer/dsl/static_expression'
2
+ require 'glimmer/dsl/parent_expression'
3
+ require 'glimmer/opal/label'
4
+
5
+ module Glimmer
6
+ module DSL
7
+ module Opal
8
+ class LabelExpression < StaticExpression
9
+ include ParentExpression
10
+
11
+ def interpret(parent, keyword, *args, &block)
12
+ Glimmer::Opal::Label.new(parent, args)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ require 'glimmer/dsl/expression'
2
+
3
+ module Glimmer
4
+ module DSL
5
+ module Opal
6
+ class PropertyExpression < StaticExpression
7
+ include TopLevelExpression
8
+
9
+ def can_interpret?(parent, keyword, *args, &block)
10
+ keyword.to_s == 'text'
11
+ end
12
+
13
+ def interpret(parent, keyword, *args, &block)
14
+ parent.text = args.first.to_s
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'glimmer/dsl/static_expression'
2
+ require 'glimmer/dsl/top_level_expression'
3
+ require 'glimmer/dsl/parent_expression'
4
+ require 'glimmer/opal/shell'
5
+
6
+ module Glimmer
7
+ module DSL
8
+ module Opal
9
+ class ShellExpression < StaticExpression
10
+ include TopLevelExpression
11
+ include ParentExpression
12
+
13
+ def interpret(parent, keyword, *args, &block)
14
+ Glimmer::Opal::Shell.new(args)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,12 @@
1
+ require 'glimmer/error'
2
+
3
+ module Glimmer
4
+ module DSL
5
+ # Mixin that represents expressions that always have a content block
6
+ module ParentExpression
7
+ def add_content(parent, &block)
8
+ block.call(parent)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,36 @@
1
+ require 'glimmer/error'
2
+ require 'glimmer/dsl/engine'
3
+ require 'glimmer/dsl/expression'
4
+
5
+ module Glimmer
6
+ module DSL
7
+ # Represents a StaticExpression for expressions where
8
+ # the keyword does not vary dynamically. These static keywords are then
9
+ # predefined as methods in Glimmer instead of needing method_missing
10
+ #
11
+ # StaticExpression subclasses may optionally implement `#can_interpret?`
12
+ # (not needed if it only checks for keyword)
13
+ #
14
+ # StaticExpression subclasses must define `#interpret`.
15
+ #
16
+ # The direct parent namespace of a StaticExpression subclass must match the DSL name (case-insensitive)
17
+ # (e.g. Glimmer::DSL::SWT::WidgetExpression has a DSL of :swt)
18
+ class StaticExpression < Expression
19
+ class << self
20
+ def inherited(base)
21
+ Glimmer::DSL::Engine.add_static_expression(base.new)
22
+ super
23
+ end
24
+
25
+ def keyword
26
+ @keyword ||= name.split(/::/).last.sub(/Expression$/, '').underscore
27
+ end
28
+ end
29
+
30
+ # Subclasses may optionally implement
31
+ def can_interpret?(parent, keyword, *args, &block)
32
+ true
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,7 @@
1
+ module Glimmer
2
+ module DSL
3
+ # Mixin that represents expressions that are always at the top with parent nil
4
+ module TopLevelExpression
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ module Glimmer
2
+ # Represents Glimmer errors that occur due to invalid use of Glimmer
3
+ # without handing control flow back to original method_missing
4
+ class Error < RuntimeError
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Glimmer
2
+ # Represents Glimmer errors that occur due to invalid use of Glimmer
3
+ # without handing control flow back to original method_missing
4
+ class InvalidKeywordError < RuntimeError
5
+ end
6
+ end
@@ -0,0 +1,31 @@
1
+ module Glimmer
2
+ module Opal
3
+ class Label
4
+ attr_reader :text
5
+
6
+ def initialize(parent, args)
7
+ @parent = parent
8
+ @args = args
9
+ @parent.add_child(self)
10
+ end
11
+
12
+ def text=(value)
13
+ @text = value
14
+ redraw
15
+ end
16
+
17
+ def redraw
18
+ old_dom = @dom
19
+ @dom = nil
20
+ old_dom.replace dom
21
+ end
22
+
23
+ def dom
24
+ label_text = @text
25
+ @dom ||= DOM {
26
+ label label_text
27
+ }
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,38 @@
1
+ module Glimmer
2
+ module Opal
3
+ class Shell
4
+ def initialize(args)
5
+ @args = args
6
+ @children = []
7
+ $document.ready do
8
+ $document.body.replace(dom)
9
+ end
10
+ end
11
+
12
+ def text
13
+ $document.title
14
+ end
15
+
16
+ def text=(value)
17
+ $document.title = value
18
+ end
19
+
20
+ def add_child(child)
21
+ return if @children.include?(child)
22
+ @children << child
23
+ dom << child.dom
24
+ end
25
+
26
+ def dom
27
+ @dom ||= DOM {
28
+ body {
29
+ }
30
+ }
31
+ end
32
+
33
+ def open
34
+ # No Op (just a placeholder since it is not needed on the web)
35
+ end
36
+ end
37
+ end
38
+ end
metadata ADDED
@@ -0,0 +1,209 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: glimmer-dsl-opal
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - AndyMaleh
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-06-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: glimmer
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.9.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.9.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec-mocks
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 3.5.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 3.5.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 3.5.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 3.5.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: puts_debuggerer
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.8.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.8.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 10.1.0
76
+ - - "<"
77
+ - !ruby/object:Gem::Version
78
+ version: 14.0.0
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: 10.1.0
86
+ - - "<"
87
+ - !ruby/object:Gem::Version
88
+ version: 14.0.0
89
+ - !ruby/object:Gem::Dependency
90
+ name: jeweler
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: 2.3.9
96
+ - - "<"
97
+ - !ruby/object:Gem::Version
98
+ version: 3.0.0
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: 2.3.9
106
+ - - "<"
107
+ - !ruby/object:Gem::Version
108
+ version: 3.0.0
109
+ - !ruby/object:Gem::Dependency
110
+ name: rdoc
111
+ requirement: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: 6.2.1
116
+ - - "<"
117
+ - !ruby/object:Gem::Version
118
+ version: 7.0.0
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: 6.2.1
126
+ - - "<"
127
+ - !ruby/object:Gem::Version
128
+ version: 7.0.0
129
+ - !ruby/object:Gem::Dependency
130
+ name: opal-rspec
131
+ requirement: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - "~>"
134
+ - !ruby/object:Gem::Version
135
+ version: 0.7.1
136
+ type: :development
137
+ prerelease: false
138
+ version_requirements: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - "~>"
141
+ - !ruby/object:Gem::Version
142
+ version: 0.7.1
143
+ - !ruby/object:Gem::Dependency
144
+ name: opal-browser
145
+ requirement: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - "~>"
148
+ - !ruby/object:Gem::Version
149
+ version: 0.2.0
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - "~>"
155
+ - !ruby/object:Gem::Version
156
+ version: 0.2.0
157
+ description: Glimmer DSL for Opal (Web GUI Adapter for Desktop Apps)
158
+ email: andy.am@gmail.com
159
+ executables: []
160
+ extensions: []
161
+ extra_rdoc_files:
162
+ - CHANGELOG.md
163
+ - LICENSE.txt
164
+ - README.md
165
+ files:
166
+ - CHANGELOG.md
167
+ - LICENSE.txt
168
+ - README.md
169
+ - VERSION
170
+ - lib/glimmer-dsl-opal.rb
171
+ - lib/glimmer/config.rb
172
+ - lib/glimmer/dsl/engine.rb
173
+ - lib/glimmer/dsl/expression.rb
174
+ - lib/glimmer/dsl/expression_handler.rb
175
+ - lib/glimmer/dsl/opal/dsl.rb
176
+ - lib/glimmer/dsl/opal/label_expression.rb
177
+ - lib/glimmer/dsl/opal/property_expression.rb
178
+ - lib/glimmer/dsl/opal/shell_expression.rb
179
+ - lib/glimmer/dsl/parent_expression.rb
180
+ - lib/glimmer/dsl/static_expression.rb
181
+ - lib/glimmer/dsl/top_level_expression.rb
182
+ - lib/glimmer/error.rb
183
+ - lib/glimmer/invalid_keyword_error.rb
184
+ - lib/glimmer/opal/label.rb
185
+ - lib/glimmer/opal/shell.rb
186
+ homepage: http://github.com/AndyObtiva/glimmer-dsl-opal
187
+ licenses:
188
+ - MIT
189
+ metadata: {}
190
+ post_install_message:
191
+ rdoc_options: []
192
+ require_paths:
193
+ - lib
194
+ required_ruby_version: !ruby/object:Gem::Requirement
195
+ requirements:
196
+ - - ">="
197
+ - !ruby/object:Gem::Version
198
+ version: '0'
199
+ required_rubygems_version: !ruby/object:Gem::Requirement
200
+ requirements:
201
+ - - ">="
202
+ - !ruby/object:Gem::Version
203
+ version: '0'
204
+ requirements: []
205
+ rubygems_version: 3.1.2
206
+ signing_key:
207
+ specification_version: 4
208
+ summary: Glimmer DSL for Opal
209
+ test_files: []