comet-cpp 0.9.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 +7 -0
- data/bin/comet-html +69 -0
- data/bin/comet-make +53 -0
- data/bin/comet-new +62 -0
- data/bin/comet-web +14 -0
- data/lib/comet-html/generator.rb +220 -0
- data/lib/comet-html/header-generator.rb +145 -0
- data/lib/comet-html/parser-binding.rb +42 -0
- data/lib/comet-html/parser-class.rb +168 -0
- data/lib/comet-html/parser-context.rb +61 -0
- data/lib/comet-html/parser-reference.rb +98 -0
- data/lib/comet-html/parser-repeater.rb +58 -0
- data/lib/comet-html/parser-slot.rb +108 -0
- data/lib/comet-html/source-generator.rb +285 -0
- data/lib/comet-html/utils.rb +88 -0
- data/lib/guard/comet-html.rb +32 -0
- data/lib/guard/comet.rb +36 -0
- data/vendor/project/Gemfile +4 -0
- data/vendor/project/Guardfile +5 -0
- data/vendor/project/app/application.hpp +29 -0
- data/vendor/project/app/collections/.gitkeep +0 -0
- data/vendor/project/app/controllers/.gitkeep +0 -0
- data/vendor/project/app/main.cpp +6 -0
- data/vendor/project/app/models/.gitkeep +0 -0
- data/vendor/project/app/routes.cpp +7 -0
- data/vendor/project/app/views/layouts/.gitkeep +0 -0
- data/vendor/project/public/index.html +7 -0
- data/vendor/src/anchorable_element.hpp +79 -0
- data/vendor/src/append_semantics.hpp +73 -0
- data/vendor/src/bindable.cpp +99 -0
- data/vendor/src/bindable.hpp +106 -0
- data/vendor/src/cheerp_parse_cookie_values.cpp +58 -0
- data/vendor/src/comment_element.cpp +11 -0
- data/vendor/src/comment_element.hpp +17 -0
- data/vendor/src/cookies.cpp +94 -0
- data/vendor/src/cookies.hpp +60 -0
- data/vendor/src/custom_element.hpp +61 -0
- data/vendor/src/datatree.cpp +198 -0
- data/vendor/src/datatree.hpp +233 -0
- data/vendor/src/document.cpp +62 -0
- data/vendor/src/document.hpp +31 -0
- data/vendor/src/element.cpp +358 -0
- data/vendor/src/element.hpp +138 -0
- data/vendor/src/events.hpp +76 -0
- data/vendor/src/exception.cpp +13 -0
- data/vendor/src/exception.hpp +11 -0
- data/vendor/src/from_string.cpp +99 -0
- data/vendor/src/from_string.hpp +37 -0
- data/vendor/src/globals.cpp +6 -0
- data/vendor/src/globals.hpp +15 -0
- data/vendor/src/http.cpp +93 -0
- data/vendor/src/http.hpp +72 -0
- data/vendor/src/lexical_cast.hpp +51 -0
- data/vendor/src/local_storage.cpp +75 -0
- data/vendor/src/local_storage.hpp +53 -0
- data/vendor/src/mvc/collection.hpp +154 -0
- data/vendor/src/mvc/controller.hpp +59 -0
- data/vendor/src/mvc/id_type.hpp +9 -0
- data/vendor/src/mvc/layout.hpp +44 -0
- data/vendor/src/mvc/model.cpp +89 -0
- data/vendor/src/mvc/model.hpp +50 -0
- data/vendor/src/object.cpp +71 -0
- data/vendor/src/object.hpp +298 -0
- data/vendor/src/parse_cookie_values.hpp +12 -0
- data/vendor/src/promise.cpp +50 -0
- data/vendor/src/promise.hpp +43 -0
- data/vendor/src/repeater.hpp +116 -0
- data/vendor/src/router.cpp +62 -0
- data/vendor/src/router.hpp +34 -0
- data/vendor/src/router_base.hpp +107 -0
- data/vendor/src/signal.hpp +150 -0
- data/vendor/src/slot_element.hpp +61 -0
- data/vendor/src/url.cpp +19 -0
- data/vendor/src/url.hpp +15 -0
- data/vendor/src/window.cpp +22 -0
- data/vendor/src/window.hpp +24 -0
- metadata +134 -0
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'comet-html/parser-context'
|
2
|
+
require 'comet-html/parser-reference'
|
3
|
+
require 'comet-html/parser-binding'
|
4
|
+
|
5
|
+
module Comet
|
6
|
+
class Class < Context
|
7
|
+
attr_accessor :typename, :inline_code, :anchor_name, :superclass
|
8
|
+
attr_reader :el, :parent, :children, :refs, :slots, :slot_plugins, :repeaters, :bindings, :event_listeners
|
9
|
+
|
10
|
+
def initialize el, parent = nil
|
11
|
+
context.classes << self
|
12
|
+
parent.children << self unless parent.nil?
|
13
|
+
el["_cheerp_class"] = self if el.class != Nokogiri::XML::NodeSet
|
14
|
+
@el = el
|
15
|
+
@superclass = if is_root? then context.template_base_type else context.template_base_subtype end
|
16
|
+
@parent = parent
|
17
|
+
@refs = []
|
18
|
+
@bindings = []
|
19
|
+
@slots = []
|
20
|
+
@slot_plugins = []
|
21
|
+
@repeaters = []
|
22
|
+
@event_listeners = []
|
23
|
+
@children = []
|
24
|
+
end
|
25
|
+
|
26
|
+
def implements_ibindable_view?
|
27
|
+
false
|
28
|
+
end
|
29
|
+
|
30
|
+
def constructor_decl
|
31
|
+
"#{@typename}(#{if parent.nil? then "" else "#{parent.typename}*" end});"
|
32
|
+
end
|
33
|
+
|
34
|
+
def find_reference_for el
|
35
|
+
@refs.each do |ref|
|
36
|
+
return ref if ref.el == el
|
37
|
+
end
|
38
|
+
return ThisReference.new if el == @el
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def find_class_for el
|
43
|
+
collect_children.each do |child|
|
44
|
+
return child if child.el == el
|
45
|
+
end
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
|
49
|
+
def is_root?
|
50
|
+
@parent.nil?
|
51
|
+
end
|
52
|
+
|
53
|
+
def is_anchorable?
|
54
|
+
false
|
55
|
+
end
|
56
|
+
|
57
|
+
def should_skip?
|
58
|
+
false
|
59
|
+
end
|
60
|
+
|
61
|
+
def collect_children
|
62
|
+
children = []
|
63
|
+
context.classes.each do |object|
|
64
|
+
children << object if object.parent == self
|
65
|
+
end
|
66
|
+
children
|
67
|
+
end
|
68
|
+
|
69
|
+
def recursively_collect_children
|
70
|
+
children = collect_children
|
71
|
+
descendants = []
|
72
|
+
children.each do |child|
|
73
|
+
descendants += child.recursively_collect_children
|
74
|
+
end
|
75
|
+
children + descendants
|
76
|
+
end
|
77
|
+
|
78
|
+
def root
|
79
|
+
current_class = @parent
|
80
|
+
current_class = current_class.parent until current_class.parent.nil?
|
81
|
+
current_class
|
82
|
+
end
|
83
|
+
|
84
|
+
def probe
|
85
|
+
probe_subtypes
|
86
|
+
probe_slots_plugins
|
87
|
+
probe_references
|
88
|
+
probe_bindings
|
89
|
+
end
|
90
|
+
|
91
|
+
def probe_subtypes root = nil
|
92
|
+
root = @el if root.nil?
|
93
|
+
root.children.each do |el|
|
94
|
+
context.use_cpp_type el.name if context.has_cpp_type?(el)
|
95
|
+
if Slot::Probe.matches? el
|
96
|
+
@slots << Slot.new(el, self)
|
97
|
+
@slots.last.probe
|
98
|
+
elsif Repeater::Probe.matches? el
|
99
|
+
@repeaters << Repeater.new(el, self)
|
100
|
+
@repeaters.last.probe
|
101
|
+
else
|
102
|
+
probe_subtypes el unless context.has_cpp_type?(el)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def probe_references root = nil
|
108
|
+
root = @el if root.nil?
|
109
|
+
root.children.each do |el|
|
110
|
+
next unless el["_cheerp_class"].nil?
|
111
|
+
next unless find_reference_for(el).nil?
|
112
|
+
if !(el["ref"].nil?)
|
113
|
+
create_reference(el, :explicit)
|
114
|
+
elsif context.has_cpp_type?(el)
|
115
|
+
create_reference(el, :implicit)
|
116
|
+
end
|
117
|
+
probe_references el unless context.has_cpp_type?(el)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def create_reference el, mode
|
122
|
+
@refs << Reference.new(el, self, mode)
|
123
|
+
end
|
124
|
+
|
125
|
+
def blocks_remote_references?
|
126
|
+
false
|
127
|
+
end
|
128
|
+
|
129
|
+
def probe_bindings root = nil
|
130
|
+
root = @el if root.nil?
|
131
|
+
root.children.each do |el|
|
132
|
+
next unless el["_cheerp_class"].nil?
|
133
|
+
probe_bindings_for el
|
134
|
+
probe_bindings el unless context.has_cpp_type?(el)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def probe_bindings_for el
|
139
|
+
el.attributes.each do |key, value|
|
140
|
+
if key.end_with? ".trigger"
|
141
|
+
@event_listeners << EventListener.new(el, self, key, value)
|
142
|
+
elsif key.end_with? ".bind"
|
143
|
+
@bindings << Binding.new(el, self, key, value)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def probe_slots_plugins root = nil
|
149
|
+
root = @el if root.nil?
|
150
|
+
root.children.each do |el|
|
151
|
+
next unless el["_cheerp_class"].nil?
|
152
|
+
if context.has_cpp_type?(el)
|
153
|
+
el.children.each do |candidate|
|
154
|
+
unless candidate["slot"].nil?
|
155
|
+
@slot_plugins << (SlotPlugin.new candidate, self, el)
|
156
|
+
@slot_plugins.last.probe
|
157
|
+
else
|
158
|
+
candidate.remove # Non-slot children for cpp custom elements must be ignored
|
159
|
+
end
|
160
|
+
end
|
161
|
+
else
|
162
|
+
probe_slots_plugins el
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Comet
|
2
|
+
class Context
|
3
|
+
class << self
|
4
|
+
attr_accessor :slot_count, :repeater_count, :element_types, :filename
|
5
|
+
attr_reader :classes, :referenced_types
|
6
|
+
|
7
|
+
def reset
|
8
|
+
@slot_count = @repeater_count = 0
|
9
|
+
@implicit_ref_count = 0
|
10
|
+
@classes = []
|
11
|
+
@element_types = {}
|
12
|
+
@referenced_types = []
|
13
|
+
@filename = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def template_base_type
|
17
|
+
"Comet::IBindableView"
|
18
|
+
end
|
19
|
+
|
20
|
+
def template_base_subtype
|
21
|
+
template_base_type
|
22
|
+
end
|
23
|
+
|
24
|
+
def element_base_type
|
25
|
+
"Comet::Element"
|
26
|
+
end
|
27
|
+
|
28
|
+
def has_cpp_type? el
|
29
|
+
@element_types.keys.include? el.name
|
30
|
+
end
|
31
|
+
|
32
|
+
def find_cpp_type name, options = {}
|
33
|
+
if @element_types.keys.include? name
|
34
|
+
@element_types[name]
|
35
|
+
else
|
36
|
+
options[:fallback] || element_base_type
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def use_cpp_type name
|
41
|
+
@referenced_types << @element_types[name]
|
42
|
+
end
|
43
|
+
|
44
|
+
def generate_new_ref_name
|
45
|
+
@implicit_ref_count += 1
|
46
|
+
"implicit_reference_#{@implicit_ref_count}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def load_global_element_types data
|
50
|
+
data.each do |element_data|
|
51
|
+
tag_name = element_data["tagName"] || element_data["require"].dasherize
|
52
|
+
@element_types[tag_name] = element_data["require"]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def context
|
58
|
+
Context
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module Comet
|
2
|
+
class ReferenceBase
|
3
|
+
def has_default_value?
|
4
|
+
false
|
5
|
+
end
|
6
|
+
|
7
|
+
def has_initializer?
|
8
|
+
false
|
9
|
+
end
|
10
|
+
|
11
|
+
def has_getter?
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
15
|
+
def has_setter?
|
16
|
+
false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class CppReference < ReferenceBase
|
21
|
+
attr_reader :el, :type, :name, :default_value
|
22
|
+
attr_accessor :initializer, :setter_enabled
|
23
|
+
|
24
|
+
def initialize el, type, name, default_value = nil
|
25
|
+
@el = el
|
26
|
+
@type = type
|
27
|
+
@name = name
|
28
|
+
@default_value = default_value
|
29
|
+
@setter_enabled = true
|
30
|
+
if type.nil? || name.nil?
|
31
|
+
raise ParseError.new(el, "incomplete attribute definition")
|
32
|
+
end
|
33
|
+
unless is_valid_cpp_variable_name?(@name)
|
34
|
+
raise ParseError.new(el, "attribute name `#{@name}` is not a valid C++ variable name")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def is_explicit? ; true ; end
|
39
|
+
def is_implicit ; false ; end
|
40
|
+
def has_default_value? ; !default_value.nil? ; end
|
41
|
+
def has_initializer? ; !@initializer.nil? end
|
42
|
+
def has_getter? ; true ; end
|
43
|
+
def has_setter? ; @setter_enabled ; end
|
44
|
+
|
45
|
+
def initializer root_getter
|
46
|
+
@initializer
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Reference < ReferenceBase
|
51
|
+
attr_reader :el, :type, :name
|
52
|
+
|
53
|
+
def initialize el, parent, mode = nil
|
54
|
+
el["_cheerp_ref"] = self
|
55
|
+
@el = el
|
56
|
+
@parent = parent
|
57
|
+
@type = @parent.context.find_cpp_type el.name
|
58
|
+
set_mode mode
|
59
|
+
end
|
60
|
+
|
61
|
+
def set_mode mode
|
62
|
+
if (mode.nil? && !@el["ref"].nil?) || (mode == :explicit)
|
63
|
+
@mode = :explicit
|
64
|
+
@name = @el["ref"].to_s
|
65
|
+
unless is_valid_cpp_variable_name?(@name)
|
66
|
+
raise ParseError.new(el, "ref `#{@name}` is not a valid c++ variable name")
|
67
|
+
end
|
68
|
+
else
|
69
|
+
@mode = :implicit
|
70
|
+
@name = "element_#{@parent.context.generate_new_ref_name}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def is_explicit? ; @mode == :explicit ; end
|
75
|
+
def is_implicit? ; @mode == :implicit ; end
|
76
|
+
end
|
77
|
+
|
78
|
+
class RemoteReference < Reference
|
79
|
+
def type
|
80
|
+
"#{@type}&"
|
81
|
+
end
|
82
|
+
|
83
|
+
def has_initializer?
|
84
|
+
true
|
85
|
+
end
|
86
|
+
|
87
|
+
def initializer root_getter
|
88
|
+
"#{root_getter}->#{name}"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class ThisReference
|
93
|
+
def name
|
94
|
+
"(*this)"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'comet-html/parser-class'
|
2
|
+
|
3
|
+
module Comet
|
4
|
+
class Repeater < Comet::Class
|
5
|
+
class Probe
|
6
|
+
class << self
|
7
|
+
def matches? el
|
8
|
+
!(el["repeat.for"].nil?)
|
9
|
+
end
|
10
|
+
|
11
|
+
def evaluate el, parent
|
12
|
+
Repeater.new el, parent
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :repeater_name, :value_type, :value_name, :list_type, :list_name, :bind_mode, :anchor
|
18
|
+
|
19
|
+
def initialize el, parent
|
20
|
+
super el, parent
|
21
|
+
value, bind_mode = extract_bind_mode_from el["repeat.for"].to_s
|
22
|
+
parts = value.to_s.match /^\s*(\[([^\]]+)\])?\s*([^\s]+)\s+of\s+\[([^\]]+)\]\s*(.*)$/
|
23
|
+
raise ParseError.new(el, "invalid repeater definition: `#{value}`") if parts.nil?
|
24
|
+
@typename = "#{context.classes.first.typename}Repeatable_#{context.repeater_count}"
|
25
|
+
@superclass = context.find_cpp_type(el.name, fallback: context.template_base_subtype)
|
26
|
+
|
27
|
+
@repeater_name = "repeater_#{context.repeater_count}"
|
28
|
+
@value_type = parts[2] || "#{parts[4]}::value_type"
|
29
|
+
@value_name = parts[3]
|
30
|
+
@list_type = parts[4]
|
31
|
+
@list_name = parts[5]
|
32
|
+
@bind_mode = bind_mode
|
33
|
+
|
34
|
+
unless is_valid_cpp_variable_name?(@value_name)
|
35
|
+
raise ParseError.new(el, "invalid variable name `#{@value_name}`")
|
36
|
+
end
|
37
|
+
|
38
|
+
context.repeater_count += 1
|
39
|
+
end
|
40
|
+
|
41
|
+
def constructor_decl
|
42
|
+
"#{@typename}(#{parent.typename}*, #{@value_type});"
|
43
|
+
end
|
44
|
+
|
45
|
+
def is_anchorable?
|
46
|
+
true
|
47
|
+
end
|
48
|
+
|
49
|
+
def blocks_remote_references?
|
50
|
+
true
|
51
|
+
end
|
52
|
+
|
53
|
+
def probe
|
54
|
+
super
|
55
|
+
probe_bindings_for el
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'comet-html/parser-class'
|
2
|
+
|
3
|
+
module Comet
|
4
|
+
class SlotBase < Comet::Class
|
5
|
+
def find_remote_reference_holder
|
6
|
+
p = @parent
|
7
|
+
until p.is_root?
|
8
|
+
return nil if p.blocks_remote_references?
|
9
|
+
p = p.parent
|
10
|
+
end
|
11
|
+
p
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_reference el, mode
|
15
|
+
ref_root = nil
|
16
|
+
if (mode == :implicit) || (ref_root = find_remote_reference_holder).nil?
|
17
|
+
super el, mode
|
18
|
+
else
|
19
|
+
ref_root.refs << Reference.new(el, ref_root, mode)
|
20
|
+
@refs << RemoteReference.new(el, self, mode)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class SlotPlugin < SlotBase
|
26
|
+
attr_reader :slot_name, :on_element
|
27
|
+
|
28
|
+
def implements_ibindable_view?
|
29
|
+
is_custom_element?
|
30
|
+
end
|
31
|
+
|
32
|
+
def is_custom_element?
|
33
|
+
context.has_cpp_type? el
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize el, parent, on_element
|
37
|
+
super el, parent
|
38
|
+
@slot_name = el["slot"].to_s
|
39
|
+
@on_element = on_element
|
40
|
+
@typename = "#{context.classes.first.typename}SlotPlugin_#{context.slot_count}"
|
41
|
+
@superclass = context.find_cpp_type el.name, fallback: context.template_base_subtype
|
42
|
+
context.use_cpp_type el.name if is_custom_element?
|
43
|
+
context.slot_count += 1
|
44
|
+
|
45
|
+
if has_ref?
|
46
|
+
ref_root = find_remote_reference_holder
|
47
|
+
if ref_root.nil?
|
48
|
+
puts "[comet-html] ignoring ref at #{context.filename}:#{el.line}"
|
49
|
+
el["ref"] = nil
|
50
|
+
else
|
51
|
+
@parent = ref_root
|
52
|
+
ref = CppReference.new el, @typename, el["ref"]
|
53
|
+
ref.initializer = constructor_params
|
54
|
+
ref.setter_enabled = false
|
55
|
+
ref_root.refs << ref
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def constructor_params
|
61
|
+
"this"
|
62
|
+
end
|
63
|
+
|
64
|
+
def has_ref?
|
65
|
+
not el["ref"].nil?
|
66
|
+
end
|
67
|
+
|
68
|
+
def probe
|
69
|
+
super
|
70
|
+
probe_bindings_for el
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class Slot < SlotBase
|
75
|
+
class Probe
|
76
|
+
class << self
|
77
|
+
def matches? el
|
78
|
+
el.name == "slot"
|
79
|
+
end
|
80
|
+
|
81
|
+
def evaluate el, parent
|
82
|
+
Slot.new el, parent
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
attr_reader :slot_name, :slot_ref, :anchor
|
88
|
+
|
89
|
+
def initialize el, parent
|
90
|
+
super el, parent
|
91
|
+
@typename = "#{context.classes.first.typename}Slot_#{context.slot_count}"
|
92
|
+
|
93
|
+
@slot_name = el["name"].to_s
|
94
|
+
@slot_ref = "slot_#{@slot_name}"
|
95
|
+
@anchor = find_anchorable_anchor(el)
|
96
|
+
|
97
|
+
unless is_valid_cpp_variable_name?(@slot_name)
|
98
|
+
raise ParseError.new(el, "slot name `#{@slot_name}` is not a valid C++ variable name")
|
99
|
+
end
|
100
|
+
|
101
|
+
context.slot_count += 1
|
102
|
+
end
|
103
|
+
|
104
|
+
def is_anchorable?
|
105
|
+
true
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|