glimmer-dsl-web 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 429afe58eb54b98a9aa229faeecbe09ceefb82ebae7e240ef3dd68ce63110164
4
- data.tar.gz: '03469f3f04757d5b95aab910b1469047e467481aeaf6169ed69a33a8ab900b6f'
3
+ metadata.gz: 528b824876642a7d3cabb52d76ba8a93f55273443f0a4a25a308f14d80460bc4
4
+ data.tar.gz: db5ba4f41d4f863074bd7d5e291b9b753995fb056612f763945ea4ad10ed2c7d
5
5
  SHA512:
6
- metadata.gz: 93b2b65475f2609476997bb7139e2078f8851b88e881d123af4298df2f293a8a2537eecf3f697d734d09e0a8d5ad87771b32899873b9161b74f3e5387e86df00
7
- data.tar.gz: 7a37b8b255486545016a982522a52ee3cf00c8238557d396a874e38da8d5689fda9e8a8b021cb698f380f641e68d341b9b9e2ea10e035692192e534693cfac21
6
+ metadata.gz: 820828cc1d4f45fbc23df7e1296f71e24959fe811e5b380470cbc8126484ffe9bef70351eb4534777e7398f1bcd30363e30172ebe33b1828871318603fe5a906
7
+ data.tar.gz: 52a96a0c75fc7cc57b8e6938784f75079f3b5caf3d4b5a49801604b8061aec73518a23576a7ab6346937f8d4899c70b0b6efa33faf9ae1d35c75cbded956101a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.2.2
4
+
5
+ - Fix bug in content data-binding that was caused by recent performance optimizations (+ fix Hello, Content Data-Binding! sample)
6
+ - Fix bug in rendering formatting elements that was caused by recent performance optimizations (+ fix Hello, Paragraph! sample)
7
+
8
+ ## 0.2.1
9
+
10
+ - Optimize performance (~800% faster):
11
+ - Optimize performance (~20% faster than 0.2.0) by not using glimmer-dsl-xml for rendering dom elements in the frontend as it is more suitable for backend rendering and we already have a separate dsl for the frontend
12
+ - Optimize performance (~287% faster than previous bullet point) by adding Glimmer shortcut methods for all HTML element DSL keywords
13
+ - Optimize performance (~235% faster than previous bullet point) by not selecting ElementProxy subclass dynamically for each element, yet always using ElementProxy
14
+
3
15
  ## 0.2.0
4
16
 
5
17
  - Support `style` element content as Glimmer DSL for CSS syntax (Ruby Programmable CSS) as an alternative to a CSS `String`
data/README.md CHANGED
@@ -1,4 +1,4 @@
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 Web 0.2.0 (Beta)
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 Web 0.2.2 (Beta)
2
2
  ## Ruby in the Browser Web GUI Frontend Library
