mullet 0.0.0 → 0.0.1

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.
Files changed (37) hide show
  1. data/lib/mullet/container.rb +8 -4
  2. data/lib/mullet/default_model.rb +9 -9
  3. data/lib/mullet/default_nested_model.rb +7 -6
  4. data/lib/mullet/html/attribute_command.rb +8 -4
  5. data/lib/mullet/html/attributes.rb +22 -0
  6. data/lib/mullet/html/command.rb +4 -3
  7. data/lib/mullet/html/command_element_renderer.rb +19 -0
  8. data/lib/mullet/html/element.rb +41 -0
  9. data/lib/mullet/html/element_renderer.rb +261 -0
  10. data/lib/mullet/html/filtered_element_handler.rb +87 -0
  11. data/lib/mullet/html/for_element_renderer.rb +47 -0
  12. data/lib/mullet/html/if_element_renderer.rb +46 -0
  13. data/lib/mullet/html/layout.rb +48 -0
  14. data/lib/mullet/html/message.rb +55 -0
  15. data/lib/mullet/html/message_attribute_command.rb +30 -0
  16. data/lib/mullet/html/model_attribute_command.rb +30 -0
  17. data/lib/mullet/html/page_builder.rb +152 -0
  18. data/lib/mullet/html/parser/attribute.rb +8 -0
  19. data/lib/mullet/html/parser/constants.rb +1061 -0
  20. data/lib/mullet/html/parser/default_handler.rb +27 -0
  21. data/lib/mullet/html/parser/input_stream.rb +711 -0
  22. data/lib/mullet/html/parser/open_element.rb +77 -0
  23. data/lib/mullet/html/parser/simple_parser.rb +128 -0
  24. data/lib/mullet/html/parser/tokenizer.rb +1085 -0
  25. data/lib/mullet/html/remove_mode.rb +30 -0
  26. data/lib/mullet/html/static_text_renderer.rb +20 -0
  27. data/lib/mullet/html/template.rb +44 -0
  28. data/lib/mullet/html/template_builder.rb +208 -63
  29. data/lib/mullet/html/template_loader.rb +77 -39
  30. data/lib/mullet/html/template_parser.rb +48 -0
  31. data/lib/mullet/html/unless_element_renderer.rb +24 -0
  32. data/lib/mullet/model.rb +2 -5
  33. data/lib/mullet/render_context.rb +24 -18
  34. data/lib/mullet/tilt.rb +37 -0
  35. data/lib/mullet/version.rb +2 -1
  36. data/lib/mullet.rb +1 -0
  37. metadata +58 -11
