2007-07-05 00:36:59 +02:00
|
|
|
require 'html5/filters/base'
|
2007-06-14 06:05:15 +02:00
|
|
|
|
2007-07-05 00:36:59 +02:00
|
|
|
module HTML5
|
2007-06-14 06:05:15 +02:00
|
|
|
module Filters
|
|
|
|
class InjectMetaCharset < Base
|
|
|
|
def initialize(source, encoding)
|
|
|
|
super(source)
|
|
|
|
@encoding = encoding
|
|
|
|
end
|
|
|
|
|
|
|
|
def each
|
|
|
|
state = :pre_head
|
|
|
|
meta_found = @encoding.nil?
|
|
|
|
pending = []
|
|
|
|
|
|
|
|
__getobj__.each do |token|
|
|
|
|
case token[:type]
|
|
|
|
when :StartTag
|
|
|
|
state = :in_head if token[:name].downcase == "head"
|
|
|
|
|
|
|
|
when :EmptyTag
|
|
|
|
if token[:name].downcase == "meta"
|
2007-06-22 10:12:08 +02:00
|
|
|
# replace charset with actual encoding
|
2007-08-30 19:19:10 +02:00
|
|
|
token[:data].each_with_index do |(name, value), index|
|
2007-06-22 10:12:08 +02:00
|
|
|
if name == 'charset'
|
2007-08-30 19:19:10 +02:00
|
|
|
token[:data][index][1] = @encoding
|
2007-06-22 10:12:08 +02:00
|
|
|
meta_found = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# replace charset with actual encoding
|
|
|
|
has_http_equiv_content_type = false
|
|
|
|
content_index = -1
|
2007-08-30 19:19:10 +02:00
|
|
|
token[:data].each_with_index do |(name, value), i|
|
2007-06-22 10:12:08 +02:00
|
|
|
if name.downcase == 'charset'
|
|
|
|
token[:data][i] = ['charset', @encoding]
|
|
|
|
meta_found = true
|
|
|
|
break
|
|
|
|
elsif name == 'http-equiv' and value.downcase == 'content-type'
|
|
|
|
has_http_equiv_content_type = true
|
|
|
|
elsif name == 'content'
|
|
|
|
content_index = i
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2007-08-30 19:19:10 +02:00
|
|
|
if !meta_found
|
|
|
|
if has_http_equiv_content_type && content_index >= 0
|
|
|
|
token[:data][content_index][1] = 'text/html; charset=%s' % @encoding
|
2007-06-22 10:12:08 +02:00
|
|
|
meta_found = true
|
|
|
|
end
|
2007-06-14 06:05:15 +02:00
|
|
|
end
|
|
|
|
|
2007-08-30 19:19:10 +02:00
|
|
|
elsif token[:name].downcase == "head" && !meta_found
|
2007-06-14 06:05:15 +02:00
|
|
|
# insert meta into empty head
|
2007-08-30 19:19:10 +02:00
|
|
|
yield :type => :StartTag, :name => "head", :data => token[:data]
|
|
|
|
yield :type => :EmptyTag, :name => "meta", :data => [["charset", @encoding]]
|
|
|
|
yield :type => :EndTag, :name => "head"
|
2007-06-14 06:05:15 +02:00
|
|
|
meta_found = true
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
|
|
|
when :EndTag
|
2007-08-30 19:19:10 +02:00
|
|
|
if token[:name].downcase == "head" && pending.any?
|
2007-06-14 06:05:15 +02:00
|
|
|
# insert meta into head (if necessary) and flush pending queue
|
|
|
|
yield pending.shift
|
2007-08-30 19:19:10 +02:00
|
|
|
yield :type => :EmptyTag, :name => "meta", :data => [["charset", @encoding]] if !meta_found
|
2007-06-14 06:05:15 +02:00
|
|
|
yield pending.shift while pending.any?
|
|
|
|
meta_found = true
|
|
|
|
state = :post_head
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if state == :in_head
|
|
|
|
pending << token
|
|
|
|
else
|
|
|
|
yield token
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|