glimmer 0.5.11 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Coverage Status](https://coveralls.io/repos/github/AndyObtiva/glimmer/badge.svg?branch=master)](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
|
![Video Widget](images/glimmer-video-widget.png)
|
@@ -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
|