glimmer 0.5.11 → 0.6.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 +4 -4
- data/README.markdown +129 -15
- data/lib/glimmer.rb +13 -1
- data/lib/glimmer/css/rule_set.rb +27 -0
- data/lib/glimmer/css/style_sheet.rb +20 -0
- data/lib/glimmer/dsl/css/css_expression.rb +21 -0
- data/lib/glimmer/dsl/css/dsl.rb +10 -0
- data/lib/glimmer/dsl/css/p_expression.rb +25 -0
- data/lib/glimmer/dsl/css/property_expression.rb +22 -0
- data/lib/glimmer/dsl/css/rule_set_expression.rb +25 -0
- data/lib/glimmer/dsl/css/s_expression.rb +26 -0
- data/lib/glimmer/dsl/engine.rb +90 -18
- data/lib/glimmer/dsl/expression.rb +9 -4
- data/lib/glimmer/dsl/static_expression.rb +13 -13
- data/lib/glimmer/dsl/swt/async_exec_expression.rb +14 -0
- data/lib/glimmer/dsl/swt/bind_expression.rb +37 -0
- data/lib/glimmer/dsl/swt/color_expression.rb +17 -0
- data/lib/glimmer/dsl/swt/column_properties_expression.rb +24 -0
- data/lib/glimmer/dsl/swt/combo_selection_data_binding_expression.rb +42 -0
- data/lib/glimmer/dsl/swt/custom_widget_expression.rb +36 -0
- data/lib/glimmer/dsl/swt/data_binding_expression.rb +34 -0
- data/lib/glimmer/dsl/swt/display_expression.rb +19 -0
- data/lib/glimmer/dsl/swt/dsl.rb +26 -0
- data/lib/glimmer/dsl/swt/exec_expression.rb +28 -0
- data/lib/glimmer/dsl/swt/layout_data_expression.rb +25 -0
- data/lib/glimmer/dsl/swt/layout_expression.rb +27 -0
- data/lib/glimmer/dsl/swt/list_selection_data_binding_expression.rb +44 -0
- data/lib/glimmer/dsl/swt/menu_bar_expression.rb +33 -0
- data/lib/glimmer/dsl/swt/menu_expression.rb +32 -0
- data/lib/glimmer/dsl/swt/observe_expression.rb +32 -0
- data/lib/glimmer/dsl/swt/property_expression.rb +22 -0
- data/lib/glimmer/dsl/swt/rgb_expression.rb +12 -0
- data/lib/glimmer/dsl/swt/rgba_expression.rb +12 -0
- data/lib/glimmer/dsl/swt/shell_expression.rb +20 -0
- data/lib/glimmer/dsl/swt/swt_expression.rb +25 -0
- data/lib/glimmer/dsl/swt/sync_exec_expression.rb +15 -0
- data/lib/glimmer/dsl/swt/tab_item_expression.rb +33 -0
- data/lib/glimmer/dsl/swt/table_items_data_binding_expression.rb +31 -0
- data/lib/glimmer/dsl/swt/tree_items_data_binding_expression.rb +31 -0
- data/lib/glimmer/dsl/swt/tree_properties_expression.rb +26 -0
- data/lib/glimmer/dsl/swt/widget_expression.rb +27 -0
- data/lib/glimmer/dsl/swt/widget_listener_expression.rb +32 -0
- data/lib/glimmer/dsl/top_level_expression.rb +7 -0
- data/lib/glimmer/dsl/xml/dsl.rb +11 -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/rake_task.rb +1 -1
- data/lib/glimmer/swt/shell_proxy.rb +1 -2
- data/lib/glimmer/swt/widget_proxy.rb +6 -3
- data/lib/glimmer/ui/custom_widget.rb +8 -4
- data/lib/glimmer/ui/video.rb +31 -28
- 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
- data/samples/gladiator.rb +52 -12
- metadata +55 -31
- data/lib/glimmer/dsl.rb +0 -26
- data/lib/glimmer/dsl/async_exec_expression.rb +0 -12
- data/lib/glimmer/dsl/bind_expression.rb +0 -35
- data/lib/glimmer/dsl/color_expression.rb +0 -22
- data/lib/glimmer/dsl/column_properties_expression.rb +0 -22
- data/lib/glimmer/dsl/combo_selection_data_binding_expression.rb +0 -40
- data/lib/glimmer/dsl/custom_widget_expression.rb +0 -33
- data/lib/glimmer/dsl/data_binding_expression.rb +0 -32
- data/lib/glimmer/dsl/display_expression.rb +0 -14
- data/lib/glimmer/dsl/exec_expression.rb +0 -23
- data/lib/glimmer/dsl/layout_data_expression.rb +0 -23
- data/lib/glimmer/dsl/layout_expression.rb +0 -25
- data/lib/glimmer/dsl/list_selection_data_binding_expression.rb +0 -42
- data/lib/glimmer/dsl/menu_bar_expression.rb +0 -31
- data/lib/glimmer/dsl/menu_expression.rb +0 -30
- data/lib/glimmer/dsl/observe_expression.rb +0 -27
- data/lib/glimmer/dsl/property_expression.rb +0 -20
- data/lib/glimmer/dsl/shell_expression.rb +0 -16
- data/lib/glimmer/dsl/swt_expression.rb +0 -23
- data/lib/glimmer/dsl/sync_exec_expression.rb +0 -13
- data/lib/glimmer/dsl/tab_item_expression.rb +0 -31
- data/lib/glimmer/dsl/table_items_data_binding_expression.rb +0 -29
- data/lib/glimmer/dsl/tree_items_data_binding_expression.rb +0 -29
- data/lib/glimmer/dsl/tree_properties_expression.rb +0 -24
- data/lib/glimmer/dsl/widget_expression.rb +0 -25
- data/lib/glimmer/dsl/widget_listener_expression.rb +0 -30
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3610ccbe7872450d8b38005411e05be5b282c6f9785dbb21f87a239944ff304b
|
|
4
|
+
data.tar.gz: d80b1a110bd98b8dd5bd84be107ef9cd316af755cc052f94449b2249ddee1d4b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9d7810d076c698cab8d9c43fb4c7c3743ba37cad314e090e5d4112dcee50d6b5b5a389dce908e63e2c35a755079e944d69acff2b8ee9620f3541d474f97190a7
|
|
7
|
+
data.tar.gz: 64843e0799b6c035ca8aafa09be1ace82fda2ae7c188553e4db61ed8579b33598bc0f141ee90d8fb99f2383e810059278f2dfec8f4cbb862eac7d6e6288c0ae7
|
data/README.markdown
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
# Glimmer 0.
|
|
1
|
+
# Glimmer 0.6.0 Beta (JRuby Desktop UI DSL + Data-Binding)
|
|
2
2
|
[](https://coveralls.io/github/AndyObtiva/glimmer?branch=master)
|
|
3
3
|
|
|
4
|
-
Glimmer is a native-UI cross-platform desktop development library written in Ruby. Glimmer's main innovation is a JRuby DSL that enables productive and efficient authoring of desktop application user-interfaces while relying on the robust
|
|
4
|
+
Glimmer is a native-UI cross-platform desktop development library written in Ruby. Glimmer's main innovation is a JRuby DSL that enables productive and efficient authoring of desktop application user-interfaces while relying on the robust Eclipse SWT library. Glimmer additionally innovates by having built-in data-binding support to greatly facilitate synchronizing the UI with domain models. As a result, that achieves true decoupling of object oriented components, enabling developers to solve business problems without worrying about UI concerns, or alternatively drive development UI-first, and then write clean business components test-first afterwards.
|
|
5
5
|
|
|
6
6
|
## Examples
|
|
7
7
|
|
|
@@ -70,7 +70,7 @@ NOTE: Glimmer is in beta mode. Please help make better by adopting for small or
|
|
|
70
70
|
## Table of Contents
|
|
71
71
|
|
|
72
72
|
<!-- TOC START min:1 max:3 link:true asterisk:false update:true -->
|
|
73
|
-
- [Glimmer 0.
|
|
73
|
+
- [Glimmer 0.6.0 Beta (JRuby Desktop UI DSL + Data-Binding)](#glimmer-058-beta-jruby-desktop-ui-dsl--data-binding)
|
|
74
74
|
- [Examples](#examples)
|
|
75
75
|
- [Hello World](#hello-world)
|
|
76
76
|
- [Tic Tac Toe](#tic-tac-toe)
|
|
@@ -163,14 +163,14 @@ Please follow these instructions to make the `glimmer` command available on your
|
|
|
163
163
|
|
|
164
164
|
Run this command to install directly:
|
|
165
165
|
```
|
|
166
|
-
jgem install glimmer -v 0.
|
|
166
|
+
jgem install glimmer -v 0.6.0
|
|
167
167
|
```
|
|
168
168
|
|
|
169
169
|
### Option 2: Bundler
|
|
170
170
|
|
|
171
171
|
Add the following to `Gemfile`:
|
|
172
172
|
```
|
|
173
|
-
gem 'glimmer', '~> 0.
|
|
173
|
+
gem 'glimmer', '~> 0.6.0'
|
|
174
174
|
```
|
|
175
175
|
|
|
176
176
|
And, then run:
|
|
@@ -1558,6 +1558,119 @@ shell(:no_resize) {
|
|
|
1558
1558
|
|
|
1559
1559
|
Also, you may invoke `Display.setAppVersion('1.0.0')` if needed for OS app version identification reasons during development, replacing `'1.0.0'` with your application version.
|
|
1560
1560
|
|
|
1561
|
+
#### Multi-DSL Support
|
|
1562
|
+
|
|
1563
|
+
Glimmer supports two other DSLs in addition to the SWT DSL; that is Glimmer XML DSL and Glimmer CSS DSL. It also allows mixing DSLs, which comes in handy when doing things like using the `browser` widget. Glimmer automatically recognizes top-level keywords in each DSL
|
|
1564
|
+
and switches DSLs accordingly until it finishes processes the top-level keywords, at which point it switches back to the prior DSL.
|
|
1565
|
+
|
|
1566
|
+
For example, the SWT DSL has the following top-level keywords:
|
|
1567
|
+
- `shell`
|
|
1568
|
+
- `display`
|
|
1569
|
+
- `observe`
|
|
1570
|
+
- `async_exec`
|
|
1571
|
+
- `sync_exec`
|
|
1572
|
+
|
|
1573
|
+
##### XML DSL
|
|
1574
|
+
|
|
1575
|
+
Simply start with `html` keyword and add HTML inside its block using Glimmer DSL syntax.
|
|
1576
|
+
Once done, you may call `to_s`, `to_xml`, or `to_html` to get the formatted HTML output.
|
|
1577
|
+
|
|
1578
|
+
Here are all the Glimmer XML DSL top-level keywords:
|
|
1579
|
+
- `html`
|
|
1580
|
+
- `tag`: enables custom tag creation for exceptional cases by passing tag name as '_name' attribute
|
|
1581
|
+
- `name_space`: enables namespacing html tags
|
|
1582
|
+
|
|
1583
|
+
Element properties are typically passed as a key/value hash (e.g. `section(id: 'main', class: 'accordion')`) . However, for properties like "selected" or "checked", you must leave value `nil` or otherwise pass in front of the hash (e.g. `input(:checked, type: 'checkbox')` )
|
|
1584
|
+
|
|
1585
|
+
Example (basic HTML / you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
|
1586
|
+
|
|
1587
|
+
```ruby
|
|
1588
|
+
@xml = html {
|
|
1589
|
+
head {
|
|
1590
|
+
meta(name: "viewport", content: "width=device-width, initial-scale=2.0")
|
|
1591
|
+
}
|
|
1592
|
+
body {
|
|
1593
|
+
h1 { "Hello, World!" }
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
puts @xml
|
|
1597
|
+
```
|
|
1598
|
+
|
|
1599
|
+
Output:
|
|
1600
|
+
|
|
1601
|
+
```
|
|
1602
|
+
<html><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=2.0\" /></head><body><h1>Hello, World!</h1></body></html>
|
|
1603
|
+
```
|
|
1604
|
+
|
|
1605
|
+
Example (explicit XML tag / you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
|
1606
|
+
|
|
1607
|
+
```ruby
|
|
1608
|
+
puts tag(:_name => "DOCUMENT")
|
|
1609
|
+
```
|
|
1610
|
+
|
|
1611
|
+
Output:
|
|
1612
|
+
|
|
1613
|
+
```
|
|
1614
|
+
<DOCUMENT/>
|
|
1615
|
+
```
|
|
1616
|
+
|
|
1617
|
+
Example (XML namespaces using `name_space` keyword / you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
|
1618
|
+
|
|
1619
|
+
```ruby
|
|
1620
|
+
@xml = name_space(:w3c) {
|
|
1621
|
+
html(:id => "thesis", :class => "document") {
|
|
1622
|
+
body(:id => "main") {
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
puts @xml
|
|
1627
|
+
```
|
|
1628
|
+
|
|
1629
|
+
Output:
|
|
1630
|
+
|
|
1631
|
+
```
|
|
1632
|
+
<w3c:html id=\"thesis\" class=\"document\"><w3c:body id=\"main\"></w3c:body></w3c:html>
|
|
1633
|
+
```
|
|
1634
|
+
|
|
1635
|
+
Example (XML namespaces using dot operator / you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
|
1636
|
+
|
|
1637
|
+
```ruby
|
|
1638
|
+
@xml = tag(:_name => "DOCUMENT") {
|
|
1639
|
+
document.body(document.id => "main") {
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
puts @xml
|
|
1643
|
+
```
|
|
1644
|
+
|
|
1645
|
+
Output:
|
|
1646
|
+
|
|
1647
|
+
```
|
|
1648
|
+
<DOCUMENT><document:body document:id="main"></document:body></DOCUMENT>
|
|
1649
|
+
```
|
|
1650
|
+
|
|
1651
|
+
|
|
1652
|
+
##### CSS DSL
|
|
1653
|
+
|
|
1654
|
+
Simply start with `css` keyword and add stylesheet rule sets inside its block using Glimmer DSL syntax.
|
|
1655
|
+
Once done, you may call `to_s` or `to_css` to get the formatted CSS output.
|
|
1656
|
+
|
|
1657
|
+
`css` is the only top-level keyword in the Glimmer CSS DSL
|
|
1658
|
+
|
|
1659
|
+
Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
|
1660
|
+
|
|
1661
|
+
```ruby
|
|
1662
|
+
@css = css {
|
|
1663
|
+
body {
|
|
1664
|
+
font_size "1.1em"
|
|
1665
|
+
}
|
|
1666
|
+
|
|
1667
|
+
s('body > h1') {
|
|
1668
|
+
background_color :red
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
puts @css
|
|
1672
|
+
```
|
|
1673
|
+
|
|
1561
1674
|
#### Video Widget
|
|
1562
1675
|
|
|
1563
1676
|

|
|
@@ -1662,15 +1775,14 @@ Example rendering HTML with JavaScript on document ready (you may copy/paste in
|
|
|
1662
1775
|
shell {
|
|
1663
1776
|
minimum_size 130, 130
|
|
1664
1777
|
@browser = browser {
|
|
1665
|
-
text
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
HTML
|
|
1778
|
+
text html {
|
|
1779
|
+
head {
|
|
1780
|
+
meta(name: "viewport", content: "width=device-width, initial-scale=2.0")
|
|
1781
|
+
}
|
|
1782
|
+
body {
|
|
1783
|
+
h1 { "Hello, World!" }
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1674
1786
|
on_completed { # on load of the page execute this JavaScript
|
|
1675
1787
|
@browser.swt_widget.execute("alert('Hello, World!');")
|
|
1676
1788
|
}
|
|
@@ -1678,6 +1790,8 @@ shell {
|
|
|
1678
1790
|
}.open
|
|
1679
1791
|
```
|
|
1680
1792
|
|
|
1793
|
+
This relies on Glimmer's [Multi-DSL Support](https://github.com/AndyObtiva/glimmer/tree/development#multi-dsl-support) for building the HTML text using Glimmer XML DSL.
|
|
1794
|
+
|
|
1681
1795
|
## Glimmer Style Guide
|
|
1682
1796
|
|
|
1683
1797
|
- Widgets are declared with underscored lowercase versions of their SWT names minus the SWT package name.
|
|
@@ -1917,7 +2031,7 @@ Glimmer employs smart defaults in packaging.
|
|
|
1917
2031
|
|
|
1918
2032
|
The package application name (shows up in top menu bar on the Mac) will be a human form of the app root directory name (e.g. "Math Bowling" for "MathBowling" or "math_bowling" app root directory name). However, application name and version may be specified explicitly via "-Bmac.CFBundleName" and "-Bmac.CFBundleVersion" options.
|
|
1919
2033
|
|
|
1920
|
-
Also, the package will only include these directories: app, config, db, lib, script, bin, images, sounds, videos
|
|
2034
|
+
Also, the package will only include these directories: app, config, db, lib, script, bin, docs, fonts, images, sounds, videos
|
|
1921
2035
|
|
|
1922
2036
|
After running once, you will find a `config/warble.rb` file. It has the JAR packaging configuration. You may adjust included directories in it if needed, and then rerun `rake glimmer:package` and it will pick up your custom configuration. Alternatively, if you'd like to customize the included directories to begin with, don't run `rake glimmer:package` right away. Run this command first:
|
|
1923
2037
|
|
data/lib/glimmer.rb
CHANGED
|
@@ -54,6 +54,16 @@ module Glimmer
|
|
|
54
54
|
def enable_logging
|
|
55
55
|
@@logger = Logger.new(STDOUT).tap {|logger| logger.level = Logger::WARN}
|
|
56
56
|
end
|
|
57
|
+
|
|
58
|
+
# Sets current DSL (e.g. :swt)
|
|
59
|
+
def dsl=(dsl_name)
|
|
60
|
+
Glimmer::DSL::Engine.dsl = dsl_name
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Currently set DSL (e.g. :swt or :xml)
|
|
64
|
+
def dsl
|
|
65
|
+
Glimmer::DSL::Engine.dsl
|
|
66
|
+
end
|
|
57
67
|
end
|
|
58
68
|
|
|
59
69
|
def method_missing(method_symbol, *args, &block)
|
|
@@ -82,7 +92,9 @@ $LOAD_PATH.unshift(File.expand_path('..', __FILE__))
|
|
|
82
92
|
require 'glimmer/launcher'
|
|
83
93
|
require Glimmer::Launcher.swt_jar_file
|
|
84
94
|
require 'glimmer/swt/packages'
|
|
85
|
-
require 'glimmer/dsl'
|
|
95
|
+
require 'glimmer/dsl/swt/dsl'
|
|
96
|
+
require 'glimmer/dsl/xml/dsl'
|
|
97
|
+
require 'glimmer/dsl/css/dsl'
|
|
86
98
|
require 'glimmer/error'
|
|
87
99
|
require 'glimmer/invalid_keyword_error'
|
|
88
100
|
require 'glimmer/ui/video'
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Glimmer
|
|
2
|
+
module CSS
|
|
3
|
+
class RuleSet
|
|
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} {\n"
|
|
18
|
+
@properties.each do |name, value|
|
|
19
|
+
css << " #{name}: #{value};\n"
|
|
20
|
+
end
|
|
21
|
+
css << "}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
alias to_s to_css
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'glimmer/css/rule_set'
|
|
2
|
+
|
|
3
|
+
module Glimmer
|
|
4
|
+
module CSS
|
|
5
|
+
class StyleSheet
|
|
6
|
+
attr_reader :rule_sets
|
|
7
|
+
|
|
8
|
+
def initialize
|
|
9
|
+
@rule_sets = []
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def to_css
|
|
13
|
+
rule_set_css = rule_sets.map(&:to_css).join("\n\n")
|
|
14
|
+
"#{rule_set_css}\n"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
alias to_s to_css
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
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,25 @@
|
|
|
1
|
+
require 'glimmer/dsl/static_expression'
|
|
2
|
+
require 'glimmer/css/style_sheet'
|
|
3
|
+
require 'glimmer/css/rule_set'
|
|
4
|
+
|
|
5
|
+
module Glimmer
|
|
6
|
+
module DSL
|
|
7
|
+
module CSS
|
|
8
|
+
class PExpression < StaticExpression
|
|
9
|
+
include ParentExpression
|
|
10
|
+
|
|
11
|
+
def can_interpret?(parent, keyword, *args, &block)
|
|
12
|
+
keyword == 'p' and
|
|
13
|
+
parent.is_a?(Glimmer::CSS::RuleSet) and
|
|
14
|
+
!block_given? and
|
|
15
|
+
!args.empty? and
|
|
16
|
+
args.size > 1
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def interpret(parent, keyword, *args, &block)
|
|
20
|
+
parent.add_property(args[0], args[1])
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'glimmer/dsl/expression'
|
|
2
|
+
require 'glimmer/css/rule_set'
|
|
3
|
+
|
|
4
|
+
module Glimmer
|
|
5
|
+
module DSL
|
|
6
|
+
module CSS
|
|
7
|
+
class PropertyExpression < Expression
|
|
8
|
+
include ParentExpression
|
|
9
|
+
|
|
10
|
+
def can_interpret?(parent, keyword, *args, &block)
|
|
11
|
+
parent.is_a?(Glimmer::CSS::RuleSet) 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,25 @@
|
|
|
1
|
+
require 'glimmer/dsl/expression'
|
|
2
|
+
require 'glimmer/css/style_sheet'
|
|
3
|
+
require 'glimmer/css/rule_set'
|
|
4
|
+
|
|
5
|
+
module Glimmer
|
|
6
|
+
module DSL
|
|
7
|
+
module CSS
|
|
8
|
+
class RuleSetExpression < Expression
|
|
9
|
+
include ParentExpression
|
|
10
|
+
|
|
11
|
+
def can_interpret?(parent, keyword, *args, &block)
|
|
12
|
+
parent.is_a?(Glimmer::CSS::StyleSheet) and
|
|
13
|
+
block_given? and
|
|
14
|
+
args.empty?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def interpret(parent, keyword, *args, &block)
|
|
18
|
+
Glimmer::CSS::RuleSet.new(keyword.to_s.downcase).tap do |rule_set|
|
|
19
|
+
parent.rule_sets << rule_set
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'glimmer/dsl/static_expression'
|
|
2
|
+
require 'glimmer/css/style_sheet'
|
|
3
|
+
require 'glimmer/css/rule_set'
|
|
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::RuleSet.new(args.first.to_s).tap do |rule_set|
|
|
20
|
+
parent.rule_sets << rule_set
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
data/lib/glimmer/dsl/engine.rb
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
require 'glimmer'
|
|
2
|
-
Dir[File.expand_path('../*_expression.rb', __FILE__)].each {|f| require f}
|
|
3
2
|
require 'glimmer/dsl/expression_handler'
|
|
4
3
|
|
|
5
4
|
module Glimmer
|
|
@@ -10,12 +9,31 @@ module Glimmer
|
|
|
10
9
|
#
|
|
11
10
|
# When DSL engine interprets an expression, it attempts to handle
|
|
12
11
|
# with ordered expression array specified via `.expressions=` method.
|
|
13
|
-
#
|
|
14
|
-
# TODO support auto-loading static_expressions in the future for expressions where
|
|
15
|
-
# the keyword does not vary dynamically. These static keywords are then
|
|
16
|
-
# predefined as methods in Glimmer instead of needing method_missing
|
|
17
12
|
class Engine
|
|
18
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
|
+
# Dynamic expression chains of responsibility indexed by dsl
|
|
28
|
+
def dynamic_expression_chains_of_responsibility
|
|
29
|
+
@dynamic_expression_chains_of_responsibility ||= {}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Static expressions indexed by keyword and dsl
|
|
33
|
+
def static_expressions
|
|
34
|
+
@static_expressions ||= {}
|
|
35
|
+
end
|
|
36
|
+
|
|
19
37
|
# Sets an ordered array of DSL expressions to support
|
|
20
38
|
#
|
|
21
39
|
# Every expression has an underscored name corresponding to an upper
|
|
@@ -23,33 +41,75 @@ module Glimmer
|
|
|
23
41
|
#
|
|
24
42
|
# They are used in order following the Chain of Responsibility Design
|
|
25
43
|
# Pattern when interpretting a DSL expression
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
expression
|
|
44
|
+
def add_dynamic_expressions(dsl_namespace, expression_names)
|
|
45
|
+
dsl = dsl_namespace.name.split("::").last.downcase.to_sym
|
|
46
|
+
dynamic_expression_chains_of_responsibility[dsl] = expression_names.reverse.map do |expression_name|
|
|
47
|
+
expression_class(dsl_namespace, expression_name).new
|
|
48
|
+
end.reduce(nil) do |last_expresion_handler, expression|
|
|
49
|
+
Glimmer.logger&.debug "Adding dynamic expression: #{expression.class.name}"
|
|
32
50
|
expression_handler = ExpressionHandler.new(expression)
|
|
33
51
|
expression_handler.next = last_expresion_handler if last_expresion_handler
|
|
34
52
|
expression_handler
|
|
35
53
|
end
|
|
36
54
|
end
|
|
37
55
|
|
|
38
|
-
def
|
|
39
|
-
|
|
56
|
+
def add_static_expression(static_expression)
|
|
57
|
+
Glimmer.logger&.debug "Adding static expression: #{static_expression.class.name}"
|
|
58
|
+
keyword = static_expression.class.keyword
|
|
59
|
+
static_expression_dsl = static_expression.class.dsl
|
|
60
|
+
static_expressions[keyword] ||= {}
|
|
61
|
+
static_expressions[keyword][static_expression_dsl] = static_expression
|
|
62
|
+
Glimmer.define_method(keyword) do |*args, &block|
|
|
63
|
+
begin
|
|
64
|
+
retrieved_static_expression = Glimmer::DSL::Engine.static_expressions[keyword][Glimmer::DSL::Engine.dsl]
|
|
65
|
+
static_expression_dsl = Glimmer::DSL::Engine.static_expressions[keyword].keys.first if retrieved_static_expression.nil?
|
|
66
|
+
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))
|
|
67
|
+
begin
|
|
68
|
+
return Glimmer::DSL::Engine.interpret(keyword, *args, &block)
|
|
69
|
+
rescue => e
|
|
70
|
+
raise e if static_expression_dsl.nil?
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
raise Glimmer::Error, "Unsupported keyword: #{keyword}" unless static_expression_dsl || retrieved_static_expression
|
|
74
|
+
Glimmer::DSL::Engine.dsl_stack.push(static_expression_dsl || Glimmer::DSL::Engine.dsl)
|
|
75
|
+
static_expression = Glimmer::DSL::Engine.static_expressions[keyword][Glimmer::DSL::Engine.dsl]
|
|
76
|
+
if !static_expression.can_interpret?(Glimmer::DSL::Engine.parent, keyword, *args, &block)
|
|
77
|
+
raise Error, "Invalid use of Glimmer keyword #{keyword} with args #{args} under parent #{Glimmer::DSL::Engine.parent}"
|
|
78
|
+
else
|
|
79
|
+
Glimmer.logger&.debug "#{static_expression.class.name} will handle expression keyword #{keyword}"
|
|
80
|
+
return static_expression.interpret(Glimmer::DSL::Engine.parent, keyword, *args, &block).tap do |ui_object|
|
|
81
|
+
Glimmer::DSL::Engine.add_content(ui_object, static_expression, &block) unless block.nil?
|
|
82
|
+
Glimmer::DSL::Engine.dsl_stack.pop
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
rescue => e
|
|
86
|
+
Glimmer::DSL::Engine.dsl_stack.pop
|
|
87
|
+
raise e
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def expression_class(dsl_namespace, expression_name)
|
|
93
|
+
dsl_namespace.const_get(expression_class_name(expression_name).to_sym)
|
|
40
94
|
end
|
|
41
95
|
|
|
42
96
|
def expression_class_name(expression_name)
|
|
43
97
|
"#{expression_name}_expression".camelcase(:upper)
|
|
44
98
|
end
|
|
45
99
|
|
|
46
|
-
# Interprets Glimmer DSL keyword, args, and block (e.g. shell(:no_resize) { ... })
|
|
100
|
+
# Interprets Glimmer dynamic DSL expression consisting of keyword, args, and block (e.g. shell(:no_resize) { ... })
|
|
47
101
|
def interpret(keyword, *args, &block)
|
|
48
102
|
keyword = keyword.to_s
|
|
49
|
-
|
|
50
|
-
|
|
103
|
+
dynamic_expression_dsl = dynamic_expression_chains_of_responsibility.keys.first if dsl.nil?
|
|
104
|
+
dsl_stack.push(dynamic_expression_dsl || dsl)
|
|
105
|
+
expression = dynamic_expression_chains_of_responsibility[dsl].handle(parent, keyword, *args, &block)
|
|
106
|
+
expression.interpret(parent, keyword, *args, &block).tap do |ui_object|
|
|
51
107
|
add_content(ui_object, expression, &block)
|
|
108
|
+
dsl_stack.pop
|
|
52
109
|
end
|
|
110
|
+
rescue => e
|
|
111
|
+
dsl_stack.pop
|
|
112
|
+
raise e
|
|
53
113
|
end
|
|
54
114
|
|
|
55
115
|
# Adds content block to parent UI object
|
|
@@ -58,21 +118,33 @@ module Glimmer
|
|
|
58
118
|
#
|
|
59
119
|
# For example, a shell widget would get properties set and children added
|
|
60
120
|
def add_content(parent, expression, &block)
|
|
121
|
+
time = Time.now.to_f
|
|
122
|
+
dsl_stack.push(expression.class.dsl)
|
|
61
123
|
parent_stack.push(parent) if expression.is_a?(ParentExpression)
|
|
62
124
|
expression.add_content(parent, &block) if block_given?
|
|
63
125
|
parent_stack.pop if expression.is_a?(ParentExpression)
|
|
126
|
+
dsl_stack.pop
|
|
64
127
|
end
|
|
65
128
|
|
|
66
129
|
# Current parent while evaluating Glimmer DSL (nil if just started or done evaluatiing)
|
|
67
130
|
#
|
|
68
131
|
# Parents are maintained in a stack while evaluating Glimmer DSL
|
|
69
132
|
# to ensure properly ordered interpretation of DSL syntax
|
|
70
|
-
def
|
|
133
|
+
def parent
|
|
71
134
|
parent_stack.last
|
|
72
135
|
end
|
|
73
136
|
|
|
74
137
|
def parent_stack
|
|
75
|
-
|
|
138
|
+
parent_stacks[dsl] ||= []
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def parent_stacks
|
|
142
|
+
@parent_stacks ||= {}
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Enables multiple DSLs to play well with each other when mixing together
|
|
146
|
+
def dsl_stack
|
|
147
|
+
@dsl_stack ||= []
|
|
76
148
|
end
|
|
77
149
|
end
|
|
78
150
|
end
|