glimmer-dsl-opal 0.2.0 → 0.3.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/CHANGELOG.md +6 -0
- data/README.md +184 -12
- data/VERSION +1 -1
- data/lib/glimmer-dsl-opal.rb +3 -0
- data/lib/glimmer-dsl-opal/ext/date.rb +13 -0
- data/lib/glimmer-dsl-opal/missing/uri.rb +38 -0
- data/lib/glimmer-dsl-opal/samples/hello/hello_custom_shell.rb +3 -3
- data/lib/glimmer/dsl/opal/custom_widget_expression.rb +22 -2
- data/lib/glimmer/dsl/opal/dsl.rb +1 -0
- data/lib/glimmer/dsl/opal/layout_expression.rb +1 -1
- data/lib/glimmer/dsl/opal/shell_expression.rb +17 -1
- data/lib/glimmer/dsl/opal/swt_expression.rb +1 -1
- data/lib/glimmer/swt/layout_data_proxy.rb +35 -0
- data/lib/glimmer/swt/layout_proxy.rb +2 -1
- data/lib/glimmer/swt/message_box_proxy.rb +1 -1
- data/lib/glimmer/swt/shell_proxy.rb +2 -1
- data/lib/glimmer/ui/custom_shell.rb +19 -1
- data/lib/glimmer/ui/custom_widget.rb +3 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 321f0f4121858de374edacf81772b65ff3bd0ee1e155531b5a04681c1e7f5fa0
|
4
|
+
data.tar.gz: 5bfab859f5b96458ca452444253a8fb1fefe5274e2bdbc892e574ab6fcd74ed0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 58ee88fda2ed5729f1c3b58035d6aa252fbb23ac2a12b120e88040aa485d7e34bf9f337c1a8e6f289c73c23528aec4dd735a00c0542c4c120c9499141815cc38
|
7
|
+
data.tar.gz: d70d728a4beb4ff5bff63c68b823155ab39b014163698fe875ffacbba09c2e18b91fc3b11fd529876857187fe7aae5e331ecf32b06f4d417a0615bd38d64877a
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.3.0
|
4
|
+
|
5
|
+
- Support opening a custom shell in a browser tab/window by passing in query parameters to URL (e.g. ?custom_shell=keyword+option1=value1 etc...)
|
6
|
+
- Make custom shells automatically open in a new tab/window (while standard shells continue to open in the same window by replacing its content)
|
7
|
+
- Hello, Custom Shell! Sample
|
8
|
+
|
3
9
|
## 0.2.0
|
4
10
|
|
5
11
|
- Color support
|
data/README.md
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Opal 0.
|
1
|
+
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Opal 0.3.0 (Webify Desktop Apps)
|
2
2
|
[](http://badge.fury.io/rb/glimmer-dsl-opal)
|
3
3
|
[](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
4
4
|
|
5
|
-
### You can finally live in pure Ruby land
|
5
|
+
### You can finally live in pure Ruby land on the web!
|
6
6
|
|
7
7
|
[Glimmer](https://github.com/AndyObtiva/glimmer) DSL for [Opal](https://opalrb.com/) is an experimental proof-of-concept web GUI adapter for [Glimmer](https://github.com/AndyObtiva/glimmer) desktop apps (i.e. apps built with [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt)). It webifies them via [Rails](https://rubyonrails.org/), allowing Ruby desktop apps to run on the web via [Opal Ruby](https://opalrb.com/) without changing a line of code. Apps may then be custom-styled for the web with standard CSS by web designers.
|
8
8
|
|
9
|
-
Glimmer DSL for Opal
|
9
|
+
Glimmer DSL for Opal successfully reuses the entire [Glimmer](https://github.com/AndyObtiva/glimmer) core DSL engine in [Opal Ruby](https://opalrb.com/) inside a web browser, and as such inherits the full range of powerful Glimmer desktop [data-binding](https://github.com/AndyObtiva/glimmer#data-binding) capabilities for the web.
|
10
10
|
|
11
|
-
NOTE: Alpha Version 0.
|
11
|
+
NOTE: Alpha Version 0.3.0 only supports bare-minimum capabilities for the following [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) [samples](https://github.com/AndyObtiva/glimmer#samples):
|
12
12
|
- [Hello, World!](#hello-world)
|
13
13
|
- [Hello, Combo!](#hello-combo)
|
14
14
|
- [Hello, Computed!](#hello-computed)
|
@@ -17,6 +17,7 @@ NOTE: Alpha Version 0.2.0 only supports bare-minimum capabilities for the follow
|
|
17
17
|
- [Hello, Browser!](#hello-browser)
|
18
18
|
- [Hello, Tab!](#hello-tab)
|
19
19
|
- [Hello, Custom Widget!](#hello-custom-widget)
|
20
|
+
- [Hello, Custom Shell!](#hello-custom-shell)
|
20
21
|
- [Login](#login)
|
21
22
|
- [Tic Tac Toe](#tic-tac-toe)
|
22
23
|
- [Contact Manager](#contact-manager)
|
@@ -44,10 +45,8 @@ Widgets:
|
|
44
45
|
- `table`
|
45
46
|
- `table_column`
|
46
47
|
- `message_box`
|
47
|
-
|
48
|
-
|
49
|
-
- `color`
|
50
|
-
- `font`
|
48
|
+
- CustomWidget (ability to define any keyword as a custom widget)
|
49
|
+
- CustomShell (ability to define any keyword as a custom shell (aka custom window) that opens in a new browser window)
|
51
50
|
|
52
51
|
Layouts:
|
53
52
|
- `grid_layout`
|
@@ -55,6 +54,10 @@ Layouts:
|
|
55
54
|
- `fill_layout`
|
56
55
|
- `layout_data`
|
57
56
|
|
57
|
+
Graphics:
|
58
|
+
- `color`
|
59
|
+
- `font`
|
60
|
+
|
58
61
|
Data-Binding/Observers:
|
59
62
|
- `bind`
|
60
63
|
- `observe`
|
@@ -86,11 +89,11 @@ Add the following to `Gemfile`:
|
|
86
89
|
|
87
90
|
```
|
88
91
|
gem 'opal-rails', '~> 1.1.2'
|
89
|
-
gem 'opal-async', '~> 1.
|
92
|
+
gem 'opal-async', '~> 1.2.0'
|
90
93
|
gem 'opal-jquery', '~> 0.4.4'
|
91
|
-
gem 'glimmer-dsl-opal', '~> 0.
|
92
|
-
gem 'glimmer-dsl-xml', '~> 1.
|
93
|
-
gem 'glimmer-dsl-css', '~> 1.
|
94
|
+
gem 'glimmer-dsl-opal', '~> 0.3.0', require: false
|
95
|
+
gem 'glimmer-dsl-xml', '~> 1.1.0', require: false
|
96
|
+
gem 'glimmer-dsl-css', '~> 1.1.0', require: false
|
94
97
|
|
95
98
|
```
|
96
99
|
|
@@ -688,6 +691,175 @@ You should see "Hello, Custom Widget!"
|
|
688
691
|
|
689
692
|

|
690
693
|
|
694
|
+
#### Hello, Custom Shell!
|
695
|
+
|
696
|
+
Add the following require statement to `app/assets/javascripts/application.rb`
|
697
|
+
|
698
|
+
```ruby
|
699
|
+
require 'glimmer-dsl-opal/samples/hello/hello_custom_shell'
|
700
|
+
```
|
701
|
+
|
702
|
+
Or add the Glimmer code directly if you prefer to play around with it:
|
703
|
+
|
704
|
+
```ruby
|
705
|
+
require 'date'
|
706
|
+
|
707
|
+
# This class declares an `email_shell` custom shell, aka custom window (by convention)
|
708
|
+
# Used to view an email message
|
709
|
+
class EmailShell
|
710
|
+
include Glimmer::UI::CustomShell
|
711
|
+
|
712
|
+
# multiple options without default values
|
713
|
+
options :date, :subject, :from, :message
|
714
|
+
|
715
|
+
# single option with default value
|
716
|
+
option :to, default: '"John Irwin" <john.irwin@example.com>'
|
717
|
+
|
718
|
+
before_body {
|
719
|
+
@swt_style |= swt(:shell_trim, :modeless)
|
720
|
+
}
|
721
|
+
|
722
|
+
body {
|
723
|
+
# pass received swt_style through to shell to customize it (e.g. :dialog_trim for a blocking shell)
|
724
|
+
shell(swt_style) {
|
725
|
+
grid_layout(2, false)
|
726
|
+
|
727
|
+
text subject
|
728
|
+
|
729
|
+
label {
|
730
|
+
text 'Date:'
|
731
|
+
}
|
732
|
+
label {
|
733
|
+
text date
|
734
|
+
}
|
735
|
+
|
736
|
+
label {
|
737
|
+
text 'From:'
|
738
|
+
}
|
739
|
+
label {
|
740
|
+
text from
|
741
|
+
}
|
742
|
+
|
743
|
+
label {
|
744
|
+
text 'To:'
|
745
|
+
}
|
746
|
+
label {
|
747
|
+
text to
|
748
|
+
}
|
749
|
+
|
750
|
+
label {
|
751
|
+
text 'Subject:'
|
752
|
+
}
|
753
|
+
label {
|
754
|
+
text subject
|
755
|
+
}
|
756
|
+
|
757
|
+
label {
|
758
|
+
layout_data(:fill, :fill, true, true) {
|
759
|
+
horizontal_span 2 #TODO implement
|
760
|
+
vertical_indent 10
|
761
|
+
}
|
762
|
+
|
763
|
+
background :white
|
764
|
+
text message
|
765
|
+
}
|
766
|
+
}
|
767
|
+
}
|
768
|
+
|
769
|
+
end
|
770
|
+
|
771
|
+
class HelloCustomShell
|
772
|
+
# including Glimmer enables the Glimmer DSL syntax, including auto-discovery of the `email_shell` custom widget
|
773
|
+
include Glimmer
|
774
|
+
|
775
|
+
Email = Struct.new(:date, :subject, :from, :message, keyword_init: true)
|
776
|
+
EmailSystem = Struct.new(:emails, keyword_init: true)
|
777
|
+
|
778
|
+
def initialize
|
779
|
+
@email_system = EmailSystem.new(
|
780
|
+
emails: [
|
781
|
+
Email.new(date: DateTime.new(2029, 10, 22, 11, 3, 0).strftime('%F %I:%M %p'), subject: '3rd Week Report', from: '"Dianne Tux" <dianne.tux@example.com>', message: "Hello,\n\nI was wondering if you'd like to go over the weekly report sometime this afternoon.\n\nDianne"),
|
782
|
+
Email.new(date: DateTime.new(2029, 10, 21, 8, 1, 0).strftime('%F %I:%M %p'), subject: 'Glimmer Upgrade v100.0', from: '"Robert McGabbins" <robert.mcgabbins@example.com>', message: "Team,\n\nWe are upgrading to Glimmer version 100.0.\n\nEveryone pull the latest code!\n\nRegards,\n\nRobert McGabbins"),
|
783
|
+
Email.new(date: DateTime.new(2029, 10, 19, 16, 58, 0).strftime('%F %I:%M %p'), subject: 'Christmas Party', from: '"Lisa Ferreira" <lisa.ferreira@example.com>', message: "Merry Christmas,\n\nAll office Christmas Party arrangements have been set\n\nMake sure to bring a Secret Santa gift\n\nBest regards,\n\nLisa Ferreira"),
|
784
|
+
Email.new(date: DateTime.new(2029, 10, 16, 9, 43, 0).strftime('%F %I:%M %p'), subject: 'Glimmer Upgrade v99.0', from: '"Robert McGabbins" <robert.mcgabbins@example.com>', message: "Team,\n\nWe are upgrading to Glimmer version 99.0.\n\nEveryone pull the latest code!\n\nRegards,\n\nRobert McGabbins"),
|
785
|
+
Email.new(date: DateTime.new(2029, 10, 15, 11, 2, 0).strftime('%F %I:%M %p'), subject: '2nd Week Report', from: '"Dianne Tux" <dianne.tux@example.com>', message: "Hello,\n\nI was wondering if you'd like to go over the weekly report sometime this afternoon.\n\nDianne"),
|
786
|
+
Email.new(date: DateTime.new(2029, 10, 2, 10, 34, 0).strftime('%F %I:%M %p'), subject: 'Glimmer Upgrade v98.0', from: '"Robert McGabbins" <robert.mcgabbins@example.com>', message: "Team,\n\nWe are upgrading to Glimmer version 98.0.\n\nEveryone pull the latest code!\n\nRegards,\n\nRobert McGabbins"),
|
787
|
+
]
|
788
|
+
)
|
789
|
+
end
|
790
|
+
|
791
|
+
def launch
|
792
|
+
shell {
|
793
|
+
grid_layout
|
794
|
+
|
795
|
+
text 'Hello, Custom Shell!'
|
796
|
+
|
797
|
+
label {
|
798
|
+
font height: 24, style: :bold
|
799
|
+
text 'Emails:'
|
800
|
+
}
|
801
|
+
|
802
|
+
label {
|
803
|
+
font height: 18
|
804
|
+
text 'Click an email to view its message'
|
805
|
+
}
|
806
|
+
|
807
|
+
table {
|
808
|
+
layout_data :fill, :fill, true, true
|
809
|
+
|
810
|
+
table_column {
|
811
|
+
text 'Date:'
|
812
|
+
width 180
|
813
|
+
}
|
814
|
+
table_column {
|
815
|
+
text 'Subject:'
|
816
|
+
width 180
|
817
|
+
}
|
818
|
+
table_column {
|
819
|
+
text 'From:'
|
820
|
+
width 360
|
821
|
+
}
|
822
|
+
|
823
|
+
items bind(@email_system, :emails), column_properties(:date, :subject, :from)
|
824
|
+
|
825
|
+
on_mouse_up { |event|
|
826
|
+
email = event.table_item.get_data
|
827
|
+
Thread.new do
|
828
|
+
async_exec {
|
829
|
+
email_shell(date: email.date, subject: email.subject, from: email.from, message: email.message).open
|
830
|
+
}
|
831
|
+
end
|
832
|
+
}
|
833
|
+
}
|
834
|
+
}.open
|
835
|
+
end
|
836
|
+
end
|
837
|
+
|
838
|
+
HelloCustomShell.new.launch
|
839
|
+
```
|
840
|
+
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
841
|
+
|
842
|
+

|
843
|
+

|
844
|
+

|
845
|
+

|
846
|
+
|
847
|
+
Glimmer app on the web (using `glimmer-dsl-opal` gem):
|
848
|
+
|
849
|
+
Start the Rails server:
|
850
|
+
```
|
851
|
+
rails s
|
852
|
+
```
|
853
|
+
|
854
|
+
Visit `http://localhost:3000`
|
855
|
+
|
856
|
+
You should see "Hello, Custom Widget!"
|
857
|
+
|
858
|
+

|
859
|
+

|
860
|
+

|
861
|
+

|
862
|
+
|
691
863
|
### Elaborate Samples
|
692
864
|
|
693
865
|
#### Login
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/lib/glimmer-dsl-opal.rb
CHANGED
@@ -8,6 +8,7 @@ if RUBY_PLATFORM == 'opal'
|
|
8
8
|
$LOAD_PATH.unshift(GLIMMER_DSL_OPAL_LIB)
|
9
9
|
$LOAD_PATH.unshift(GLIMMER_DSL_OPAL_MISSING) # missing Ruby classes/methods
|
10
10
|
|
11
|
+
require 'opal-parser'
|
11
12
|
require 'native' # move this to opal-async
|
12
13
|
require 'opal-async'
|
13
14
|
require 'async/ext'
|
@@ -16,6 +17,8 @@ if RUBY_PLATFORM == 'opal'
|
|
16
17
|
require 'glimmer'
|
17
18
|
require 'facets/hash/symbolize_keys'
|
18
19
|
require 'glimmer-dsl-opal/ext/exception'
|
20
|
+
require 'glimmer-dsl-opal/ext/date'
|
21
|
+
require 'glimmer-dsl-opal/missing/uri'
|
19
22
|
|
20
23
|
# Spiking async logging
|
21
24
|
# logger = Glimmer::Config.logger
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
class DateTime < Date
|
5
|
+
def initialize(*args, &block)
|
6
|
+
@time = Time.new(*args, &block)
|
7
|
+
@time.methods.each do |method|
|
8
|
+
singleton_class.define_method(method) do |*args, &block|
|
9
|
+
@time.send(method, *args, &block)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -16,9 +16,47 @@ module URI
|
|
16
16
|
|
17
17
|
def to_s
|
18
18
|
url
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
TBLENCWWWCOMP_ = {"\u0000"=>"%00", "\u0001"=>"%01", "\u0002"=>"%02", "\u0003"=>"%03", "\u0004"=>"%04", "\u0005"=>"%05", "\u0006"=>"%06", "\a"=>"%07", "\b"=>"%08", "\t"=>"%09", "\n"=>"%0A", "\v"=>"%0B", "\f"=>"%0C", "\r"=>"%0D", "\u000E"=>"%0E", "\u000F"=>"%0F", "\u0010"=>"%10", "\u0011"=>"%11", "\u0012"=>"%12", "\u0013"=>"%13", "\u0014"=>"%14", "\u0015"=>"%15", "\u0016"=>"%16", "\u0017"=>"%17", "\u0018"=>"%18", "\u0019"=>"%19", "\u001A"=>"%1A", "\e"=>"%1B", "\u001C"=>"%1C", "\u001D"=>"%1D", "\u001E"=>"%1E", "\u001F"=>"%1F", " "=>"+", "!"=>"%21", "\""=>"%22", "#"=>"%23", "$"=>"%24", "%"=>"%25", "&"=>"%26", "'"=>"%27", "("=>"%28", ")"=>"%29", "*"=>"%2A", "+"=>"%2B", ","=>"%2C", "-"=>"%2D", "."=>"%2E", "/"=>"%2F", "0"=>"%30", "1"=>"%31", "2"=>"%32", "3"=>"%33", "4"=>"%34", "5"=>"%35", "6"=>"%36", "7"=>"%37", "8"=>"%38", "9"=>"%39", ":"=>"%3A", ";"=>"%3B", "<"=>"%3C", "="=>"%3D", ">"=>"%3E", "?"=>"%3F", "@"=>"%40", "A"=>"%41", "B"=>"%42", "C"=>"%43", "D"=>"%44", "E"=>"%45", "F"=>"%46", "G"=>"%47", "H"=>"%48", "I"=>"%49", "J"=>"%4A", "K"=>"%4B", "L"=>"%4C", "M"=>"%4D", "N"=>"%4E", "O"=>"%4F", "P"=>"%50", "Q"=>"%51", "R"=>"%52", "S"=>"%53", "T"=>"%54", "U"=>"%55", "V"=>"%56", "W"=>"%57", "X"=>"%58", "Y"=>"%59", "Z"=>"%5A", "["=>"%5B", "\\"=>"%5C", "]"=>"%5D", "^"=>"%5E", "_"=>"%5F", "`"=>"%60", "a"=>"%61", "b"=>"%62", "c"=>"%63", "d"=>"%64", "e"=>"%65", "f"=>"%66", "g"=>"%67", "h"=>"%68", "i"=>"%69", "j"=>"%6A", "k"=>"%6B", "l"=>"%6C", "m"=>"%6D", "n"=>"%6E", "o"=>"%6F", "p"=>"%70", "q"=>"%71", "r"=>"%72", "s"=>"%73", "t"=>"%74", "u"=>"%75", "v"=>"%76", "w"=>"%77", "x"=>"%78", "y"=>"%79", "z"=>"%7A", "{"=>"%7B", "|"=>"%7C", "}"=>"%7D", "~"=>"%7E", "\u007F"=>"%7F", "\u0080"=>"%80", "\u0081"=>"%81", "\u0082"=>"%82", "\u0083"=>"%83", "\u0084"=>"%84", "\u0085"=>"%85", "\u0086"=>"%86", "\u0087"=>"%87", "\u0088"=>"%88", "\u0089"=>"%89", "\u008A"=>"%8A", "\u008B"=>"%8B", "\u008C"=>"%8C", "\u008D"=>"%8D", "\u008E"=>"%8E", "\u008F"=>"%8F", "\u0090"=>"%90", "\u0091"=>"%91", "\u0092"=>"%92", "\u0093"=>"%93", "\u0094"=>"%94", "\u0095"=>"%95", "\u0096"=>"%96", "\u0097"=>"%97", "\u0098"=>"%98", "\u0099"=>"%99", "\u009A"=>"%9A", "\u009B"=>"%9B", "\u009C"=>"%9C", "\u009D"=>"%9D", "\u009E"=>"%9E", "\u009F"=>"%9F", "\u00A0"=>"%A0", "\u00A1"=>"%A1", "\u00A2"=>"%A2", "\u00A3"=>"%A3", "\u00A4"=>"%A4", "\u00A5"=>"%A5", "\u00A6"=>"%A6", "\u00A7"=>"%A7", "\u00A8"=>"%A8", "\u00A9"=>"%A9", "\u00AA"=>"%AA", "\u00AB"=>"%AB", "\u00AC"=>"%AC", "\u00AD"=>"%AD", "\u00AE"=>"%AE", "\u00AF"=>"%AF", "\u00B0"=>"%B0", "\u00B1"=>"%B1", "\u00B2"=>"%B2", "\u00B3"=>"%B3", "\u00B4"=>"%B4", "\u00B5"=>"%B5", "\u00B6"=>"%B6", "\u00B7"=>"%B7", "\u00B8"=>"%B8", "\u00B9"=>"%B9", "\u00BA"=>"%BA", "\u00BB"=>"%BB", "\u00BC"=>"%BC", "\u00BD"=>"%BD", "\u00BE"=>"%BE", "\u00BF"=>"%BF", "\u00C0"=>"%C0", "\u00C1"=>"%C1", "\u00C2"=>"%C2", "\u00C3"=>"%C3", "\u00C4"=>"%C4", "\u00C5"=>"%C5", "\u00C6"=>"%C6", "\u00C7"=>"%C7", "\u00C8"=>"%C8", "\u00C9"=>"%C9", "\u00CA"=>"%CA", "\u00CB"=>"%CB", "\u00CC"=>"%CC", "\u00CD"=>"%CD", "\u00CE"=>"%CE", "\u00CF"=>"%CF", "\u00D0"=>"%D0", "\u00D1"=>"%D1", "\u00D2"=>"%D2", "\u00D3"=>"%D3", "\u00D4"=>"%D4", "\u00D5"=>"%D5", "\u00D6"=>"%D6", "\u00D7"=>"%D7", "\u00D8"=>"%D8", "\u00D9"=>"%D9", "\u00DA"=>"%DA", "\u00DB"=>"%DB", "\u00DC"=>"%DC", "\u00DD"=>"%DD", "\u00DE"=>"%DE", "\u00DF"=>"%DF", "\u00E0"=>"%E0", "\u00E1"=>"%E1", "\u00E2"=>"%E2", "\u00E3"=>"%E3", "\u00E4"=>"%E4", "\u00E5"=>"%E5", "\u00E6"=>"%E6", "\u00E7"=>"%E7", "\u00E8"=>"%E8", "\u00E9"=>"%E9", "\u00EA"=>"%EA", "\u00EB"=>"%EB", "\u00EC"=>"%EC", "\u00ED"=>"%ED", "\u00EE"=>"%EE", "\u00EF"=>"%EF", "\u00F0"=>"%F0", "\u00F1"=>"%F1", "\u00F2"=>"%F2", "\u00F3"=>"%F3", "\u00F4"=>"%F4", "\u00F5"=>"%F5", "\u00F6"=>"%F6", "\u00F7"=>"%F7", "\u00F8"=>"%F8", "\u00F9"=>"%F9", "\u00FA"=>"%FA", "\u00FB"=>"%FB", "\u00FC"=>"%FC", "\u00FD"=>"%FD", "\u00FE"=>"%FE", "\u00FF"=>"%FF"}.freeze
|
23
|
+
TBLDECWWWCOMP_ = TBLENCWWWCOMP_.invert.freeze
|
24
|
+
|
25
|
+
# Encodes given +str+ to URL-encoded form data.
|
26
|
+
#
|
27
|
+
# This method doesn't convert *, -, ., 0-9, A-Z, _, a-z, but does convert SP
|
28
|
+
# (ASCII space) to + and converts others to %XX.
|
29
|
+
#
|
30
|
+
# If +enc+ is given, convert +str+ to the encoding before percent encoding.
|
31
|
+
#
|
32
|
+
# This is an implementation of
|
33
|
+
# https://www.w3.org/TR/2013/CR-html5-20130806/forms.html#url-encoded-form-data.
|
34
|
+
#
|
35
|
+
# See URI.decode_www_form_component, URI.encode_www_form.
|
36
|
+
def self.encode_www_form_component(str, enc=nil)
|
37
|
+
str = str.to_s.dup
|
38
|
+
if str.encoding != Encoding::ASCII_8BIT
|
39
|
+
if enc && enc != Encoding::ASCII_8BIT
|
40
|
+
str.encode!(Encoding::UTF_8, invalid: :replace, undef: :replace)
|
41
|
+
str.encode!(enc, fallback: ->(x){"&##{x.ord};"})
|
42
|
+
end
|
43
|
+
str.force_encoding(Encoding::ASCII_8BIT)
|
19
44
|
end
|
45
|
+
str = str.gsub(/[^*\-.0-9A-Z_a-z]/, TBLENCWWWCOMP_)
|
46
|
+
str.force_encoding(Encoding::US_ASCII)
|
20
47
|
end
|
48
|
+
|
49
|
+
# Decodes given +str+ of URL-encoded form data.
|
50
|
+
#
|
51
|
+
# This decodes + to SP.
|
52
|
+
#
|
53
|
+
# See URI.encode_www_form_component, URI.decode_www_form.
|
54
|
+
def self.decode_www_form_component(str, enc=Encoding::UTF_8)
|
55
|
+
raise ArgumentError, "invalid %-encoding (#{str})" if /%(?![0-9a-fA-F][0-9a-fA-F])/ =~ str
|
56
|
+
str.b.gsub(/\+|%[0-9a-fA-F][0-9a-fA-F]/, TBLDECWWWCOMP_).force_encoding(enc)
|
57
|
+
end
|
21
58
|
end
|
59
|
+
|
22
60
|
module Kernel
|
23
61
|
def URI(url)
|
24
62
|
URI::HTTP.new(url)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c)
|
1
|
+
# Copyright (c) 2020 Andy Maleh
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
# a copy of this software and associated documentation files (the
|
@@ -73,8 +73,8 @@ class EmailShell
|
|
73
73
|
|
74
74
|
label {
|
75
75
|
layout_data(:fill, :fill, true, true) {
|
76
|
-
horizontal_span 2
|
77
|
-
|
76
|
+
horizontal_span 2 #TODO implement
|
77
|
+
vertical_indent 10
|
78
78
|
}
|
79
79
|
|
80
80
|
background :white
|
@@ -39,11 +39,31 @@ module Glimmer
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def interpret(parent, keyword, *args, &block)
|
42
|
-
|
43
|
-
|
42
|
+
custom_widget_class = UI::CustomWidget.for(keyword)
|
43
|
+
# TODO clean code by extracting methods into CustomShell
|
44
|
+
if !Glimmer::UI::CustomShell.requested? && custom_widget_class.ancestors.include?(Glimmer::UI::CustomShell)
|
45
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
46
|
+
options = options.merge('swt_style' => args.join(',')) unless args.join(',').empty?
|
47
|
+
params = {
|
48
|
+
'custom_shell' => keyword
|
49
|
+
}.merge(options)
|
50
|
+
param_string = params.to_a.map {|k, v| "#{k}=#{URI.encode_www_form_component(v)}"}.join('&')
|
51
|
+
url = "#{`document.location.href`}?#{param_string}"
|
52
|
+
`window.open(#{url})`
|
53
|
+
# just a placeholder that has an open method # TODO return an actual CustomShell in the future that does the work happening above in the #open method
|
54
|
+
Struct.new(:open).new(true)
|
55
|
+
else
|
56
|
+
custom_widget_class.new(parent, *args, options, &block)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def add_content(parent, &content)
|
61
|
+
content.call(parent) if parent.is_a?(Glimmer::SWT::ShellProxy) || parent.is_a?(Glimmer::UI::CustomShell)
|
44
62
|
end
|
63
|
+
|
45
64
|
|
46
65
|
def add_content(parent, &block)
|
66
|
+
return unless parent.is_a?(Glimmer::UI::CustomWidget)
|
47
67
|
# TODO consider avoiding source_location
|
48
68
|
if block.source_location == parent.content&.__getobj__.source_location
|
49
69
|
parent.content.call(parent) unless parent.content.called?
|
data/lib/glimmer/dsl/opal/dsl.rb
CHANGED
@@ -20,6 +20,7 @@ require 'glimmer/dsl/opal/color_expression'
|
|
20
20
|
require 'glimmer/dsl/opal/rgb_expression'
|
21
21
|
require 'glimmer/dsl/opal/rgba_expression'
|
22
22
|
require 'glimmer/dsl/opal/custom_widget_expression'
|
23
|
+
require 'glimmer/dsl/opal/swt_expression'
|
23
24
|
|
24
25
|
module Glimmer
|
25
26
|
module DSL
|
@@ -9,7 +9,7 @@ module Glimmer
|
|
9
9
|
include ParentExpression
|
10
10
|
|
11
11
|
def can_interpret?(parent, keyword, *args, &block)
|
12
|
-
parent.is_a?(Glimmer::SWT::CompositeProxy)
|
12
|
+
(parent.is_a?(Glimmer::SWT::CompositeProxy) or (parent.is_a?(Glimmer::UI::CustomWidget) and parent.body_root.is_a?(Glimmer::SWT::CompositeProxy))) and
|
13
13
|
Glimmer::SWT::LayoutProxy.layout_exists?(keyword)
|
14
14
|
end
|
15
15
|
|
@@ -2,6 +2,8 @@ require 'glimmer/dsl/static_expression'
|
|
2
2
|
require 'glimmer/dsl/top_level_expression'
|
3
3
|
require 'glimmer/dsl/parent_expression'
|
4
4
|
require 'glimmer/swt/shell_proxy'
|
5
|
+
require 'glimmer/ui/custom_shell'
|
6
|
+
require 'glimmer/dsl/opal/custom_widget_expression'
|
5
7
|
|
6
8
|
module Glimmer
|
7
9
|
module DSL
|
@@ -11,7 +13,21 @@ module Glimmer
|
|
11
13
|
include ParentExpression
|
12
14
|
|
13
15
|
def interpret(parent, keyword, *args, &block)
|
14
|
-
Glimmer::
|
16
|
+
if Glimmer::UI::CustomShell.requested_and_not_handled?
|
17
|
+
parameters = Glimmer::UI::CustomShell.request_parameter_string.split("&").map {|str| str.split("=")}.to_h
|
18
|
+
`history.pushState(#{parameters.merge('custom_shell_handled' => 'true')}, document.title, #{"?#{Glimmer::UI::CustomShell.encoded_request_parameter_string}&custom_shell_handled=true"})`
|
19
|
+
custom_shell_keyword = parameters.delete('custom_shell')
|
20
|
+
CustomWidgetExpression.new.interpret(nil, custom_shell_keyword, *[parameters])
|
21
|
+
`history.pushState(#{parameters.reject {|k,v| k == 'custom_shell_handled'}}, document.title, #{"?#{Glimmer::UI::CustomShell.encoded_request_parameter_string.sub('&custom_shell_handled=true', '')}"})`
|
22
|
+
# just a placeholder that has an open method # TODO return an actual CustomShell in the future that does the work happening above in the #open method
|
23
|
+
Struct.new(:open).new(true)
|
24
|
+
else
|
25
|
+
Glimmer::SWT::ShellProxy.new(*args)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def add_content(parent, &content)
|
30
|
+
content.call(parent) if parent.is_a?(Glimmer::SWT::ShellProxy)
|
15
31
|
end
|
16
32
|
end
|
17
33
|
end
|
@@ -8,6 +8,10 @@ module Glimmer
|
|
8
8
|
:args,
|
9
9
|
:horizontal_alignment,
|
10
10
|
:vertical_alignment,
|
11
|
+
:horizontal_span,
|
12
|
+
:vertical_span,
|
13
|
+
:horizontal_indent,
|
14
|
+
:vertical_indent,
|
11
15
|
:grab_excess_horizontal_space,
|
12
16
|
:grab_excess_vertical_space,
|
13
17
|
:height_hint
|
@@ -15,31 +19,62 @@ module Glimmer
|
|
15
19
|
def initialize(parent, args)
|
16
20
|
@parent = parent
|
17
21
|
@args = args
|
22
|
+
# TODO spread args correctly
|
23
|
+
# TODO avoid using reapply
|
18
24
|
reapply
|
19
25
|
end
|
20
26
|
|
21
27
|
def height_hint=(height_hint)
|
22
28
|
@height_hint = height_hint
|
29
|
+
# TODO
|
23
30
|
reapply
|
24
31
|
end
|
25
32
|
|
26
33
|
def horizontal_alignment=(horizontal_alignment)
|
27
34
|
@horizontal_alignment = horizontal_alignment
|
35
|
+
# TODO
|
28
36
|
reapply
|
29
37
|
end
|
30
38
|
|
31
39
|
def vertical_alignment=(vertical_alignment)
|
32
40
|
@vertical_alignment = vertical_alignment
|
41
|
+
# TODO
|
42
|
+
reapply
|
43
|
+
end
|
44
|
+
|
45
|
+
def horizontal_span=(value)
|
46
|
+
@horizontal_span = value
|
47
|
+
@parent.dom_element.css('grid-column-start', "span #{@horizontal_span}")
|
48
|
+
reapply
|
49
|
+
end
|
50
|
+
|
51
|
+
def vertical_span=(value)
|
52
|
+
@vertical_span = value
|
53
|
+
@parent.dom_element.css('grid-row-start', "span #{@horizontal_span}")
|
54
|
+
reapply
|
55
|
+
end
|
56
|
+
|
57
|
+
def horizontal_indent=(value)
|
58
|
+
@horizontal_indent = value
|
59
|
+
@parent.dom_element.css('padding-left', @horizontal_indent)
|
60
|
+
reapply
|
61
|
+
end
|
62
|
+
|
63
|
+
def vertical_indent=(value)
|
64
|
+
@vertical_indent = value
|
65
|
+
@parent.dom_element.css('padding-top', @vertical_indent)
|
33
66
|
reapply
|
34
67
|
end
|
35
68
|
|
36
69
|
def grab_excess_horizontal_space=(grab_excess_horizontal_space)
|
37
70
|
@grab_excess_horizontal_space = grab_excess_horizontal_space
|
71
|
+
# TODO
|
38
72
|
reapply
|
39
73
|
end
|
40
74
|
|
41
75
|
def grab_excess_vertical_space=(grab_excess_vertical_space)
|
42
76
|
@grab_excess_vertical_space = grab_excess_vertical_space
|
77
|
+
# TODO
|
43
78
|
reapply
|
44
79
|
end
|
45
80
|
|
@@ -29,8 +29,9 @@ module Glimmer
|
|
29
29
|
|
30
30
|
attr_reader :parent, :args
|
31
31
|
|
32
|
-
def initialize(parent, args)
|
32
|
+
def initialize(parent, args)
|
33
33
|
@parent = parent
|
34
|
+
@parent = parent.body_root if @parent.is_a?(Glimmer::UI::CustomWidget)
|
34
35
|
@parent.css_classes.each do |css_class|
|
35
36
|
@parent.remove_css_class(css_class) if css_class.include?('layout')
|
36
37
|
end
|
@@ -9,7 +9,7 @@ module Glimmer
|
|
9
9
|
|
10
10
|
WIDTH_MIN = 130
|
11
11
|
HEIGHT_MIN = 0
|
12
|
-
|
12
|
+
|
13
13
|
def initialize(args)
|
14
14
|
@args = args
|
15
15
|
@children = []
|
@@ -238,6 +238,7 @@ module Glimmer
|
|
238
238
|
end
|
239
239
|
|
240
240
|
def open
|
241
|
+
# TODO consider the idea of delaying rendering till the open method
|
241
242
|
# TODO make it start as hidden and show shell upon open
|
242
243
|
end
|
243
244
|
end
|
@@ -19,6 +19,7 @@
|
|
19
19
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
20
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
21
|
|
22
|
+
require 'glimmer/ui/custom_widget'
|
22
23
|
require 'glimmer/error'
|
23
24
|
|
24
25
|
module Glimmer
|
@@ -32,15 +33,32 @@ module Glimmer
|
|
32
33
|
klass.include(Glimmer)
|
33
34
|
Glimmer::UI::CustomWidget.add_custom_widget_namespaces_for(klass)
|
34
35
|
end
|
36
|
+
|
37
|
+
def request_parameter_string
|
38
|
+
URI.decode_www_form_component(`document.location.href`.match(/\?(.*)$/).to_a[1].to_s)
|
39
|
+
end
|
40
|
+
|
41
|
+
def encoded_request_parameter_string
|
42
|
+
`document.location.href`.match(/\?(.*)$/).to_a[1].to_s
|
43
|
+
end
|
44
|
+
|
45
|
+
def requested_and_not_handled?
|
46
|
+
requested? && !request_parameter_string.include?('custom_shell_handled=true')
|
47
|
+
end
|
48
|
+
|
49
|
+
def requested?
|
50
|
+
request_parameter_string.include?('custom_shell=')
|
51
|
+
end
|
35
52
|
end
|
36
53
|
|
37
54
|
def initialize(parent, args, options, &content)
|
38
|
-
super
|
55
|
+
super(parent, args, options, &content)
|
39
56
|
raise Error, 'Invalid custom shell body root! Must be a shell or another custom shell.' unless body_root.is_a?(Glimmer::SWT::ShellProxy)
|
40
57
|
end
|
41
58
|
|
42
59
|
# Classes may override
|
43
60
|
def open
|
61
|
+
# TODO consider the idea of delaying rendering till the open method
|
44
62
|
body_root.open
|
45
63
|
end
|
46
64
|
|
@@ -152,13 +152,14 @@ module Glimmer
|
|
152
152
|
|
153
153
|
def initialize(parent, args, options, &content)
|
154
154
|
@parent = parent
|
155
|
-
options = args.delete_at(-1) if args.is_a?(Array) && args.last.is_a?(Hash)
|
155
|
+
options = args.delete_at(-1) if options.nil? && args.is_a?(Array) && args.last.is_a?(Hash)
|
156
156
|
if args.is_a?(Hash)
|
157
157
|
options = args
|
158
158
|
args = []
|
159
159
|
end
|
160
|
+
args = options.delete('swt_style').split(',').map(&:to_sym) if options['swt_style']
|
160
161
|
@args = args
|
161
|
-
@swt_style = SWT::SWTProxy[
|
162
|
+
@swt_style = SWT::SWTProxy[*@args]
|
162
163
|
options ||= {}
|
163
164
|
@options = self.class.options.merge(options)
|
164
165
|
@content = Util::ProcTracker.new(content) if content
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer-dsl-opal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AndyMaleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-10-
|
11
|
+
date: 2020-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: glimmer
|
@@ -210,6 +210,7 @@ files:
|
|
210
210
|
- README.md
|
211
211
|
- VERSION
|
212
212
|
- lib/glimmer-dsl-opal.rb
|
213
|
+
- lib/glimmer-dsl-opal/ext/date.rb
|
213
214
|
- lib/glimmer-dsl-opal/ext/exception.rb
|
214
215
|
- lib/glimmer-dsl-opal/missing/net/http.rb
|
215
216
|
- lib/glimmer-dsl-opal/missing/uri.rb
|