glimmer-dsl-css 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +20 -0
  3. data/README.md +111 -0
  4. data/VERSION +1 -0
  5. data/lib/glimmer-dsl-css.rb +7 -0
  6. data/lib/glimmer/config.rb +22 -0
  7. data/lib/glimmer/css/rule.rb +25 -0
  8. data/lib/glimmer/css/style_sheet.rb +19 -0
  9. data/lib/glimmer/dsl/css/css_expression.rb +21 -0
  10. data/lib/glimmer/dsl/css/dsl.rb +21 -0
  11. data/lib/glimmer/dsl/css/dynamic_property_expression.rb +12 -0
  12. data/lib/glimmer/dsl/css/property_expression.rb +22 -0
  13. data/lib/glimmer/dsl/css/pv_expression.rb +17 -0
  14. data/lib/glimmer/dsl/css/rule_expression.rb +26 -0
  15. data/lib/glimmer/dsl/css/s_expression.rb +26 -0
  16. data/lib/glimmer/dsl/engine.rb +193 -0
  17. data/lib/glimmer/dsl/expression.rb +42 -0
  18. data/lib/glimmer/dsl/expression_handler.rb +48 -0
  19. data/lib/glimmer/dsl/opal/dsl.rb +41 -0
  20. data/lib/glimmer/dsl/opal/label_expression.rb +17 -0
  21. data/lib/glimmer/dsl/opal/property_expression.rb +19 -0
  22. data/lib/glimmer/dsl/opal/shell_expression.rb +19 -0
  23. data/lib/glimmer/dsl/parent_expression.rb +12 -0
  24. data/lib/glimmer/dsl/static_expression.rb +36 -0
  25. data/lib/glimmer/dsl/top_level_expression.rb +7 -0
  26. data/lib/glimmer/dsl/xml/dsl.rb +23 -0
  27. data/lib/glimmer/dsl/xml/html_expression.rb +25 -0
  28. data/lib/glimmer/dsl/xml/meta_expression.rb +23 -0
  29. data/lib/glimmer/dsl/xml/name_space_expression.rb +37 -0
  30. data/lib/glimmer/dsl/xml/node_parent_expression.rb +33 -0
  31. data/lib/glimmer/dsl/xml/tag_expression.rb +29 -0
  32. data/lib/glimmer/dsl/xml/text_expression.rb +22 -0
  33. data/lib/glimmer/dsl/xml/xml_expression.rb +21 -0
  34. data/lib/glimmer/error.rb +6 -0
  35. data/lib/glimmer/invalid_keyword_error.rb +6 -0
  36. data/lib/glimmer/opal/label.rb +31 -0
  37. data/lib/glimmer/opal/shell.rb +34 -0
  38. data/lib/glimmer/xml/depth_first_search_iterator.rb +22 -0
  39. data/lib/glimmer/xml/name_space_visitor.rb +21 -0
  40. data/lib/glimmer/xml/node.rb +75 -0
  41. data/lib/glimmer/xml/node_visitor.rb +13 -0
  42. data/lib/glimmer/xml/xml_visitor.rb +65 -0
  43. metadata +201 -0