@@ -0,0 +1,77 @@
1
+ require 'mullet/html/parser/attribute'
2
+ require 'mullet/html/parser/constants'
3
+ require 'mullet/html/parser/input_stream'
4
+
5
+ module Mullet; module HTML; module Parser
6
+
7
+ # Element where the parser has seen the start tag but not yet seen the end
8
+ # tag.
9
+ class OpenElement
10
+
11
+ XMLNS_ATTRIBUTE = 'xmlns'
12
+ XMLNS_ATTRIBUTE_PREFIX = XMLNS_ATTRIBUTE + ':'
13
+
14
+ attr_reader :parent, :qualified_name, :prefix, :local_name, :uri
15
+ attr_reader :attributes, :namespace_declarations
16
+
17
+ def initialize(parent, qualified_name, raw_attributes)
18
+ # namespace prefix to URI map
19
+ @namespace_declarations = Hash.new()
20
+
21
+ @parent = parent
22
+
23
+ process_namespace_declarations(raw_attributes)
24
+ @qualified_name = qualified_name
25
+ @prefix, @local_name = extract_prefix_and_local_name(qualified_name)
26
+ @uri = resolve_prefix_to_uri(@prefix)
27
+
28
+ @attributes = to_namespace_aware_attributes(raw_attributes)
29
+ end
30
+
31
+ def resolve_prefix_to_uri(prefix)
32
+ uri = @namespace_declarations.fetch(prefix, nil)
33
+ if uri == nil && @parent != nil
34
+ return @parent.resolve_prefix_to_uri(prefix)
35
+ end
36
+ return uri
37
+ end
38
+
39
+ private
40
+
41
+ def declare_namespace(raw_attribute_name, uri)
42
+ if raw_attribute_name.start_with?(XMLNS_ATTRIBUTE_PREFIX)
43
+ prefix = raw_attribute_name[XMLNS_ATTRIBUTE_PREFIX.length()..-1]
44
+ else
45
+ prefix = nil
46
+ end
47
+ @namespace_declarations.store(prefix, uri)
48
+ end
49
+
50
+ def process_namespace_declarations(raw_attributes)
51
+ raw_attributes.each do |attribute_name, attribute_value|
52
+ if attribute_name.start_with?(XMLNS_ATTRIBUTE)
53
+ declare_namespace(attribute_name, attribute_value)
54
+ end
55
+ end
56
+ end
57
+
58
+ def extract_prefix_and_local_name(qualified_name)
59
+ name_parts = qualified_name.split(':', 2)
60
+ prefix = (name_parts.size() > 1) ? name_parts[0] : nil
61
+ local_name = (name_parts.size() > 1) ? name_parts[1] : qualified_name
62
+ return [prefix, local_name]
63
+ end
64
+
65
+ def to_namespace_aware_attributes(raw_attributes)
66
+ attributes = []
67
+ raw_attributes.each do |qualified_name, attribute_value|
68
+ prefix, local_name = extract_prefix_and_local_name(qualified_name)
69
+ uri = resolve_prefix_to_uri(prefix)
70
+ attributes << Attribute.new(local_name, prefix, uri, attribute_value)
71
+ end
72
+
73
+ return attributes
74
+ end
75
+ end
76
+
77
+ end; end; end
@@ -0,0 +1,128 @@
1
+ require 'mullet/html/parser/open_element'
2
+ require 'mullet/html/parser/tokenizer'
3
+ require 'mullet/template_error'
4
+
5
+ module Mullet; module HTML; module Parser
6
+
7
+ # SAX parser that reports elements in the order they appear in the input.
8
+ # Does not move elements to another parent.
9
+ class SimpleParser
10
+
11
+ # special namespace URI indicating parser generated an implicit end tag
12
+ IMPLICIT_END_TAG_NS_URI = 'http://pukkaone.github.com/mullet/end-tag'
13
+
14
+ # Constructor
15
+ #
16
+ # @param [DefaultHandler] handler
17
+ # object to receive events
18
+ def initialize(handler)
19
+ @handler = handler
20
+ end
21
+
22
+ def parse(input)
23
+ @open_element = nil
24
+ @handler.start_document()
25
+
26
+ tokenizer = Tokenizer.new(input)
27
+ tokenizer.each do |token|
28
+ case token[:type]
29
+ when :Doctype
30
+ doctype(token[:name], token[:publicId], token[:systemId])
31
+ when :StartTag
32
+ start_tag(token[:name], token[:data])
33
+ when :EndTag
34
+ end_tag(token[:name])
35
+ when :Characters, :SpaceCharacters
36
+ characters(token[:data])
37
+ when :CDATA
38
+ cdata(token[:data])
39
+ when :Comment
40
+ comment(token[:data])
41
+ end
42
+ end
43
+
44
+ @handler.end_document()
45
+ end
46
+
47
+ private
48
+
49
+ def doctype(name, public_id, system_id)
50
+ @handler.doctype(name, public_id, system_id)
51
+ end
52
+
53
+ def start_tag(name, attributes)
54
+ # Push open element onto stack.
55
+ element = OpenElement.new(@open_element, name, attributes)
56
+ @open_element = element
57
+
58
+ @handler.start_element_namespace(
59
+ element.local_name,
60
+ element.attributes,
61
+ element.prefix,
62
+ element.uri,
63
+ element.namespace_declarations)
64
+ end
65
+
66
+ def pop_open_element()
67
+ element = @open_element
68
+ if @open_element != nil
69
+ @open_element = @open_element.parent
70
+ end
71
+ return element
72
+ end
73
+
74
+ def raise_mismatched_end_tag(name)
75
+ raise TemplateError.new("End tag </#{name}> has no matching start tag")
76
+ end
77
+
78
+ def end_tag(name)
79
+ element = pop_open_element()
80
+ if element == nil
81
+ raise_mismatched_end_tag(name)
82
+ end
83
+
84
+ # Generate implicit end tags up to this element.
85
+ while element.qualified_name != name
86
+ # KLUDGE: Indicate a generated implicit end tag by passing a special
87
+ # value for the namespace URI.
88
+ @handler.end_element_namespace(name, nil, IMPLICIT_END_TAG_NS_URI)
89
+
90
+ element = pop_open_element()
91
+ if element == nil
92
+ raise_mismatched_end_tag(name)
93
+ end
94
+ end
95
+
96
+ @handler.end_element_namespace(element.qualified_name, nil, nil)
97
+ end
98
+
99
+ def characters(data)
100
+ @handler.characters(data)
101
+ end
102
+
103
+ def cdata(data)
104
+ @handler.cdata_block(data)
105
+ end
106
+
107
+ def processing_instruction(data)
108
+ @handler.processing_instruction(data)
109
+ end
110
+
111
+ def comment(data)
112
+ # FIXME: The HTML5 tokenizer treats <? as a bogus comment and emits it as
113
+ # a comment. If the comment begins with ? then turn it into a processing
114
+ # instruction. The problem is any legitimate comment beginning with ?
115
+ # will also be turned into a processing instruction.
116
+ if data.start_with?('?')
117
+ last_index = data.length() - 1
118
+ if last_index > 0 && data[last_index] == '?'
119
+ last_index -= 1
120
+ end
121
+ processing_instruction(data[1..last_index])
122
+ else
123
+ @handler.comment(data)
124
+ end
125
+ end
126
+ end
127
+
128
+ end; end; end