3
3
  [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-web.svg)](http://badge.fury.io/rb/glimmer-dsl-web)
4
4
  [![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
@@ -1141,7 +1141,7 @@ rails new glimmer_app_server
1141
1141
  Add the following to `Gemfile`:
1142
1142
 
1143
1143
  ```
1144
- gem 'glimmer-dsl-web', '~> 0.2.0'
1144
+ gem 'glimmer-dsl-web', '~> 0.2.2'
1145
1145
  ```
1146
1146
 
1147
1147
  Run:
@@ -1362,7 +1362,7 @@ Disable the `webpacker` gem line in `Gemfile`:
1362
1362
  Add the following to `Gemfile`:
1363
1363
 
1364
1364
  ```ruby
1365
- gem 'glimmer-dsl-web', '~> 0.2.0'
1365
+ gem 'glimmer-dsl-web', '~> 0.2.2'
1366
1366
  ```
1367
1367
 
1368
1368
  Run:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.2.2
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: glimmer-dsl-web 0.2.0 ruby lib
5
+ # stub: glimmer-dsl-web 0.2.2 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "glimmer-dsl-web".freeze
9
- s.version = "0.2.0".freeze
9
+ s.version = "0.2.2".freeze
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Andy Maleh".freeze]
14
- s.date = "2024-01-08"
14
+ s.date = "2024-01-09"
15
15
  s.description = "Glimmer DSL for Web (Ruby in the Browser Web GUI Frontend Library) enables building Web GUI frontends using Ruby in the Browser, as per Matz's recommendation in his RubyConf 2022 keynote speech to replace JavaScript with Ruby. It aims at providing the simplest, most intuitive, most straight-forward, and most productive frontend library in existence. The library follows the Ruby way (with DSLs and TIMTOWTDI) and the Rails way (Convention over Configuration) while supporting both Unidirectional (One-Way) Data-Binding (using <=) and Bidirectional (Two-Way) Data-Binding (using <=>). Dynamic rendering (and re-rendering) of HTML content is also supported via Content Data-Binding. And, modular design is supported with Glimmer Web Components. You can finally live in pure Rubyland on the Web in both the frontend and backend with Glimmer DSL for Web! This library relies on Opal Ruby.".freeze
16
16
  s.email = "andy.am@gmail.com".freeze
17
17
  s.extra_rdoc_files = [
@@ -24,8 +24,8 @@ require 'glimmer/dsl/web/element_expression'
24
24
  require 'glimmer/dsl/web/formatting_element_expression'
25
25
  require 'glimmer/dsl/web/listener_expression'
26
26
  require 'glimmer/dsl/web/property_expression'
27
- require 'glimmer/dsl/web/p_expression'
28
- require 'glimmer/dsl/web/select_expression'
27
+ # require 'glimmer/dsl/web/p_expression'
28
+ # require 'glimmer/dsl/web/select_expression'
29
29
  require 'glimmer/dsl/web/style_expression'
30
30
  require 'glimmer/dsl/web/bind_expression'
31
31
  require 'glimmer/dsl/web/data_binding_expression'
@@ -16,3 +16,14 @@ module Glimmer
16
16
  end
17
17
  end
18
18
  end
19
+
20
+ module Glimmer
21
+ # Optimize performance through shortcut methods for all HTML elements that circumvent the DSL chain of responsibility
22
+ element_expression = Glimmer::DSL::Web::ElementExpression.new
23
+ (Glimmer::Web::ElementProxy::ELEMENT_KEYWORDS - ['style']).each do |keyword|
24
+ Glimmer::DSL::Engine.static_expressions[keyword] ||= Concurrent::Hash.new
25
+ element_expression_dsl = element_expression.class.dsl
26
+ Glimmer::DSL::Engine.static_expressions[keyword][element_expression_dsl] = element_expression
27
+ Glimmer.send(:define_method, keyword, &Glimmer::DSL::Engine::STATIC_EXPRESSION_METHOD_FACTORY.call(keyword))
28
+ end
29
+ end
@@ -8,7 +8,7 @@ module Glimmer
8
8
  include ParentExpression
9
9
 
10
10
  def interpret(parent, keyword, *args, &block)
11
- Glimmer::Web::ElementProxy.for(keyword, parent, args, block)
11
+ Glimmer::Web::ElementProxy.new(keyword, parent, args, block)
12
12
  end
13
13
 
14
14
  def add_content(parent, keyword, *args, &block)
@@ -31,11 +31,14 @@ module Glimmer
31
31
  ELEMENT_KEYWORDS.include?(keyword.to_s)
32
32
  end
33
33
 
34
+ # NOTE: Avoid using this method until we start supporting ElementProxy subclasses
35
+ # in which case, we must cache them to avoid the slow performance of element_type
34
36
  # Factory Method that translates a Glimmer DSL keyword into a ElementProxy object
35
37
  def for(keyword, parent, args, block)
36
38
  element_type(keyword).new(keyword, parent, args, block)
37
39
  end
38
40
 
41
+ # NOTE: Avoid using this method for now as it has slow performance
39
42
  # returns Ruby proxy class (type) that would handle this keyword
40
43
  def element_type(keyword)
41
44
  class_name_main = "#{keyword.camelcase(:upper)}Proxy"
@@ -67,6 +70,19 @@ module Glimmer
67
70
  def widget_handling_listener
68
71
  @@widget_handling_listener
69
72
  end
73
+
74
+ def render_html(element, attributes, content = nil)
75
+ attributes = attributes.reduce('') do |output, option_pair|
76
+ attribute, value = option_pair
77
+ value = value.to_s.sub('"', '&quot;').sub("'", '&apos;')
78
+ output += " #{attribute}=\"#{value}\""
79
+ end
80
+ if content.nil?
81
+ "<#{element}#{attributes} />"
82
+ else
83
+ "<#{element}#{attributes}>#{content}</#{element}>"
84
+ end
85
+ end
70
86
  end
71
87
 
72
88
  include Glimmer
@@ -74,18 +90,18 @@ module Glimmer
74
90
  Event = Struct.new(:widget, keyword_init: true)
75
91
 
76
92
  ELEMENT_KEYWORDS = [
77
- "a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b",
78
- "base", "basefont", "bdi", "bdo", "bgsound", "big", "blink", "blockquote", "body", "br",
79
- "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "content", "data",
80
- "datalist", "dd", "decorator", "del", "details", "dfn", "dir", "div", "dl", "dt",
81
- "element", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame",
93
+ "a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio",
94
+ "base", "basefont", "bdi", "bdo", "bgsound", "big", "blink", "blockquote", "body",
95
+ "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "data",
96
+ "datalist", "dd", "decorator", "details", "dfn", "dir", "div", "dl", "dt",
97
+ "element", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame",
82
98
  "frameset", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup",
83
- "hr", "html", "i", "iframe", "img", "input", "ins", "isindex", "kbd", "keygen",
84
- "label", "legend", "li", "link", "listing", "main", "map", "mark", "marquee", "menu",
99
+ "hr", "html", "iframe", "img", "input", "isindex", "kbd", "keygen",
100
+ "label", "legend", "li", "link", "listing", "main", "map", "marquee", "menu",
85
101
  "menuitem", "meta", "meter", "nav", "nobr", "noframes", "noscript", "object", "ol", "optgroup",
86
102
  "option", "output", "p", "param", "plaintext", "pre", "progress", "q", "rp", "rt",
87
- "ruby", "s", "samp", "script", "section", "select", "shadow", "small", "source", "spacer",
88
- "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td",
103
+ "ruby", "s", "samp", "script", "section", "select", "shadow", "source", "spacer",
104
+ "span", "strike", "style", "summary", "table", "tbody", "td",
89
105
  "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "tt",
90
106
  "u", "ul", "var", "video", "wbr", "xmp",
91
107
  ]
@@ -249,8 +265,7 @@ module Glimmer
249
265
  @parent = nil
250
266
  end
251
267
  the_parent_dom_element = custom_parent_dom_element || parent_dom_element
252
- old_element = dom_element
253
- brand_new = @dom.nil? || old_element.empty? || !options[:parent].to_s.empty? || brand_new
268
+ brand_new ||= @dom.nil? || !options[:parent].to_s.empty? || (old_element = dom_element).empty?
254
269
  build_dom(layout: !custom_parent_dom_element) # TODO handle custom parent layout by passing parent instead of parent dom element
255
270
  if brand_new
256
271
  attach(the_parent_dom_element)
@@ -310,19 +325,16 @@ module Glimmer
310
325
 
311
326
  def build_dom(layout: true)
312
327
  # TODO consider passing parent element instead and having table item include a table cell widget only for opal
313
- @dom = nil
314
328
  @dom = dom # TODO unify how to build dom for most widgets based on element, id, and name (class)
315
- @dom
316
329
  end
317
330
 
318
331
  def dom
319
332
  # TODO auto-convert known glimmer attributes like parent to data attributes like data-parent
320
333
  # TODO check if we need to avoid rendering content block if no content is available
321
- @dom ||= html {
322
- send(keyword, html_options) {
323
- args.first if args.first.is_a?(String)
324
- }
325
- }.to_s
334
+ @dom ||= begin
335
+ content = args.first if args.first.is_a?(String)
336
+ ElementProxy.render_html(keyword, html_options, content)
337
+ end
326
338
  end
327
339
 
328
340
  def html_options
@@ -21,6 +21,8 @@
21
21
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
22
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
23
 
24
+ require 'glimmer/web/element_proxy'
25
+
24
26
  module Glimmer
25
27
  module Web
26
28
  class FormattingElementProxy
@@ -43,10 +45,7 @@ module Glimmer
43
45
  content = args.first.to_s
44
46
  end
45
47
  attribute_hash = args.last.is_a?(Hash) ? args.last : {}
46
- content_block = proc { content } unless content.nil?
47
- html {
48
- send(keyword, attribute_hash, &content_block)
49
- }.to_s
48
+ ElementProxy.render_html(keyword, attribute_hash, content)
50
49
  end
51
50
  end
52
51
 
@@ -77,7 +77,6 @@ else
77
77
 
78
78
  require 'glimmer/dsl/web/dsl'
79
79
  require 'glimmer/config/opal_logger'
80
- require 'glimmer-dsl-xml'
81
80
  require 'glimmer-dsl-css'
82
81
 
83
82
  Glimmer::Config.loop_max_count = 50 # TODO consider disabling if preferred
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-dsl-web
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Maleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-08 00:00:00.000000000 Z
11
+ date: 2024-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer