markaby 0.8.1 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
- require 'markaby/tags'
2
- require 'markaby/builder_tags'
1
+ require "markaby/tagset"
2
+ require "markaby/builder_tags"
3
3
 
4
4
  module Markaby
5
5
  RUBY_VERSION_ID = RUBY_VERSION.split(".").join.to_i
@@ -23,30 +23,13 @@ module Markaby
23
23
  #
24
24
  class Builder
25
25
  include Markaby::BuilderTags
26
-
27
- DEFAULT_OPTIONS = {
28
- :indent => 0,
29
- :output_helpers => true,
30
- :output_xml_instruction => true,
31
- :output_meta_tag => 'xhtml',
32
- :auto_validation => true,
33
- :tagset => Markaby::XHTMLTransitional,
34
- :root_attributes => {
35
- :xmlns => 'http://www.w3.org/1999/xhtml',
36
- :'xml:lang' => 'en',
37
- :lang => 'en'
38
- }
26
+ GENERIC_OPTIONS = {
27
+ indent: 0,
28
+ auto_validation: true
39
29
  }
40
30
 
41
- HTML5_OPTIONS = {
42
- :indent => 0,
43
- :output_helpers => true,
44
- :output_xml_instruction => false,
45
- :output_meta_tag => 'html5',
46
- :auto_validation => true,
47
- :tagset => Markaby::HTML5,
48
- :root_attributes => {}
49
- }
31
+ HTML5_OPTIONS = HTML5.default_options.dup
32
+ DEFAULT_OPTIONS = GENERIC_OPTIONS.merge(HTML5_OPTIONS)
50
33
 
51
34
  @@options = DEFAULT_OPTIONS.dup
52
35
 
@@ -54,10 +37,6 @@ module Markaby
54
37
  @@options = DEFAULT_OPTIONS.dup
55
38
  end
56
39
 
57
- def self.set_html5_options!
58
- @@options = HTML5_OPTIONS.dup
59
- end
60
-
61
40
  def self.set(option, value)
62
41
  @@options[option] = value
63
42
  end
@@ -66,15 +45,15 @@ module Markaby
66
45
  @@options[option]
67
46
  end
68
47
 
69
- def self.ignored_helpers
70
- @@ignored_helpers ||= []
71
- end
48
+ attr_reader :tagset
72
49
 
73
- def self.ignore_helpers(*helpers)
74
- ignored_helpers.concat helpers
75
- end
50
+ def tagset=(tagset)
51
+ @tagset = tagset
76
52
 
77
- attr_accessor :output_helpers, :tagset
53
+ tagset.default_options.each do |k, v|
54
+ instance_variable_set("@#{k}".to_sym, v)
55
+ end
56
+ end
78
57
 
79
58
  # Create a Markaby builder object. Pass in a hash of variable assignments to
80
59
  # +assigns+ which will be available as instance variables inside tag construction
@@ -105,13 +84,11 @@ module Markaby
105
84
  instance_variable_set("@#{k}", v)
106
85
  end
107
86
 
108
- if helper
109
- helper.instance_variables.each do |iv|
110
- instance_variable_set(iv, helper.instance_variable_get(iv))
111
- end
87
+ helper&.instance_variables&.each do |iv|
88
+ instance_variable_set(iv, helper.instance_variable_get(iv))
112
89
  end
113
90
 
114
- @builder = XmlMarkup.new(:indent => @indent, :target => @streams.last)
91
+ @builder = XmlMarkup.new(indent: @indent, target: @streams.last)
115
92
 
116
93
  text(capture(&block)) if block
117
94
  end
@@ -170,50 +147,24 @@ module Markaby
170
147
  # Create a tag named +tag+. Other than the first argument which is the tag name,
171
148
  # the arguments are the same as the tags implemented via method_missing.
172
149
  def tag!(tag, *args, &block)
173
- ele_id = nil
150
+ attributes = {}
174
151
  if @auto_validation && @tagset
175
- if !@tagset.tagset.has_key?(tag)
176
- raise InvalidXhtmlError, "no element `#{tag}' for #{tagset.doctype}"
177
- elsif args.last.respond_to?(:to_hash)
178
- attrs = args.last.to_hash
179
-
180
- if @tagset.forms.include?(tag) && attrs[:id]
181
- attrs[:name] ||= attrs[:id]
182
- end
183
-
184
- attrs.each do |k, v|
185
- atname = k.to_s.downcase.intern
186
- unless k =~ /:/ or @tagset.tagset[tag].include? atname
187
- raise InvalidXhtmlError, "no attribute `#{k}' on #{tag} elements"
188
- end
189
- if atname == :id
190
- ele_id = v.to_s
191
- if @used_ids.has_key? ele_id
192
- raise InvalidXhtmlError, "id `#{ele_id}' already used (id's must be unique)."
193
- end
194
- end
195
- if AttrsBoolean.include? atname
196
- if v
197
- attrs[k] = atname.to_s
198
- else
199
- attrs.delete k
200
- end
201
- end
202
- end
203
- end
152
+ attributes = @tagset.validate_and_transform_attributes!(tag, *args)
153
+ tag = @tagset.validate_and_transform_tag_name! tag
204
154
  end
205
-
155
+ element_id = attributes[:id].to_s
156
+ raise InvalidXhtmlError, "id `#{element_id}' already used (id's must be unique)." if @used_ids.has_key?(element_id)
206
157
  if block
207
158
  str = capture(&block)
208
159
  block = proc { text(str) }
209
160
  end
210
161
 
211
162
  f = fragment { @builder.tag!(tag, *args, &block) }
212
- @used_ids[ele_id] = f if ele_id
163
+ @used_ids[element_id] = f unless element_id.empty?
213
164
  f
214
165
  end
215
166
 
216
- private
167
+ private
217
168
 
218
169
  # This method is used to intercept calls to helper methods and instance
219
170
  # variables. Here is the order of interception:
@@ -224,37 +175,40 @@ module Markaby
224
175
  # * If +sym+ is also the name of an instance variable, the
225
176
  # value of the instance variable is returned.
226
177
  # * If +sym+ has come this far and no +tagset+ is found, +sym+ and its arguments are passed to tag!
227
- # * If a tagset is found, though, +NoMethodError+ is raised.
178
+ # * If a tagset is found, the tagset is tole to handle +sym+
228
179
  #
229
180
  # method_missing used to be the lynchpin in Markaby, but it's no longer used to handle
230
181
  # HTML tags. See html_tag for that.
231
182
  def method_missing(sym, *args, &block)
232
- if @_helper.respond_to?(sym, true) && !self.class.ignored_helpers.include?(sym)
233
- r = @_helper.send(sym, *args, &block)
234
- if @output_helpers && r.respond_to?(:to_str)
235
- fragment { @builder << r }
236
- else
237
- r
238
- end
239
- elsif @assigns.has_key?(sym)
240
- @assigns[sym]
241
- elsif @assigns.has_key?(stringy_key = sym.to_s)
242
- # Rails' ActionView assigns hash has string keys for
243
- # instance variables that are defined in the controller.
244
- @assigns[stringy_key]
245
- elsif instance_variables_for(self).include?(ivar = "@#{sym}".to_sym)
246
- instance_variable_get(ivar)
247
- elsif @_helper && instance_variables_for(@_helper).include?(ivar)
248
- @_helper.instance_variable_get(ivar)
249
- elsif instance_methods_for(::Builder::XmlMarkup).include?(sym)
250
- @builder.__send__(sym, *args, &block)
251
- elsif !@tagset
252
- tag!(sym, *args, &block)
253
- else
254
- super
183
+ case response_for(sym)
184
+ when :helper then @_helper.send(sym, *args, &block)
185
+ when :assigns then @assigns[sym]
186
+ when :stringy_assigns then @assigns[sym.to_s]
187
+ when :ivar then instance_variable_get(ivar)
188
+ when :helper_ivar then @_helper.instance_variable_get(ivar)
189
+ when :xml_markup then @builder.__send__(sym, *args, &block)
190
+ when :tag then tag!(sym, *args, &block)
191
+ when :tagset then @tagset.handle_tag sym, self, *args, &block
192
+ else super
255
193
  end
256
194
  end
257
195
 
196
+ def response_for sym
197
+ return :helper if @_helper.respond_to?(sym, true)
198
+ return :assigns if @assigns.has_key?(sym)
199
+ return :stringy_assigns if @assigns.has_key?(sym.to_s)
200
+ return :ivar if instance_variables_for(self).include?(ivar = "@#{sym}".to_sym)
201
+ return :helper_ivar if @_helper && instance_variables_for(@_helper).include?(ivar)
202
+ return :xml_markup if instance_methods_for(::Builder::XmlMarkup).include?(sym)
203
+ return :tag if @tagset.nil?
204
+ return :tagset if @tagset.can_handle? sym
205
+ nil
206
+ end
207
+
208
+ def respond_to_missing? sym, include_private = false
209
+ !response_for(sym).nil?
210
+ end
211
+
258
212
  if RUBY_VERSION_ID >= 191
259
213
  def instance_variables_for(obj)
260
214
  obj.instance_variables
@@ -301,11 +255,15 @@ module Markaby
301
255
  undef_method method if method_defined?(method)
302
256
  end
303
257
 
304
- private
258
+ private
305
259
 
306
- def method_missing(*args, &block)
260
+ def method_missing(...)
307
261
  transform_stream unless transformed_stream?
308
- @str.__send__(*args, &block)
262
+ @str.__send__(...)
263
+ end
264
+
265
+ def respond_to_missing? sym, *args
266
+ @str.respond_to? sym
309
267
  end
310
268
 
311
269
  def transform_stream
@@ -1,7 +1,9 @@
1
+ require "markaby/html5"
2
+
1
3
  module Markaby
2
4
  module BuilderTags
3
5
  (HTML5.tags - [:head]).each do |k|
4
- class_eval <<-CODE, __FILE__, __LINE__
6
+ class_eval <<-CODE, __FILE__, __LINE__ + 1
5
7
  def #{k}(*args, &block)
6
8
  html_tag(#{k.inspect}, *args, &block)
7
9
  end
@@ -28,8 +30,8 @@ module Markaby
28
30
  # set to <tt>text/html; charset=utf-8</tt>.
29
31
  def head(*args, &block)
30
32
  tag!(:head, *args) do
31
- tag!(:meta, "http-equiv" => "Content-Type", "content" => "text/html; charset=utf-8") if @output_meta_tag == 'xhtml'
32
- tag!(:meta, "charset" => "utf-8") if @output_meta_tag == 'html5'
33
+ tag!(:meta, "http-equiv" => "Content-Type", "content" => "text/html; charset=utf-8") if @output_meta_tag == "xhtml"
34
+ tag!(:meta, "charset" => "utf-8") if @output_meta_tag == "html5"
33
35
  instance_eval(&block)
34
36
  end
35
37
  end
@@ -56,19 +58,15 @@ module Markaby
56
58
 
57
59
  # Builds an html tag with HTML5 doctype instead.
58
60
  def html5(attrs = {}, &block)
59
- enable_html5!
61
+ self.tagset = Markaby::HTML5
60
62
  html5_html(attrs, &block)
61
63
  end
62
64
 
63
65
  def enable_html5!
64
- self.tagset = Markaby::HTML5
65
-
66
- Markaby::Builder::HTML5_OPTIONS.each do |k, v|
67
- self.instance_variable_set("@#{k}".to_sym, v)
68
- end
66
+ raise NotImplementedError, "Deprecated! Call self.tagset = Markaby::HTML5"
69
67
  end
70
68
 
71
- private
69
+ private
72
70
 
73
71
  def xhtml_html(attrs = {}, &block)
74
72
  instruct! if @output_xml_instruction
@@ -6,9 +6,9 @@ module Markaby
6
6
  class CssProxy
7
7
  def initialize(builder, stream, sym)
8
8
  @builder = builder
9
- @stream = stream
10
- @sym = sym
11
- @attrs = {}
9
+ @stream = stream
10
+ @sym = sym
11
+ @attrs = {}
12
12
 
13
13
  @original_stream_length = @stream.length
14
14
 
@@ -16,10 +16,10 @@ module Markaby
16
16
  end
17
17
 
18
18
  def respond_to?(sym, include_private = false)
19
- include_private || !private_methods.map { |m| m.to_sym }.include?(sym.to_sym) ? true : false
19
+ (include_private || !private_methods.map { |m| m.to_sym }.include?(sym.to_sym)) ? true : false
20
20
  end
21
21
 
22
- private
22
+ private
23
23
 
24
24
  # Adds attributes to an element. Bang methods set the :id attribute.
25
25
  # Other methods add to the :class attribute.
@@ -0,0 +1,118 @@
1
+ require "markaby/xhtml_transitional"
2
+ module Markaby
3
+ class HTML5 < Tagset
4
+ class << self
5
+ def default_options
6
+ super.merge({
7
+ output_xml_instruction: false,
8
+ output_meta_tag: "html5",
9
+ root_attributes: {}
10
+ })
11
+ end
12
+
13
+ def custom_element? tag_name
14
+ tag_name.to_s.include? "_"
15
+ end
16
+
17
+ def can_handle? tag_name
18
+ custom_element? tag_name
19
+ end
20
+
21
+ def handle_tag tag_name, builder, *args, &block
22
+ builder.tag! tag_name, *args, &block
23
+ end
24
+
25
+ def validate_and_transform_tag_name! tag_name
26
+ custom_element?(tag_name) ? custom_element_tag_for(tag_name) : super
27
+ end
28
+
29
+ def custom_element_tag_for tag_name
30
+ tag_name.to_s.tr("_", "-").to_sym
31
+ end
32
+
33
+ def validate_attribute! tag_name, attribute_name
34
+ custom_element?(tag_name) || super
35
+ end
36
+ end
37
+
38
+ @doctype = ["html"]
39
+ @tagset = XHTMLTransitional.tagset.merge({
40
+ abbr: Attrs,
41
+ article: Attrs,
42
+ aside: Attrs,
43
+ audio: Attrs,
44
+ bdi: Attrs,
45
+ canvas: Attrs,
46
+ command: Attrs,
47
+ datalist: Attrs,
48
+ details: Attrs,
49
+ embed: Attrs,
50
+ figure: Attrs,
51
+ figcaption: Attrs,
52
+ footer: Attrs,
53
+ header: Attrs,
54
+ hgroup: Attrs,
55
+ keygen: Attrs,
56
+ mark: Attrs,
57
+ menu: Attrs,
58
+ meter: Attrs,
59
+ nav: Attrs,
60
+ output: Attrs,
61
+ progress: Attrs,
62
+ rp: Attrs,
63
+ rt: Attrs,
64
+ ruby: Attrs,
65
+ section: Attrs,
66
+ source: Attrs,
67
+ time: Attrs,
68
+ track: Attrs,
69
+ video: Attrs,
70
+ wbr: Attrs
71
+ })
72
+
73
+ # Additional attributes found in HTML5
74
+ additional_tags = {
75
+ a: [:media, :download, :ping],
76
+ area: [:media, :download, :ping, :hreflang, :rel, :type],
77
+ base: [:target],
78
+ button: [:autofocus, :form, :formaction, :formenctype, :formmethod,
79
+ :formnovalidate, :formtarget],
80
+ fieldset: [:form, :disabled, :name],
81
+ form: [:novalidate],
82
+ label: [:form],
83
+ html: [:manifest],
84
+ iframe: [:sandbox, :seamless, :srcdoc],
85
+ img: [:crossorigin],
86
+ input: [:autofocus, :placeholder, :form, :required, :autocomplete,
87
+ :min, :max, :multiple, :pattern, :step, :list, :width, :height,
88
+ :dirname, :formaction, :formenctype, :formmethod,
89
+ :formnovalidate, :formtarget],
90
+ link: [:sizes],
91
+ meta: [:charset],
92
+ menu: [:type, :label],
93
+ object: [:form, :typemustmatch],
94
+ ol: [:reversed],
95
+ output: [:form],
96
+ script: [:async],
97
+ select: [:autofocus, :form, :required],
98
+ style: [:scoped],
99
+ textarea: [:autofocus, :placeholder, :form, :required, :dirname,
100
+ :maxlength, :wrap]
101
+ }
102
+
103
+ AttrsHTML5 = [:contenteditable, :contextmentu, :draggable, :dropzone,
104
+ :hidden, :role, :spellcheck, :translate]
105
+
106
+ additional_tags.each do |k, v|
107
+ @tagset[k] += v
108
+ end
109
+
110
+ @tagset.each do |k, v|
111
+ @tagset[k] += AttrsHTML5
112
+ end
113
+
114
+ @tags = @tagset.keys
115
+ @forms = @tags & FORM_TAGS
116
+ @self_closing = @tags & SELF_CLOSING_TAGS
117
+ end
118
+ end
@@ -1,8 +1,9 @@
1
1
  # You'll need to <tt>require 'markaby/kernel_method'</tt> for this.
2
+ require "markaby"
3
+
2
4
  module Kernel
3
5
  # Shortcut for creating a quick block of Markaby.
4
- def mab(*args, &block)
5
- Markaby::Builder.new(*args, &block).to_s
6
+ def mab(...)
7
+ Markaby::Builder.new(...).to_s
6
8
  end
7
9
  end
8
-
@@ -0,0 +1,36 @@
1
+ require "markaby"
2
+
3
+ module Markaby
4
+ module Rails
5
+ class TemplateHandler
6
+ class << self
7
+ def register!(options = {})
8
+ self.options = options
9
+ ActionView::Template.register_template_handler(:mab, new)
10
+ end
11
+
12
+ # TODO: Do we need this?
13
+ # Default format used by Markaby
14
+ # class_attribute :default_format
15
+ # self.default_format = :html
16
+
17
+ def options
18
+ @options ||= {}
19
+ end
20
+
21
+ def options=(val)
22
+ options.merge!(val)
23
+ options
24
+ end
25
+ end
26
+
27
+ def call(template, source = template.source)
28
+ <<-CODE
29
+ Markaby::Builder.new(Markaby::Rails::TemplateHandler.options, self) do
30
+ #{source}
31
+ end.to_s
32
+ CODE
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,89 @@
1
+ module Markaby
2
+ FORM_TAGS = [:form, :input, :select, :textarea]
3
+ SELF_CLOSING_TAGS = [:area, :base, :br, :col, :command, :embed, :frame, :hr,
4
+ :img, :input, :keygen, :link, :meta, :param, :source,
5
+ :track, :wbr]
6
+
7
+ # Common sets of attributes.
8
+ AttrCore = [:id, :class, :style, :title]
9
+ AttrI18n = [:lang, :"xml:lang", :dir]
10
+ AttrEvents = [:onclick,
11
+ :ondblclick,
12
+ :onmousedown,
13
+ :onmouseup,
14
+ :onmouseover,
15
+ :onmousemove,
16
+ :onmouseout,
17
+ :onkeypress,
18
+ :onkeydown,
19
+ :onkeyup]
20
+ AttrFocus = [:accesskey, :tabindex, :onfocus, :onblur]
21
+ AttrHAlign = [:align, :char, :charoff]
22
+ AttrVAlign = [:valign]
23
+ Attrs = AttrCore + AttrI18n + AttrEvents
24
+
25
+ AttrsBoolean = [
26
+ :checked, :disabled, :multiple, :readonly, :selected, # standard forms
27
+ :autofocus, :required, :novalidate, :formnovalidate, # HTML5 forms
28
+ :defer, :ismap, # <script defer>, <img ismap>
29
+ :compact, :declare, :noresize, :noshade, :nowrap # deprecated or unused
30
+ ]
31
+ class Tagset
32
+ class << self
33
+ attr_accessor :tags, :tagset, :forms, :self_closing, :doctype
34
+
35
+ def default_options
36
+ {tagset: self}
37
+ end
38
+
39
+ def can_handle? tag_name
40
+ false
41
+ end
42
+
43
+ def handle_tag tag_name, builder, *args, &block
44
+ raise NoMethodError.new
45
+ end
46
+
47
+ def validate_and_transform_tag_name! tag_name
48
+ raise(InvalidXhtmlError, "no element `#{tag_name}' for #{doctype}") unless @tagset.has_key?(tag_name)
49
+ tag_name
50
+ end
51
+
52
+ def validate_and_transform_attributes! tag_name, *args
53
+ args.last.respond_to?(:to_hash) ? transform_attributes(tag_name, args.last.to_hash) : {}
54
+ end
55
+
56
+ def transform_attributes tag_name, attributes
57
+ attributes[:name] ||= attributes[:id] if forms.include?(tag_name) && attributes[:id]
58
+ attributes.transform_keys! { |name| transform_attribute_name name }
59
+ hashed_attributes = attributes.keys.select { |name| attributes[name].is_a? Hash }
60
+ hashed_attributes.each { |name| transform_attribute_hash attributes, name }
61
+ attributes.reject! { |name, value| name.nil? || (AttrsBoolean.include?(name) && value.nil?) }
62
+ attributes.keys.each { |name| validate_attribute! tag_name, name }
63
+ attributes
64
+ end
65
+
66
+ def transform_attribute_name name
67
+ name.to_s.downcase.tr("_", "-").to_sym
68
+ end
69
+
70
+ def transform_attribute_hash attributes, prefix
71
+ values = attributes[prefix]
72
+ expanded_attributes = {}
73
+ values.each do |suffix, value|
74
+ name = transform_attribute_name "#{prefix}-#{suffix}"
75
+ expanded_attributes[name] = value
76
+ end
77
+ attributes.merge!(expanded_attributes).delete(prefix)
78
+ end
79
+
80
+ def validate_attribute! tag_name, attribute_name
81
+ raise InvalidXhtmlError, "no attribute `#{attribute_name}' on #{tag_name} elements" unless valid_attribute_name? tag_name, attribute_name
82
+ end
83
+
84
+ def valid_attribute_name? tag_name, attribute_name
85
+ attribute_name.to_s.start_with?(":", "data-", "aria-") || @tagset[tag_name].include?(attribute_name)
86
+ end
87
+ end
88
+ end
89
+ end
@@ -1,3 +1,7 @@
1
1
  module Markaby
2
- VERSION = '0.8.1'
2
+ MAJOR = 0
3
+ MINOR = 9
4
+ TINY = 1
5
+
6
+ VERSION = "#{MAJOR}.#{MINOR}.#{TINY}"
3
7
  end
@@ -0,0 +1,13 @@
1
+ module Markaby
2
+ class XHTMLFrameset < XmlTagset
3
+ @doctype = ["-//W3C//DTD XHTML 1.0 Frameset//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"]
4
+ @tagset = XHTMLTransitional.tagset.merge({
5
+ frameset: AttrCore + [:rows, :cols, :onload, :onunload],
6
+ frame: AttrCore + [:longdesc, :name, :src, :frameborder, :marginwidth, :marginheight, :noresize, :scrolling]
7
+ })
8
+
9
+ @tags = @tagset.keys
10
+ @forms = @tags & FORM_TAGS
11
+ @self_closing = @tags & SELF_CLOSING_TAGS
12
+ end
13
+ end
@@ -0,0 +1,89 @@
1
+ module Markaby
2
+ # All the tags and attributes from XHTML 1.0 Strict
3
+ class XHTMLStrict < XmlTagset
4
+ @doctype = ["-//W3C//DTD XHTML 1.0 Strict//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"]
5
+ @tagset = {
6
+ html: AttrI18n + [:id, :xmlns],
7
+ head: AttrI18n + [:id, :profile],
8
+ title: AttrI18n + [:id],
9
+ base: [:href, :id],
10
+ meta: AttrI18n + [:id, :http, :name, :content, :scheme, :"http-equiv"],
11
+ link: Attrs + [:charset, :href, :hreflang, :type, :rel, :rev, :media],
12
+ style: AttrI18n + [:id, :type, :media, :title, :"xml:space"],
13
+ script: [:id, :charset, :type, :src, :defer, :"xml:space"],
14
+ noscript: Attrs,
15
+ body: Attrs + [:onload, :onunload],
16
+ div: Attrs,
17
+ p: Attrs,
18
+ ul: Attrs,
19
+ ol: Attrs,
20
+ li: Attrs,
21
+ dl: Attrs,
22
+ dt: Attrs,
23
+ dd: Attrs,
24
+ address: Attrs,
25
+ hr: Attrs,
26
+ pre: Attrs + [:"xml:space"],
27
+ blockquote: Attrs + [:cite],
28
+ ins: Attrs + [:cite, :datetime],
29
+ del: Attrs + [:cite, :datetime],
30
+ a: Attrs + AttrFocus + [:charset, :type, :name, :href, :hreflang, :rel, :rev, :shape, :coords],
31
+ span: Attrs,
32
+ bdo: AttrCore + AttrEvents + [:lang, :"xml:lang", :dir],
33
+ br: AttrCore,
34
+ em: Attrs,
35
+ strong: Attrs,
36
+ dfn: Attrs,
37
+ code: Attrs,
38
+ samp: Attrs,
39
+ kbd: Attrs,
40
+ var: Attrs,
41
+ cite: Attrs,
42
+ abbr: Attrs,
43
+ acronym: Attrs,
44
+ q: Attrs + [:cite],
45
+ sub: Attrs,
46
+ sup: Attrs,
47
+ tt: Attrs,
48
+ i: Attrs,
49
+ b: Attrs,
50
+ big: Attrs,
51
+ small: Attrs,
52
+ object: Attrs + [:declare, :classid, :codebase, :data, :type, :codetype, :archive, :standby, :height, :width, :usemap, :name, :tabindex],
53
+ param: [:id, :name, :value, :valuetype, :type],
54
+ img: Attrs + [:src, :alt, :longdesc, :height, :width, :usemap, :ismap],
55
+ map: AttrI18n + AttrEvents + [:id, :class, :style, :title, :name],
56
+ area: Attrs + AttrFocus + [:shape, :coords, :href, :nohref, :alt],
57
+ form: Attrs + [:action, :method, :enctype, :onsubmit, :onreset, :accept, :accept],
58
+ label: Attrs + [:for, :accesskey, :onfocus, :onblur],
59
+ input: Attrs + AttrFocus + [:type, :name, :value, :checked, :disabled, :readonly, :size, :maxlength, :src, :alt, :usemap, :onselect, :onchange, :accept],
60
+ select: Attrs + [:name, :size, :multiple, :disabled, :tabindex, :onfocus, :onblur, :onchange],
61
+ optgroup: Attrs + [:disabled, :label],
62
+ option: Attrs + [:selected, :disabled, :label, :value],
63
+ textarea: Attrs + AttrFocus + [:name, :rows, :cols, :disabled, :readonly, :onselect, :onchange],
64
+ fieldset: Attrs,
65
+ legend: Attrs + [:accesskey],
66
+ button: Attrs + AttrFocus + [:name, :value, :type, :disabled],
67
+ table: Attrs + [:summary, :width, :border, :frame, :rules, :cellspacing, :cellpadding],
68
+ caption: Attrs,
69
+ colgroup: Attrs + AttrHAlign + AttrVAlign + [:span, :width],
70
+ col: Attrs + AttrHAlign + AttrVAlign + [:span, :width],
71
+ thead: Attrs + AttrHAlign + AttrVAlign,
72
+ tfoot: Attrs + AttrHAlign + AttrVAlign,
73
+ tbody: Attrs + AttrHAlign + AttrVAlign,
74
+ tr: Attrs + AttrHAlign + AttrVAlign,
75
+ th: Attrs + AttrHAlign + AttrVAlign + [:abbr, :axis, :headers, :scope, :rowspan, :colspan],
76
+ td: Attrs + AttrHAlign + AttrVAlign + [:abbr, :axis, :headers, :scope, :rowspan, :colspan],
77
+ h1: Attrs,
78
+ h2: Attrs,
79
+ h3: Attrs,
80
+ h4: Attrs,
81
+ h5: Attrs,
82
+ h6: Attrs
83
+ }
84
+
85
+ @tags = @tagset.keys
86
+ @forms = @tags & FORM_TAGS
87
+ @self_closing = @tags & SELF_CLOSING_TAGS
88
+ end
89
+ end