glimmer-dsl-css 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +20 -0
- data/README.md +111 -0
- data/VERSION +1 -0
- data/lib/glimmer-dsl-css.rb +7 -0
- data/lib/glimmer/config.rb +22 -0
- data/lib/glimmer/css/rule.rb +25 -0
- data/lib/glimmer/css/style_sheet.rb +19 -0
- data/lib/glimmer/dsl/css/css_expression.rb +21 -0
- data/lib/glimmer/dsl/css/dsl.rb +21 -0
- data/lib/glimmer/dsl/css/dynamic_property_expression.rb +12 -0
- data/lib/glimmer/dsl/css/property_expression.rb +22 -0
- data/lib/glimmer/dsl/css/pv_expression.rb +17 -0
- data/lib/glimmer/dsl/css/rule_expression.rb +26 -0
- data/lib/glimmer/dsl/css/s_expression.rb +26 -0
- data/lib/glimmer/dsl/engine.rb +193 -0
- data/lib/glimmer/dsl/expression.rb +42 -0
- data/lib/glimmer/dsl/expression_handler.rb +48 -0
- data/lib/glimmer/dsl/opal/dsl.rb +41 -0
- data/lib/glimmer/dsl/opal/label_expression.rb +17 -0
- data/lib/glimmer/dsl/opal/property_expression.rb +19 -0
- data/lib/glimmer/dsl/opal/shell_expression.rb +19 -0
- data/lib/glimmer/dsl/parent_expression.rb +12 -0
- data/lib/glimmer/dsl/static_expression.rb +36 -0
- data/lib/glimmer/dsl/top_level_expression.rb +7 -0
- data/lib/glimmer/dsl/xml/dsl.rb +23 -0
- data/lib/glimmer/dsl/xml/html_expression.rb +25 -0
- data/lib/glimmer/dsl/xml/meta_expression.rb +23 -0
- data/lib/glimmer/dsl/xml/name_space_expression.rb +37 -0
- data/lib/glimmer/dsl/xml/node_parent_expression.rb +33 -0
- data/lib/glimmer/dsl/xml/tag_expression.rb +29 -0
- data/lib/glimmer/dsl/xml/text_expression.rb +22 -0
- data/lib/glimmer/dsl/xml/xml_expression.rb +21 -0
- data/lib/glimmer/error.rb +6 -0
- data/lib/glimmer/invalid_keyword_error.rb +6 -0
- data/lib/glimmer/opal/label.rb +31 -0
- data/lib/glimmer/opal/shell.rb +34 -0
- data/lib/glimmer/xml/depth_first_search_iterator.rb +22 -0
- data/lib/glimmer/xml/name_space_visitor.rb +21 -0
- data/lib/glimmer/xml/node.rb +75 -0
- data/lib/glimmer/xml/node_visitor.rb +13 -0
- data/lib/glimmer/xml/xml_visitor.rb +65 -0
- metadata +201 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b8bc05a543f2281ad44c1073149fda8c8f947ebf4205d98cc106219e1477f14e
|
4
|
+
data.tar.gz: e4f674a887a0c6d231a6ed6e259662de616eb3a6be770e20ddff30ca52946a00
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8c0aadaad6a38cabfea3b4e2d62aea9d429389b298c3b89187a5548ed50ad90a91a00dce46773edc9b93248561c55f2966bba19f2af3f2031b7eec14e777f04f
|
7
|
+
data.tar.gz: ffe9a44219bca30c59fa961df2792792c3957e49118ea16da617fb026e843088b5ffa8c22f7cfded1a794a018c61b2fb082284bbe86c961bdf417edba71a2bf6
|
data/LICENSE.txt
ADDED
@@ -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.
|
data/README.md
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
# Glimmer DSL for CSS 0.1.0 Beta (Cascading Style Sheets)
|
2
|
+
[](http://badge.fury.io/rb/glimmer-dsl-css)
|
3
|
+
[](https://travis-ci.com/github/AndyObtiva/glimmer-dsl-css)
|
4
|
+
|
5
|
+
[Glimmer](https://github.com/AndyObtiva/glimmer) DSL for CSS provides Ruby syntax for building CSS (Cascading Style Sheets).
|
6
|
+
|
7
|
+
Within the context of desktop development, Glimmer DSL for CSS is useful in providing CSS for the [SWT Browser widget](https://github.com/AndyObtiva/glimmer/tree/master#browser-widget).
|
8
|
+
|
9
|
+
## Setup
|
10
|
+
|
11
|
+
Please follow these instructions to make the `glimmer` command available on your system.
|
12
|
+
|
13
|
+
### Option 1: Direct Install
|
14
|
+
|
15
|
+
Run this command to install directly:
|
16
|
+
```
|
17
|
+
jgem install glimmer-dsl-xml -v 0.1.0
|
18
|
+
```
|
19
|
+
|
20
|
+
`jgem` is JRuby's version of `gem` command.
|
21
|
+
RVM allows running `gem` as an alias.
|
22
|
+
Otherwise, you may also run `jruby -S gem install ...`
|
23
|
+
|
24
|
+
Add `require 'glimmer-dsl-xml'` to your code after `require glimmer-dsl-swt` or `require glimmer-dsl-opal`
|
25
|
+
|
26
|
+
### Option 2: Bundler
|
27
|
+
|
28
|
+
Add the following to `Gemfile` after `glimmer-dsl-swt` or `glimmer-dsl-opal`:
|
29
|
+
```
|
30
|
+
gem 'glimmer-dsl-xml', '~> 0.1.0'
|
31
|
+
```
|
32
|
+
|
33
|
+
And, then run:
|
34
|
+
```
|
35
|
+
jruby -S bundle install
|
36
|
+
```
|
37
|
+
|
38
|
+
That's it! Requiring the gem activates the Glimmer XML DSL automatically.
|
39
|
+
|
40
|
+
## CSS DSL
|
41
|
+
|
42
|
+
Simply start with `css` keyword and add stylesheet rule sets inside its block using Glimmer DSL syntax.
|
43
|
+
Once done, you may call `to_s` or `to_css` to get the formatted CSS output.
|
44
|
+
|
45
|
+
`css` is the only top-level keyword in the Glimmer CSS DSL
|
46
|
+
|
47
|
+
Selectors may be specified by `s` keyword or HTML element keyword directly (e.g. `body`)
|
48
|
+
Rule property values may be specified by `pv` keyword or underscored property name directly (e.g. `font_size`)
|
49
|
+
|
50
|
+
Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
@css = css {
|
54
|
+
body {
|
55
|
+
font_size '1.1em'
|
56
|
+
pv 'background', 'white'
|
57
|
+
}
|
58
|
+
|
59
|
+
s('body > h1') {
|
60
|
+
background_color :red
|
61
|
+
pv 'font-size', '2em'
|
62
|
+
}
|
63
|
+
}
|
64
|
+
puts @css
|
65
|
+
```
|
66
|
+
|
67
|
+
## Multi-DSL Support
|
68
|
+
|
69
|
+
Learn more about how to use this DSL alongside other Glimmer DSLs:
|
70
|
+
|
71
|
+
[Glimmer Multi-DSL Support](https://github.com/AndyObtiva/glimmer/tree/master#multi-dsl-support)
|
72
|
+
|
73
|
+
## Help
|
74
|
+
|
75
|
+
### Issues
|
76
|
+
|
77
|
+
You may submit [issues](https://github.com/AndyObtiva/glimmer/issues) on [GitHub](https://github.com/AndyObtiva/glimmer/issues).
|
78
|
+
|
79
|
+
[Click here to submit an issue.](https://github.com/AndyObtiva/glimmer/issues)
|
80
|
+
|
81
|
+
### IRC Channel
|
82
|
+
|
83
|
+
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.
|
84
|
+
|
85
|
+
[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)
|
86
|
+
|
87
|
+
## Feature Suggestions
|
88
|
+
|
89
|
+
These features have been suggested. You might see them in a future version of Glimmer. You are welcome to contribute more feature suggestions.
|
90
|
+
|
91
|
+
[TODO.md](TODO.md)
|
92
|
+
|
93
|
+
## Change Log
|
94
|
+
|
95
|
+
[CHANGELOG.md](CHANGELOG.md)
|
96
|
+
|
97
|
+
## Contributing
|
98
|
+
|
99
|
+
[CONTRIBUTING.md](CONTRIBUTING.md)
|
100
|
+
|
101
|
+
## Contributors
|
102
|
+
|
103
|
+
* [Andy Maleh](https://github.com/AndyObtiva) (Founder)
|
104
|
+
* [Dennis Theisen](https://github.com/Soleone) (Contributor)
|
105
|
+
|
106
|
+
[Click here to view contributor commits.](https://github.com/AndyObtiva/glimmer/graphs/contributors)
|
107
|
+
|
108
|
+
## License
|
109
|
+
|
110
|
+
Copyright (c) 2007-2020 Andy Maleh.
|
111
|
+
See LICENSE.txt for further details.
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -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,25 @@
|
|
1
|
+
module Glimmer
|
2
|
+
module CSS
|
3
|
+
class Rule
|
4
|
+
attr_reader :selector, :properties
|
5
|
+
|
6
|
+
def initialize(selector)
|
7
|
+
@selector = selector
|
8
|
+
@properties = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_property(keyword, *args)
|
12
|
+
keyword = keyword.to_s.downcase.gsub('_', '-')
|
13
|
+
@properties[keyword] = args.first
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_css
|
17
|
+
css = "#{@selector}{"
|
18
|
+
css << @properties.map { |name, value| "#{name}:#{value}" }.join(';')
|
19
|
+
css << "}"
|
20
|
+
end
|
21
|
+
|
22
|
+
alias to_s to_css
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'glimmer/dsl/static_expression'
|
2
|
+
require 'glimmer/dsl/top_level_expression'
|
3
|
+
require 'glimmer/dsl/parent_expression'
|
4
|
+
require 'glimmer/css/style_sheet'
|
5
|
+
|
6
|
+
module Glimmer
|
7
|
+
module DSL
|
8
|
+
module CSS
|
9
|
+
# This static html expression flips the DSL switch on for
|
10
|
+
# XML DSL in Glimmer
|
11
|
+
class CssExpression < StaticExpression
|
12
|
+
include TopLevelExpression
|
13
|
+
include ParentExpression
|
14
|
+
|
15
|
+
def interpret(parent, keyword, *args, &block)
|
16
|
+
Glimmer::CSS::StyleSheet.new
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'glimmer/dsl/engine'
|
2
|
+
# Dir[File.expand_path('../*_expression.rb', __FILE__)].each {|f| require f} # cannot in Opal
|
3
|
+
require 'glimmer/dsl/css/rule_expression'
|
4
|
+
require 'glimmer/dsl/css/dynamic_property_expression'
|
5
|
+
require 'glimmer/dsl/css/css_expression'
|
6
|
+
require 'glimmer/dsl/css/s_expression'
|
7
|
+
require 'glimmer/dsl/css/pv_expression'
|
8
|
+
|
9
|
+
module Glimmer
|
10
|
+
module DSL
|
11
|
+
module CSS
|
12
|
+
Engine.add_dynamic_expressions(
|
13
|
+
CSS,
|
14
|
+
%w[
|
15
|
+
rule
|
16
|
+
dynamic_property
|
17
|
+
]
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'glimmer/dsl/expression'
|
2
|
+
require 'glimmer/css/rule'
|
3
|
+
|
4
|
+
module Glimmer
|
5
|
+
module DSL
|
6
|
+
module CSS
|
7
|
+
module PropertyExpression
|
8
|
+
include ParentExpression
|
9
|
+
|
10
|
+
def can_interpret?(parent, keyword, *args, &block)
|
11
|
+
parent.is_a?(Glimmer::CSS::Rule) and
|
12
|
+
!block_given? and
|
13
|
+
!args.empty?
|
14
|
+
end
|
15
|
+
|
16
|
+
def interpret(parent, keyword, *args, &block)
|
17
|
+
parent.add_property(keyword, *args)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'glimmer/dsl/static_expression'
|
2
|
+
require 'glimmer/dsl/css/property_expression'
|
3
|
+
|
4
|
+
module Glimmer
|
5
|
+
module DSL
|
6
|
+
module CSS
|
7
|
+
# Static keyword 'pv' version of CSS DSL dynamic property expression
|
8
|
+
class PVExpression < StaticExpression
|
9
|
+
include PropertyExpression
|
10
|
+
|
11
|
+
def interpret(parent, keyword, *args, &block)
|
12
|
+
parent.add_property(args[0], args[1])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'glimmer/dsl/expression'
|
2
|
+
require 'glimmer/dsl/parent_expression'
|
3
|
+
require 'glimmer/css/style_sheet'
|
4
|
+
require 'glimmer/css/rule'
|
5
|
+
|
6
|
+
module Glimmer
|
7
|
+
module DSL
|
8
|
+
module CSS
|
9
|
+
class RuleExpression < Expression
|
10
|
+
include ParentExpression
|
11
|
+
|
12
|
+
def can_interpret?(parent, keyword, *args, &block)
|
13
|
+
parent.is_a?(Glimmer::CSS::StyleSheet) and
|
14
|
+
block_given? and
|
15
|
+
args.empty?
|
16
|
+
end
|
17
|
+
|
18
|
+
def interpret(parent, keyword, *args, &block)
|
19
|
+
Glimmer::CSS::Rule.new(keyword.to_s.downcase).tap do |rule|
|
20
|
+
parent.rules << rule
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'glimmer/dsl/static_expression'
|
2
|
+
require 'glimmer/css/style_sheet'
|
3
|
+
require 'glimmer/css/rule'
|
4
|
+
|
5
|
+
module Glimmer
|
6
|
+
module DSL
|
7
|
+
module CSS
|
8
|
+
class SExpression < StaticExpression
|
9
|
+
include ParentExpression
|
10
|
+
|
11
|
+
def can_interpret?(parent, keyword, *args, &block)
|
12
|
+
keyword == 's' and
|
13
|
+
parent.is_a?(Glimmer::CSS::StyleSheet) and
|
14
|
+
block_given? and
|
15
|
+
!args.empty?
|
16
|
+
end
|
17
|
+
|
18
|
+
def interpret(parent, keyword, *args, &block)
|
19
|
+
Glimmer::CSS::Rule.new(args.first.to_s).tap do |rule|
|
20
|
+
parent.rules << rule
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
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
|