@@ -0,0 +1,42 @@
1
+ require 'glimmer/error'
2
+
3
+ module Glimmer
4
+ module DSL
5
+ # Represents a Glimmer DSL expression (e.g. label(:center) { ... })
6
+ #
7
+ # An expression object can interpret a keyword, args, and a block into a UI object
8
+ #
9
+ # Expressions subclasses follow the convention of using `and` and `or`
10
+ # english versino of Ruby's boolean operations. This allows easy DSL-like
11
+ # readability of the rules, and easy tagging with pd when troubleshooting.
12
+ class Expression
13
+ class << self
14
+ def dsl
15
+ @dsl ||= name.split(/::/)[-2].downcase.to_sym
16
+ end
17
+ end
18
+
19
+ # Checks if it can interpret parameters (subclass must override)
20
+ def can_interpret?(parent, keyword, *args, &block)
21
+ raise Error, "#can_interpret? must be implemented by an Expression subclass"
22
+ end
23
+
24
+ # Interprets parameters (subclass must override)
25
+ def interpret(parent, keyword, *args, &block)
26
+ raise Error, "#interpret must be implemented by an Expression subclass"
27
+ end
28
+
29
+ # Adds block content to specified parent UI object (Optional)
30
+ #
31
+ # Only expressions that receive a content block should implement
32
+ def add_content(parent, &block)
33
+ # No Op by default
34
+ end
35
+
36
+ # Checks if object is a Symbol or a String
37
+ def textual?(object)
38
+ object.is_a?(Symbol) or object.is_a?(String)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,48 @@
1
+ require 'glimmer/invalid_keyword_error'
2
+
3
+ module Glimmer
4
+ module DSL
5
+ # Expression handler for a Glimmer DSL specific expression
6
+ #
7
+ # Follows the Chain of Responsibility Design Pattern
8
+ #
9
+ # Handlers are configured in Glimmer::DSL in the right order
10
+ # to attempt handling Glimmer DSL interpretation calls
11
+ #
12
+ # Each handler knows the next handler in the chain of responsibility.
13
+ #
14
+ # If it handles successfully, it returns. Otherwise, it forwards to the next
15
+ # handler in the chain of responsibility
16
+ class ExpressionHandler
17
+ def initialize(expression)
18
+ @expression = expression
19
+ end
20
+
21
+ # Handles interpretation of Glimmer DSL expression if expression supports it
22
+ # If it succeeds, it returns the correct Glimmer DSL expression object
23
+ # Otherwise, it forwards to the next handler configured via `#next=` method
24
+ # If there is no handler next, then it raises an error
25
+ def handle(parent, keyword, *args, &block)
26
+ Glimmer::Config.logger&.debug "Attempting to handle #{keyword} with #{@expression.class.name.split(":").last}"
27
+ if @expression.can_interpret?(parent, keyword, *args, &block)
28
+ Glimmer::Config.logger&.debug "#{@expression.class.name} will handle expression keyword #{keyword}"
29
+ return @expression
30
+ elsif @next_expression_handler
31
+ return @next_expression_handler.handle(parent, keyword, *args, &block)
32
+ else
33
+ # TODO see if we need a better response here (e.g. dev mode error raising vs production mode silent failure)
34
+ message = "Glimmer keyword #{keyword} with args #{args} cannot be handled"
35
+ message += " inside parent #{parent}" if parent
36
+ message += "! Check the validity of the code."
37
+ # Glimmer::Config.logger&.error message
38
+ raise InvalidKeywordError, message
39
+ end
40
+ end
41
+
42
+ # Sets the next handler in the expression handler chain of responsibility
43
+ def next=(next_expression_handler)
44
+ @next_expression_handler = next_expression_handler
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,41 @@
1
+ require 'opal'
2
+ # require 'opal-jquery'
3
+ require 'browser'
4
+
5
+ class String
6
+ def underscore
7
+ gsub(/[A-Z]/) {|m| "_#{m.downcase}"}.sub(/^_/, '')
8
+ end
9
+
10
+ def camelcase(option=nil)
11
+ new_string = split("_").map {|word| word[0].upcase + word[1..-1]}.join
12
+ if option == :upper
13
+ new_string
14
+ else
15
+ new_string.sub(/^./) {|c| c.downcase}
16
+ end
17
+ end
18
+
19
+ # def titlecase
20
+ # #TODO
21
+ # end
22
+ end
23
+
24
+ require 'glimmer/dsl/engine'
25
+ # Dir[File.expand_path('../*_expression.rb', __FILE__)].each {|f| require f}
26
+ require 'glimmer/dsl/opal/shell_expression'
27
+ require 'glimmer/dsl/opal/label_expression'
28
+ require 'glimmer/dsl/opal/property_expression'
29
+
30
+ module Glimmer
31
+ module DSL
32
+ module Opal
33
+ Engine.add_dynamic_expressions(
34
+ Opal,
35
+ %w[
36
+ property
37
+ ]
38
+ )
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,17 @@
1
+ require 'glimmer/dsl/static_expression'
2
+ require 'glimmer/dsl/parent_expression'
3
+ require 'glimmer/opal/label'
4
+
5
+ module Glimmer
6
+ module DSL
7
+ module Opal
8
+ class LabelExpression < StaticExpression
9
+ include ParentExpression
10
+
11
+ def interpret(parent, keyword, *args, &block)
12
+ Glimmer::Opal::Label.new(parent, args)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ require 'glimmer/dsl/expression'
2
+
3
+ module Glimmer
4
+ module DSL
5
+ module Opal
6
+ class PropertyExpression < StaticExpression
7
+ include TopLevelExpression
8
+
9
+ def can_interpret?(parent, keyword, *args, &block)
10
+ keyword.to_s == 'text'
11
+ end
12
+
13
+ def interpret(parent, keyword, *args, &block)
14
+ parent.text = args.first.to_s
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'glimmer/dsl/static_expression'
2
+ require 'glimmer/dsl/top_level_expression'
3
+ require 'glimmer/dsl/parent_expression'
4
+ require 'glimmer/opal/shell'
5
+
6
+ module Glimmer
7
+ module DSL
8
+ module Opal
9
+ class ShellExpression < StaticExpression
10
+ include TopLevelExpression
11
+ include ParentExpression
12
+
13
+ def interpret(parent, keyword, *args, &block)
14
+ Glimmer::Opal::Shell.new(args)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,12 @@
1
+ require 'glimmer/error'
2
+
3
+ module Glimmer
4
+ module DSL
5
+ # Mixin that represents expressions that always have a content block
6
+ module ParentExpression
7
+ def add_content(parent, &block)
8
+ block.call(parent)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,36 @@
1
+ require 'glimmer/error'
2
+ require 'glimmer/dsl/engine'
3
+ require 'glimmer/dsl/expression'
4
+
5
+ module Glimmer
6
+ module DSL
7
+ # Represents a StaticExpression for expressions where
8
+ # the keyword does not vary dynamically. These static keywords are then
9
+ # predefined as methods in Glimmer instead of needing method_missing
10
+ #
11
+ # StaticExpression subclasses may optionally implement `#can_interpret?`
12
+ # (not needed if it only checks for keyword)
13
+ #
14
+ # StaticExpression subclasses must define `#interpret`.
15
+ #
16
+ # The direct parent namespace of a StaticExpression subclass must match the DSL name (case-insensitive)
17
+ # (e.g. Glimmer::DSL::SWT::WidgetExpression has a DSL of :swt)
18
+ class StaticExpression < Expression
19
+ class << self
20
+ def inherited(base)
21
+ Glimmer::DSL::Engine.add_static_expression(base.new)
22
+ super
23
+ end
24
+
25
+ def keyword
26
+ @keyword ||= name.split(/::/).last.sub(/Expression$/, '').underscore
27
+ end
28
+ end
29
+
30
+ # Subclasses may optionally implement
31
+ def can_interpret?(parent, keyword, *args, &block)
32
+ true
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,7 @@
1
+ module Glimmer
2
+ module DSL
3
+ # Mixin that represents expressions that are always at the top with parent nil
4
+ module TopLevelExpression
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,23 @@
1
+ require 'glimmer/dsl/engine'
2
+ # Dir[File.expand_path('../*_expression.rb', __FILE__)].each {|f| require f} # cannot in Opal
3
+ require 'glimmer/dsl/xml/text_expression'
4
+ require 'glimmer/dsl/xml/tag_expression'
5
+ require 'glimmer/dsl/xml/xml_expression'
6
+ require 'glimmer/dsl/xml/html_expression'
7
+ require 'glimmer/dsl/xml/meta_expression'
8
+ require 'glimmer/dsl/xml/name_space_expression'
9
+
10
+ module Glimmer
11
+ module DSL
12
+ module XML
13
+ Engine.add_dynamic_expressions(
14
+ XML,
15
+ %w[
16
+ text
17
+ tag
18
+ xml
19
+ ]
20
+ )
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ require 'glimmer/dsl/xml/node_parent_expression'
2
+ require 'glimmer/dsl/xml/xml_expression'
3
+ require 'glimmer/dsl/static_expression'
4
+ require 'glimmer/dsl/top_level_expression'
5
+
6
+ module Glimmer
7
+ module DSL
8
+ module XML
9
+ # This static html expression flips the DSL switch on for
10
+ # XML DSL in Glimmer
11
+ class HtmlExpression < StaticExpression
12
+ include TopLevelExpression
13
+ include NodeParentExpression
14
+
15
+ def interpret(parent, keyword, *args, &block)
16
+ xml_expression.interpret(parent, keyword, *args, &block)
17
+ end
18
+
19
+ def xml_expression
20
+ @xml_expression ||= XmlExpression.new
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ require 'glimmer/dsl/xml/node_parent_expression'
2
+ require 'glimmer/dsl/xml/xml_expression'
3
+ require 'glimmer/dsl/static_expression'
4
+
5
+ module Glimmer
6
+ module DSL
7
+ module XML
8
+ # This static html expression flips the DSL switch on for
9
+ # XML DSL in Glimmer
10
+ class MetaExpression < StaticExpression
11
+ include NodeParentExpression
12
+
13
+ def interpret(parent, keyword, *args, &block)
14
+ xml_expression.interpret(parent, keyword, *args, &block)
15
+ end
16
+
17
+ def xml_expression
18
+ @xml_expression ||= XmlExpression.new
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,37 @@
1
+ require 'glimmer/dsl/static_expression'
2
+ require 'glimmer/dsl/top_level_expression'
3
+ require 'glimmer/xml/node'
4
+ require 'glimmer/xml/depth_first_search_iterator'
5
+ require 'glimmer/xml/name_space_visitor'
6
+
7
+ module Glimmer
8
+ module DSL
9
+ module XML
10
+ class NameSpaceExpression < StaticExpression
11
+ include TopLevelExpression
12
+
13
+ def can_interpret?(parent, keyword, *args, &block)
14
+ (parent == nil or parent.is_a?(Glimmer::XML::Node)) and
15
+ (keyword.to_s == "name_space")
16
+ (args.size == 1) and
17
+ (args[0].is_a?(Symbol)) and
18
+ block
19
+ end
20
+
21
+ def interpret(parent, keyword, *args, &block)
22
+ node = block.call
23
+ unless node.is_a?(String)
24
+ name_space_visitor = Glimmer::XML::NameSpaceVisitor.new(args[0].to_s)
25
+ Glimmer::XML::DepthFirstSearchIterator.new(node, name_space_visitor).iterate
26
+ def node.process_block(block)
27
+ Glimmer::Config.logger&.debug 'block'
28
+ #NOOP
29
+ end
30
+ end
31
+ parent.children << node if parent and !parent.children.include?(node)
32
+ node
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,33 @@
1
+ require 'glimmer'
2
+ require 'glimmer/dsl/parent_expression'
3
+ require 'glimmer/xml/node'
4
+
5
+ module Glimmer
6
+ module DSL
7
+ module XML
8
+ module NodeParentExpression
9
+ include ParentExpression
10
+ include Glimmer
11
+
12
+ def add_content(parent, &block)
13
+ return_value = block.call(parent)
14
+ if !return_value.is_a?(Glimmer::XML::Node) and !parent.children.include?(return_value)
15
+ text = return_value.to_s
16
+ first_match = text.match(/[#][^{]+[{][^}]+[}]/)
17
+ match = first_match
18
+ while (match)
19
+ instance_eval(parent.text_command(match.pre_match))
20
+ tag_text = match.to_s
21
+ instance_eval(parent.rubyize(tag_text))
22
+ text = tag_text
23
+ post_match = match.post_match
24
+ match = text.match(/[#]\w+[{]\w+[}]/)
25
+ end
26
+ instance_eval(parent.text_command(post_match)) if post_match
27
+ parent.children << return_value unless first_match
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,29 @@
1
+ require 'glimmer/dsl/xml/node_parent_expression'
2
+ require 'glimmer/dsl/xml/xml_expression'
3
+ require 'glimmer/dsl/static_expression'
4
+ require 'glimmer/dsl/top_level_expression'
5
+ require 'glimmer/xml/node'
6
+
7
+ module Glimmer
8
+ module DSL
9
+ module XML
10
+ class TagExpression < StaticExpression
11
+ include TopLevelExpression
12
+ include NodeParentExpression
13
+
14
+ def can_interpret?(parent, keyword, *args, &block)
15
+ (parent == nil or parent.is_a?(Glimmer::XML::Node)) and
16
+ (keyword.to_s == "tag") and
17
+ args[0].include?(:_name)
18
+ end
19
+
20
+ def interpret(parent, keyword, *args, &block)
21
+ attributes = args[0] if (args.size == 1)
22
+ tag_name = attributes[:_name]
23
+ attributes.delete(:_name)
24
+ Glimmer::XML::Node.new(parent, tag_name, attributes, &block)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,22 @@
1
+ require 'glimmer/dsl/static_expression'
2
+ require 'glimmer/xml/node'
3
+
4
+ module Glimmer
5
+ module DSL
6
+ module XML
7
+ class TextExpression < StaticExpression
8
+ def can_interpret?(parent, keyword, *args, &block)
9
+ (parent == nil or parent.is_a?(Glimmer::XML::Node)) and
10
+ (keyword.to_s == "text") and
11
+ (args.size == 1) and
12
+ !block
13
+ end
14
+
15
+ def interpret(parent, keyword, *args, &block)
16
+ parent.children << args[0].to_s if parent
17
+ args[0].to_s
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end